blob: 30f21da90ea33dc874d76c491c4b9ab626e3844c [file] [log] [blame]
Gilles Peskine66e7b902021-02-12 23:40:58 +01001/** 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
Dave Rodgman16799db2023-11-02 19:47:20 +00007 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Gilles Peskine66e7b902021-02-12 23:40:58 +01008 */
9
10#include <test/helpers.h>
11#include <test/macros.h>
Gilles Peskinee78b0022021-02-13 00:41:11 +010012#include <test/psa_exercise_key.h>
Gilles Peskine66e7b902021-02-12 23:40:58 +010013
14#if defined(MBEDTLS_PSA_CRYPTO_C)
15
Gilles Peskinee78b0022021-02-13 00:41:11 +010016#include <mbedtls/asn1.h>
Gilles Peskine66e7b902021-02-12 23:40:58 +010017#include <psa/crypto.h>
18
Gilles Peskinee78b0022021-02-13 00:41:11 +010019#include <test/asn1_helpers.h>
Przemyslaw Stekiel53de2622021-11-03 09:35:35 +010020#include <psa_crypto_slot_management.h>
Gilles Peskinee78b0022021-02-13 00:41:11 +010021#include <test/psa_crypto_helpers.h>
22
Gilles Peskine6fe8a062024-02-15 17:21:17 +010023#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
Gilles Peskinee78b0022021-02-13 00:41:11 +010033#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010034static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
Gilles Peskinee78b0022021-02-13 00:41:11 +010035{
Gilles Peskine449bd832023-01-11 14:50:10 +010036 return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
37 PSA_KEY_LOCATION_LOCAL_STORAGE;
Gilles Peskinee78b0022021-02-13 00:41:11 +010038}
39#endif
40
Ryan Everettf08a93f2024-03-12 16:00:08 +000041static int check_key_attributes_sanity(mbedtls_svc_key_id_t key,
42 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +010043{
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;
Gilles Peskine6b362e62021-02-15 12:03:16 +010049 size_t bits;
Ryan Everettf08a93f2024-03-12 16:00:08 +000050 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);
Gilles Peskine449bd832023-01-11 14:50:10 +010057 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);
Gilles Peskinee78b0022021-02-13 00:41:11 +010061
62 /* Persistence */
Gilles Peskine449bd832023-01-11 14:50:10 +010063 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010064 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010065 (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 {
Gilles Peskinee78b0022021-02-13 00:41:11 +010070 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010071 (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));
Gilles Peskinee78b0022021-02-13 00:41:11 +010073 }
74#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Ryan Everettf08a93f2024-03-12 16:00:08 +000075 /* 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 }
Gilles Peskinee78b0022021-02-13 00:41:11 +010089 }
90#endif
91
92 /* Type and size */
Gilles Peskine449bd832023-01-11 14:50:10 +010093 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 }
Gilles Peskinee78b0022021-02-13 00:41:11 +010099
100 /* MAX macros concerning specific key types */
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 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);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100107
108 ok = 1;
109
110exit:
111 /*
112 * Key attributes may have been returned by psa_get_key_attributes()
113 * thus reset them as required.
114 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100116
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100118}
119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120static int exercise_mac_key(mbedtls_svc_key_id_t key,
121 psa_key_usage_t usage,
122 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100123{
124 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
125 const unsigned char input[] = "foo";
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
127 size_t mac_length = sizeof(mac);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100128
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100129 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
131 alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100132 }
133
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
135 PSA_ASSERT(psa_mac_sign_setup(&operation, key, alg));
136 PSA_ASSERT(psa_mac_update(&operation,
137 input, sizeof(input)));
138 PSA_ASSERT(psa_mac_sign_finish(&operation,
139 mac, sizeof(mac),
140 &mac_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100141 }
142
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100144 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 (usage & PSA_KEY_USAGE_SIGN_HASH ?
146 PSA_SUCCESS :
147 PSA_ERROR_INVALID_SIGNATURE);
148 PSA_ASSERT(psa_mac_verify_setup(&operation, key, alg));
149 PSA_ASSERT(psa_mac_update(&operation,
150 input, sizeof(input)));
151 TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
152 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100153 }
154
Gilles Peskine449bd832023-01-11 14:50:10 +0100155 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100156
157exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 psa_mac_abort(&operation);
159 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100160}
161
Gilles Peskine449bd832023-01-11 14:50:10 +0100162static int exercise_cipher_key(mbedtls_svc_key_id_t key,
163 psa_key_usage_t usage,
164 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100165{
166 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100167 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
Gilles Peskine5eef11a2022-04-21 11:14:30 +0200168 size_t iv_length;
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100169 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
170 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100171 const unsigned char plaintext[16] = "Hello, world...";
172 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 size_t ciphertext_length = sizeof(ciphertext);
174 unsigned char decrypted[sizeof(ciphertext)];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100175 size_t part_length;
176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
178 key_type = psa_get_key_type(&attributes);
179 iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 if (usage & PSA_KEY_USAGE_ENCRYPT) {
182 PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
183 if (iv_length != 0) {
184 PSA_ASSERT(psa_cipher_generate_iv(&operation,
185 iv, sizeof(iv),
186 &iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100187 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100188 PSA_ASSERT(psa_cipher_update(&operation,
189 plaintext, sizeof(plaintext),
190 ciphertext, sizeof(ciphertext),
191 &ciphertext_length));
192 PSA_ASSERT(psa_cipher_finish(&operation,
193 ciphertext + ciphertext_length,
194 sizeof(ciphertext) - ciphertext_length,
195 &part_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100196 ciphertext_length += part_length;
197 }
198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100200 psa_status_t status;
201 int maybe_invalid_padding = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
203 maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100204 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
206 if (iv_length != 0) {
207 PSA_ASSERT(psa_cipher_set_iv(&operation,
208 iv, iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100209 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 PSA_ASSERT(psa_cipher_update(&operation,
211 ciphertext, ciphertext_length,
212 decrypted, sizeof(decrypted),
213 &part_length));
214 status = psa_cipher_finish(&operation,
215 decrypted + part_length,
216 sizeof(decrypted) - part_length,
217 &part_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100218 /* For a stream cipher, all inputs are valid. For a block cipher,
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800219 * if the input is some arbitrary data rather than an actual
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 ciphertext, a padding error is likely. */
221 if (maybe_invalid_padding) {
222 TEST_ASSERT(status == PSA_SUCCESS ||
223 status == PSA_ERROR_INVALID_PADDING);
224 } else {
225 PSA_ASSERT(status);
226 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100227 }
228
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100230
231exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 psa_cipher_abort(&operation);
233 psa_reset_key_attributes(&attributes);
234 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100235}
236
Gilles Peskine449bd832023-01-11 14:50:10 +0100237static int exercise_aead_key(mbedtls_svc_key_id_t key,
238 psa_key_usage_t usage,
239 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100240{
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
Gilles Peskine7acb1982022-03-19 11:03:32 +0100242 size_t nonce_length;
243 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
244 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100245 unsigned char plaintext[16] = "Hello, world...";
246 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 size_t ciphertext_length = sizeof(ciphertext);
248 size_t plaintext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100249
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100250 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
252 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100253 }
254
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
256 key_type = psa_get_key_type(&attributes);
257 nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
Steven Cooremanaaec3412021-02-18 13:30:34 +0100258
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 if (usage & PSA_KEY_USAGE_ENCRYPT) {
260 PSA_ASSERT(psa_aead_encrypt(key, alg,
261 nonce, nonce_length,
262 NULL, 0,
263 plaintext, sizeof(plaintext),
264 ciphertext, sizeof(ciphertext),
265 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100266 }
267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100269 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100270 (usage & PSA_KEY_USAGE_ENCRYPT ?
271 PSA_SUCCESS :
272 PSA_ERROR_INVALID_SIGNATURE);
273 TEST_EQUAL(psa_aead_decrypt(key, alg,
274 nonce, nonce_length,
275 NULL, 0,
276 ciphertext, ciphertext_length,
277 plaintext, sizeof(plaintext),
278 &plaintext_length),
279 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100280 }
281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100283
284exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 psa_reset_key_attributes(&attributes);
286 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100287}
288
Gilles Peskine449bd832023-01-11 14:50:10 +0100289static int can_sign_or_verify_message(psa_key_usage_t usage,
290 psa_algorithm_t alg)
Gilles Peskined586b822022-03-19 11:15:41 +0100291{
292 /* Sign-the-unspecified-hash algorithms can only be used with
293 * {sign,verify}_hash, not with {sign,verify}_message. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
295 return 0;
296 }
297 return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
298 PSA_KEY_USAGE_VERIFY_MESSAGE);
Gilles Peskined586b822022-03-19 11:15:41 +0100299}
300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301static int exercise_signature_key(mbedtls_svc_key_id_t key,
302 psa_key_usage_t usage,
303 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100304{
Gilles Peskine4781bd92024-02-09 17:32:45 +0100305 /* If the policy allows signing with any hash, just pick one. */
306 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
307 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
308 usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
309 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
310#if defined(KNOWN_SUPPORTED_HASH_ALG)
311 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
312 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
313#else
314 TEST_FAIL("No hash algorithm for hash-and-sign testing");
315#endif
316 }
317
oberon-skf7a824b2023-02-15 19:43:30 +0100318 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
319 PSA_ALG_IS_SIGN_HASH(alg)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200321 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
323 size_t signature_length = sizeof(signature);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200324
Janos Follath4c0b60e2021-06-14 12:34:30 +0100325 /* Some algorithms require the payload to have the size of
326 * the hash encoded in the algorithm. Use this input size
327 * even for algorithms that allow other input sizes. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 if (hash_alg != 0) {
329 payload_length = PSA_HASH_LENGTH(hash_alg);
330 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100331
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
333 PSA_ASSERT(psa_sign_hash(key, alg,
334 payload, payload_length,
335 signature, sizeof(signature),
336 &signature_length));
337 }
338
339 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
340 psa_status_t verify_status =
341 (usage & PSA_KEY_USAGE_SIGN_HASH ?
342 PSA_SUCCESS :
343 PSA_ERROR_INVALID_SIGNATURE);
344 TEST_EQUAL(psa_verify_hash(key, alg,
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200345 payload, payload_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 signature, signature_length),
347 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200348 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100349 }
350
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200352 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200354 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100356
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
358 PSA_ASSERT(psa_sign_message(key, alg,
359 message, message_length,
360 signature, sizeof(signature),
361 &signature_length));
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200362 }
363
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200365 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
367 PSA_SUCCESS :
368 PSA_ERROR_INVALID_SIGNATURE);
369 TEST_EQUAL(psa_verify_message(key, alg,
370 message, message_length,
371 signature, signature_length),
372 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200373 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100374 }
375
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100377
378exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100380}
381
Gilles Peskine449bd832023-01-11 14:50:10 +0100382static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
383 psa_key_usage_t usage,
384 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100385{
Gilles Peskinef50cd592024-02-15 13:13:26 +0100386 unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100387 "Hello, world...";
Gilles Peskinef50cd592024-02-15 13:13:26 +0100388 unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100389 "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100391 size_t plaintext_length = 16;
392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 if (usage & PSA_KEY_USAGE_ENCRYPT) {
394 PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
395 plaintext, plaintext_length,
396 NULL, 0,
397 ciphertext, sizeof(ciphertext),
398 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100399 }
400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100402 psa_status_t status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 psa_asymmetric_decrypt(key, alg,
404 ciphertext, ciphertext_length,
405 NULL, 0,
406 plaintext, sizeof(plaintext),
407 &plaintext_length);
408 TEST_ASSERT(status == PSA_SUCCESS ||
409 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
410 (status == PSA_ERROR_INVALID_ARGUMENT ||
411 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100412 }
413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100415
416exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100418}
419
420int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100422 mbedtls_svc_key_id_t key,
423 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 const unsigned char *input1, size_t input1_length,
425 const unsigned char *input2, size_t input2_length,
426 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100427{
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
429 if (PSA_ALG_IS_HKDF(alg)) {
430 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
431 PSA_KEY_DERIVATION_INPUT_SALT,
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_INFO,
438 input2,
439 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530440 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
441 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
442 PSA_KEY_DERIVATION_INPUT_SALT,
443 input1, input1_length));
444 PSA_ASSERT(psa_key_derivation_input_key(operation,
445 PSA_KEY_DERIVATION_INPUT_SECRET,
446 key));
447 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
448 PSA_ASSERT(psa_key_derivation_input_key(operation,
449 PSA_KEY_DERIVATION_INPUT_SECRET,
450 key));
451 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
452 PSA_KEY_DERIVATION_INPUT_INFO,
453 input2,
454 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
456 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
457 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
458 PSA_KEY_DERIVATION_INPUT_SEED,
459 input1, input1_length));
460 PSA_ASSERT(psa_key_derivation_input_key(operation,
461 PSA_KEY_DERIVATION_INPUT_SECRET,
462 key));
463 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
464 PSA_KEY_DERIVATION_INPUT_LABEL,
465 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530466 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530467 PSA_ASSERT(psa_key_derivation_input_integer(operation,
468 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530469 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530470 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
471 PSA_KEY_DERIVATION_INPUT_SALT,
472 input2,
473 input2_length));
474 PSA_ASSERT(psa_key_derivation_input_key(operation,
475 PSA_KEY_DERIVATION_INPUT_PASSWORD,
476 key));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530477 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
478 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
479 PSA_KEY_DERIVATION_INPUT_SECRET,
480 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100482 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100483 }
484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 if (capacity != SIZE_MAX) {
486 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
487 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100488
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100490
491exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100493}
494
495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
497 psa_key_usage_t usage,
498 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100499{
500 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
501 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100503 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100505 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100507
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 if (usage & PSA_KEY_USAGE_DERIVE) {
509 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
510 input1, input1_length,
511 input2, input2_length,
512 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100513 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100515
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
517 output,
518 capacity));
519 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100520 }
521
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100523
524exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100526}
527
528/* We need two keys to exercise key agreement. Exercise the
529 * private key against its own public key. */
530psa_status_t mbedtls_test_psa_key_agreement_with_self(
531 psa_key_derivation_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100533{
534 psa_key_type_t private_key_type;
535 psa_key_type_t public_key_type;
536 size_t key_bits;
537 uint8_t *public_key = NULL;
538 size_t public_key_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
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 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);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100550 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
552 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100553
554 status = psa_key_derivation_key_agreement(
555 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100557exit:
558 /*
559 * Key attributes may have been returned by psa_get_key_attributes()
560 * thus reset them as required.
561 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100563
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 mbedtls_free(public_key);
565 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100566}
567
568/* We need two keys to exercise key agreement. Exercise the
569 * private key against its own public key. */
570psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
571 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100573{
574 psa_key_type_t private_key_type;
575 psa_key_type_t public_key_type;
576 size_t key_bits;
577 uint8_t *public_key = NULL;
578 size_t public_key_length;
579 uint8_t output[1024];
580 size_t output_length;
581 /* Return GENERIC_ERROR if something other than the final call to
582 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
583 * but it's good enough: callers will report it as a failed test anyway. */
584 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
585 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
586
Gilles Peskine449bd832023-01-11 14:50:10 +0100587 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
588 private_key_type = psa_get_key_type(&attributes);
589 key_bits = psa_get_key_bits(&attributes);
590 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
591 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100592 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100593 PSA_ASSERT(psa_export_public_key(key,
594 public_key, public_key_length,
595 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100596
Gilles Peskine449bd832023-01-11 14:50:10 +0100597 status = psa_raw_key_agreement(alg, key,
598 public_key, public_key_length,
599 output, sizeof(output), &output_length);
600 if (status == PSA_SUCCESS) {
601 TEST_ASSERT(output_length <=
602 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
603 key_bits));
604 TEST_ASSERT(output_length <=
605 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100606 }
607
Gilles Peskinee78b0022021-02-13 00:41:11 +0100608exit:
609 /*
610 * Key attributes may have been returned by psa_get_key_attributes()
611 * thus reset them as required.
612 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 mbedtls_free(public_key);
616 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100617}
618
Gilles Peskine449bd832023-01-11 14:50:10 +0100619static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
620 psa_key_usage_t usage,
621 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100622{
623 int ok = 0;
624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100626 /* We need two keys to exercise key agreement. Exercise the
627 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100629 }
630 ok = 1;
631
632exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100634}
635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
637 psa_key_usage_t usage,
638 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100639{
640 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200641 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100642 unsigned char output[1];
643 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200645 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100646
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100648 /* We need two keys to exercise key agreement. Exercise the
649 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
651 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
652 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
653 PSA_ASSERT(psa_key_derivation_input_bytes(
654 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
655 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100656 }
657
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
659 PSA_ASSERT(psa_key_derivation_input_bytes(
660 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
661 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200662 }
663
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200664 /* For HKDF_EXPAND input secret may fail as secret size may not match
665 to expected PRK size. In practice it means that key bits must match
666 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200668 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
670 size_t key_bits = psa_get_key_bits(&attributes);
671 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200672
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200674 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200676 }
677
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
679 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200680
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 if (expected_key_agreement_status != PSA_SUCCESS) {
682 return 1;
683 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
686 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
687 PSA_ASSERT(psa_key_derivation_input_bytes(
688 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
689 input, sizeof(input)));
690 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
691 PSA_ASSERT(psa_key_derivation_input_bytes(
692 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
693 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100694 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
696 output,
697 sizeof(output)));
698 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100699 }
700 ok = 1;
701
702exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100704}
705
706int mbedtls_test_psa_exported_key_sanity_check(
707 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100709{
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100711
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
713 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
714 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100715
Ronald Cron64df7382021-07-06 09:23:06 +0200716#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
718 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100719 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100720 size_t len;
721 /* RSAPrivateKey ::= SEQUENCE {
722 * version INTEGER, -- must be 0
723 * modulus INTEGER, -- n
724 * publicExponent INTEGER, -- e
725 * privateExponent INTEGER, -- d
726 * prime1 INTEGER, -- p
727 * prime2 INTEGER, -- q
728 * exponent1 INTEGER, -- d mod (p-1)
729 * exponent2 INTEGER, -- d mod (q-1)
730 * coefficient INTEGER, -- (inverse of q) mod p
731 * }
732 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
734 MBEDTLS_ASN1_SEQUENCE |
735 MBEDTLS_ASN1_CONSTRUCTED), 0);
736 TEST_EQUAL(len, end - p);
737 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100738 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 }
740 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100741 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 }
743 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100744 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100746 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100748 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100750 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100752 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 }
754 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100755 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 }
757 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100758 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 }
760 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100761 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 }
763 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100764 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 }
766 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100767
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
769 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200770#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100773 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100775
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
777 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100778
Ronald Cron64df7382021-07-06 09:23:06 +0200779#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
781 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100782 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100783 size_t len;
784 /* RSAPublicKey ::= SEQUENCE {
785 * modulus INTEGER, -- n
786 * publicExponent INTEGER } -- e
787 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
789 MBEDTLS_ASN1_SEQUENCE |
790 MBEDTLS_ASN1_CONSTRUCTED),
791 0);
792 TEST_EQUAL(len, end - p);
793 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100794 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 }
796 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100797 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 }
799 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100800
801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 TEST_ASSERT(exported_length <=
803 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
804 TEST_ASSERT(exported_length <=
805 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
806 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200807#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100808
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100810
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 TEST_ASSERT(exported_length <=
812 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
813 TEST_ASSERT(exported_length <=
814 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100815
Gilles Peskine449bd832023-01-11 14:50:10 +0100816 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100817 /* The representation of an ECC Montgomery public key is
818 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100820 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100821 /* The representation of an ECC Edwards public key is
822 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100823 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100824 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100825 /* The representation of an ECC Weierstrass public key is:
826 * - The byte 0x04;
827 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
828 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
829 * - where m is the bit size associated with the curve.
830 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100831 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
832 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100833 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100834 } else
835 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200836 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100837 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
838 TEST_ASSERT(exported_length <=
839 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200840 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100841 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100842 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100843 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100844
Gilles Peskinecc9db302021-02-14 01:29:52 +0100845#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100847 /* Check the parity bits. */
848 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100850 unsigned bit_count = 0;
851 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 for (m = 1; m <= 0x100; m <<= 1) {
853 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100854 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100856 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100858 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100859 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100860#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100861
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100863
864exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100866}
867
Gilles Peskine449bd832023-01-11 14:50:10 +0100868static int exercise_export_key(mbedtls_svc_key_id_t key,
869 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100870{
871 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
872 uint8_t *exported = NULL;
873 size_t exported_size = 0;
874 size_t exported_length = 0;
875 int ok = 0;
876
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100878
879 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 psa_get_key_type(&attributes),
881 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100882 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
885 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
886 TEST_EQUAL(psa_export_key(key, exported,
887 exported_size, &exported_length),
888 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100889 ok = 1;
890 goto exit;
891 }
892
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 PSA_ASSERT(psa_export_key(key,
894 exported, exported_size,
895 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100896 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
898 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100899
900exit:
901 /*
902 * Key attributes may have been returned by psa_get_key_attributes()
903 * thus reset them as required.
904 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100906
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 mbedtls_free(exported);
908 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100909}
910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100912{
913 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
914 psa_key_type_t public_type;
915 uint8_t *exported = NULL;
916 size_t exported_size = 0;
917 size_t exported_length = 0;
918 int ok = 0;
919
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
921 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100922 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 psa_get_key_type(&attributes),
924 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100925 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100926
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 TEST_EQUAL(psa_export_public_key(key, exported,
928 exported_size, &exported_length),
929 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100930 ok = 1;
931 goto exit;
932 }
933
934 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 psa_get_key_type(&attributes));
936 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
937 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100938 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100939
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 PSA_ASSERT(psa_export_public_key(key,
941 exported, exported_size,
942 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100943 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 public_type, psa_get_key_bits(&attributes),
945 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100946
947exit:
948 /*
949 * Key attributes may have been returned by psa_get_key_attributes()
950 * thus reset them as required.
951 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 mbedtls_free(exported);
955 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100956}
957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
959 psa_key_usage_t usage,
Ryan Everett0a271fd2024-03-12 16:34:02 +0000960 psa_algorithm_t alg,
961 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100962{
Gilles Peskine2385f712021-02-14 01:34:21 +0100963 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100964
Ryan Everett0a271fd2024-03-12 16:34:02 +0000965 if (!check_key_attributes_sanity(key, key_destroyable)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 return 0;
967 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100968
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800970 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 } else if (PSA_ALG_IS_MAC(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000972 ok = exercise_mac_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 } else if (PSA_ALG_IS_CIPHER(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000974 ok = exercise_cipher_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 } else if (PSA_ALG_IS_AEAD(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000976 ok = exercise_aead_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 } else if (PSA_ALG_IS_SIGN(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000978 ok = exercise_signature_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000980 ok = exercise_asymmetric_encryption_key(key, usage, alg,
981 key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000983 ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000985 ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000987 ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100989 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100991
Ryan Everett0a271fd2024-03-12 16:34:02 +0000992 ok = ok && exercise_export_key(key,
993 usage,
994 key_destroyable);
995 ok = ok && exercise_export_public_key(key,
996 key_destroyable);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100997
Gilles Peskine2385f712021-02-14 01:34:21 +0100998exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001000}
1001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1003 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001004{
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1006 if (PSA_ALG_IS_SIGN_HASH(alg)) {
1007 if (PSA_ALG_SIGN_GET_HASH(alg)) {
1008 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1009 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1010 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1011 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1012 }
1013 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1014 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1015 PSA_KEY_USAGE_VERIFY_MESSAGE :
1016 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001017 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001018
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1020 PSA_KEY_USAGE_VERIFY_HASH :
1021 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1022 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1023 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1024 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1025 PSA_KEY_USAGE_ENCRYPT :
1026 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1027 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1028 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1029 return PSA_KEY_USAGE_DERIVE;
1030 } else {
1031 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001032 }
1033
1034}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001035
Gilles Peskine34955672024-02-12 14:19:24 +01001036int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1037{
1038 /* Reject algorithms that we know are not supported. Default to
1039 * attempting exercise, so that if an algorithm is missing from this
1040 * function, the result will be a test failure and not silently
1041 * omitting exercise. */
1042#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1043 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1044 return 0;
1045 }
1046#endif
1047#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1048 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1049 return 0;
1050 }
1051#endif
1052#if !defined(PSA_WANT_ALG_RSA_PSS)
1053 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1054 return 0;
1055 }
1056#endif
1057#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1058 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1059 return 0;
1060 }
1061#endif
1062#if !defined(PSA_WANT_ALG_ECDSA)
1063 if (PSA_ALG_IS_ECDSA(alg)) {
1064 return 0;
1065 }
1066#endif
1067#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1068 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1069 return 0;
1070 }
1071#endif
1072#if !defined(PSA_WANT_ALG_ECDH)
1073 if (PSA_ALG_IS_ECDH(alg)) {
1074 return 0;
1075 }
1076#endif
1077 (void) alg;
1078 return 1;
1079}
1080
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001081#if defined(MBEDTLS_PK_C)
1082int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1083 const mbedtls_pk_context *pk)
1084{
1085 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1086 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1087 int ok = 0;
1088
1089 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1090 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1091 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1092
1093 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1094 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1095 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1096
1097 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1098 const uint8_t *pk_public = NULL;
1099 size_t pk_public_length = 0;
1100
1101 switch (pk_type) {
1102#if defined(MBEDTLS_RSA_C)
1103 case MBEDTLS_PK_RSA:
1104 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1105 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1106 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1107 uint8_t *cursor = end;
1108 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1109 pk_public_buffer, &cursor));
1110 pk_public = cursor;
1111 pk_public_length = end - pk_public;
1112 break;
1113#endif
1114
1115#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1116 case MBEDTLS_PK_ECKEY:
1117 case MBEDTLS_PK_ECKEY_DH:
1118 case MBEDTLS_PK_ECDSA:
1119 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1120 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1121 pk_public = pk->pub_raw;
1122 pk_public_length = pk->pub_raw_len;
1123 break;
1124#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1125
1126#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1127 case MBEDTLS_PK_ECKEY:
1128 case MBEDTLS_PK_ECKEY_DH:
1129 case MBEDTLS_PK_ECDSA:
1130 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1131 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1132 TEST_EQUAL(mbedtls_ecp_write_public_key(
1133 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1134 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1135 pk_public = pk_public_buffer;
1136 break;
1137#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */
1138
1139#if defined(MBEDTLS_USE_PSA_CRYPTO)
1140 case MBEDTLS_PK_OPAQUE:
1141 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1142 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1143 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1144 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1145 PSA_ASSERT(psa_export_public_key(psa_key,
1146 pk_public_buffer,
1147 sizeof(pk_public_buffer),
1148 &pk_public_length));
1149 pk_public = pk_public_buffer;
1150 break;
1151#endif /* MBEDTLS_USE_PSA_CRYPTO */
1152
1153 default:
1154 TEST_FAIL("pk type not supported");
1155 }
1156
1157 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1158 size_t psa_public_length = 0;
1159 PSA_ASSERT(psa_export_public_key(psa_key,
1160 psa_public, sizeof(psa_public),
1161 &psa_public_length));
1162 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1163 psa_public, psa_public_length);
1164
1165 ok = 1;
1166
1167exit:
1168 psa_reset_key_attributes(&psa_attributes);
1169 psa_reset_key_attributes(&pk_attributes);
1170 return ok;
1171}
1172#endif /* MBEDTLS_PK_C */
1173
Gilles Peskine66e7b902021-02-12 23:40:58 +01001174#endif /* MBEDTLS_PSA_CRYPTO_C */