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