1 /** Code to exercise a PSA key object, i.e. validate that it seems well-formed
2 * and can do what it is supposed to do.
3 */
4
5 /*
6 * Copyright The Mbed TLS Contributors
7 * SPDX-License-Identifier: Apache-2.0
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
10 * not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21
22 #include <test/helpers.h>
23 #include <test/macros.h>
24 #include <test/psa_exercise_key.h>
25
26 #if defined(MBEDTLS_PSA_CRYPTO_C)
27
28 #include <mbedtls/asn1.h>
29 #include <psa/crypto.h>
30
31 #include <test/asn1_helpers.h>
32 #include <psa_crypto_slot_management.h>
33 #include <test/psa_crypto_helpers.h>
34
35 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)36 static int lifetime_is_dynamic_secure_element( psa_key_lifetime_t lifetime )
37 {
38 return( PSA_KEY_LIFETIME_GET_LOCATION( lifetime ) !=
39 PSA_KEY_LOCATION_LOCAL_STORAGE );
40 }
41 #endif
42
check_key_attributes_sanity(mbedtls_svc_key_id_t key)43 static int check_key_attributes_sanity( mbedtls_svc_key_id_t key )
44 {
45 int ok = 0;
46 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
47 psa_key_lifetime_t lifetime;
48 mbedtls_svc_key_id_t id;
49 psa_key_type_t type;
50 size_t bits;
51
52 PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
53 lifetime = psa_get_key_lifetime( &attributes );
54 id = psa_get_key_id( &attributes );
55 type = psa_get_key_type( &attributes );
56 bits = psa_get_key_bits( &attributes );
57
58 /* Persistence */
59 if( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) )
60 {
61 TEST_ASSERT(
62 ( PSA_KEY_ID_VOLATILE_MIN <=
63 MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) ) &&
64 ( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) <=
65 PSA_KEY_ID_VOLATILE_MAX ) );
66 }
67 else
68 {
69 TEST_ASSERT(
70 ( PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) ) &&
71 ( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) <= PSA_KEY_ID_USER_MAX ) );
72 }
73 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
74 /* randomly-generated 64-bit constant, should never appear in test data */
75 psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
76 psa_status_t status = psa_get_key_slot_number( &attributes, &slot_number );
77 if( lifetime_is_dynamic_secure_element( lifetime ) )
78 {
79 /* Mbed Crypto currently always exposes the slot number to
80 * applications. This is not mandated by the PSA specification
81 * and may change in future versions. */
82 TEST_EQUAL( status, 0 );
83 TEST_ASSERT( slot_number != 0xec94d4a5058a1a21 );
84 }
85 else
86 {
87 TEST_EQUAL( status, PSA_ERROR_INVALID_ARGUMENT );
88 }
89 #endif
90
91 /* Type and size */
92 TEST_ASSERT( type != 0 );
93 TEST_ASSERT( bits != 0 );
94 TEST_ASSERT( bits <= PSA_MAX_KEY_BITS );
95 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
96 TEST_ASSERT( bits % 8 == 0 );
97
98 /* MAX macros concerning specific key types */
99 if( PSA_KEY_TYPE_IS_ECC( type ) )
100 TEST_ASSERT( bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS );
101 else if( PSA_KEY_TYPE_IS_RSA( type ) )
102 TEST_ASSERT( bits <= PSA_VENDOR_RSA_MAX_KEY_BITS );
103 TEST_ASSERT( PSA_BLOCK_CIPHER_BLOCK_LENGTH( type ) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE );
104
105 ok = 1;
106
107 exit:
108 /*
109 * Key attributes may have been returned by psa_get_key_attributes()
110 * thus reset them as required.
111 */
112 psa_reset_key_attributes( &attributes );
113
114 return( ok );
115 }
116
exercise_mac_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)117 static int exercise_mac_key( mbedtls_svc_key_id_t key,
118 psa_key_usage_t usage,
119 psa_algorithm_t alg )
120 {
121 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
122 const unsigned char input[] = "foo";
123 unsigned char mac[PSA_MAC_MAX_SIZE] = {0};
124 size_t mac_length = sizeof( mac );
125
126 /* Convert wildcard algorithm to exercisable algorithm */
127 if( alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG )
128 {
129 alg = PSA_ALG_TRUNCATED_MAC( alg, PSA_MAC_TRUNCATED_LENGTH( alg ) );
130 }
131
132 if( usage & PSA_KEY_USAGE_SIGN_HASH )
133 {
134 PSA_ASSERT( psa_mac_sign_setup( &operation, key, alg ) );
135 PSA_ASSERT( psa_mac_update( &operation,
136 input, sizeof( input ) ) );
137 PSA_ASSERT( psa_mac_sign_finish( &operation,
138 mac, sizeof( mac ),
139 &mac_length ) );
140 }
141
142 if( usage & PSA_KEY_USAGE_VERIFY_HASH )
143 {
144 psa_status_t verify_status =
145 ( usage & PSA_KEY_USAGE_SIGN_HASH ?
146 PSA_SUCCESS :
147 PSA_ERROR_INVALID_SIGNATURE );
148 PSA_ASSERT( psa_mac_verify_setup( &operation, key, alg ) );
149 PSA_ASSERT( psa_mac_update( &operation,
150 input, sizeof( input ) ) );
151 TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
152 verify_status );
153 }
154
155 return( 1 );
156
157 exit:
158 psa_mac_abort( &operation );
159 return( 0 );
160 }
161
exercise_cipher_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)162 static int exercise_cipher_key( mbedtls_svc_key_id_t key,
163 psa_key_usage_t usage,
164 psa_algorithm_t alg )
165 {
166 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
167 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = {0};
168 size_t iv_length;
169 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
170 psa_key_type_t key_type;
171 const unsigned char plaintext[16] = "Hello, world...";
172 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
173 size_t ciphertext_length = sizeof( ciphertext );
174 unsigned char decrypted[sizeof( ciphertext )];
175 size_t part_length;
176
177 PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
178 key_type = psa_get_key_type( &attributes );
179 iv_length = PSA_CIPHER_IV_LENGTH( key_type, alg );
180
181 if( usage & PSA_KEY_USAGE_ENCRYPT )
182 {
183 PSA_ASSERT( psa_cipher_encrypt_setup( &operation, key, alg ) );
184 if( iv_length != 0 )
185 {
186 PSA_ASSERT( psa_cipher_generate_iv( &operation,
187 iv, sizeof( iv ),
188 &iv_length ) );
189 }
190 PSA_ASSERT( psa_cipher_update( &operation,
191 plaintext, sizeof( plaintext ),
192 ciphertext, sizeof( ciphertext ),
193 &ciphertext_length ) );
194 PSA_ASSERT( psa_cipher_finish( &operation,
195 ciphertext + ciphertext_length,
196 sizeof( ciphertext ) - ciphertext_length,
197 &part_length ) );
198 ciphertext_length += part_length;
199 }
200
201 if( usage & PSA_KEY_USAGE_DECRYPT )
202 {
203 psa_status_t status;
204 int maybe_invalid_padding = 0;
205 if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
206 {
207 maybe_invalid_padding = ! PSA_ALG_IS_STREAM_CIPHER( alg );
208 }
209 PSA_ASSERT( psa_cipher_decrypt_setup( &operation, key, alg ) );
210 if( iv_length != 0 )
211 {
212 PSA_ASSERT( psa_cipher_set_iv( &operation,
213 iv, iv_length ) );
214 }
215 PSA_ASSERT( psa_cipher_update( &operation,
216 ciphertext, ciphertext_length,
217 decrypted, sizeof( decrypted ),
218 &part_length ) );
219 status = psa_cipher_finish( &operation,
220 decrypted + part_length,
221 sizeof( decrypted ) - part_length,
222 &part_length );
223 /* For a stream cipher, all inputs are valid. For a block cipher,
224 * if the input is some arbitrary data rather than an actual
225 ciphertext, a padding error is likely. */
226 if( maybe_invalid_padding )
227 TEST_ASSERT( status == PSA_SUCCESS ||
228 status == PSA_ERROR_INVALID_PADDING );
229 else
230 PSA_ASSERT( status );
231 }
232
233 return( 1 );
234
235 exit:
236 psa_cipher_abort( &operation );
237 psa_reset_key_attributes( &attributes );
238 return( 0 );
239 }
240
exercise_aead_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)241 static int exercise_aead_key( mbedtls_svc_key_id_t key,
242 psa_key_usage_t usage,
243 psa_algorithm_t alg )
244 {
245 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = {0};
246 size_t nonce_length;
247 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
248 psa_key_type_t key_type;
249 unsigned char plaintext[16] = "Hello, world...";
250 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
251 size_t ciphertext_length = sizeof( ciphertext );
252 size_t plaintext_length = sizeof( ciphertext );
253
254 /* Convert wildcard algorithm to exercisable algorithm */
255 if( alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG )
256 {
257 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, PSA_ALG_AEAD_GET_TAG_LENGTH( alg ) );
258 }
259
260 PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
261 key_type = psa_get_key_type( &attributes );
262 nonce_length = PSA_AEAD_NONCE_LENGTH( key_type, alg );
263
264 if( usage & PSA_KEY_USAGE_ENCRYPT )
265 {
266 PSA_ASSERT( psa_aead_encrypt( key, alg,
267 nonce, nonce_length,
268 NULL, 0,
269 plaintext, sizeof( plaintext ),
270 ciphertext, sizeof( ciphertext ),
271 &ciphertext_length ) );
272 }
273
274 if( usage & PSA_KEY_USAGE_DECRYPT )
275 {
276 psa_status_t verify_status =
277 ( usage & PSA_KEY_USAGE_ENCRYPT ?
278 PSA_SUCCESS :
279 PSA_ERROR_INVALID_SIGNATURE );
280 TEST_EQUAL( psa_aead_decrypt( key, alg,
281 nonce, nonce_length,
282 NULL, 0,
283 ciphertext, ciphertext_length,
284 plaintext, sizeof( plaintext ),
285 &plaintext_length ),
286 verify_status );
287 }
288
289 return( 1 );
290
291 exit:
292 psa_reset_key_attributes( &attributes );
293 return( 0 );
294 }
295
can_sign_or_verify_message(psa_key_usage_t usage,psa_algorithm_t alg)296 static int can_sign_or_verify_message( psa_key_usage_t usage,
297 psa_algorithm_t alg )
298 {
299 /* Sign-the-unspecified-hash algorithms can only be used with
300 * {sign,verify}_hash, not with {sign,verify}_message. */
301 if( alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
302 return( 0 );
303 return( usage & ( PSA_KEY_USAGE_SIGN_MESSAGE |
304 PSA_KEY_USAGE_VERIFY_MESSAGE ) );
305 }
306
exercise_signature_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)307 static int exercise_signature_key( mbedtls_svc_key_id_t key,
308 psa_key_usage_t usage,
309 psa_algorithm_t alg )
310 {
311 if( usage & ( PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH ) )
312 {
313 unsigned char payload[PSA_HASH_MAX_SIZE] = {1};
314 size_t payload_length = 16;
315 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = {0};
316 size_t signature_length = sizeof( signature );
317 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
318
319 /* If the policy allows signing with any hash, just pick one. */
320 if( PSA_ALG_IS_SIGN_HASH( alg ) && hash_alg == PSA_ALG_ANY_HASH )
321 {
322 #if defined(KNOWN_SUPPORTED_HASH_ALG)
323 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
324 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
325 #else
326 TEST_ASSERT( ! "No hash algorithm for hash-and-sign testing" );
327 #endif
328 }
329
330 /* Some algorithms require the payload to have the size of
331 * the hash encoded in the algorithm. Use this input size
332 * even for algorithms that allow other input sizes. */
333 if( hash_alg != 0 )
334 payload_length = PSA_HASH_LENGTH( hash_alg );
335
336 if( usage & PSA_KEY_USAGE_SIGN_HASH )
337 {
338 PSA_ASSERT( psa_sign_hash( key, alg,
339 payload, payload_length,
340 signature, sizeof( signature ),
341 &signature_length ) );
342 }
343
344 if( usage & PSA_KEY_USAGE_VERIFY_HASH )
345 {
346 psa_status_t verify_status =
347 ( usage & PSA_KEY_USAGE_SIGN_HASH ?
348 PSA_SUCCESS :
349 PSA_ERROR_INVALID_SIGNATURE );
350 TEST_EQUAL( psa_verify_hash( key, alg,
351 payload, payload_length,
352 signature, signature_length ),
353 verify_status );
354 }
355 }
356
357 if( can_sign_or_verify_message( usage, alg ) )
358 {
359 unsigned char message[256] = "Hello, world...";
360 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = {0};
361 size_t message_length = 16;
362 size_t signature_length = sizeof( signature );
363
364 if( usage & PSA_KEY_USAGE_SIGN_MESSAGE )
365 {
366 PSA_ASSERT( psa_sign_message( key, alg,
367 message, message_length,
368 signature, sizeof( signature ),
369 &signature_length ) );
370 }
371
372 if( usage & PSA_KEY_USAGE_VERIFY_MESSAGE )
373 {
374 psa_status_t verify_status =
375 ( usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
376 PSA_SUCCESS :
377 PSA_ERROR_INVALID_SIGNATURE );
378 TEST_EQUAL( psa_verify_message( key, alg,
379 message, message_length,
380 signature, signature_length ),
381 verify_status );
382 }
383 }
384
385 return( 1 );
386
387 exit:
388 return( 0 );
389 }
390
exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)391 static int exercise_asymmetric_encryption_key( mbedtls_svc_key_id_t key,
392 psa_key_usage_t usage,
393 psa_algorithm_t alg )
394 {
395 unsigned char plaintext[256] = "Hello, world...";
396 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
397 size_t ciphertext_length = sizeof( ciphertext );
398 size_t plaintext_length = 16;
399
400 if( usage & PSA_KEY_USAGE_ENCRYPT )
401 {
402 PSA_ASSERT( psa_asymmetric_encrypt( key, alg,
403 plaintext, plaintext_length,
404 NULL, 0,
405 ciphertext, sizeof( ciphertext ),
406 &ciphertext_length ) );
407 }
408
409 if( usage & PSA_KEY_USAGE_DECRYPT )
410 {
411 psa_status_t status =
412 psa_asymmetric_decrypt( key, alg,
413 ciphertext, ciphertext_length,
414 NULL, 0,
415 plaintext, sizeof( plaintext ),
416 &plaintext_length );
417 TEST_ASSERT( status == PSA_SUCCESS ||
418 ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
419 ( status == PSA_ERROR_INVALID_ARGUMENT ||
420 status == PSA_ERROR_INVALID_PADDING ) ) );
421 }
422
423 return( 1 );
424
425 exit:
426 return( 0 );
427 }
428
mbedtls_test_psa_setup_key_derivation_wrap(psa_key_derivation_operation_t * operation,mbedtls_svc_key_id_t key,psa_algorithm_t alg,const unsigned char * input1,size_t input1_length,const unsigned char * input2,size_t input2_length,size_t capacity)429 int mbedtls_test_psa_setup_key_derivation_wrap(
430 psa_key_derivation_operation_t* operation,
431 mbedtls_svc_key_id_t key,
432 psa_algorithm_t alg,
433 const unsigned char* input1, size_t input1_length,
434 const unsigned char* input2, size_t input2_length,
435 size_t capacity )
436 {
437 PSA_ASSERT( psa_key_derivation_setup( operation, alg ) );
438 if( PSA_ALG_IS_HKDF( alg ) )
439 {
440 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
441 PSA_KEY_DERIVATION_INPUT_SALT,
442 input1, input1_length ) );
443 PSA_ASSERT( psa_key_derivation_input_key( operation,
444 PSA_KEY_DERIVATION_INPUT_SECRET,
445 key ) );
446 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
447 PSA_KEY_DERIVATION_INPUT_INFO,
448 input2,
449 input2_length ) );
450 }
451 else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
452 PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
453 {
454 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
455 PSA_KEY_DERIVATION_INPUT_SEED,
456 input1, input1_length ) );
457 PSA_ASSERT( psa_key_derivation_input_key( operation,
458 PSA_KEY_DERIVATION_INPUT_SECRET,
459 key ) );
460 PSA_ASSERT( psa_key_derivation_input_bytes( operation,
461 PSA_KEY_DERIVATION_INPUT_LABEL,
462 input2, input2_length ) );
463 }
464 else
465 {
466 TEST_ASSERT( ! "Key derivation algorithm not supported" );
467 }
468
469 if( capacity != SIZE_MAX )
470 PSA_ASSERT( psa_key_derivation_set_capacity( operation, capacity ) );
471
472 return( 1 );
473
474 exit:
475 return( 0 );
476 }
477
478
exercise_key_derivation_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)479 static int exercise_key_derivation_key( mbedtls_svc_key_id_t key,
480 psa_key_usage_t usage,
481 psa_algorithm_t alg )
482 {
483 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
484 unsigned char input1[] = "Input 1";
485 size_t input1_length = sizeof( input1 );
486 unsigned char input2[] = "Input 2";
487 size_t input2_length = sizeof( input2 );
488 unsigned char output[1];
489 size_t capacity = sizeof( output );
490
491 if( usage & PSA_KEY_USAGE_DERIVE )
492 {
493 if( !mbedtls_test_psa_setup_key_derivation_wrap( &operation, key, alg,
494 input1, input1_length,
495 input2, input2_length,
496 capacity ) )
497 goto exit;
498
499 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
500 output,
501 capacity ) );
502 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
503 }
504
505 return( 1 );
506
507 exit:
508 return( 0 );
509 }
510
511 /* We need two keys to exercise key agreement. Exercise the
512 * private key against its own public key. */
mbedtls_test_psa_key_agreement_with_self(psa_key_derivation_operation_t * operation,mbedtls_svc_key_id_t key)513 psa_status_t mbedtls_test_psa_key_agreement_with_self(
514 psa_key_derivation_operation_t *operation,
515 mbedtls_svc_key_id_t key )
516 {
517 psa_key_type_t private_key_type;
518 psa_key_type_t public_key_type;
519 size_t key_bits;
520 uint8_t *public_key = NULL;
521 size_t public_key_length;
522 /* Return GENERIC_ERROR if something other than the final call to
523 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
524 * but it's good enough: callers will report it as a failed test anyway. */
525 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
526 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
527
528 PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
529 private_key_type = psa_get_key_type( &attributes );
530 key_bits = psa_get_key_bits( &attributes );
531 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
532 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( public_key_type, key_bits );
533 ASSERT_ALLOC( public_key, public_key_length );
534 PSA_ASSERT( psa_export_public_key( key, public_key, public_key_length,
535 &public_key_length ) );
536
537 status = psa_key_derivation_key_agreement(
538 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
539 public_key, public_key_length );
540 exit:
541 /*
542 * Key attributes may have been returned by psa_get_key_attributes()
543 * thus reset them as required.
544 */
545 psa_reset_key_attributes( &attributes );
546
547 mbedtls_free( public_key );
548 return( status );
549 }
550
551 /* We need two keys to exercise key agreement. Exercise the
552 * private key against its own public key. */
mbedtls_test_psa_raw_key_agreement_with_self(psa_algorithm_t alg,mbedtls_svc_key_id_t key)553 psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
554 psa_algorithm_t alg,
555 mbedtls_svc_key_id_t key )
556 {
557 psa_key_type_t private_key_type;
558 psa_key_type_t public_key_type;
559 size_t key_bits;
560 uint8_t *public_key = NULL;
561 size_t public_key_length;
562 uint8_t output[1024];
563 size_t output_length;
564 /* Return GENERIC_ERROR if something other than the final call to
565 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
566 * but it's good enough: callers will report it as a failed test anyway. */
567 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
568 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
569
570 PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
571 private_key_type = psa_get_key_type( &attributes );
572 key_bits = psa_get_key_bits( &attributes );
573 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type );
574 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( public_key_type, key_bits );
575 ASSERT_ALLOC( public_key, public_key_length );
576 PSA_ASSERT( psa_export_public_key( key,
577 public_key, public_key_length,
578 &public_key_length ) );
579
580 status = psa_raw_key_agreement( alg, key,
581 public_key, public_key_length,
582 output, sizeof( output ), &output_length );
583 if ( status == PSA_SUCCESS )
584 {
585 TEST_ASSERT( output_length <=
586 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE( private_key_type,
587 key_bits ) );
588 TEST_ASSERT( output_length <=
589 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE );
590 }
591
592 exit:
593 /*
594 * Key attributes may have been returned by psa_get_key_attributes()
595 * thus reset them as required.
596 */
597 psa_reset_key_attributes( &attributes );
598
599 mbedtls_free( public_key );
600 return( status );
601 }
602
exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)603 static int exercise_raw_key_agreement_key( mbedtls_svc_key_id_t key,
604 psa_key_usage_t usage,
605 psa_algorithm_t alg )
606 {
607 int ok = 0;
608
609 if( usage & PSA_KEY_USAGE_DERIVE )
610 {
611 /* We need two keys to exercise key agreement. Exercise the
612 * private key against its own public key. */
613 PSA_ASSERT( mbedtls_test_psa_raw_key_agreement_with_self( alg, key ) );
614 }
615 ok = 1;
616
617 exit:
618 return( ok );
619 }
620
exercise_key_agreement_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)621 static int exercise_key_agreement_key( mbedtls_svc_key_id_t key,
622 psa_key_usage_t usage,
623 psa_algorithm_t alg )
624 {
625 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
626 unsigned char input[1] = { 0 };
627 unsigned char output[1];
628 int ok = 0;
629 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg );
630 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
631
632 if( usage & PSA_KEY_USAGE_DERIVE )
633 {
634 /* We need two keys to exercise key agreement. Exercise the
635 * private key against its own public key. */
636 PSA_ASSERT( psa_key_derivation_setup( &operation, alg ) );
637 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
638 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
639 {
640 PSA_ASSERT( psa_key_derivation_input_bytes(
641 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
642 input, sizeof( input ) ) );
643 }
644
645 if( PSA_ALG_IS_HKDF_EXTRACT( kdf_alg ) )
646 {
647 PSA_ASSERT( psa_key_derivation_input_bytes(
648 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
649 input, sizeof( input ) ) );
650 }
651
652 /* For HKDF_EXPAND input secret may fail as secret size may not match
653 to expected PRK size. In practice it means that key bits must match
654 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
655 if( PSA_ALG_IS_HKDF_EXPAND( kdf_alg ) )
656 {
657 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
658 PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
659 size_t key_bits = psa_get_key_bits( &attributes );
660 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( kdf_alg );
661
662 if( PSA_BITS_TO_BYTES( key_bits ) != PSA_HASH_LENGTH( hash_alg ) )
663 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
664 }
665
666 TEST_EQUAL( mbedtls_test_psa_key_agreement_with_self( &operation, key ),
667 expected_key_agreement_status );
668
669 if( expected_key_agreement_status != PSA_SUCCESS )
670 return( 1 );
671
672 if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ||
673 PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
674 {
675 PSA_ASSERT( psa_key_derivation_input_bytes(
676 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
677 input, sizeof( input ) ) );
678 }
679 else if( PSA_ALG_IS_HKDF( kdf_alg ) || PSA_ALG_IS_HKDF_EXPAND( kdf_alg ) )
680 {
681 PSA_ASSERT( psa_key_derivation_input_bytes(
682 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
683 input, sizeof( input ) ) );
684 }
685 PSA_ASSERT( psa_key_derivation_output_bytes( &operation,
686 output,
687 sizeof( output ) ) );
688 PSA_ASSERT( psa_key_derivation_abort( &operation ) );
689 }
690 ok = 1;
691
692 exit:
693 return( ok );
694 }
695
mbedtls_test_psa_exported_key_sanity_check(psa_key_type_t type,size_t bits,const uint8_t * exported,size_t exported_length)696 int mbedtls_test_psa_exported_key_sanity_check(
697 psa_key_type_t type, size_t bits,
698 const uint8_t *exported, size_t exported_length )
699 {
700 TEST_ASSERT( exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE( type, bits ) );
701
702 if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
703 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
704 else
705
706 #if defined(MBEDTLS_ASN1_PARSE_C)
707 if( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
708 {
709 uint8_t *p = (uint8_t*) exported;
710 const uint8_t *end = exported + exported_length;
711 size_t len;
712 /* RSAPrivateKey ::= SEQUENCE {
713 * version INTEGER, -- must be 0
714 * modulus INTEGER, -- n
715 * publicExponent INTEGER, -- e
716 * privateExponent INTEGER, -- d
717 * prime1 INTEGER, -- p
718 * prime2 INTEGER, -- q
719 * exponent1 INTEGER, -- d mod (p-1)
720 * exponent2 INTEGER, -- d mod (q-1)
721 * coefficient INTEGER, -- (inverse of q) mod p
722 * }
723 */
724 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
725 MBEDTLS_ASN1_SEQUENCE |
726 MBEDTLS_ASN1_CONSTRUCTED ), 0 );
727 TEST_EQUAL( len, end - p );
728 if( ! mbedtls_test_asn1_skip_integer( &p, end, 0, 0, 0 ) )
729 goto exit;
730 if( ! mbedtls_test_asn1_skip_integer( &p, end, bits, bits, 1 ) )
731 goto exit;
732 if( ! mbedtls_test_asn1_skip_integer( &p, end, 2, bits, 1 ) )
733 goto exit;
734 /* Require d to be at least half the size of n. */
735 if( ! mbedtls_test_asn1_skip_integer( &p, end, bits / 2, bits, 1 ) )
736 goto exit;
737 /* Require p and q to be at most half the size of n, rounded up. */
738 if( ! mbedtls_test_asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
739 goto exit;
740 if( ! mbedtls_test_asn1_skip_integer( &p, end, bits / 2, bits / 2 + 1, 1 ) )
741 goto exit;
742 if( ! mbedtls_test_asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
743 goto exit;
744 if( ! mbedtls_test_asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
745 goto exit;
746 if( ! mbedtls_test_asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
747 goto exit;
748 TEST_EQUAL( p - end, 0 );
749
750 TEST_ASSERT( exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE );
751 }
752 else
753 #endif /* MBEDTLS_ASN1_PARSE_C */
754
755 #if defined(MBEDTLS_ECP_C)
756 if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
757 {
758 /* Just the secret value */
759 TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
760
761 TEST_ASSERT( exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE );
762 }
763 else
764 #endif /* MBEDTLS_ECP_C */
765
766 #if defined(MBEDTLS_ASN1_PARSE_C)
767 if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
768 {
769 uint8_t *p = (uint8_t*) exported;
770 const uint8_t *end = exported + exported_length;
771 size_t len;
772 /* RSAPublicKey ::= SEQUENCE {
773 * modulus INTEGER, -- n
774 * publicExponent INTEGER } -- e
775 */
776 TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
777 MBEDTLS_ASN1_SEQUENCE |
778 MBEDTLS_ASN1_CONSTRUCTED ),
779 0 );
780 TEST_EQUAL( len, end - p );
781 if( ! mbedtls_test_asn1_skip_integer( &p, end, bits, bits, 1 ) )
782 goto exit;
783 if( ! mbedtls_test_asn1_skip_integer( &p, end, 2, bits, 1 ) )
784 goto exit;
785 TEST_EQUAL( p - end, 0 );
786
787
788 TEST_ASSERT( exported_length <=
789 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( type, bits ) );
790 TEST_ASSERT( exported_length <=
791 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE );
792 }
793 else
794 #endif /* MBEDTLS_ASN1_PARSE_C */
795
796 #if defined(MBEDTLS_ECP_C)
797 if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) )
798 {
799
800 TEST_ASSERT( exported_length <=
801 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( type, bits ) );
802 TEST_ASSERT( exported_length <=
803 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE );
804
805 if( PSA_KEY_TYPE_ECC_GET_FAMILY( type ) == PSA_ECC_FAMILY_MONTGOMERY )
806 {
807 /* The representation of an ECC Montgomery public key is
808 * the raw compressed point */
809 TEST_EQUAL( PSA_BITS_TO_BYTES( bits ), exported_length );
810 }
811 else
812 {
813 /* The representation of an ECC Weierstrass public key is:
814 * - The byte 0x04;
815 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
816 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
817 * - where m is the bit size associated with the curve.
818 */
819 TEST_EQUAL( 1 + 2 * PSA_BITS_TO_BYTES( bits ), exported_length );
820 TEST_EQUAL( exported[0], 4 );
821 }
822 }
823 else
824 #endif /* MBEDTLS_ECP_C */
825
826 {
827 (void) exported;
828 TEST_ASSERT( ! "Sanity check not implemented for this key type" );
829 }
830
831 #if defined(MBEDTLS_DES_C)
832 if( type == PSA_KEY_TYPE_DES )
833 {
834 /* Check the parity bits. */
835 unsigned i;
836 for( i = 0; i < bits / 8; i++ )
837 {
838 unsigned bit_count = 0;
839 unsigned m;
840 for( m = 1; m <= 0x100; m <<= 1 )
841 {
842 if( exported[i] & m )
843 ++bit_count;
844 }
845 TEST_ASSERT( bit_count % 2 != 0 );
846 }
847 }
848 #endif
849
850 return( 1 );
851
852 exit:
853 return( 0 );
854 }
855
exercise_export_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage)856 static int exercise_export_key( mbedtls_svc_key_id_t key,
857 psa_key_usage_t usage )
858 {
859 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
860 uint8_t *exported = NULL;
861 size_t exported_size = 0;
862 size_t exported_length = 0;
863 int ok = 0;
864
865 PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
866
867 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
868 psa_get_key_type( &attributes ),
869 psa_get_key_bits( &attributes ) );
870 ASSERT_ALLOC( exported, exported_size );
871
872 if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
873 ! PSA_KEY_TYPE_IS_PUBLIC_KEY( psa_get_key_type( &attributes ) ) )
874 {
875 TEST_EQUAL( psa_export_key( key, exported,
876 exported_size, &exported_length ),
877 PSA_ERROR_NOT_PERMITTED );
878 ok = 1;
879 goto exit;
880 }
881
882 PSA_ASSERT( psa_export_key( key,
883 exported, exported_size,
884 &exported_length ) );
885 ok = mbedtls_test_psa_exported_key_sanity_check(
886 psa_get_key_type( &attributes ), psa_get_key_bits( &attributes ),
887 exported, exported_length );
888
889 exit:
890 /*
891 * Key attributes may have been returned by psa_get_key_attributes()
892 * thus reset them as required.
893 */
894 psa_reset_key_attributes( &attributes );
895
896 mbedtls_free( exported );
897 return( ok );
898 }
899
exercise_export_public_key(mbedtls_svc_key_id_t key)900 static int exercise_export_public_key( mbedtls_svc_key_id_t key )
901 {
902 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
903 psa_key_type_t public_type;
904 uint8_t *exported = NULL;
905 size_t exported_size = 0;
906 size_t exported_length = 0;
907 int ok = 0;
908
909 PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
910 if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( psa_get_key_type( &attributes ) ) )
911 {
912 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
913 psa_get_key_type( &attributes ),
914 psa_get_key_bits( &attributes ) );
915 ASSERT_ALLOC( exported, exported_size );
916
917 TEST_EQUAL( psa_export_public_key( key, exported,
918 exported_size, &exported_length ),
919 PSA_ERROR_INVALID_ARGUMENT );
920 ok = 1;
921 goto exit;
922 }
923
924 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
925 psa_get_key_type( &attributes ) );
926 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( public_type,
927 psa_get_key_bits( &attributes ) );
928 ASSERT_ALLOC( exported, exported_size );
929
930 PSA_ASSERT( psa_export_public_key( key,
931 exported, exported_size,
932 &exported_length ) );
933 ok = mbedtls_test_psa_exported_key_sanity_check(
934 public_type, psa_get_key_bits( &attributes ),
935 exported, exported_length );
936
937 exit:
938 /*
939 * Key attributes may have been returned by psa_get_key_attributes()
940 * thus reset them as required.
941 */
942 psa_reset_key_attributes( &attributes );
943
944 mbedtls_free( exported );
945 return( ok );
946 }
947
mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)948 int mbedtls_test_psa_exercise_key( mbedtls_svc_key_id_t key,
949 psa_key_usage_t usage,
950 psa_algorithm_t alg )
951 {
952 int ok = 0;
953
954 if( ! check_key_attributes_sanity( key ) )
955 return( 0 );
956
957 if( alg == 0 )
958 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
959 else if( PSA_ALG_IS_MAC( alg ) )
960 ok = exercise_mac_key( key, usage, alg );
961 else if( PSA_ALG_IS_CIPHER( alg ) )
962 ok = exercise_cipher_key( key, usage, alg );
963 else if( PSA_ALG_IS_AEAD( alg ) )
964 ok = exercise_aead_key( key, usage, alg );
965 else if( PSA_ALG_IS_SIGN( alg ) )
966 ok = exercise_signature_key( key, usage, alg );
967 else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
968 ok = exercise_asymmetric_encryption_key( key, usage, alg );
969 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) )
970 ok = exercise_key_derivation_key( key, usage, alg );
971 else if( PSA_ALG_IS_RAW_KEY_AGREEMENT( alg ) )
972 ok = exercise_raw_key_agreement_key( key, usage, alg );
973 else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) )
974 ok = exercise_key_agreement_key( key, usage, alg );
975 else
976 TEST_ASSERT( ! "No code to exercise this category of algorithm" );
977
978 ok = ok && exercise_export_key( key, usage );
979 ok = ok && exercise_export_public_key( key );
980
981 exit:
982 return( ok );
983 }
984
mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,psa_algorithm_t alg)985 psa_key_usage_t mbedtls_test_psa_usage_to_exercise( psa_key_type_t type,
986 psa_algorithm_t alg )
987 {
988 if( PSA_ALG_IS_MAC( alg ) || PSA_ALG_IS_SIGN( alg ) )
989 {
990 if( PSA_ALG_IS_SIGN_HASH( alg ) )
991 {
992 if( PSA_ALG_SIGN_GET_HASH( alg ) )
993 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
994 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE:
995 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
996 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE );
997 }
998 else if( PSA_ALG_IS_SIGN_MESSAGE( alg) )
999 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1000 PSA_KEY_USAGE_VERIFY_MESSAGE :
1001 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE );
1002
1003 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1004 PSA_KEY_USAGE_VERIFY_HASH :
1005 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH );
1006 }
1007 else if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ||
1008 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
1009 {
1010 return( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ?
1011 PSA_KEY_USAGE_ENCRYPT :
1012 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
1013 }
1014 else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ||
1015 PSA_ALG_IS_KEY_AGREEMENT( alg ) )
1016 {
1017 return( PSA_KEY_USAGE_DERIVE );
1018 }
1019 else
1020 {
1021 return( 0 );
1022 }
1023
1024 }
1025
1026 #endif /* MBEDTLS_PSA_CRYPTO_C */
1027