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_PSA_CRYPTO_SE_C)
lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)24 static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
25 {
26 return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
27 PSA_KEY_LOCATION_LOCAL_STORAGE;
28 }
29 #endif
30
check_key_attributes_sanity(mbedtls_svc_key_id_t key)31 static int check_key_attributes_sanity(mbedtls_svc_key_id_t key)
32 {
33 int ok = 0;
34 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
35 psa_key_lifetime_t lifetime;
36 mbedtls_svc_key_id_t id;
37 psa_key_type_t type;
38 size_t bits;
39
40 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
41 lifetime = psa_get_key_lifetime(&attributes);
42 id = psa_get_key_id(&attributes);
43 type = psa_get_key_type(&attributes);
44 bits = psa_get_key_bits(&attributes);
45
46 /* Persistence */
47 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
48 TEST_ASSERT(
49 (PSA_KEY_ID_VOLATILE_MIN <=
50 MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
51 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
52 PSA_KEY_ID_VOLATILE_MAX));
53 } else {
54 TEST_ASSERT(
55 (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
56 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
57 }
58 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
59 /* randomly-generated 64-bit constant, should never appear in test data */
60 psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
61 psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number);
62 if (lifetime_is_dynamic_secure_element(lifetime)) {
63 /* Mbed TLS currently always exposes the slot number to
64 * applications. This is not mandated by the PSA specification
65 * and may change in future versions. */
66 TEST_EQUAL(status, 0);
67 TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
68 } else {
69 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
70 }
71 #endif
72
73 /* Type and size */
74 TEST_ASSERT(type != 0);
75 TEST_ASSERT(bits != 0);
76 TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
77 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
78 TEST_ASSERT(bits % 8 == 0);
79 }
80
81 /* MAX macros concerning specific key types */
82 if (PSA_KEY_TYPE_IS_ECC(type)) {
83 TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
84 } else if (PSA_KEY_TYPE_IS_RSA(type)) {
85 TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
86 }
87 TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
88
89 ok = 1;
90
91 exit:
92 /*
93 * Key attributes may have been returned by psa_get_key_attributes()
94 * thus reset them as required.
95 */
96 psa_reset_key_attributes(&attributes);
97
98 return ok;
99 }
100
exercise_mac_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)101 static int exercise_mac_key(mbedtls_svc_key_id_t key,
102 psa_key_usage_t usage,
103 psa_algorithm_t alg)
104 {
105 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
106 const unsigned char input[] = "foo";
107 unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
108 size_t mac_length = sizeof(mac);
109
110 /* Convert wildcard algorithm to exercisable algorithm */
111 if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
112 alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
113 }
114
115 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
116 PSA_ASSERT(psa_mac_sign_setup(&operation, key, alg));
117 PSA_ASSERT(psa_mac_update(&operation,
118 input, sizeof(input)));
119 PSA_ASSERT(psa_mac_sign_finish(&operation,
120 mac, sizeof(mac),
121 &mac_length));
122 }
123
124 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
125 psa_status_t verify_status =
126 (usage & PSA_KEY_USAGE_SIGN_HASH ?
127 PSA_SUCCESS :
128 PSA_ERROR_INVALID_SIGNATURE);
129 PSA_ASSERT(psa_mac_verify_setup(&operation, key, alg));
130 PSA_ASSERT(psa_mac_update(&operation,
131 input, sizeof(input)));
132 TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
133 verify_status);
134 }
135
136 return 1;
137
138 exit:
139 psa_mac_abort(&operation);
140 return 0;
141 }
142
exercise_cipher_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)143 static int exercise_cipher_key(mbedtls_svc_key_id_t key,
144 psa_key_usage_t usage,
145 psa_algorithm_t alg)
146 {
147 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
148 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
149 size_t iv_length;
150 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
151 psa_key_type_t key_type;
152 const unsigned char plaintext[16] = "Hello, world...";
153 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
154 size_t ciphertext_length = sizeof(ciphertext);
155 unsigned char decrypted[sizeof(ciphertext)];
156 size_t part_length;
157
158 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
159 key_type = psa_get_key_type(&attributes);
160 iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
161
162 if (usage & PSA_KEY_USAGE_ENCRYPT) {
163 PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
164 if (iv_length != 0) {
165 PSA_ASSERT(psa_cipher_generate_iv(&operation,
166 iv, sizeof(iv),
167 &iv_length));
168 }
169 PSA_ASSERT(psa_cipher_update(&operation,
170 plaintext, sizeof(plaintext),
171 ciphertext, sizeof(ciphertext),
172 &ciphertext_length));
173 PSA_ASSERT(psa_cipher_finish(&operation,
174 ciphertext + ciphertext_length,
175 sizeof(ciphertext) - ciphertext_length,
176 &part_length));
177 ciphertext_length += part_length;
178 }
179
180 if (usage & PSA_KEY_USAGE_DECRYPT) {
181 psa_status_t status;
182 int maybe_invalid_padding = 0;
183 if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
184 maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
185 }
186 PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
187 if (iv_length != 0) {
188 PSA_ASSERT(psa_cipher_set_iv(&operation,
189 iv, iv_length));
190 }
191 PSA_ASSERT(psa_cipher_update(&operation,
192 ciphertext, ciphertext_length,
193 decrypted, sizeof(decrypted),
194 &part_length));
195 status = psa_cipher_finish(&operation,
196 decrypted + part_length,
197 sizeof(decrypted) - part_length,
198 &part_length);
199 /* For a stream cipher, all inputs are valid. For a block cipher,
200 * if the input is some arbitrary data rather than an actual
201 ciphertext, a padding error is likely. */
202 if (maybe_invalid_padding) {
203 TEST_ASSERT(status == PSA_SUCCESS ||
204 status == PSA_ERROR_INVALID_PADDING);
205 } else {
206 PSA_ASSERT(status);
207 }
208 }
209
210 return 1;
211
212 exit:
213 psa_cipher_abort(&operation);
214 psa_reset_key_attributes(&attributes);
215 return 0;
216 }
217
exercise_aead_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)218 static int exercise_aead_key(mbedtls_svc_key_id_t key,
219 psa_key_usage_t usage,
220 psa_algorithm_t alg)
221 {
222 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
223 size_t nonce_length;
224 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
225 psa_key_type_t key_type;
226 unsigned char plaintext[16] = "Hello, world...";
227 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
228 size_t ciphertext_length = sizeof(ciphertext);
229 size_t plaintext_length = sizeof(ciphertext);
230
231 /* Convert wildcard algorithm to exercisable algorithm */
232 if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
233 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
234 }
235
236 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
237 key_type = psa_get_key_type(&attributes);
238 nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
239
240 if (usage & PSA_KEY_USAGE_ENCRYPT) {
241 PSA_ASSERT(psa_aead_encrypt(key, alg,
242 nonce, nonce_length,
243 NULL, 0,
244 plaintext, sizeof(plaintext),
245 ciphertext, sizeof(ciphertext),
246 &ciphertext_length));
247 }
248
249 if (usage & PSA_KEY_USAGE_DECRYPT) {
250 psa_status_t verify_status =
251 (usage & PSA_KEY_USAGE_ENCRYPT ?
252 PSA_SUCCESS :
253 PSA_ERROR_INVALID_SIGNATURE);
254 TEST_EQUAL(psa_aead_decrypt(key, alg,
255 nonce, nonce_length,
256 NULL, 0,
257 ciphertext, ciphertext_length,
258 plaintext, sizeof(plaintext),
259 &plaintext_length),
260 verify_status);
261 }
262
263 return 1;
264
265 exit:
266 psa_reset_key_attributes(&attributes);
267 return 0;
268 }
269
can_sign_or_verify_message(psa_key_usage_t usage,psa_algorithm_t alg)270 static int can_sign_or_verify_message(psa_key_usage_t usage,
271 psa_algorithm_t alg)
272 {
273 /* Sign-the-unspecified-hash algorithms can only be used with
274 * {sign,verify}_hash, not with {sign,verify}_message. */
275 if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
276 return 0;
277 }
278 return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
279 PSA_KEY_USAGE_VERIFY_MESSAGE);
280 }
281
exercise_signature_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)282 static int exercise_signature_key(mbedtls_svc_key_id_t key,
283 psa_key_usage_t usage,
284 psa_algorithm_t alg)
285 {
286 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
287 PSA_ALG_IS_SIGN_HASH(alg)) {
288 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
289 size_t payload_length = 16;
290 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
291 size_t signature_length = sizeof(signature);
292 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
293
294 /* If the policy allows signing with any hash, just pick one. */
295 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH) {
296 #if defined(KNOWN_SUPPORTED_HASH_ALG)
297 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
298 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
299 #else
300 TEST_FAIL("No hash algorithm for hash-and-sign testing");
301 #endif
302 }
303
304 /* Some algorithms require the payload to have the size of
305 * the hash encoded in the algorithm. Use this input size
306 * even for algorithms that allow other input sizes. */
307 if (hash_alg != 0) {
308 payload_length = PSA_HASH_LENGTH(hash_alg);
309 }
310
311 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
312 PSA_ASSERT(psa_sign_hash(key, alg,
313 payload, payload_length,
314 signature, sizeof(signature),
315 &signature_length));
316 }
317
318 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
319 psa_status_t verify_status =
320 (usage & PSA_KEY_USAGE_SIGN_HASH ?
321 PSA_SUCCESS :
322 PSA_ERROR_INVALID_SIGNATURE);
323 TEST_EQUAL(psa_verify_hash(key, alg,
324 payload, payload_length,
325 signature, signature_length),
326 verify_status);
327 }
328 }
329
330 if (can_sign_or_verify_message(usage, alg)) {
331 unsigned char message[256] = "Hello, world...";
332 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
333 size_t message_length = 16;
334 size_t signature_length = sizeof(signature);
335
336 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
337 PSA_ASSERT(psa_sign_message(key, alg,
338 message, message_length,
339 signature, sizeof(signature),
340 &signature_length));
341 }
342
343 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
344 psa_status_t verify_status =
345 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
346 PSA_SUCCESS :
347 PSA_ERROR_INVALID_SIGNATURE);
348 TEST_EQUAL(psa_verify_message(key, alg,
349 message, message_length,
350 signature, signature_length),
351 verify_status);
352 }
353 }
354
355 return 1;
356
357 exit:
358 return 0;
359 }
360
exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)361 static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
362 psa_key_usage_t usage,
363 psa_algorithm_t alg)
364 {
365 unsigned char plaintext[256] = "Hello, world...";
366 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
367 size_t ciphertext_length = sizeof(ciphertext);
368 size_t plaintext_length = 16;
369
370 if (usage & PSA_KEY_USAGE_ENCRYPT) {
371 PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
372 plaintext, plaintext_length,
373 NULL, 0,
374 ciphertext, sizeof(ciphertext),
375 &ciphertext_length));
376 }
377
378 if (usage & PSA_KEY_USAGE_DECRYPT) {
379 psa_status_t status =
380 psa_asymmetric_decrypt(key, alg,
381 ciphertext, ciphertext_length,
382 NULL, 0,
383 plaintext, sizeof(plaintext),
384 &plaintext_length);
385 TEST_ASSERT(status == PSA_SUCCESS ||
386 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
387 (status == PSA_ERROR_INVALID_ARGUMENT ||
388 status == PSA_ERROR_INVALID_PADDING)));
389 }
390
391 return 1;
392
393 exit:
394 return 0;
395 }
396
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)397 int mbedtls_test_psa_setup_key_derivation_wrap(
398 psa_key_derivation_operation_t *operation,
399 mbedtls_svc_key_id_t key,
400 psa_algorithm_t alg,
401 const unsigned char *input1, size_t input1_length,
402 const unsigned char *input2, size_t input2_length,
403 size_t capacity)
404 {
405 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
406 if (PSA_ALG_IS_HKDF(alg)) {
407 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
408 PSA_KEY_DERIVATION_INPUT_SALT,
409 input1, input1_length));
410 PSA_ASSERT(psa_key_derivation_input_key(operation,
411 PSA_KEY_DERIVATION_INPUT_SECRET,
412 key));
413 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
414 PSA_KEY_DERIVATION_INPUT_INFO,
415 input2,
416 input2_length));
417 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
418 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
419 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
420 PSA_KEY_DERIVATION_INPUT_SEED,
421 input1, input1_length));
422 PSA_ASSERT(psa_key_derivation_input_key(operation,
423 PSA_KEY_DERIVATION_INPUT_SECRET,
424 key));
425 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
426 PSA_KEY_DERIVATION_INPUT_LABEL,
427 input2, input2_length));
428 } else if (PSA_ALG_IS_PBKDF2(alg)) {
429 PSA_ASSERT(psa_key_derivation_input_integer(operation,
430 PSA_KEY_DERIVATION_INPUT_COST,
431 1U));
432 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
433 PSA_KEY_DERIVATION_INPUT_SALT,
434 input2,
435 input2_length));
436 PSA_ASSERT(psa_key_derivation_input_key(operation,
437 PSA_KEY_DERIVATION_INPUT_PASSWORD,
438 key));
439 } else {
440 TEST_FAIL("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 TEST_CALLOC(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 TEST_CALLOC(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 (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
731 /* Just the secret value */
732 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
733
734 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
735 } else
736
737 #if defined(MBEDTLS_ASN1_PARSE_C)
738 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
739 uint8_t *p = (uint8_t *) exported;
740 const uint8_t *end = exported + exported_length;
741 size_t len;
742 /* RSAPublicKey ::= SEQUENCE {
743 * modulus INTEGER, -- n
744 * publicExponent INTEGER } -- e
745 */
746 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
747 MBEDTLS_ASN1_SEQUENCE |
748 MBEDTLS_ASN1_CONSTRUCTED),
749 0);
750 TEST_EQUAL(len, end - p);
751 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
752 goto exit;
753 }
754 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
755 goto exit;
756 }
757 TEST_EQUAL(p - end, 0);
758
759
760 TEST_ASSERT(exported_length <=
761 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
762 TEST_ASSERT(exported_length <=
763 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
764 } else
765 #endif /* MBEDTLS_ASN1_PARSE_C */
766
767 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
768
769 TEST_ASSERT(exported_length <=
770 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
771 TEST_ASSERT(exported_length <=
772 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
773
774 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
775 /* The representation of an ECC Montgomery public key is
776 * the raw compressed point */
777 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
778 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
779 /* The representation of an ECC Edwards public key is
780 * the raw compressed point */
781 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
782 } else {
783 /* The representation of an ECC Weierstrass public key is:
784 * - The byte 0x04;
785 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
786 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
787 * - where m is the bit size associated with the curve.
788 */
789 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
790 TEST_EQUAL(exported[0], 4);
791 }
792 } else
793 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
794 TEST_ASSERT(exported_length ==
795 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
796 TEST_ASSERT(exported_length <=
797 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
798 } else {
799 (void) exported;
800 TEST_FAIL("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 TEST_CALLOC(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 TEST_CALLOC(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 TEST_CALLOC(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_FAIL("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