blob: a496de0212212489ad57e3d857b31e3184463434 [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
David Horstmann8660e4b2024-09-06 14:55:05 +010014#if ((MBEDTLS_VERSION_MAJOR < 4) \
15 && defined(MBEDTLS_PSA_CRYPTO_C)) \
16 || defined(MBEDTLS_PSA_CRYPTO_CLIENT)
Gilles Peskine66e7b902021-02-12 23:40:58 +010017
Gilles Peskinee78b0022021-02-13 00:41:11 +010018#include <mbedtls/asn1.h>
Gilles Peskine66e7b902021-02-12 23:40:58 +010019#include <psa/crypto.h>
20
Gilles Peskinee78b0022021-02-13 00:41:11 +010021#include <test/asn1_helpers.h>
Przemyslaw Stekiel53de2622021-11-03 09:35:35 +010022#include <psa_crypto_slot_management.h>
Gilles Peskinee78b0022021-02-13 00:41:11 +010023#include <test/psa_crypto_helpers.h>
24
Gilles Peskine6fe8a062024-02-15 17:21:17 +010025#if defined(MBEDTLS_PK_C)
26#include <pk_internal.h>
27#endif
28#if defined(MBEDTLS_ECP_C)
29#include <mbedtls/ecp.h>
30#endif
31#if defined(MBEDTLS_RSA_C)
32#include <rsa_internal.h>
33#endif
34
Gilles Peskinee78b0022021-02-13 00:41:11 +010035#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010036static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
Gilles Peskinee78b0022021-02-13 00:41:11 +010037{
Gilles Peskine449bd832023-01-11 14:50:10 +010038 return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
39 PSA_KEY_LOCATION_LOCAL_STORAGE;
Gilles Peskinee78b0022021-02-13 00:41:11 +010040}
41#endif
42
Ryan Everettf08a93f2024-03-12 16:00:08 +000043static int check_key_attributes_sanity(mbedtls_svc_key_id_t key,
44 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +010045{
46 int ok = 0;
47 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
48 psa_key_lifetime_t lifetime;
49 mbedtls_svc_key_id_t id;
50 psa_key_type_t type;
Gilles Peskine6b362e62021-02-15 12:03:16 +010051 size_t bits;
Ryan Everettf08a93f2024-03-12 16:00:08 +000052 psa_status_t status = psa_get_key_attributes(key, &attributes);
53 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
54 /* The key has been destroyed. */
55 psa_reset_key_attributes(&attributes);
56 return 1;
57 }
58 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +010059 lifetime = psa_get_key_lifetime(&attributes);
60 id = psa_get_key_id(&attributes);
61 type = psa_get_key_type(&attributes);
62 bits = psa_get_key_bits(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +010063
64 /* Persistence */
Gilles Peskine449bd832023-01-11 14:50:10 +010065 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010066 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010067 (PSA_KEY_ID_VOLATILE_MIN <=
68 MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
69 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
70 PSA_KEY_ID_VOLATILE_MAX));
71 } else {
Gilles Peskinee78b0022021-02-13 00:41:11 +010072 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010073 (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
74 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
Gilles Peskinee78b0022021-02-13 00:41:11 +010075 }
76#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Ryan Everettf08a93f2024-03-12 16:00:08 +000077 /* MBEDTLS_PSA_CRYPTO_SE_C does not support thread safety. */
78 if (key_destroyable == 0) {
79 /* randomly-generated 64-bit constant, should never appear in test data */
80 psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
81 status = psa_get_key_slot_number(&attributes, &slot_number);
82 if (lifetime_is_dynamic_secure_element(lifetime)) {
83 /* Mbed TLS currently always exposes the slot number to
84 * applications. This is not mandated by the PSA specification
85 * and may change in future versions. */
86 TEST_EQUAL(status, 0);
87 TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
88 } else {
89 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
90 }
Gilles Peskinee78b0022021-02-13 00:41:11 +010091 }
92#endif
93
94 /* Type and size */
Gilles Peskine449bd832023-01-11 14:50:10 +010095 TEST_ASSERT(type != 0);
96 TEST_ASSERT(bits != 0);
97 TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
98 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
99 TEST_ASSERT(bits % 8 == 0);
100 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100101
102 /* MAX macros concerning specific key types */
Gilles Peskine449bd832023-01-11 14:50:10 +0100103 if (PSA_KEY_TYPE_IS_ECC(type)) {
104 TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
105 } else if (PSA_KEY_TYPE_IS_RSA(type)) {
106 TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
107 }
108 TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100109
110 ok = 1;
111
112exit:
113 /*
114 * Key attributes may have been returned by psa_get_key_attributes()
115 * thus reset them as required.
116 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100118
Gilles Peskine449bd832023-01-11 14:50:10 +0100119 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100120}
121
Gilles Peskine449bd832023-01-11 14:50:10 +0100122static int exercise_mac_key(mbedtls_svc_key_id_t key,
123 psa_key_usage_t usage,
Ryan Everett77635502024-03-12 16:02:23 +0000124 psa_algorithm_t alg,
125 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100126{
127 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
128 const unsigned char input[] = "foo";
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
130 size_t mac_length = sizeof(mac);
Ryan Everett77635502024-03-12 16:02:23 +0000131 psa_status_t status = PSA_SUCCESS;
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100132 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
134 alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100135 }
136
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
Ryan Everett77635502024-03-12 16:02:23 +0000138 status = psa_mac_sign_setup(&operation, key, alg);
139 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
140 /* The key has been destroyed. */
141 PSA_ASSERT(psa_mac_abort(&operation));
142 return 1;
143 }
144 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 PSA_ASSERT(psa_mac_update(&operation,
146 input, sizeof(input)));
147 PSA_ASSERT(psa_mac_sign_finish(&operation,
148 mac, sizeof(mac),
149 &mac_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100150 }
151
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100153 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 (usage & PSA_KEY_USAGE_SIGN_HASH ?
155 PSA_SUCCESS :
156 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett77635502024-03-12 16:02:23 +0000157 status = psa_mac_verify_setup(&operation, key, alg);
158 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
159 /* The key has been destroyed. */
160 PSA_ASSERT(psa_mac_abort(&operation));
161 return 1;
162 }
163 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100164 PSA_ASSERT(psa_mac_update(&operation,
165 input, sizeof(input)));
166 TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
167 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100168 }
169
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100171
172exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 psa_mac_abort(&operation);
174 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100175}
176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177static int exercise_cipher_key(mbedtls_svc_key_id_t key,
178 psa_key_usage_t usage,
Ryan Everett70691f32024-03-12 16:04:45 +0000179 psa_algorithm_t alg,
180 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100181{
182 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
Gilles Peskine5eef11a2022-04-21 11:14:30 +0200184 size_t iv_length;
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100185 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
186 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100187 const unsigned char plaintext[16] = "Hello, world...";
188 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 size_t ciphertext_length = sizeof(ciphertext);
190 unsigned char decrypted[sizeof(ciphertext)];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100191 size_t part_length;
Ryan Everett70691f32024-03-12 16:04:45 +0000192 psa_status_t status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
195 key_type = psa_get_key_type(&attributes);
196 iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100197
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everett70691f32024-03-12 16:04:45 +0000199 status = psa_cipher_encrypt_setup(&operation, key, alg);
200 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
201 /* The key has been destroyed. */
202 PSA_ASSERT(psa_cipher_abort(&operation));
203 return 1;
204 }
205 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 if (iv_length != 0) {
207 PSA_ASSERT(psa_cipher_generate_iv(&operation,
208 iv, sizeof(iv),
209 &iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100210 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100211 PSA_ASSERT(psa_cipher_update(&operation,
212 plaintext, sizeof(plaintext),
213 ciphertext, sizeof(ciphertext),
214 &ciphertext_length));
215 PSA_ASSERT(psa_cipher_finish(&operation,
216 ciphertext + ciphertext_length,
217 sizeof(ciphertext) - ciphertext_length,
218 &part_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100219 ciphertext_length += part_length;
220 }
221
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100223 int maybe_invalid_padding = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
225 maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100226 }
Ryan Everett70691f32024-03-12 16:04:45 +0000227 status = psa_cipher_decrypt_setup(&operation, key, alg);
228 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
229 /* The key has been destroyed. */
230 PSA_ASSERT(psa_cipher_abort(&operation));
231 return 1;
232 }
233 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 if (iv_length != 0) {
235 PSA_ASSERT(psa_cipher_set_iv(&operation,
236 iv, iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100237 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 PSA_ASSERT(psa_cipher_update(&operation,
239 ciphertext, ciphertext_length,
240 decrypted, sizeof(decrypted),
241 &part_length));
242 status = psa_cipher_finish(&operation,
243 decrypted + part_length,
244 sizeof(decrypted) - part_length,
245 &part_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100246 /* For a stream cipher, all inputs are valid. For a block cipher,
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800247 * if the input is some arbitrary data rather than an actual
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 ciphertext, a padding error is likely. */
249 if (maybe_invalid_padding) {
250 TEST_ASSERT(status == PSA_SUCCESS ||
251 status == PSA_ERROR_INVALID_PADDING);
252 } else {
253 PSA_ASSERT(status);
254 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100255 }
256
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100258
259exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 psa_cipher_abort(&operation);
261 psa_reset_key_attributes(&attributes);
262 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100263}
264
Gilles Peskine449bd832023-01-11 14:50:10 +0100265static int exercise_aead_key(mbedtls_svc_key_id_t key,
266 psa_key_usage_t usage,
Ryan Everettfbe703d2024-03-12 16:09:25 +0000267 psa_algorithm_t alg,
268 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100269{
Gilles Peskine449bd832023-01-11 14:50:10 +0100270 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
Gilles Peskine7acb1982022-03-19 11:03:32 +0100271 size_t nonce_length;
272 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
273 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100274 unsigned char plaintext[16] = "Hello, world...";
275 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 size_t ciphertext_length = sizeof(ciphertext);
277 size_t plaintext_length = sizeof(ciphertext);
Ryan Everettfbe703d2024-03-12 16:09:25 +0000278 psa_status_t status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100279
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100280 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
282 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100283 }
284
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
286 key_type = psa_get_key_type(&attributes);
287 nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
Steven Cooremanaaec3412021-02-18 13:30:34 +0100288
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everettfbe703d2024-03-12 16:09:25 +0000290 status = psa_aead_encrypt(key, alg,
291 nonce, nonce_length,
292 NULL, 0,
293 plaintext, sizeof(plaintext),
294 ciphertext, sizeof(ciphertext),
295 &ciphertext_length);
296 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
297 /* The key has been destroyed. */
298 return 1;
299 }
300 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100301 }
302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100304 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 (usage & PSA_KEY_USAGE_ENCRYPT ?
306 PSA_SUCCESS :
307 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everettfbe703d2024-03-12 16:09:25 +0000308 status = psa_aead_decrypt(key, alg,
309 nonce, nonce_length,
310 NULL, 0,
311 ciphertext, ciphertext_length,
312 plaintext, sizeof(plaintext),
313 &plaintext_length);
314 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
315 /* The key has been destroyed. */
316 return 1;
317 }
318 TEST_ASSERT(status == verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100319 }
320
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100322
323exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 psa_reset_key_attributes(&attributes);
325 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100326}
327
Gilles Peskine449bd832023-01-11 14:50:10 +0100328static int can_sign_or_verify_message(psa_key_usage_t usage,
329 psa_algorithm_t alg)
Gilles Peskined586b822022-03-19 11:15:41 +0100330{
331 /* Sign-the-unspecified-hash algorithms can only be used with
332 * {sign,verify}_hash, not with {sign,verify}_message. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
334 return 0;
335 }
336 return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
337 PSA_KEY_USAGE_VERIFY_MESSAGE);
Gilles Peskined586b822022-03-19 11:15:41 +0100338}
339
Gilles Peskine449bd832023-01-11 14:50:10 +0100340static int exercise_signature_key(mbedtls_svc_key_id_t key,
341 psa_key_usage_t usage,
Ryan Everett6edd4082024-03-12 16:11:01 +0000342 psa_algorithm_t alg,
343 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100344{
Gilles Peskine4781bd92024-02-09 17:32:45 +0100345 /* If the policy allows signing with any hash, just pick one. */
346 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
347 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
348 usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
349 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
350#if defined(KNOWN_SUPPORTED_HASH_ALG)
351 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
352 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
353#else
354 TEST_FAIL("No hash algorithm for hash-and-sign testing");
355#endif
356 }
Ryan Everett6edd4082024-03-12 16:11:01 +0000357 psa_status_t status = PSA_SUCCESS;
Gilles Peskine4781bd92024-02-09 17:32:45 +0100358
oberon-skf7a824b2023-02-15 19:43:30 +0100359 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
360 PSA_ALG_IS_SIGN_HASH(alg)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200362 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
364 size_t signature_length = sizeof(signature);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200365
Janos Follath4c0b60e2021-06-14 12:34:30 +0100366 /* Some algorithms require the payload to have the size of
367 * the hash encoded in the algorithm. Use this input size
368 * even for algorithms that allow other input sizes. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 if (hash_alg != 0) {
370 payload_length = PSA_HASH_LENGTH(hash_alg);
371 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100372
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
Ryan Everett6edd4082024-03-12 16:11:01 +0000374 status = psa_sign_hash(key, alg,
375 payload, payload_length,
376 signature, sizeof(signature),
377 &signature_length);
378 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
379 /* The key has been destroyed. */
380 return 1;
381 }
382 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 }
384
385 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
386 psa_status_t verify_status =
387 (usage & PSA_KEY_USAGE_SIGN_HASH ?
388 PSA_SUCCESS :
389 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett6edd4082024-03-12 16:11:01 +0000390 status = psa_verify_hash(key, alg,
391 payload, payload_length,
392 signature, signature_length);
393 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
394 /* The key has been destroyed. */
395 return 1;
396 }
397 TEST_ASSERT(status == verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200398 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100399 }
400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200402 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200404 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100406
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
Ryan Everett6edd4082024-03-12 16:11:01 +0000408 status = psa_sign_message(key, alg,
409 message, message_length,
410 signature, sizeof(signature),
411 &signature_length);
412 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
413 /* The key has been destroyed. */
414 return 1;
415 }
416 PSA_ASSERT(status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200417 }
418
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200420 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
422 PSA_SUCCESS :
423 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett6edd4082024-03-12 16:11:01 +0000424 status = psa_verify_message(key, alg,
425 message, message_length,
426 signature, signature_length);
427 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
428 /* The key has been destroyed. */
429 return 1;
430 }
431 TEST_ASSERT(status == verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200432 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100433 }
434
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100436
437exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100439}
440
Gilles Peskine449bd832023-01-11 14:50:10 +0100441static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
442 psa_key_usage_t usage,
Ryan Everettd48fc102024-03-12 16:12:41 +0000443 psa_algorithm_t alg,
444 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100445{
Gilles Peskinef50cd592024-02-15 13:13:26 +0100446 unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100447 "Hello, world...";
Gilles Peskinef50cd592024-02-15 13:13:26 +0100448 unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100449 "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100451 size_t plaintext_length = 16;
Ryan Everettd48fc102024-03-12 16:12:41 +0000452 psa_status_t status = PSA_SUCCESS;
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everettd48fc102024-03-12 16:12:41 +0000454 status = psa_asymmetric_encrypt(key, alg,
455 plaintext, plaintext_length,
456 NULL, 0,
457 ciphertext, sizeof(ciphertext),
458 &ciphertext_length);
459 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
460 /* The key has been destroyed. */
461 return 1;
462 }
463 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100464 }
465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 if (usage & PSA_KEY_USAGE_DECRYPT) {
Ryan Everettd48fc102024-03-12 16:12:41 +0000467 status = psa_asymmetric_decrypt(key, alg,
468 ciphertext, ciphertext_length,
469 NULL, 0,
470 plaintext, sizeof(plaintext),
471 &plaintext_length);
472 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
473 /* The key has been destroyed. */
474 return 1;
475 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 TEST_ASSERT(status == PSA_SUCCESS ||
477 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
478 (status == PSA_ERROR_INVALID_ARGUMENT ||
479 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100480 }
481
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100483
484exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100486}
487
488int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100490 mbedtls_svc_key_id_t key,
491 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 const unsigned char *input1, size_t input1_length,
493 const unsigned char *input2, size_t input2_length,
Ryan Everettc1cc6682024-03-12 16:17:43 +0000494 size_t capacity, int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100495{
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000497 psa_status_t status = PSA_SUCCESS;
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 if (PSA_ALG_IS_HKDF(alg)) {
499 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
500 PSA_KEY_DERIVATION_INPUT_SALT,
501 input1, input1_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000502 status = psa_key_derivation_input_key(operation,
503 PSA_KEY_DERIVATION_INPUT_SECRET,
504 key);
505 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
506 /* The key has been destroyed. */
507 return 1;
508 }
509 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
511 PSA_KEY_DERIVATION_INPUT_INFO,
512 input2,
513 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530514 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
515 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
516 PSA_KEY_DERIVATION_INPUT_SALT,
517 input1, input1_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000518 status = psa_key_derivation_input_key(operation,
519 PSA_KEY_DERIVATION_INPUT_SECRET,
520 key);
521 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
522 /* The key has been destroyed. */
523 return 1;
524 }
525 PSA_ASSERT(status);
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530526 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
Ryan Everettc1cc6682024-03-12 16:17:43 +0000527 status = psa_key_derivation_input_key(operation,
528 PSA_KEY_DERIVATION_INPUT_SECRET,
529 key);
530 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
531 /* The key has been destroyed. */
532 return 1;
533 }
534 PSA_ASSERT(status);
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530535 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
536 PSA_KEY_DERIVATION_INPUT_INFO,
537 input2,
538 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
540 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
541 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
542 PSA_KEY_DERIVATION_INPUT_SEED,
543 input1, input1_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000544 status = psa_key_derivation_input_key(operation,
545 PSA_KEY_DERIVATION_INPUT_SECRET,
546 key);
547 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
548 /* The key has been destroyed. */
549 return 1;
550 }
551 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
553 PSA_KEY_DERIVATION_INPUT_LABEL,
554 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530555 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530556 PSA_ASSERT(psa_key_derivation_input_integer(operation,
557 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530558 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530559 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
560 PSA_KEY_DERIVATION_INPUT_SALT,
561 input2,
562 input2_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000563 status = psa_key_derivation_input_key(operation,
564 PSA_KEY_DERIVATION_INPUT_PASSWORD,
565 key);
566 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
567 /* The key has been destroyed. */
568 return 1;
569 }
570 PSA_ASSERT(status);
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530571 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
572 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
573 PSA_KEY_DERIVATION_INPUT_SECRET,
574 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100576 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100577 }
578
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 if (capacity != SIZE_MAX) {
580 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
581 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100584
585exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100587}
588
589
Gilles Peskine449bd832023-01-11 14:50:10 +0100590static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
591 psa_key_usage_t usage,
Ryan Everettc1cc6682024-03-12 16:17:43 +0000592 psa_algorithm_t alg,
593 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100594{
595 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
596 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100597 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100598 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100600 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100602
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 if (usage & PSA_KEY_USAGE_DERIVE) {
604 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
605 input1, input1_length,
606 input2, input2_length,
Ryan Everettc1cc6682024-03-12 16:17:43 +0000607 capacity, key_destroyable)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100608 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100610
Ryan Everettc1cc6682024-03-12 16:17:43 +0000611 psa_status_t status = psa_key_derivation_output_bytes(&operation,
612 output,
613 capacity);
614 if (key_destroyable && status == PSA_ERROR_BAD_STATE) {
615 /* The key has been destroyed. */
616 PSA_ASSERT(psa_key_derivation_abort(&operation));
617 } else {
618 PSA_ASSERT(status);
619 PSA_ASSERT(psa_key_derivation_abort(&operation));
620 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100621 }
622
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100624
625exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100627}
628
629/* We need two keys to exercise key agreement. Exercise the
630 * private key against its own public key. */
631psa_status_t mbedtls_test_psa_key_agreement_with_self(
632 psa_key_derivation_operation_t *operation,
Ryan Everett73e4ea32024-03-12 16:29:55 +0000633 mbedtls_svc_key_id_t key, int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100634{
635 psa_key_type_t private_key_type;
636 psa_key_type_t public_key_type;
637 size_t key_bits;
638 uint8_t *public_key = NULL;
639 size_t public_key_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100640 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
641
Ryan Everett73e4ea32024-03-12 16:29:55 +0000642 psa_status_t status = psa_get_key_attributes(key, &attributes);
643 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
644 /* The key has been destroyed. */
645 psa_reset_key_attributes(&attributes);
646 return PSA_SUCCESS;
647 }
648 PSA_ASSERT(status);
649
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 private_key_type = psa_get_key_type(&attributes);
651 key_bits = psa_get_key_bits(&attributes);
652 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
653 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100654 TEST_CALLOC(public_key, public_key_length);
Ryan Everett73e4ea32024-03-12 16:29:55 +0000655 status = psa_export_public_key(key, public_key, public_key_length,
656 &public_key_length);
657 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
658 /* The key has been destroyed. */
659 status = PSA_SUCCESS;
660 goto exit;
661 }
662 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100663
664 status = psa_key_derivation_key_agreement(
665 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 public_key, public_key_length);
Ryan Everett73e4ea32024-03-12 16:29:55 +0000667 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
668 /* The key has been destroyed. */
669 status = PSA_SUCCESS;
670 goto exit;
671 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100672exit:
673 /*
674 * Key attributes may have been returned by psa_get_key_attributes()
675 * thus reset them as required.
676 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 mbedtls_free(public_key);
680 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100681}
682
683/* We need two keys to exercise key agreement. Exercise the
684 * private key against its own public key. */
685psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
686 psa_algorithm_t alg,
Ryan Everett81630282024-03-12 16:21:12 +0000687 mbedtls_svc_key_id_t key,
688 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100689{
690 psa_key_type_t private_key_type;
691 psa_key_type_t public_key_type;
692 size_t key_bits;
693 uint8_t *public_key = NULL;
694 size_t public_key_length;
695 uint8_t output[1024];
696 size_t output_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100697 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
698
Ryan Everett81630282024-03-12 16:21:12 +0000699 psa_status_t status = psa_get_key_attributes(key, &attributes);
700 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
701 /* The key has been destroyed. */
702 psa_reset_key_attributes(&attributes);
703 return PSA_SUCCESS;
704 }
705 PSA_ASSERT(status);
706
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 private_key_type = psa_get_key_type(&attributes);
708 key_bits = psa_get_key_bits(&attributes);
709 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
710 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100711 TEST_CALLOC(public_key, public_key_length);
Ryan Everett81630282024-03-12 16:21:12 +0000712 status = psa_export_public_key(key,
713 public_key, public_key_length,
714 &public_key_length);
715 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
716 /* The key has been destroyed. */
717 status = PSA_SUCCESS;
718 goto exit;
719 }
Ryan Everett6de38ac2024-03-14 17:50:39 +0000720 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100721
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 status = psa_raw_key_agreement(alg, key,
723 public_key, public_key_length,
724 output, sizeof(output), &output_length);
Ryan Everett81630282024-03-12 16:21:12 +0000725 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
726 /* The key has been destroyed. */
727 status = PSA_SUCCESS;
728 goto exit;
729 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 if (status == PSA_SUCCESS) {
731 TEST_ASSERT(output_length <=
732 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
733 key_bits));
734 TEST_ASSERT(output_length <=
735 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100736 }
737
Gilles Peskinee78b0022021-02-13 00:41:11 +0100738exit:
739 /*
740 * Key attributes may have been returned by psa_get_key_attributes()
741 * thus reset them as required.
742 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100744
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 mbedtls_free(public_key);
746 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100747}
748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
750 psa_key_usage_t usage,
Ryan Everett81630282024-03-12 16:21:12 +0000751 psa_algorithm_t alg,
752 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100753{
754 int ok = 0;
755
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100757 /* We need two keys to exercise key agreement. Exercise the
758 * private key against its own public key. */
Ryan Everett81630282024-03-12 16:21:12 +0000759 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key,
760 key_destroyable));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100761 }
762 ok = 1;
763
764exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100766}
767
Gilles Peskine449bd832023-01-11 14:50:10 +0100768static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
769 psa_key_usage_t usage,
Ryan Everett73e4ea32024-03-12 16:29:55 +0000770 psa_algorithm_t alg,
771 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100772{
773 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200774 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100775 unsigned char output[1];
776 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200778 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100781 /* We need two keys to exercise key agreement. Exercise the
782 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
784 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
785 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
786 PSA_ASSERT(psa_key_derivation_input_bytes(
787 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
788 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100789 }
790
Gilles Peskine449bd832023-01-11 14:50:10 +0100791 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
792 PSA_ASSERT(psa_key_derivation_input_bytes(
793 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
794 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200795 }
796
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200797 /* For HKDF_EXPAND input secret may fail as secret size may not match
798 to expected PRK size. In practice it means that key bits must match
799 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200801 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ryan Everett73e4ea32024-03-12 16:29:55 +0000802 psa_status_t status = psa_get_key_attributes(key, &attributes);
803 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
804 /* The key has been destroyed. */
805 ok = 1;
806 }
807 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 size_t key_bits = psa_get_key_bits(&attributes);
809 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200810
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200812 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200814 }
815
Ryan Everett73e4ea32024-03-12 16:29:55 +0000816 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key,
817 key_destroyable),
Gilles Peskine449bd832023-01-11 14:50:10 +0100818 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200819
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 if (expected_key_agreement_status != PSA_SUCCESS) {
821 return 1;
822 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100823
Gilles Peskine449bd832023-01-11 14:50:10 +0100824 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
825 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
826 PSA_ASSERT(psa_key_derivation_input_bytes(
827 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
828 input, sizeof(input)));
829 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
830 PSA_ASSERT(psa_key_derivation_input_bytes(
831 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
832 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100833 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
835 output,
836 sizeof(output)));
837 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100838 }
839 ok = 1;
840
841exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100843}
844
845int mbedtls_test_psa_exported_key_sanity_check(
846 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100848{
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
852 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
853 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100854
Ronald Cron64df7382021-07-06 09:23:06 +0200855#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
857 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100858 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100859 size_t len;
860 /* RSAPrivateKey ::= SEQUENCE {
861 * version INTEGER, -- must be 0
862 * modulus INTEGER, -- n
863 * publicExponent INTEGER, -- e
864 * privateExponent INTEGER, -- d
865 * prime1 INTEGER, -- p
866 * prime2 INTEGER, -- q
867 * exponent1 INTEGER, -- d mod (p-1)
868 * exponent2 INTEGER, -- d mod (q-1)
869 * coefficient INTEGER, -- (inverse of q) mod p
870 * }
871 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
873 MBEDTLS_ASN1_SEQUENCE |
874 MBEDTLS_ASN1_CONSTRUCTED), 0);
875 TEST_EQUAL(len, end - p);
876 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100877 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 }
879 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100880 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 }
882 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100883 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100885 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100887 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100889 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100891 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 }
893 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100894 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 }
896 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100897 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 }
899 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100900 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 }
902 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100903 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 }
905 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100906
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
908 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200909#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100912 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100914
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
916 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100917
Ronald Cron64df7382021-07-06 09:23:06 +0200918#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
920 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100921 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100922 size_t len;
923 /* RSAPublicKey ::= SEQUENCE {
924 * modulus INTEGER, -- n
925 * publicExponent INTEGER } -- e
926 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
928 MBEDTLS_ASN1_SEQUENCE |
929 MBEDTLS_ASN1_CONSTRUCTED),
930 0);
931 TEST_EQUAL(len, end - p);
932 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100933 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 }
935 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100936 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 }
938 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100939
940
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 TEST_ASSERT(exported_length <=
942 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
943 TEST_ASSERT(exported_length <=
944 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
945 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200946#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100947
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 TEST_ASSERT(exported_length <=
951 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
952 TEST_ASSERT(exported_length <=
953 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100954
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100956 /* The representation of an ECC Montgomery public key is
957 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100959 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100960 /* The representation of an ECC Edwards public key is
961 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100962 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100964 /* The representation of an ECC Weierstrass public key is:
965 * - The byte 0x04;
966 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
967 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
968 * - where m is the bit size associated with the curve.
969 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
971 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100972 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100973 } else
974 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200975 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100976 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
977 TEST_ASSERT(exported_length <=
978 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200979 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100980 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100981 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100982 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100983
Gilles Peskinecc9db302021-02-14 01:29:52 +0100984#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100986 /* Check the parity bits. */
987 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100989 unsigned bit_count = 0;
990 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 for (m = 1; m <= 0x100; m <<= 1) {
992 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100993 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100995 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100996 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100997 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100998 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100999#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +01001000
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001002
1003exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001005}
1006
Gilles Peskine449bd832023-01-11 14:50:10 +01001007static int exercise_export_key(mbedtls_svc_key_id_t key,
Ryan Everettfbf815d2024-03-12 16:32:29 +00001008 psa_key_usage_t usage,
1009 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001010{
1011 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1012 uint8_t *exported = NULL;
1013 size_t exported_size = 0;
1014 size_t exported_length = 0;
1015 int ok = 0;
1016
Ryan Everettfbf815d2024-03-12 16:32:29 +00001017 psa_status_t status = psa_get_key_attributes(key, &attributes);
1018 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1019 /* The key has been destroyed. */
1020 psa_reset_key_attributes(&attributes);
1021 return 1;
1022 }
1023 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001024
1025 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 psa_get_key_type(&attributes),
1027 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001028 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001029
Ryan Everettfbf815d2024-03-12 16:32:29 +00001030 status = psa_export_key(key, exported, exported_size, &exported_length);
1031 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1032 /* The key has been destroyed. */
1033 ok = 1;
1034 goto exit;
1035 } else if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
1036 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
1037 TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001038 ok = 1;
1039 goto exit;
1040 }
Ryan Everettfbf815d2024-03-12 16:32:29 +00001041 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001042 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
1044 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001045
1046exit:
1047 /*
1048 * Key attributes may have been returned by psa_get_key_attributes()
1049 * thus reset them as required.
1050 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001052
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 mbedtls_free(exported);
1054 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001055}
1056
Ryan Everettfbf815d2024-03-12 16:32:29 +00001057static int exercise_export_public_key(mbedtls_svc_key_id_t key,
1058 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001059{
1060 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1061 psa_key_type_t public_type;
1062 uint8_t *exported = NULL;
1063 size_t exported_size = 0;
1064 size_t exported_length = 0;
1065 int ok = 0;
1066
Ryan Everettfbf815d2024-03-12 16:32:29 +00001067 psa_status_t status = psa_get_key_attributes(key, &attributes);
1068 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1069 /* The key has been destroyed. */
1070 psa_reset_key_attributes(&attributes);
1071 return 1;
1072 }
1073 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +01001075 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 psa_get_key_type(&attributes),
1077 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001078 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001079
Ryan Everettfbf815d2024-03-12 16:32:29 +00001080 status = psa_export_public_key(key, exported,
1081 exported_size, &exported_length);
1082 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1083 /* The key has been destroyed. */
1084 ok = 1;
1085 goto exit;
1086 }
1087 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001088 ok = 1;
1089 goto exit;
1090 }
1091
1092 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 psa_get_key_type(&attributes));
1094 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
1095 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001096 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001097
Ryan Everettfbf815d2024-03-12 16:32:29 +00001098 status = psa_export_public_key(key, exported,
1099 exported_size, &exported_length);
1100 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1101 /* The key has been destroyed. */
1102 ok = 1;
1103 goto exit;
1104 }
1105 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001106 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 public_type, psa_get_key_bits(&attributes),
1108 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001109
1110exit:
1111 /*
1112 * Key attributes may have been returned by psa_get_key_attributes()
1113 * thus reset them as required.
1114 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001115 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001116
Gilles Peskine449bd832023-01-11 14:50:10 +01001117 mbedtls_free(exported);
1118 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001119}
1120
Gilles Peskine449bd832023-01-11 14:50:10 +01001121int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
1122 psa_key_usage_t usage,
Ryan Everett0a271fd2024-03-12 16:34:02 +00001123 psa_algorithm_t alg,
1124 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001125{
Gilles Peskine2385f712021-02-14 01:34:21 +01001126 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001127
Ryan Everett0a271fd2024-03-12 16:34:02 +00001128 if (!check_key_attributes_sanity(key, key_destroyable)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001129 return 0;
1130 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001131
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001133 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 } else if (PSA_ALG_IS_MAC(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001135 ok = exercise_mac_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001136 } else if (PSA_ALG_IS_CIPHER(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001137 ok = exercise_cipher_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 } else if (PSA_ALG_IS_AEAD(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001139 ok = exercise_aead_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 } else if (PSA_ALG_IS_SIGN(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001141 ok = exercise_signature_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001142 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001143 ok = exercise_asymmetric_encryption_key(key, usage, alg,
1144 key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001146 ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001147 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001148 ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001149 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001150 ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +01001152 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +01001153 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001154
Ryan Everett0a271fd2024-03-12 16:34:02 +00001155 ok = ok && exercise_export_key(key,
1156 usage,
1157 key_destroyable);
1158 ok = ok && exercise_export_public_key(key,
1159 key_destroyable);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001160
Gilles Peskine2385f712021-02-14 01:34:21 +01001161exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001163}
1164
Gilles Peskine449bd832023-01-11 14:50:10 +01001165psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1166 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001167{
Gilles Peskine449bd832023-01-11 14:50:10 +01001168 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1169 if (PSA_ALG_IS_SIGN_HASH(alg)) {
1170 if (PSA_ALG_SIGN_GET_HASH(alg)) {
1171 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1172 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1173 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1174 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1175 }
1176 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1177 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1178 PSA_KEY_USAGE_VERIFY_MESSAGE :
1179 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001180 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001181
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1183 PSA_KEY_USAGE_VERIFY_HASH :
1184 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1185 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1186 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1187 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1188 PSA_KEY_USAGE_ENCRYPT :
1189 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1190 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1191 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1192 return PSA_KEY_USAGE_DERIVE;
1193 } else {
1194 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001195 }
1196
1197}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001198
Gilles Peskine34955672024-02-12 14:19:24 +01001199int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1200{
1201 /* Reject algorithms that we know are not supported. Default to
1202 * attempting exercise, so that if an algorithm is missing from this
1203 * function, the result will be a test failure and not silently
1204 * omitting exercise. */
1205#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1206 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1207 return 0;
1208 }
1209#endif
1210#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1211 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1212 return 0;
1213 }
1214#endif
1215#if !defined(PSA_WANT_ALG_RSA_PSS)
1216 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1217 return 0;
1218 }
1219#endif
1220#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1221 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1222 return 0;
1223 }
1224#endif
1225#if !defined(PSA_WANT_ALG_ECDSA)
1226 if (PSA_ALG_IS_ECDSA(alg)) {
1227 return 0;
1228 }
1229#endif
1230#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1231 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1232 return 0;
1233 }
1234#endif
1235#if !defined(PSA_WANT_ALG_ECDH)
1236 if (PSA_ALG_IS_ECDH(alg)) {
1237 return 0;
1238 }
1239#endif
1240 (void) alg;
1241 return 1;
1242}
1243
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001244#if defined(MBEDTLS_PK_C)
1245int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1246 const mbedtls_pk_context *pk)
1247{
1248 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1249 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1250 int ok = 0;
1251
1252 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1253 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1254 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1255
1256 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1257 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1258 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1259
1260 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1261 const uint8_t *pk_public = NULL;
1262 size_t pk_public_length = 0;
1263
1264 switch (pk_type) {
1265#if defined(MBEDTLS_RSA_C)
1266 case MBEDTLS_PK_RSA:
1267 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1268 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1269 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1270 uint8_t *cursor = end;
1271 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1272 pk_public_buffer, &cursor));
1273 pk_public = cursor;
1274 pk_public_length = end - pk_public;
1275 break;
1276#endif
1277
1278#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1279 case MBEDTLS_PK_ECKEY:
1280 case MBEDTLS_PK_ECKEY_DH:
1281 case MBEDTLS_PK_ECDSA:
1282 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1283 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1284 pk_public = pk->pub_raw;
1285 pk_public_length = pk->pub_raw_len;
1286 break;
1287#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1288
David Horstmann8660e4b2024-09-06 14:55:05 +01001289#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001290 case MBEDTLS_PK_ECKEY:
1291 case MBEDTLS_PK_ECKEY_DH:
1292 case MBEDTLS_PK_ECDSA:
1293 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1294 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1295 TEST_EQUAL(mbedtls_ecp_write_public_key(
1296 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1297 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1298 pk_public = pk_public_buffer;
1299 break;
David Horstmann8660e4b2024-09-06 14:55:05 +01001300#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY && !MBEDTLS_PK_USE_PSA_EC_DATA */
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001301
1302#if defined(MBEDTLS_USE_PSA_CRYPTO)
1303 case MBEDTLS_PK_OPAQUE:
1304 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1305 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1306 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1307 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1308 PSA_ASSERT(psa_export_public_key(psa_key,
1309 pk_public_buffer,
1310 sizeof(pk_public_buffer),
1311 &pk_public_length));
1312 pk_public = pk_public_buffer;
1313 break;
1314#endif /* MBEDTLS_USE_PSA_CRYPTO */
1315
1316 default:
1317 TEST_FAIL("pk type not supported");
1318 }
1319
1320 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1321 size_t psa_public_length = 0;
1322 PSA_ASSERT(psa_export_public_key(psa_key,
1323 psa_public, sizeof(psa_public),
1324 &psa_public_length));
1325 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1326 psa_public, psa_public_length);
1327
1328 ok = 1;
1329
1330exit:
1331 psa_reset_key_attributes(&psa_attributes);
1332 psa_reset_key_attributes(&pk_attributes);
1333 return ok;
1334}
1335#endif /* MBEDTLS_PK_C */
1336
David Horstmann8660e4b2024-09-06 14:55:05 +01001337#endif /* MBEDTLS_PSA_CRYPTO_C || MBEDTLS_PSA_CRYPTO_CLIENT */