blob: 278e42899ab70295a0af17c0dfe21c819ce817ef [file] [log] [blame]
Steven Cooreman37941cb2020-07-28 18:49:51 +02001/*
2 * Test driver for cipher functions.
3 * Currently only supports multi-part operations using AES-CTR.
4 */
Steven Cooreman3ec40182020-09-02 16:27:46 +02005/* Copyright The Mbed TLS Contributors
Steven Cooreman37941cb2020-07-28 18:49:51 +02006 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
Steven Cooreman37941cb2020-07-28 18:49:51 +020019 */
20
21#if !defined(MBEDTLS_CONFIG_FILE)
22#include "mbedtls/config.h"
23#else
24#include MBEDTLS_CONFIG_FILE
25#endif
26
27#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(PSA_CRYPTO_DRIVER_TEST)
28#include "psa/crypto.h"
29#include "mbedtls/cipher.h"
30
31#include "drivers/cipher.h"
32
33#include "test/random.h"
34
35#include <string.h>
36
37/* If non-null, on success, copy this to the output. */
38void *test_driver_cipher_forced_output = NULL;
39size_t test_driver_cipher_forced_output_length = 0;
40
Steven Cooreman8b122252020-09-03 15:30:32 +020041/* Test driver implements AES-CTR by default when it's status is not overridden.
42 * Set test_transparent_cipher_status to PSA_ERROR_NOT_SUPPORTED to use fallback
43 * even for AES-CTR.
44 * Keep in mind this code is only exercised during the crypto drivers test target,
45 * meaning the other test runs will still test only the non-driver implementation. */
46psa_status_t test_transparent_cipher_status = PSA_SUCCESS;
Steven Cooreman37941cb2020-07-28 18:49:51 +020047unsigned long test_transparent_cipher_hit = 0;
48
49psa_status_t test_transparent_cipher_encrypt(
50 const psa_key_attributes_t *attributes,
51 const uint8_t *key, size_t key_length,
52 psa_algorithm_t alg,
53 const uint8_t *input, size_t input_length,
54 uint8_t *output, size_t output_size, size_t *output_length)
55{
56 (void) attributes;
57 (void) key;
58 (void) key_length;
59 (void) alg;
60 (void) input;
61 (void) input_length;
62 test_transparent_cipher_hit++;
63
64 if( test_transparent_cipher_status != PSA_SUCCESS )
65 return test_transparent_cipher_status;
66 if( output_size < test_driver_cipher_forced_output_length )
67 return PSA_ERROR_BUFFER_TOO_SMALL;
68
69 memcpy(output, test_driver_cipher_forced_output, test_driver_cipher_forced_output_length);
70 *output_length = test_driver_cipher_forced_output_length;
71
72 return test_transparent_cipher_status;
73}
74
75psa_status_t test_transparent_cipher_decrypt(
76 const psa_key_attributes_t *attributes,
77 const uint8_t *key, size_t key_length,
78 psa_algorithm_t alg,
79 const uint8_t *input, size_t input_length,
80 uint8_t *output, size_t output_size, size_t *output_length)
81{
82 (void) attributes;
83 (void) key;
84 (void) key_length;
85 (void) alg;
86 (void) input;
87 (void) input_length;
88 test_transparent_cipher_hit++;
89
90 if( test_transparent_cipher_status != PSA_SUCCESS )
91 return test_transparent_cipher_status;
92 if( output_size < test_driver_cipher_forced_output_length )
93 return PSA_ERROR_BUFFER_TOO_SMALL;
94
95 memcpy(output, test_driver_cipher_forced_output, test_driver_cipher_forced_output_length);
96 *output_length = test_driver_cipher_forced_output_length;
97
98 return test_transparent_cipher_status;
99}
100
101psa_status_t test_transparent_cipher_encrypt_setup(
102 test_transparent_cipher_operation_t *operation,
103 const psa_key_attributes_t *attributes,
104 const uint8_t *key, size_t key_length,
105 psa_algorithm_t alg)
106{
Steven Cooreman8b122252020-09-03 15:30:32 +0200107 const mbedtls_cipher_info_t *cipher_info = NULL;
108 int ret = 0;
Steven Cooreman37941cb2020-07-28 18:49:51 +0200109
110 test_transparent_cipher_hit++;
Steven Cooreman8b122252020-09-03 15:30:32 +0200111
112 if( operation->alg != 0 )
113 return PSA_ERROR_BAD_STATE;
114
115 /* write our struct, this will trigger memory corruption failures
116 * in test when we go outside of bounds, or when the function is called
117 * without first destroying the context object. */
118 memset(operation, 0, sizeof(test_transparent_cipher_operation_t));
119
120 /* Test driver supports AES-CTR only, to verify operation calls. */
121 if( alg != PSA_ALG_CTR || psa_get_key_type( attributes ) != PSA_KEY_TYPE_AES )
122 return PSA_ERROR_NOT_SUPPORTED;
123
124 operation->alg = alg;
125 operation->iv_size = 16;
126 operation->block_size = 16;
127
128 cipher_info = mbedtls_cipher_info_from_values( MBEDTLS_CIPHER_ID_AES,
129 key_length * 8,
130 MBEDTLS_MODE_CTR );
131 if( cipher_info == NULL )
132 return PSA_ERROR_NOT_SUPPORTED;
133
134 mbedtls_cipher_init( &operation->cipher );
135
136 ret = mbedtls_cipher_setup( &operation->cipher, cipher_info );
137 if( ret != 0 ) {
138 mbedtls_cipher_free( &operation->cipher );
139 return mbedtls_to_psa_error( ret );
140 }
141
142 ret = mbedtls_cipher_setkey( &operation->cipher,
143 key,
144 key_length * 8, MBEDTLS_ENCRYPT );
145 if( ret != 0 ) {
146 mbedtls_cipher_free( &operation->cipher );
147 return mbedtls_to_psa_error( ret );
148 }
149
150 operation->iv_set = 0;
151 operation->iv_required = 1;
152 operation->key_set = 1;
153
154 /* Allow overriding return value for testing purposes */
155 if( test_transparent_cipher_status != PSA_SUCCESS )
156 mbedtls_cipher_free( &operation->cipher );
157
Steven Cooreman37941cb2020-07-28 18:49:51 +0200158 return test_transparent_cipher_status;
159}
160
161psa_status_t test_transparent_cipher_decrypt_setup(
162 test_transparent_cipher_operation_t *operation,
163 const psa_key_attributes_t *attributes,
164 const uint8_t *key, size_t key_length,
165 psa_algorithm_t alg)
166{
Steven Cooreman8b122252020-09-03 15:30:32 +0200167const mbedtls_cipher_info_t *cipher_info = NULL;
168 int ret = 0;
Steven Cooreman37941cb2020-07-28 18:49:51 +0200169
170 test_transparent_cipher_hit++;
Steven Cooreman8b122252020-09-03 15:30:32 +0200171
172 if( operation->alg != 0 )
173 return PSA_ERROR_BAD_STATE;
174
175 /* write our struct, this will trigger memory corruption failures
176 * in test when we go outside of bounds, or when the function is called
177 * without first destroying the context object. */
178 memset(operation, 0, sizeof(test_transparent_cipher_operation_t));
179
180 /* Test driver supports AES-CTR only, to verify operation calls. */
181 if( alg != PSA_ALG_CTR || psa_get_key_type( attributes ) != PSA_KEY_TYPE_AES )
182 return PSA_ERROR_NOT_SUPPORTED;
183
184 operation->alg = alg;
185 operation->iv_size = 16;
186 operation->block_size = 16;
187
188 mbedtls_cipher_init( &operation->cipher );
189
190 cipher_info = mbedtls_cipher_info_from_values( MBEDTLS_CIPHER_ID_AES,
191 key_length * 8,
192 MBEDTLS_MODE_CTR );
193 if( cipher_info == NULL )
194 return PSA_ERROR_NOT_SUPPORTED;
195
196 ret = mbedtls_cipher_setup( &operation->cipher, cipher_info );
197 if( ret != 0 )
198 return mbedtls_to_psa_error( ret );
199
200 ret = mbedtls_cipher_setkey( &operation->cipher,
201 key,
202 key_length * 8, MBEDTLS_DECRYPT );
203 if( ret != 0 )
204 return mbedtls_to_psa_error( ret );
205
206 operation->iv_set = 0;
207 operation->iv_required = 1;
208 operation->key_set = 1;
209
210 /* Allow overriding return value for testing purposes */
211 if( test_transparent_cipher_status != PSA_SUCCESS )
212 mbedtls_cipher_free( &operation->cipher );
213
Steven Cooreman37941cb2020-07-28 18:49:51 +0200214 return test_transparent_cipher_status;
215}
216
217psa_status_t test_transparent_cipher_abort(
218 test_transparent_cipher_operation_t *operation)
219{
Steven Cooreman8b122252020-09-03 15:30:32 +0200220 if( operation->alg == 0 )
221 return( PSA_SUCCESS );
222 if( operation->alg != PSA_ALG_CTR )
223 return( PSA_ERROR_BAD_STATE );
224
225 mbedtls_cipher_free( &operation->cipher );
226
Steven Cooreman37941cb2020-07-28 18:49:51 +0200227 /* write our struct, this will trigger memory corruption failures
228 * in test when we go outside of bounds. */
229 memset(operation, 0, sizeof(test_transparent_cipher_operation_t));
230
231 test_transparent_cipher_hit++;
Steven Cooreman8b122252020-09-03 15:30:32 +0200232 return PSA_SUCCESS;
Steven Cooreman37941cb2020-07-28 18:49:51 +0200233}
234
235psa_status_t test_transparent_cipher_generate_iv(
236 test_transparent_cipher_operation_t *operation,
237 uint8_t *iv,
238 size_t iv_size,
239 size_t *iv_length)
240{
Steven Cooreman8b122252020-09-03 15:30:32 +0200241 psa_status_t status;
242 mbedtls_test_rnd_pseudo_info rnd_info;
243 memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
Steven Cooreman37941cb2020-07-28 18:49:51 +0200244
245 test_transparent_cipher_hit++;
Steven Cooreman8b122252020-09-03 15:30:32 +0200246
247 if( operation->alg != PSA_ALG_CTR )
248 return( PSA_ERROR_BAD_STATE );
249
250 if( operation->iv_set || ! operation->iv_required )
251 return( PSA_ERROR_BAD_STATE );
252
253 if( iv_size < operation->iv_size )
254 return( PSA_ERROR_BUFFER_TOO_SMALL );
255
256 status = mbedtls_to_psa_error(
257 mbedtls_test_rnd_pseudo_rand( &rnd_info,
258 iv,
259 operation->iv_size ) );
260 if( status != PSA_SUCCESS )
261 return status;
262
263 *iv_length = operation->iv_size;
264 status = test_transparent_cipher_set_iv( operation, iv, *iv_length );
265
266 return status;
Steven Cooreman37941cb2020-07-28 18:49:51 +0200267}
268
269psa_status_t test_transparent_cipher_set_iv(
270 test_transparent_cipher_operation_t *operation,
271 const uint8_t *iv,
272 size_t iv_length)
273{
Steven Cooreman8b122252020-09-03 15:30:32 +0200274 psa_status_t status;
Steven Cooreman37941cb2020-07-28 18:49:51 +0200275
276 test_transparent_cipher_hit++;
Steven Cooreman8b122252020-09-03 15:30:32 +0200277
278 if( operation->alg != PSA_ALG_CTR )
279 return PSA_ERROR_BAD_STATE;
280
281 if( operation->iv_set || ! operation->iv_required )
282 return( PSA_ERROR_BAD_STATE );
283
284 if( iv_length != operation->iv_size )
285 return( PSA_ERROR_INVALID_ARGUMENT );
286
287 status = mbedtls_to_psa_error(
288 mbedtls_cipher_set_iv( &operation->cipher, iv, iv_length ) );
289
290 if( status == PSA_SUCCESS )
291 operation->iv_set = 1;
292
293 return status;
Steven Cooreman37941cb2020-07-28 18:49:51 +0200294}
295
296psa_status_t test_transparent_cipher_update(
297 test_transparent_cipher_operation_t *operation,
298 const uint8_t *input,
299 size_t input_length,
300 uint8_t *output,
301 size_t output_size,
302 size_t *output_length)
303{
Steven Cooreman8b122252020-09-03 15:30:32 +0200304 size_t expected_output_size;
305 psa_status_t status;
306
Steven Cooreman37941cb2020-07-28 18:49:51 +0200307 test_transparent_cipher_hit++;
308
Steven Cooreman8b122252020-09-03 15:30:32 +0200309 if( operation->alg != PSA_ALG_CTR )
310 return( PSA_ERROR_BAD_STATE );
Steven Cooreman37941cb2020-07-28 18:49:51 +0200311
Steven Cooreman8b122252020-09-03 15:30:32 +0200312 expected_output_size = ( operation->cipher.unprocessed_len + input_length )
313 / operation->block_size * operation->block_size;
314
315 if( output_size < expected_output_size )
316 return( PSA_ERROR_BUFFER_TOO_SMALL );
317
318 status = mbedtls_to_psa_error(
319 mbedtls_cipher_update( &operation->cipher, input,
320 input_length, output, output_length ) );
321
322 if( status != PSA_SUCCESS )
323 return status;
324
325 if( test_driver_cipher_forced_output != NULL )
326 {
327 if( output_size < test_driver_cipher_forced_output_length )
328 return PSA_ERROR_BUFFER_TOO_SMALL;
329
330 memcpy(output, test_driver_cipher_forced_output, test_driver_cipher_forced_output_length);
331 *output_length = test_driver_cipher_forced_output_length;
332 }
Steven Cooreman37941cb2020-07-28 18:49:51 +0200333
334 return test_transparent_cipher_status;
335}
336
337psa_status_t test_transparent_cipher_finish(
338 test_transparent_cipher_operation_t *operation,
339 uint8_t *output,
340 size_t output_size,
341 size_t *output_length)
342{
Steven Cooreman8b122252020-09-03 15:30:32 +0200343 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
344 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
345
Steven Cooreman37941cb2020-07-28 18:49:51 +0200346 test_transparent_cipher_hit++;
347
Steven Cooreman8b122252020-09-03 15:30:32 +0200348 if( operation->alg != PSA_ALG_CTR )
349 return( PSA_ERROR_BAD_STATE );
Steven Cooreman37941cb2020-07-28 18:49:51 +0200350
Steven Cooreman8b122252020-09-03 15:30:32 +0200351 if( ! operation->key_set )
352 return( PSA_ERROR_BAD_STATE );
353
354 if( operation->iv_required && ! operation->iv_set )
355 return( PSA_ERROR_BAD_STATE );
356
357 status = mbedtls_to_psa_error(
358 mbedtls_cipher_finish( &operation->cipher,
359 temp_output_buffer,
360 output_length ) );
361
362 mbedtls_cipher_free( &operation->cipher );
363
364 if( status != PSA_SUCCESS )
365 return( status );
366
367 if( *output_length == 0 )
368 ; /* Nothing to copy. Note that output may be NULL in this case. */
369 else if( output_size >= *output_length )
370 memcpy( output, temp_output_buffer, *output_length );
371 else
372 return( PSA_ERROR_BUFFER_TOO_SMALL );
373
374
375 if( test_driver_cipher_forced_output != NULL )
376 {
377 if( output_size < test_driver_cipher_forced_output_length )
378 return PSA_ERROR_BUFFER_TOO_SMALL;
379
380 memcpy(output, test_driver_cipher_forced_output, test_driver_cipher_forced_output_length);
381 *output_length = test_driver_cipher_forced_output_length;
382 }
Steven Cooreman37941cb2020-07-28 18:49:51 +0200383
384 return test_transparent_cipher_status;
385}
386
387/*
388 * opaque versions, to do
389 */
390psa_status_t test_opaque_cipher_encrypt(
391 const psa_key_attributes_t *attributes,
392 const uint8_t *key, size_t key_length,
393 psa_algorithm_t alg,
394 const uint8_t *input, size_t input_length,
395 uint8_t *output, size_t output_size, size_t *output_length)
396{
397 (void) attributes;
398 (void) key;
399 (void) key_length;
400 (void) alg;
401 (void) input;
402 (void) input_length;
403 (void) output;
404 (void) output_size;
405 (void) output_length;
406 return PSA_ERROR_NOT_SUPPORTED;
407}
408
409psa_status_t test_opaque_cipher_decrypt(
410 const psa_key_attributes_t *attributes,
411 const uint8_t *key, size_t key_length,
412 psa_algorithm_t alg,
413 const uint8_t *input, size_t input_length,
414 uint8_t *output, size_t output_size, size_t *output_length)
415{
416 (void) attributes;
417 (void) key;
418 (void) key_length;
419 (void) alg;
420 (void) input;
421 (void) input_length;
422 (void) output;
423 (void) output_size;
424 (void) output_length;
425 return PSA_ERROR_NOT_SUPPORTED;
426}
427
428psa_status_t test_opaque_cipher_encrypt_setup(
429 test_opaque_cipher_operation_t *operation,
430 const psa_key_attributes_t *attributes,
431 const uint8_t *key, size_t key_length,
432 psa_algorithm_t alg)
433{
434 (void) operation;
435 (void) attributes;
436 (void) key;
437 (void) key_length;
438 (void) alg;
439 return PSA_ERROR_NOT_SUPPORTED;
440}
441
442psa_status_t test_opaque_cipher_decrypt_setup(
443 test_opaque_cipher_operation_t *operation,
444 const psa_key_attributes_t *attributes,
445 const uint8_t *key, size_t key_length,
446 psa_algorithm_t alg)
447{
448 (void) operation;
449 (void) attributes;
450 (void) key;
451 (void) key_length;
452 (void) alg;
453 return PSA_ERROR_NOT_SUPPORTED;
454}
455
456psa_status_t test_opaque_cipher_abort(
457 test_opaque_cipher_operation_t *operation)
458{
459 (void) operation;
460 return PSA_ERROR_NOT_SUPPORTED;
461}
462
463psa_status_t test_opaque_cipher_generate_iv(
464 test_opaque_cipher_operation_t *operation,
465 uint8_t *iv,
466 size_t iv_size,
467 size_t *iv_length)
468{
469 (void) operation;
470 (void) iv;
471 (void) iv_size;
472 (void) iv_length;
473 return PSA_ERROR_NOT_SUPPORTED;
474}
475
476psa_status_t test_opaque_cipher_set_iv(
477 test_opaque_cipher_operation_t *operation,
478 const uint8_t *iv,
479 size_t iv_length)
480{
481 (void) operation;
482 (void) iv;
483 (void) iv_length;
484 return PSA_ERROR_NOT_SUPPORTED;
485}
486
487psa_status_t test_opaque_cipher_update(
488 test_opaque_cipher_operation_t *operation,
489 const uint8_t *input,
490 size_t input_length,
491 uint8_t *output,
492 size_t output_size,
493 size_t *output_length)
494{
495 (void) operation;
496 (void) input;
497 (void) input_length;
498 (void) output;
499 (void) output_size;
500 (void) output_length;
501 return PSA_ERROR_NOT_SUPPORTED;
502}
503
504psa_status_t test_opaque_cipher_finish(
505 test_opaque_cipher_operation_t *operation,
506 uint8_t *output,
507 size_t output_size,
508 size_t *output_length)
509{
510 (void) operation;
511 (void) output;
512 (void) output_size;
513 (void) output_length;
514 return PSA_ERROR_NOT_SUPPORTED;
515}
516#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */