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