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