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 OR GPL-2.0-or-later
8  */
9 
10 #include <test/helpers.h>
11 #include <test/macros.h>
12 #include <test/psa_exercise_key.h>
13 
14 #if defined(MBEDTLS_PSA_CRYPTO_C)
15 
16 #include <mbedtls/asn1.h>
17 #include <psa/crypto.h>
18 
19 #include <test/asn1_helpers.h>
20 #include <psa_crypto_slot_management.h>
21 #include <test/psa_crypto_helpers.h>
22 
23 #if defined(MBEDTLS_PK_C)
24 #include <pk_internal.h>
25 #endif
26 #if defined(MBEDTLS_ECP_C)
27 #include <mbedtls/ecp.h>
28 #endif
29 #if defined(MBEDTLS_RSA_C)
30 #include <rsa_internal.h>
31 #endif
32 
33 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)34 static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
35 {
36     return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
37            PSA_KEY_LOCATION_LOCAL_STORAGE;
38 }
39 #endif
40 
check_key_attributes_sanity(mbedtls_svc_key_id_t key,int key_destroyable)41 static int check_key_attributes_sanity(mbedtls_svc_key_id_t key,
42                                        int key_destroyable)
43 {
44     int ok = 0;
45     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
46     psa_key_lifetime_t lifetime;
47     mbedtls_svc_key_id_t id;
48     psa_key_type_t type;
49     size_t bits;
50     psa_status_t status = psa_get_key_attributes(key, &attributes);
51     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
52         /* The key has been destroyed. */
53         psa_reset_key_attributes(&attributes);
54         return 1;
55     }
56     PSA_ASSERT(status);
57     lifetime = psa_get_key_lifetime(&attributes);
58     id = psa_get_key_id(&attributes);
59     type = psa_get_key_type(&attributes);
60     bits = psa_get_key_bits(&attributes);
61 
62     /* Persistence */
63     if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
64         TEST_ASSERT(
65             (PSA_KEY_ID_VOLATILE_MIN <=
66              MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
67             (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
68              PSA_KEY_ID_VOLATILE_MAX));
69     } else {
70         TEST_ASSERT(
71             (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
72             (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
73     }
74 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
75     /* MBEDTLS_PSA_CRYPTO_SE_C does not support thread safety. */
76     if (key_destroyable == 0) {
77         /* randomly-generated 64-bit constant, should never appear in test data */
78         psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
79         status = psa_get_key_slot_number(&attributes, &slot_number);
80         if (lifetime_is_dynamic_secure_element(lifetime)) {
81             /* Mbed TLS currently always exposes the slot number to
82              * applications. This is not mandated by the PSA specification
83              * and may change in future versions. */
84             TEST_EQUAL(status, 0);
85             TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
86         } else {
87             TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
88         }
89     }
90 #endif
91 
92     /* Type and size */
93     TEST_ASSERT(type != 0);
94     TEST_ASSERT(bits != 0);
95     TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
96     if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
97         TEST_ASSERT(bits % 8 == 0);
98     }
99 
100     /* MAX macros concerning specific key types */
101     if (PSA_KEY_TYPE_IS_ECC(type)) {
102         TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
103     } else if (PSA_KEY_TYPE_IS_RSA(type)) {
104         TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
105     }
106     TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
107 
108     ok = 1;
109 
110 exit:
111     /*
112      * Key attributes may have been returned by psa_get_key_attributes()
113      * thus reset them as required.
114      */
115     psa_reset_key_attributes(&attributes);
116 
117     return ok;
118 }
119 
exercise_mac_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg,int key_destroyable)120 static int exercise_mac_key(mbedtls_svc_key_id_t key,
121                             psa_key_usage_t usage,
122                             psa_algorithm_t alg,
123                             int key_destroyable)
124 {
125     psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
126     const unsigned char input[] = "foo";
127     unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
128     size_t mac_length = sizeof(mac);
129     psa_status_t status = PSA_SUCCESS;
130     /* Convert wildcard algorithm to exercisable algorithm */
131     if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
132         alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
133     }
134 
135     if (usage & PSA_KEY_USAGE_SIGN_HASH) {
136         status = psa_mac_sign_setup(&operation, key, alg);
137         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
138             /* The key has been destroyed. */
139             PSA_ASSERT(psa_mac_abort(&operation));
140             return 1;
141         }
142         PSA_ASSERT(status);
143         PSA_ASSERT(psa_mac_update(&operation,
144                                   input, sizeof(input)));
145         PSA_ASSERT(psa_mac_sign_finish(&operation,
146                                        mac, sizeof(mac),
147                                        &mac_length));
148     }
149 
150     if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
151         psa_status_t verify_status =
152             (usage & PSA_KEY_USAGE_SIGN_HASH ?
153              PSA_SUCCESS :
154              PSA_ERROR_INVALID_SIGNATURE);
155         status = psa_mac_verify_setup(&operation, key, alg);
156         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
157             /* The key has been destroyed. */
158             PSA_ASSERT(psa_mac_abort(&operation));
159             return 1;
160         }
161         PSA_ASSERT(status);
162         PSA_ASSERT(psa_mac_update(&operation,
163                                   input, sizeof(input)));
164         TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
165                    verify_status);
166     }
167 
168     return 1;
169 
170 exit:
171     psa_mac_abort(&operation);
172     return 0;
173 }
174 
exercise_cipher_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg,int key_destroyable)175 static int exercise_cipher_key(mbedtls_svc_key_id_t key,
176                                psa_key_usage_t usage,
177                                psa_algorithm_t alg,
178                                int key_destroyable)
179 {
180     psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
181     unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
182     size_t iv_length;
183     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
184     psa_key_type_t key_type;
185     const unsigned char plaintext[16] = "Hello, world...";
186     unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
187     size_t ciphertext_length = sizeof(ciphertext);
188     unsigned char decrypted[sizeof(ciphertext)];
189     size_t part_length;
190     psa_status_t status = PSA_SUCCESS;
191 
192     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
193     key_type = psa_get_key_type(&attributes);
194     iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
195 
196     if (usage & PSA_KEY_USAGE_ENCRYPT) {
197         status = psa_cipher_encrypt_setup(&operation, key, alg);
198         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
199             /* The key has been destroyed. */
200             PSA_ASSERT(psa_cipher_abort(&operation));
201             return 1;
202         }
203         PSA_ASSERT(status);
204         if (iv_length != 0) {
205             PSA_ASSERT(psa_cipher_generate_iv(&operation,
206                                               iv, sizeof(iv),
207                                               &iv_length));
208         }
209         PSA_ASSERT(psa_cipher_update(&operation,
210                                      plaintext, sizeof(plaintext),
211                                      ciphertext, sizeof(ciphertext),
212                                      &ciphertext_length));
213         PSA_ASSERT(psa_cipher_finish(&operation,
214                                      ciphertext + ciphertext_length,
215                                      sizeof(ciphertext) - ciphertext_length,
216                                      &part_length));
217         ciphertext_length += part_length;
218     }
219 
220     if (usage & PSA_KEY_USAGE_DECRYPT) {
221         int maybe_invalid_padding = 0;
222         if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
223             maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
224         }
225         status = psa_cipher_decrypt_setup(&operation, key, alg);
226         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
227             /* The key has been destroyed. */
228             PSA_ASSERT(psa_cipher_abort(&operation));
229             return 1;
230         }
231         PSA_ASSERT(status);
232         if (iv_length != 0) {
233             PSA_ASSERT(psa_cipher_set_iv(&operation,
234                                          iv, iv_length));
235         }
236         PSA_ASSERT(psa_cipher_update(&operation,
237                                      ciphertext, ciphertext_length,
238                                      decrypted, sizeof(decrypted),
239                                      &part_length));
240         status = psa_cipher_finish(&operation,
241                                    decrypted + part_length,
242                                    sizeof(decrypted) - part_length,
243                                    &part_length);
244         /* For a stream cipher, all inputs are valid. For a block cipher,
245          * if the input is some arbitrary data rather than an actual
246            ciphertext, a padding error is likely.  */
247         if (maybe_invalid_padding) {
248             TEST_ASSERT(status == PSA_SUCCESS ||
249                         status == PSA_ERROR_INVALID_PADDING);
250         } else {
251             PSA_ASSERT(status);
252         }
253     }
254 
255     return 1;
256 
257 exit:
258     psa_cipher_abort(&operation);
259     psa_reset_key_attributes(&attributes);
260     return 0;
261 }
262 
exercise_aead_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg,int key_destroyable)263 static int exercise_aead_key(mbedtls_svc_key_id_t key,
264                              psa_key_usage_t usage,
265                              psa_algorithm_t alg,
266                              int key_destroyable)
267 {
268     unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
269     size_t nonce_length;
270     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
271     psa_key_type_t key_type;
272     unsigned char plaintext[16] = "Hello, world...";
273     unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
274     size_t ciphertext_length = sizeof(ciphertext);
275     size_t plaintext_length = sizeof(ciphertext);
276     psa_status_t status = PSA_SUCCESS;
277 
278     /* Convert wildcard algorithm to exercisable algorithm */
279     if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
280         alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
281     }
282 
283     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
284     key_type = psa_get_key_type(&attributes);
285     nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
286 
287     if (usage & PSA_KEY_USAGE_ENCRYPT) {
288         status = psa_aead_encrypt(key, alg,
289                                   nonce, nonce_length,
290                                   NULL, 0,
291                                   plaintext, sizeof(plaintext),
292                                   ciphertext, sizeof(ciphertext),
293                                   &ciphertext_length);
294         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
295             /* The key has been destroyed. */
296             return 1;
297         }
298         PSA_ASSERT(status);
299     }
300 
301     if (usage & PSA_KEY_USAGE_DECRYPT) {
302         psa_status_t verify_status =
303             (usage & PSA_KEY_USAGE_ENCRYPT ?
304              PSA_SUCCESS :
305              PSA_ERROR_INVALID_SIGNATURE);
306         status = psa_aead_decrypt(key, alg,
307                                   nonce, nonce_length,
308                                   NULL, 0,
309                                   ciphertext, ciphertext_length,
310                                   plaintext, sizeof(plaintext),
311                                   &plaintext_length);
312         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
313             /* The key has been destroyed. */
314             return 1;
315         }
316         TEST_ASSERT(status == verify_status);
317     }
318 
319     return 1;
320 
321 exit:
322     psa_reset_key_attributes(&attributes);
323     return 0;
324 }
325 
can_sign_or_verify_message(psa_key_usage_t usage,psa_algorithm_t alg)326 static int can_sign_or_verify_message(psa_key_usage_t usage,
327                                       psa_algorithm_t alg)
328 {
329     /* Sign-the-unspecified-hash algorithms can only be used with
330      * {sign,verify}_hash, not with {sign,verify}_message. */
331     if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
332         return 0;
333     }
334     return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
335                     PSA_KEY_USAGE_VERIFY_MESSAGE);
336 }
337 
exercise_signature_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg,int key_destroyable)338 static int exercise_signature_key(mbedtls_svc_key_id_t key,
339                                   psa_key_usage_t usage,
340                                   psa_algorithm_t alg,
341                                   int key_destroyable)
342 {
343     /* If the policy allows signing with any hash, just pick one. */
344     psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
345     if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
346         usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
347                  PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
348 #if defined(KNOWN_SUPPORTED_HASH_ALG)
349         hash_alg = KNOWN_SUPPORTED_HASH_ALG;
350         alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
351 #else
352         TEST_FAIL("No hash algorithm for hash-and-sign testing");
353 #endif
354     }
355     psa_status_t status = PSA_SUCCESS;
356 
357     if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
358         PSA_ALG_IS_SIGN_HASH(alg)) {
359         unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
360         size_t payload_length = 16;
361         unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
362         size_t signature_length = sizeof(signature);
363 
364         /* Some algorithms require the payload to have the size of
365          * the hash encoded in the algorithm. Use this input size
366          * even for algorithms that allow other input sizes. */
367         if (hash_alg != 0) {
368             payload_length = PSA_HASH_LENGTH(hash_alg);
369         }
370 
371         if (usage & PSA_KEY_USAGE_SIGN_HASH) {
372             status = psa_sign_hash(key, alg,
373                                    payload, payload_length,
374                                    signature, sizeof(signature),
375                                    &signature_length);
376             if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
377                 /* The key has been destroyed. */
378                 return 1;
379             }
380             PSA_ASSERT(status);
381         }
382 
383         if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
384             psa_status_t verify_status =
385                 (usage & PSA_KEY_USAGE_SIGN_HASH ?
386                  PSA_SUCCESS :
387                  PSA_ERROR_INVALID_SIGNATURE);
388             status = psa_verify_hash(key, alg,
389                                      payload, payload_length,
390                                      signature, signature_length);
391             if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
392                 /* The key has been destroyed. */
393                 return 1;
394             }
395             TEST_ASSERT(status == verify_status);
396         }
397     }
398 
399     if (can_sign_or_verify_message(usage, alg)) {
400         unsigned char message[256] = "Hello, world...";
401         unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
402         size_t message_length = 16;
403         size_t signature_length = sizeof(signature);
404 
405         if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
406             status = psa_sign_message(key, alg,
407                                       message, message_length,
408                                       signature, sizeof(signature),
409                                       &signature_length);
410             if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
411                 /* The key has been destroyed. */
412                 return 1;
413             }
414             PSA_ASSERT(status);
415         }
416 
417         if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
418             psa_status_t verify_status =
419                 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
420                  PSA_SUCCESS :
421                  PSA_ERROR_INVALID_SIGNATURE);
422             status = psa_verify_message(key, alg,
423                                         message, message_length,
424                                         signature, signature_length);
425             if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
426                 /* The key has been destroyed. */
427                 return 1;
428             }
429             TEST_ASSERT(status == verify_status);
430         }
431     }
432 
433     return 1;
434 
435 exit:
436     return 0;
437 }
438 
exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg,int key_destroyable)439 static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
440                                               psa_key_usage_t usage,
441                                               psa_algorithm_t alg,
442                                               int key_destroyable)
443 {
444     unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
445         "Hello, world...";
446     unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
447         "(wabblewebblewibblewobblewubble)";
448     size_t ciphertext_length = sizeof(ciphertext);
449     size_t plaintext_length = 16;
450     psa_status_t status = PSA_SUCCESS;
451     if (usage & PSA_KEY_USAGE_ENCRYPT) {
452         status = psa_asymmetric_encrypt(key, alg,
453                                         plaintext, plaintext_length,
454                                         NULL, 0,
455                                         ciphertext, sizeof(ciphertext),
456                                         &ciphertext_length);
457         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
458             /* The key has been destroyed. */
459             return 1;
460         }
461         PSA_ASSERT(status);
462     }
463 
464     if (usage & PSA_KEY_USAGE_DECRYPT) {
465         status = psa_asymmetric_decrypt(key, alg,
466                                         ciphertext, ciphertext_length,
467                                         NULL, 0,
468                                         plaintext, sizeof(plaintext),
469                                         &plaintext_length);
470         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
471             /* The key has been destroyed. */
472             return 1;
473         }
474         TEST_ASSERT(status == PSA_SUCCESS ||
475                     ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
476                      (status == PSA_ERROR_INVALID_ARGUMENT ||
477                       status == PSA_ERROR_INVALID_PADDING)));
478     }
479 
480     return 1;
481 
482 exit:
483     return 0;
484 }
485 
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,int key_destroyable)486 int mbedtls_test_psa_setup_key_derivation_wrap(
487     psa_key_derivation_operation_t *operation,
488     mbedtls_svc_key_id_t key,
489     psa_algorithm_t alg,
490     const unsigned char *input1, size_t input1_length,
491     const unsigned char *input2, size_t input2_length,
492     size_t capacity, int key_destroyable)
493 {
494     PSA_ASSERT(psa_key_derivation_setup(operation, alg));
495     psa_status_t status = PSA_SUCCESS;
496     if (PSA_ALG_IS_HKDF(alg)) {
497         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
498                                                   PSA_KEY_DERIVATION_INPUT_SALT,
499                                                   input1, input1_length));
500         status = psa_key_derivation_input_key(operation,
501                                               PSA_KEY_DERIVATION_INPUT_SECRET,
502                                               key);
503         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
504             /* The key has been destroyed. */
505             return 1;
506         }
507         PSA_ASSERT(status);
508         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
509                                                   PSA_KEY_DERIVATION_INPUT_INFO,
510                                                   input2,
511                                                   input2_length));
512     } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
513         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
514                                                   PSA_KEY_DERIVATION_INPUT_SALT,
515                                                   input1, input1_length));
516         status = psa_key_derivation_input_key(operation,
517                                               PSA_KEY_DERIVATION_INPUT_SECRET,
518                                               key);
519         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
520             /* The key has been destroyed. */
521             return 1;
522         }
523         PSA_ASSERT(status);
524     } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
525         status = psa_key_derivation_input_key(operation,
526                                               PSA_KEY_DERIVATION_INPUT_SECRET,
527                                               key);
528         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
529             /* The key has been destroyed. */
530             return 1;
531         }
532         PSA_ASSERT(status);
533         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
534                                                   PSA_KEY_DERIVATION_INPUT_INFO,
535                                                   input2,
536                                                   input2_length));
537     } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
538                PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
539         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
540                                                   PSA_KEY_DERIVATION_INPUT_SEED,
541                                                   input1, input1_length));
542         status = psa_key_derivation_input_key(operation,
543                                               PSA_KEY_DERIVATION_INPUT_SECRET,
544                                               key);
545         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
546             /* The key has been destroyed. */
547             return 1;
548         }
549         PSA_ASSERT(status);
550         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
551                                                   PSA_KEY_DERIVATION_INPUT_LABEL,
552                                                   input2, input2_length));
553     } else if (PSA_ALG_IS_PBKDF2(alg)) {
554         PSA_ASSERT(psa_key_derivation_input_integer(operation,
555                                                     PSA_KEY_DERIVATION_INPUT_COST,
556                                                     1U));
557         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
558                                                   PSA_KEY_DERIVATION_INPUT_SALT,
559                                                   input2,
560                                                   input2_length));
561         status = psa_key_derivation_input_key(operation,
562                                               PSA_KEY_DERIVATION_INPUT_PASSWORD,
563                                               key);
564         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
565             /* The key has been destroyed. */
566             return 1;
567         }
568         PSA_ASSERT(status);
569     } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
570         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
571                                                   PSA_KEY_DERIVATION_INPUT_SECRET,
572                                                   input1, input1_length));
573     } else {
574         TEST_FAIL("Key derivation algorithm not supported");
575     }
576 
577     if (capacity != SIZE_MAX) {
578         PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
579     }
580 
581     return 1;
582 
583 exit:
584     return 0;
585 }
586 
587 
exercise_key_derivation_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg,int key_destroyable)588 static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
589                                        psa_key_usage_t usage,
590                                        psa_algorithm_t alg,
591                                        int key_destroyable)
592 {
593     psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
594     unsigned char input1[] = "Input 1";
595     size_t input1_length = sizeof(input1);
596     unsigned char input2[] = "Input 2";
597     size_t input2_length = sizeof(input2);
598     unsigned char output[1];
599     size_t capacity = sizeof(output);
600 
601     if (usage & PSA_KEY_USAGE_DERIVE) {
602         if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
603                                                         input1, input1_length,
604                                                         input2, input2_length,
605                                                         capacity, key_destroyable)) {
606             goto exit;
607         }
608 
609         psa_status_t status = psa_key_derivation_output_bytes(&operation,
610                                                               output,
611                                                               capacity);
612         if (key_destroyable && status == PSA_ERROR_BAD_STATE) {
613             /* The key has been destroyed. */
614             PSA_ASSERT(psa_key_derivation_abort(&operation));
615         } else {
616             PSA_ASSERT(status);
617             PSA_ASSERT(psa_key_derivation_abort(&operation));
618         }
619     }
620 
621     return 1;
622 
623 exit:
624     return 0;
625 }
626 
627 /* We need two keys to exercise key agreement. Exercise the
628  * 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,int key_destroyable)629 psa_status_t mbedtls_test_psa_key_agreement_with_self(
630     psa_key_derivation_operation_t *operation,
631     mbedtls_svc_key_id_t key, int key_destroyable)
632 {
633     psa_key_type_t private_key_type;
634     psa_key_type_t public_key_type;
635     size_t key_bits;
636     uint8_t *public_key = NULL;
637     size_t public_key_length;
638     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
639 
640     psa_status_t status = psa_get_key_attributes(key, &attributes);
641     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
642         /* The key has been destroyed. */
643         psa_reset_key_attributes(&attributes);
644         return PSA_SUCCESS;
645     }
646     PSA_ASSERT(status);
647 
648     private_key_type = psa_get_key_type(&attributes);
649     key_bits = psa_get_key_bits(&attributes);
650     public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
651     public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
652     TEST_CALLOC(public_key, public_key_length);
653     status = psa_export_public_key(key, public_key, public_key_length,
654                                    &public_key_length);
655     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
656         /* The key has been destroyed. */
657         status = PSA_SUCCESS;
658         goto exit;
659     }
660     PSA_ASSERT(status);
661 
662     status = psa_key_derivation_key_agreement(
663         operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
664         public_key, public_key_length);
665     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
666         /* The key has been destroyed. */
667         status = PSA_SUCCESS;
668         goto exit;
669     }
670 exit:
671     /*
672      * Key attributes may have been returned by psa_get_key_attributes()
673      * thus reset them as required.
674      */
675     psa_reset_key_attributes(&attributes);
676 
677     mbedtls_free(public_key);
678     return status;
679 }
680 
681 /* We need two keys to exercise key agreement. Exercise the
682  * 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,int key_destroyable)683 psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
684     psa_algorithm_t alg,
685     mbedtls_svc_key_id_t key,
686     int key_destroyable)
687 {
688     psa_key_type_t private_key_type;
689     psa_key_type_t public_key_type;
690     size_t key_bits;
691     uint8_t *public_key = NULL;
692     size_t public_key_length;
693     uint8_t output[1024];
694     size_t output_length;
695     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
696 
697     psa_status_t status = psa_get_key_attributes(key, &attributes);
698     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
699         /* The key has been destroyed. */
700         psa_reset_key_attributes(&attributes);
701         return PSA_SUCCESS;
702     }
703     PSA_ASSERT(status);
704 
705     private_key_type = psa_get_key_type(&attributes);
706     key_bits = psa_get_key_bits(&attributes);
707     public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
708     public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
709     TEST_CALLOC(public_key, public_key_length);
710     status = psa_export_public_key(key,
711                                    public_key, public_key_length,
712                                    &public_key_length);
713     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
714         /* The key has been destroyed. */
715         status = PSA_SUCCESS;
716         goto exit;
717     }
718     PSA_ASSERT(status);
719 
720     status = psa_raw_key_agreement(alg, key,
721                                    public_key, public_key_length,
722                                    output, sizeof(output), &output_length);
723     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
724         /* The key has been destroyed. */
725         status = PSA_SUCCESS;
726         goto exit;
727     }
728     if (status == PSA_SUCCESS) {
729         TEST_ASSERT(output_length <=
730                     PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
731                                                       key_bits));
732         TEST_ASSERT(output_length <=
733                     PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
734     }
735 
736 exit:
737     /*
738      * Key attributes may have been returned by psa_get_key_attributes()
739      * thus reset them as required.
740      */
741     psa_reset_key_attributes(&attributes);
742 
743     mbedtls_free(public_key);
744     return status;
745 }
746 
exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg,int key_destroyable)747 static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
748                                           psa_key_usage_t usage,
749                                           psa_algorithm_t alg,
750                                           int key_destroyable)
751 {
752     int ok = 0;
753 
754     if (usage & PSA_KEY_USAGE_DERIVE) {
755         /* We need two keys to exercise key agreement. Exercise the
756          * private key against its own public key. */
757         PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key,
758                                                                 key_destroyable));
759     }
760     ok = 1;
761 
762 exit:
763     return ok;
764 }
765 
exercise_key_agreement_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg,int key_destroyable)766 static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
767                                       psa_key_usage_t usage,
768                                       psa_algorithm_t alg,
769                                       int key_destroyable)
770 {
771     psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
772     unsigned char input[1] = { 0 };
773     unsigned char output[1];
774     int ok = 0;
775     psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
776     psa_status_t expected_key_agreement_status = PSA_SUCCESS;
777 
778     if (usage & PSA_KEY_USAGE_DERIVE) {
779         /* We need two keys to exercise key agreement. Exercise the
780          * private key against its own public key. */
781         PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
782         if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
783             PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
784             PSA_ASSERT(psa_key_derivation_input_bytes(
785                            &operation, PSA_KEY_DERIVATION_INPUT_SEED,
786                            input, sizeof(input)));
787         }
788 
789         if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
790             PSA_ASSERT(psa_key_derivation_input_bytes(
791                            &operation, PSA_KEY_DERIVATION_INPUT_SALT,
792                            input, sizeof(input)));
793         }
794 
795         /* For HKDF_EXPAND input secret may fail as secret size may not match
796            to expected PRK size. In practice it means that key bits must match
797            hash length. Otherwise test should fail with INVALID_ARGUMENT. */
798         if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
799             psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
800             psa_status_t status = psa_get_key_attributes(key, &attributes);
801             if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
802                 /* The key has been destroyed. */
803                 ok = 1;
804             }
805             PSA_ASSERT(status);
806             size_t key_bits = psa_get_key_bits(&attributes);
807             psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
808 
809             if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
810                 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
811             }
812         }
813 
814         TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key,
815                                                             key_destroyable),
816                    expected_key_agreement_status);
817 
818         if (expected_key_agreement_status != PSA_SUCCESS) {
819             return 1;
820         }
821 
822         if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
823             PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
824             PSA_ASSERT(psa_key_derivation_input_bytes(
825                            &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
826                            input, sizeof(input)));
827         } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
828             PSA_ASSERT(psa_key_derivation_input_bytes(
829                            &operation, PSA_KEY_DERIVATION_INPUT_INFO,
830                            input, sizeof(input)));
831         }
832         PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
833                                                    output,
834                                                    sizeof(output)));
835         PSA_ASSERT(psa_key_derivation_abort(&operation));
836     }
837     ok = 1;
838 
839 exit:
840     return ok;
841 }
842 
mbedtls_test_psa_exported_key_sanity_check(psa_key_type_t type,size_t bits,const uint8_t * exported,size_t exported_length)843 int mbedtls_test_psa_exported_key_sanity_check(
844     psa_key_type_t type, size_t bits,
845     const uint8_t *exported, size_t exported_length)
846 {
847     TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
848 
849     if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
850         TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
851     } else
852 
853 #if defined(MBEDTLS_ASN1_PARSE_C)
854     if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
855         uint8_t *p = (uint8_t *) exported;
856         const uint8_t *end = exported + exported_length;
857         size_t len;
858         /*   RSAPrivateKey ::= SEQUENCE {
859          *       version             INTEGER,  -- must be 0
860          *       modulus             INTEGER,  -- n
861          *       publicExponent      INTEGER,  -- e
862          *       privateExponent     INTEGER,  -- d
863          *       prime1              INTEGER,  -- p
864          *       prime2              INTEGER,  -- q
865          *       exponent1           INTEGER,  -- d mod (p-1)
866          *       exponent2           INTEGER,  -- d mod (q-1)
867          *       coefficient         INTEGER,  -- (inverse of q) mod p
868          *   }
869          */
870         TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
871                                         MBEDTLS_ASN1_SEQUENCE |
872                                         MBEDTLS_ASN1_CONSTRUCTED), 0);
873         TEST_EQUAL(len, end - p);
874         if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
875             goto exit;
876         }
877         if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
878             goto exit;
879         }
880         if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
881             goto exit;
882         }
883         /* Require d to be at least half the size of n. */
884         if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
885             goto exit;
886         }
887         /* Require p and q to be at most half the size of n, rounded up. */
888         if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
889             goto exit;
890         }
891         if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
892             goto exit;
893         }
894         if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
895             goto exit;
896         }
897         if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
898             goto exit;
899         }
900         if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
901             goto exit;
902         }
903         TEST_EQUAL(p - end, 0);
904 
905         TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
906     } else
907 #endif /* MBEDTLS_ASN1_PARSE_C */
908 
909     if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
910         /* Just the secret value */
911         TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
912 
913         TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
914     } else
915 
916 #if defined(MBEDTLS_ASN1_PARSE_C)
917     if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
918         uint8_t *p = (uint8_t *) exported;
919         const uint8_t *end = exported + exported_length;
920         size_t len;
921         /*   RSAPublicKey ::= SEQUENCE {
922          *      modulus            INTEGER,    -- n
923          *      publicExponent     INTEGER  }  -- e
924          */
925         TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
926                                         MBEDTLS_ASN1_SEQUENCE |
927                                         MBEDTLS_ASN1_CONSTRUCTED),
928                    0);
929         TEST_EQUAL(len, end - p);
930         if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
931             goto exit;
932         }
933         if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
934             goto exit;
935         }
936         TEST_EQUAL(p - end, 0);
937 
938 
939         TEST_ASSERT(exported_length <=
940                     PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
941         TEST_ASSERT(exported_length <=
942                     PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
943     } else
944 #endif /* MBEDTLS_ASN1_PARSE_C */
945 
946     if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
947 
948         TEST_ASSERT(exported_length <=
949                     PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
950         TEST_ASSERT(exported_length <=
951                     PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
952 
953         if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
954             /* The representation of an ECC Montgomery public key is
955              * the raw compressed point */
956             TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
957         } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
958             /* The representation of an ECC Edwards public key is
959              * the raw compressed point */
960             TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
961         } else {
962             /* The representation of an ECC Weierstrass public key is:
963              *      - The byte 0x04;
964              *      - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
965              *      - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
966              *      - where m is the bit size associated with the curve.
967              */
968             TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
969             TEST_EQUAL(exported[0], 4);
970         }
971     } else
972     if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
973         TEST_ASSERT(exported_length ==
974                     PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
975         TEST_ASSERT(exported_length <=
976                     PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
977     } else {
978         (void) exported;
979         TEST_FAIL("Sanity check not implemented for this key type");
980     }
981 
982 #if defined(MBEDTLS_DES_C)
983     if (type == PSA_KEY_TYPE_DES) {
984         /* Check the parity bits. */
985         unsigned i;
986         for (i = 0; i < bits / 8; i++) {
987             unsigned bit_count = 0;
988             unsigned m;
989             for (m = 1; m <= 0x100; m <<= 1) {
990                 if (exported[i] & m) {
991                     ++bit_count;
992                 }
993             }
994             TEST_ASSERT(bit_count % 2 != 0);
995         }
996     }
997 #endif
998 
999     return 1;
1000 
1001 exit:
1002     return 0;
1003 }
1004 
exercise_export_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,int key_destroyable)1005 static int exercise_export_key(mbedtls_svc_key_id_t key,
1006                                psa_key_usage_t usage,
1007                                int key_destroyable)
1008 {
1009     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1010     uint8_t *exported = NULL;
1011     size_t exported_size = 0;
1012     size_t exported_length = 0;
1013     int ok = 0;
1014 
1015     psa_status_t status = psa_get_key_attributes(key, &attributes);
1016     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1017         /* The key has been destroyed. */
1018         psa_reset_key_attributes(&attributes);
1019         return 1;
1020     }
1021     PSA_ASSERT(status);
1022 
1023     exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
1024         psa_get_key_type(&attributes),
1025         psa_get_key_bits(&attributes));
1026     TEST_CALLOC(exported, exported_size);
1027 
1028     status = psa_export_key(key, exported, exported_size, &exported_length);
1029     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1030         /* The key has been destroyed. */
1031         ok = 1;
1032         goto exit;
1033     } else if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
1034                !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
1035         TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED);
1036         ok = 1;
1037         goto exit;
1038     }
1039     PSA_ASSERT(status);
1040     ok = mbedtls_test_psa_exported_key_sanity_check(
1041         psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
1042         exported, exported_length);
1043 
1044 exit:
1045     /*
1046      * Key attributes may have been returned by psa_get_key_attributes()
1047      * thus reset them as required.
1048      */
1049     psa_reset_key_attributes(&attributes);
1050 
1051     mbedtls_free(exported);
1052     return ok;
1053 }
1054 
exercise_export_public_key(mbedtls_svc_key_id_t key,int key_destroyable)1055 static int exercise_export_public_key(mbedtls_svc_key_id_t key,
1056                                       int key_destroyable)
1057 {
1058     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1059     psa_key_type_t public_type;
1060     uint8_t *exported = NULL;
1061     size_t exported_size = 0;
1062     size_t exported_length = 0;
1063     int ok = 0;
1064 
1065     psa_status_t status = psa_get_key_attributes(key, &attributes);
1066     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1067         /* The key has been destroyed. */
1068         psa_reset_key_attributes(&attributes);
1069         return 1;
1070     }
1071     PSA_ASSERT(status);
1072     if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
1073         exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
1074             psa_get_key_type(&attributes),
1075             psa_get_key_bits(&attributes));
1076         TEST_CALLOC(exported, exported_size);
1077 
1078         status = psa_export_public_key(key, exported,
1079                                        exported_size, &exported_length);
1080         if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1081             /* The key has been destroyed. */
1082             ok = 1;
1083             goto exit;
1084         }
1085         TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
1086         ok = 1;
1087         goto exit;
1088     }
1089 
1090     public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
1091         psa_get_key_type(&attributes));
1092     exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
1093                                                       psa_get_key_bits(&attributes));
1094     TEST_CALLOC(exported, exported_size);
1095 
1096     status = psa_export_public_key(key, exported,
1097                                    exported_size, &exported_length);
1098     if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1099         /* The key has been destroyed. */
1100         ok = 1;
1101         goto exit;
1102     }
1103     PSA_ASSERT(status);
1104     ok = mbedtls_test_psa_exported_key_sanity_check(
1105         public_type, psa_get_key_bits(&attributes),
1106         exported, exported_length);
1107 
1108 exit:
1109     /*
1110      * Key attributes may have been returned by psa_get_key_attributes()
1111      * thus reset them as required.
1112      */
1113     psa_reset_key_attributes(&attributes);
1114 
1115     mbedtls_free(exported);
1116     return ok;
1117 }
1118 
mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg,int key_destroyable)1119 int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
1120                                   psa_key_usage_t usage,
1121                                   psa_algorithm_t alg,
1122                                   int key_destroyable)
1123 {
1124     int ok = 0;
1125 
1126     if (!check_key_attributes_sanity(key, key_destroyable)) {
1127         return 0;
1128     }
1129 
1130     if (alg == 0) {
1131         ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
1132     } else if (PSA_ALG_IS_MAC(alg)) {
1133         ok = exercise_mac_key(key, usage, alg, key_destroyable);
1134     } else if (PSA_ALG_IS_CIPHER(alg)) {
1135         ok = exercise_cipher_key(key, usage, alg, key_destroyable);
1136     } else if (PSA_ALG_IS_AEAD(alg)) {
1137         ok = exercise_aead_key(key, usage, alg, key_destroyable);
1138     } else if (PSA_ALG_IS_SIGN(alg)) {
1139         ok = exercise_signature_key(key, usage, alg, key_destroyable);
1140     } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1141         ok = exercise_asymmetric_encryption_key(key, usage, alg,
1142                                                 key_destroyable);
1143     } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
1144         ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
1145     } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
1146         ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
1147     } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1148         ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
1149     } else {
1150         TEST_FAIL("No code to exercise this category of algorithm");
1151     }
1152 
1153     ok = ok && exercise_export_key(key,
1154                                    usage,
1155                                    key_destroyable);
1156     ok = ok && exercise_export_public_key(key,
1157                                           key_destroyable);
1158 
1159 exit:
1160     return ok;
1161 }
1162 
mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,psa_algorithm_t alg)1163 psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1164                                                    psa_algorithm_t alg)
1165 {
1166     if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1167         if (PSA_ALG_IS_SIGN_HASH(alg)) {
1168             if (PSA_ALG_SIGN_GET_HASH(alg)) {
1169                 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1170                        PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1171                        PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1172                        PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1173             }
1174         } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1175             return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1176                    PSA_KEY_USAGE_VERIFY_MESSAGE :
1177                    PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1178         }
1179 
1180         return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1181                PSA_KEY_USAGE_VERIFY_HASH :
1182                PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1183     } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1184                PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1185         return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1186                PSA_KEY_USAGE_ENCRYPT :
1187                PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1188     } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1189                PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1190         return PSA_KEY_USAGE_DERIVE;
1191     } else {
1192         return 0;
1193     }
1194 
1195 }
1196 
mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)1197 int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1198 {
1199     /* Reject algorithms that we know are not supported. Default to
1200      * attempting exercise, so that if an algorithm is missing from this
1201      * function, the result will be a test failure and not silently
1202      * omitting exercise. */
1203 #if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1204     if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1205         return 0;
1206     }
1207 #endif
1208 #if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1209     if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1210         return 0;
1211     }
1212 #endif
1213 #if !defined(PSA_WANT_ALG_RSA_PSS)
1214     if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1215         return 0;
1216     }
1217 #endif
1218 #if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1219     if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1220         return 0;
1221     }
1222 #endif
1223 #if !defined(PSA_WANT_ALG_ECDSA)
1224     if (PSA_ALG_IS_ECDSA(alg)) {
1225         return 0;
1226     }
1227 #endif
1228 #if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1229     if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1230         return 0;
1231     }
1232 #endif
1233 #if !defined(PSA_WANT_ALG_ECDH)
1234     if (PSA_ALG_IS_ECDH(alg)) {
1235         return 0;
1236     }
1237 #endif
1238     (void) alg;
1239     return 1;
1240 }
1241 
1242 #if defined(MBEDTLS_PK_C)
mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,const mbedtls_pk_context * pk)1243 int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1244                                         const mbedtls_pk_context *pk)
1245 {
1246     psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1247     psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1248     int ok = 0;
1249 
1250     PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1251     psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1252     mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1253 
1254     TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1255                 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1256     TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1257 
1258     uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1259     const uint8_t *pk_public = NULL;
1260     size_t pk_public_length = 0;
1261 
1262     switch (pk_type) {
1263 #if defined(MBEDTLS_RSA_C)
1264         case MBEDTLS_PK_RSA:
1265             TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1266             const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1267             uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1268             uint8_t *cursor = end;
1269             TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1270                                                   pk_public_buffer, &cursor));
1271             pk_public = cursor;
1272             pk_public_length = end - pk_public;
1273             break;
1274 #endif
1275 
1276 #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1277         case MBEDTLS_PK_ECKEY:
1278         case MBEDTLS_PK_ECKEY_DH:
1279         case MBEDTLS_PK_ECDSA:
1280             TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1281             TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1282             pk_public = pk->pub_raw;
1283             pk_public_length = pk->pub_raw_len;
1284             break;
1285 #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1286 
1287 #if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1288         case MBEDTLS_PK_ECKEY:
1289         case MBEDTLS_PK_ECKEY_DH:
1290         case MBEDTLS_PK_ECDSA:
1291             TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1292             const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1293             TEST_EQUAL(mbedtls_ecp_write_public_key(
1294                            ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1295                            pk_public_buffer, sizeof(pk_public_buffer)), 0);
1296             pk_public = pk_public_buffer;
1297             break;
1298 #endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */
1299 
1300 #if defined(MBEDTLS_USE_PSA_CRYPTO)
1301         case MBEDTLS_PK_OPAQUE:
1302             PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1303             psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1304             TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1305                        PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1306             PSA_ASSERT(psa_export_public_key(psa_key,
1307                                              pk_public_buffer,
1308                                              sizeof(pk_public_buffer),
1309                                              &pk_public_length));
1310             pk_public = pk_public_buffer;
1311             break;
1312 #endif /* MBEDTLS_USE_PSA_CRYPTO */
1313 
1314         default:
1315             TEST_FAIL("pk type not supported");
1316     }
1317 
1318     uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1319     size_t psa_public_length = 0;
1320     PSA_ASSERT(psa_export_public_key(psa_key,
1321                                      psa_public, sizeof(psa_public),
1322                                      &psa_public_length));
1323     TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1324                         psa_public, psa_public_length);
1325 
1326     ok = 1;
1327 
1328 exit:
1329     psa_reset_key_attributes(&psa_attributes);
1330     psa_reset_key_attributes(&pk_attributes);
1331     return ok;
1332 }
1333 #endif /* MBEDTLS_PK_C */
1334 
1335 #endif /* MBEDTLS_PSA_CRYPTO_C */
1336