blob: 7b082a341babec8a082e81fb0be2ef4ce1ded1e8 [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 Horstmann08ccf6a2024-10-23 16:55:20 +010014#if (MBEDTLS_VERSION_MAJOR < 4 && defined(MBEDTLS_PSA_CRYPTO_C)) || \
15 (MBEDTLS_VERSION_MAJOR >= 4 && defined(MBEDTLS_PSA_CRYPTO_CLIENT))
Gilles Peskine66e7b902021-02-12 23:40:58 +010016
Gilles Peskinee78b0022021-02-13 00:41:11 +010017#include <mbedtls/asn1.h>
Gilles Peskine66e7b902021-02-12 23:40:58 +010018#include <psa/crypto.h>
19
Gilles Peskinee78b0022021-02-13 00:41:11 +010020#include <test/asn1_helpers.h>
Przemyslaw Stekiel53de2622021-11-03 09:35:35 +010021#include <psa_crypto_slot_management.h>
Gilles Peskinee78b0022021-02-13 00:41:11 +010022#include <test/psa_crypto_helpers.h>
23
Gilles Peskine6fe8a062024-02-15 17:21:17 +010024#if defined(MBEDTLS_PK_C)
25#include <pk_internal.h>
26#endif
27#if defined(MBEDTLS_ECP_C)
28#include <mbedtls/ecp.h>
29#endif
30#if defined(MBEDTLS_RSA_C)
31#include <rsa_internal.h>
32#endif
33
Gilles Peskinee78b0022021-02-13 00:41:11 +010034#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010035static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
Gilles Peskinee78b0022021-02-13 00:41:11 +010036{
Gilles Peskine449bd832023-01-11 14:50:10 +010037 return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
38 PSA_KEY_LOCATION_LOCAL_STORAGE;
Gilles Peskinee78b0022021-02-13 00:41:11 +010039}
40#endif
41
Ryan Everettf08a93f2024-03-12 16:00:08 +000042static int check_key_attributes_sanity(mbedtls_svc_key_id_t key,
43 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +010044{
45 int ok = 0;
46 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
47 psa_key_lifetime_t lifetime;
48 mbedtls_svc_key_id_t id;
49 psa_key_type_t type;
Gilles Peskine6b362e62021-02-15 12:03:16 +010050 size_t bits;
Ryan Everettf08a93f2024-03-12 16:00:08 +000051 psa_status_t status = psa_get_key_attributes(key, &attributes);
52 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
53 /* The key has been destroyed. */
54 psa_reset_key_attributes(&attributes);
55 return 1;
56 }
57 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +010058 lifetime = psa_get_key_lifetime(&attributes);
59 id = psa_get_key_id(&attributes);
60 type = psa_get_key_type(&attributes);
61 bits = psa_get_key_bits(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +010062
63 /* Persistence */
Gilles Peskine449bd832023-01-11 14:50:10 +010064 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010065 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010066 (PSA_KEY_ID_VOLATILE_MIN <=
67 MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
68 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
69 PSA_KEY_ID_VOLATILE_MAX));
70 } else {
Gilles Peskinee78b0022021-02-13 00:41:11 +010071 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010072 (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
73 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
Gilles Peskinee78b0022021-02-13 00:41:11 +010074 }
75#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Ryan Everettf08a93f2024-03-12 16:00:08 +000076 /* MBEDTLS_PSA_CRYPTO_SE_C does not support thread safety. */
77 if (key_destroyable == 0) {
78 /* randomly-generated 64-bit constant, should never appear in test data */
79 psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
80 status = psa_get_key_slot_number(&attributes, &slot_number);
81 if (lifetime_is_dynamic_secure_element(lifetime)) {
82 /* Mbed TLS currently always exposes the slot number to
83 * applications. This is not mandated by the PSA specification
84 * and may change in future versions. */
85 TEST_EQUAL(status, 0);
86 TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
87 } else {
88 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
89 }
Gilles Peskinee78b0022021-02-13 00:41:11 +010090 }
91#endif
92
93 /* Type and size */
Gilles Peskine449bd832023-01-11 14:50:10 +010094 TEST_ASSERT(type != 0);
95 TEST_ASSERT(bits != 0);
96 TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
97 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
98 TEST_ASSERT(bits % 8 == 0);
99 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100100
101 /* MAX macros concerning specific key types */
Gilles Peskine449bd832023-01-11 14:50:10 +0100102 if (PSA_KEY_TYPE_IS_ECC(type)) {
103 TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
104 } else if (PSA_KEY_TYPE_IS_RSA(type)) {
105 TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
106 }
107 TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100108
109 ok = 1;
110
111exit:
112 /*
113 * Key attributes may have been returned by psa_get_key_attributes()
114 * thus reset them as required.
115 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100117
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100119}
120
Gilles Peskine449bd832023-01-11 14:50:10 +0100121static int exercise_mac_key(mbedtls_svc_key_id_t key,
122 psa_key_usage_t usage,
Ryan Everett77635502024-03-12 16:02:23 +0000123 psa_algorithm_t alg,
124 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100125{
126 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
127 const unsigned char input[] = "foo";
Gilles Peskine449bd832023-01-11 14:50:10 +0100128 unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
129 size_t mac_length = sizeof(mac);
Ryan Everett77635502024-03-12 16:02:23 +0000130 psa_status_t status = PSA_SUCCESS;
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100131 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
133 alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100134 }
135
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
Ryan Everett77635502024-03-12 16:02:23 +0000137 status = psa_mac_sign_setup(&operation, key, alg);
138 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
139 /* The key has been destroyed. */
140 PSA_ASSERT(psa_mac_abort(&operation));
141 return 1;
142 }
143 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100144 PSA_ASSERT(psa_mac_update(&operation,
145 input, sizeof(input)));
146 PSA_ASSERT(psa_mac_sign_finish(&operation,
147 mac, sizeof(mac),
148 &mac_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100149 }
150
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100152 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 (usage & PSA_KEY_USAGE_SIGN_HASH ?
154 PSA_SUCCESS :
155 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett77635502024-03-12 16:02:23 +0000156 status = psa_mac_verify_setup(&operation, key, alg);
157 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
158 /* The key has been destroyed. */
159 PSA_ASSERT(psa_mac_abort(&operation));
160 return 1;
161 }
162 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 PSA_ASSERT(psa_mac_update(&operation,
164 input, sizeof(input)));
165 TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
166 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100167 }
168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100170
171exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100172 psa_mac_abort(&operation);
173 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100174}
175
Gilles Peskine449bd832023-01-11 14:50:10 +0100176static int exercise_cipher_key(mbedtls_svc_key_id_t key,
177 psa_key_usage_t usage,
Ryan Everett70691f32024-03-12 16:04:45 +0000178 psa_algorithm_t alg,
179 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100180{
181 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
Gilles Peskine5eef11a2022-04-21 11:14:30 +0200183 size_t iv_length;
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100184 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
185 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100186 const unsigned char plaintext[16] = "Hello, world...";
187 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100188 size_t ciphertext_length = sizeof(ciphertext);
189 unsigned char decrypted[sizeof(ciphertext)];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100190 size_t part_length;
Ryan Everett70691f32024-03-12 16:04:45 +0000191 psa_status_t status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100192
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
194 key_type = psa_get_key_type(&attributes);
195 iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everett70691f32024-03-12 16:04:45 +0000198 status = psa_cipher_encrypt_setup(&operation, key, alg);
199 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
200 /* The key has been destroyed. */
201 PSA_ASSERT(psa_cipher_abort(&operation));
202 return 1;
203 }
204 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 if (iv_length != 0) {
206 PSA_ASSERT(psa_cipher_generate_iv(&operation,
207 iv, sizeof(iv),
208 &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 plaintext, sizeof(plaintext),
212 ciphertext, sizeof(ciphertext),
213 &ciphertext_length));
214 PSA_ASSERT(psa_cipher_finish(&operation,
215 ciphertext + ciphertext_length,
216 sizeof(ciphertext) - ciphertext_length,
217 &part_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100218 ciphertext_length += part_length;
219 }
220
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100222 int maybe_invalid_padding = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
224 maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100225 }
Ryan Everett70691f32024-03-12 16:04:45 +0000226 status = psa_cipher_decrypt_setup(&operation, key, alg);
227 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
228 /* The key has been destroyed. */
229 PSA_ASSERT(psa_cipher_abort(&operation));
230 return 1;
231 }
232 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 if (iv_length != 0) {
234 PSA_ASSERT(psa_cipher_set_iv(&operation,
235 iv, iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100236 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100237 PSA_ASSERT(psa_cipher_update(&operation,
238 ciphertext, ciphertext_length,
239 decrypted, sizeof(decrypted),
240 &part_length));
241 status = psa_cipher_finish(&operation,
242 decrypted + part_length,
243 sizeof(decrypted) - part_length,
244 &part_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100245 /* For a stream cipher, all inputs are valid. For a block cipher,
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800246 * if the input is some arbitrary data rather than an actual
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 ciphertext, a padding error is likely. */
248 if (maybe_invalid_padding) {
249 TEST_ASSERT(status == PSA_SUCCESS ||
250 status == PSA_ERROR_INVALID_PADDING);
251 } else {
252 PSA_ASSERT(status);
253 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100254 }
255
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100257
258exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 psa_cipher_abort(&operation);
260 psa_reset_key_attributes(&attributes);
261 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100262}
263
Gilles Peskine449bd832023-01-11 14:50:10 +0100264static int exercise_aead_key(mbedtls_svc_key_id_t key,
265 psa_key_usage_t usage,
Ryan Everettfbe703d2024-03-12 16:09:25 +0000266 psa_algorithm_t alg,
267 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100268{
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
Gilles Peskine7acb1982022-03-19 11:03:32 +0100270 size_t nonce_length;
271 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
272 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100273 unsigned char plaintext[16] = "Hello, world...";
274 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100275 size_t ciphertext_length = sizeof(ciphertext);
276 size_t plaintext_length = sizeof(ciphertext);
Ryan Everettfbe703d2024-03-12 16:09:25 +0000277 psa_status_t status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100278
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100279 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
281 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100282 }
283
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
285 key_type = psa_get_key_type(&attributes);
286 nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
Steven Cooremanaaec3412021-02-18 13:30:34 +0100287
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everettfbe703d2024-03-12 16:09:25 +0000289 status = psa_aead_encrypt(key, alg,
290 nonce, nonce_length,
291 NULL, 0,
292 plaintext, sizeof(plaintext),
293 ciphertext, sizeof(ciphertext),
294 &ciphertext_length);
295 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
296 /* The key has been destroyed. */
297 return 1;
298 }
299 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100300 }
301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100303 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100304 (usage & PSA_KEY_USAGE_ENCRYPT ?
305 PSA_SUCCESS :
306 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everettfbe703d2024-03-12 16:09:25 +0000307 status = psa_aead_decrypt(key, alg,
308 nonce, nonce_length,
309 NULL, 0,
310 ciphertext, ciphertext_length,
311 plaintext, sizeof(plaintext),
312 &plaintext_length);
313 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
314 /* The key has been destroyed. */
315 return 1;
316 }
317 TEST_ASSERT(status == verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100318 }
319
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100321
322exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 psa_reset_key_attributes(&attributes);
324 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100325}
326
Gilles Peskine449bd832023-01-11 14:50:10 +0100327static int can_sign_or_verify_message(psa_key_usage_t usage,
328 psa_algorithm_t alg)
Gilles Peskined586b822022-03-19 11:15:41 +0100329{
330 /* Sign-the-unspecified-hash algorithms can only be used with
331 * {sign,verify}_hash, not with {sign,verify}_message. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
333 return 0;
334 }
335 return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
336 PSA_KEY_USAGE_VERIFY_MESSAGE);
Gilles Peskined586b822022-03-19 11:15:41 +0100337}
338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339static int exercise_signature_key(mbedtls_svc_key_id_t key,
340 psa_key_usage_t usage,
Ryan Everett6edd4082024-03-12 16:11:01 +0000341 psa_algorithm_t alg,
342 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100343{
Gilles Peskine4781bd92024-02-09 17:32:45 +0100344 /* If the policy allows signing with any hash, just pick one. */
345 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
346 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
347 usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
348 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
349#if defined(KNOWN_SUPPORTED_HASH_ALG)
350 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
351 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
352#else
353 TEST_FAIL("No hash algorithm for hash-and-sign testing");
354#endif
355 }
Ryan Everett6edd4082024-03-12 16:11:01 +0000356 psa_status_t status = PSA_SUCCESS;
Gilles Peskine4781bd92024-02-09 17:32:45 +0100357
oberon-skf7a824b2023-02-15 19:43:30 +0100358 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
359 PSA_ALG_IS_SIGN_HASH(alg)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200361 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
363 size_t signature_length = sizeof(signature);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200364
Janos Follath4c0b60e2021-06-14 12:34:30 +0100365 /* Some algorithms require the payload to have the size of
366 * the hash encoded in the algorithm. Use this input size
367 * even for algorithms that allow other input sizes. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 if (hash_alg != 0) {
369 payload_length = PSA_HASH_LENGTH(hash_alg);
370 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100371
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
Ryan Everett6edd4082024-03-12 16:11:01 +0000373 status = psa_sign_hash(key, alg,
374 payload, payload_length,
375 signature, sizeof(signature),
376 &signature_length);
377 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
378 /* The key has been destroyed. */
379 return 1;
380 }
381 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 }
383
384 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
385 psa_status_t verify_status =
386 (usage & PSA_KEY_USAGE_SIGN_HASH ?
387 PSA_SUCCESS :
388 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett6edd4082024-03-12 16:11:01 +0000389 status = psa_verify_hash(key, alg,
390 payload, payload_length,
391 signature, signature_length);
392 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
393 /* The key has been destroyed. */
394 return 1;
395 }
396 TEST_ASSERT(status == verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200397 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100398 }
399
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200401 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200403 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100405
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
Ryan Everett6edd4082024-03-12 16:11:01 +0000407 status = psa_sign_message(key, alg,
408 message, message_length,
409 signature, sizeof(signature),
410 &signature_length);
411 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
412 /* The key has been destroyed. */
413 return 1;
414 }
415 PSA_ASSERT(status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200416 }
417
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200419 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
421 PSA_SUCCESS :
422 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett6edd4082024-03-12 16:11:01 +0000423 status = psa_verify_message(key, alg,
424 message, message_length,
425 signature, signature_length);
426 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
427 /* The key has been destroyed. */
428 return 1;
429 }
430 TEST_ASSERT(status == verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200431 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100432 }
433
Gilles Peskine449bd832023-01-11 14:50:10 +0100434 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100435
436exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100438}
439
Gilles Peskine449bd832023-01-11 14:50:10 +0100440static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
441 psa_key_usage_t usage,
Ryan Everettd48fc102024-03-12 16:12:41 +0000442 psa_algorithm_t alg,
443 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100444{
Gilles Peskinef50cd592024-02-15 13:13:26 +0100445 unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100446 "Hello, world...";
Gilles Peskinef50cd592024-02-15 13:13:26 +0100447 unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100448 "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100450 size_t plaintext_length = 16;
Ryan Everettd48fc102024-03-12 16:12:41 +0000451 psa_status_t status = PSA_SUCCESS;
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everettd48fc102024-03-12 16:12:41 +0000453 status = psa_asymmetric_encrypt(key, alg,
454 plaintext, plaintext_length,
455 NULL, 0,
456 ciphertext, sizeof(ciphertext),
457 &ciphertext_length);
458 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
459 /* The key has been destroyed. */
460 return 1;
461 }
462 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100463 }
464
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 if (usage & PSA_KEY_USAGE_DECRYPT) {
Ryan Everettd48fc102024-03-12 16:12:41 +0000466 status = psa_asymmetric_decrypt(key, alg,
467 ciphertext, ciphertext_length,
468 NULL, 0,
469 plaintext, sizeof(plaintext),
470 &plaintext_length);
471 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
472 /* The key has been destroyed. */
473 return 1;
474 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100475 TEST_ASSERT(status == PSA_SUCCESS ||
476 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
477 (status == PSA_ERROR_INVALID_ARGUMENT ||
478 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100479 }
480
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100482
483exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100485}
486
487int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100489 mbedtls_svc_key_id_t key,
490 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 const unsigned char *input1, size_t input1_length,
492 const unsigned char *input2, size_t input2_length,
Ryan Everettc1cc6682024-03-12 16:17:43 +0000493 size_t capacity, int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100494{
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000496 psa_status_t status = PSA_SUCCESS;
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 if (PSA_ALG_IS_HKDF(alg)) {
498 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
499 PSA_KEY_DERIVATION_INPUT_SALT,
500 input1, input1_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000501 status = psa_key_derivation_input_key(operation,
502 PSA_KEY_DERIVATION_INPUT_SECRET,
503 key);
504 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
505 /* The key has been destroyed. */
506 return 1;
507 }
508 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
510 PSA_KEY_DERIVATION_INPUT_INFO,
511 input2,
512 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530513 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
514 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
515 PSA_KEY_DERIVATION_INPUT_SALT,
516 input1, input1_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000517 status = psa_key_derivation_input_key(operation,
518 PSA_KEY_DERIVATION_INPUT_SECRET,
519 key);
520 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
521 /* The key has been destroyed. */
522 return 1;
523 }
524 PSA_ASSERT(status);
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530525 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
Ryan Everettc1cc6682024-03-12 16:17:43 +0000526 status = psa_key_derivation_input_key(operation,
527 PSA_KEY_DERIVATION_INPUT_SECRET,
528 key);
529 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
530 /* The key has been destroyed. */
531 return 1;
532 }
533 PSA_ASSERT(status);
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530534 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
535 PSA_KEY_DERIVATION_INPUT_INFO,
536 input2,
537 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
539 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
540 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
541 PSA_KEY_DERIVATION_INPUT_SEED,
542 input1, input1_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000543 status = psa_key_derivation_input_key(operation,
544 PSA_KEY_DERIVATION_INPUT_SECRET,
545 key);
546 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
547 /* The key has been destroyed. */
548 return 1;
549 }
550 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
552 PSA_KEY_DERIVATION_INPUT_LABEL,
553 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530554 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530555 PSA_ASSERT(psa_key_derivation_input_integer(operation,
556 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530557 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530558 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
559 PSA_KEY_DERIVATION_INPUT_SALT,
560 input2,
561 input2_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000562 status = psa_key_derivation_input_key(operation,
563 PSA_KEY_DERIVATION_INPUT_PASSWORD,
564 key);
565 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
566 /* The key has been destroyed. */
567 return 1;
568 }
569 PSA_ASSERT(status);
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530570 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
571 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
572 PSA_KEY_DERIVATION_INPUT_SECRET,
573 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100575 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100576 }
577
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 if (capacity != SIZE_MAX) {
579 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
580 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100581
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100583
584exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100586}
587
588
Gilles Peskine449bd832023-01-11 14:50:10 +0100589static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
590 psa_key_usage_t usage,
Ryan Everettc1cc6682024-03-12 16:17:43 +0000591 psa_algorithm_t alg,
592 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100593{
594 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
595 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100597 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100599 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 if (usage & PSA_KEY_USAGE_DERIVE) {
603 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
604 input1, input1_length,
605 input2, input2_length,
Ryan Everettc1cc6682024-03-12 16:17:43 +0000606 capacity, key_destroyable)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100607 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100609
Ryan Everettc1cc6682024-03-12 16:17:43 +0000610 psa_status_t status = psa_key_derivation_output_bytes(&operation,
611 output,
612 capacity);
613 if (key_destroyable && status == PSA_ERROR_BAD_STATE) {
614 /* The key has been destroyed. */
615 PSA_ASSERT(psa_key_derivation_abort(&operation));
616 } else {
617 PSA_ASSERT(status);
618 PSA_ASSERT(psa_key_derivation_abort(&operation));
619 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100620 }
621
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100623
624exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100626}
627
628/* We need two keys to exercise key agreement. Exercise the
629 * private key against its own public key. */
630psa_status_t mbedtls_test_psa_key_agreement_with_self(
631 psa_key_derivation_operation_t *operation,
Ryan Everett73e4ea32024-03-12 16:29:55 +0000632 mbedtls_svc_key_id_t key, int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100633{
634 psa_key_type_t private_key_type;
635 psa_key_type_t public_key_type;
636 size_t key_bits;
637 uint8_t *public_key = NULL;
638 size_t public_key_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100639 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
640
Ryan Everett73e4ea32024-03-12 16:29:55 +0000641 psa_status_t status = psa_get_key_attributes(key, &attributes);
642 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
643 /* The key has been destroyed. */
644 psa_reset_key_attributes(&attributes);
645 return PSA_SUCCESS;
646 }
647 PSA_ASSERT(status);
648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 private_key_type = psa_get_key_type(&attributes);
650 key_bits = psa_get_key_bits(&attributes);
651 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
652 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100653 TEST_CALLOC(public_key, public_key_length);
Ryan Everett73e4ea32024-03-12 16:29:55 +0000654 status = psa_export_public_key(key, public_key, public_key_length,
655 &public_key_length);
656 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
657 /* The key has been destroyed. */
658 status = PSA_SUCCESS;
659 goto exit;
660 }
661 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100662
663 status = psa_key_derivation_key_agreement(
664 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 public_key, public_key_length);
Ryan Everett73e4ea32024-03-12 16:29:55 +0000666 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
667 /* The key has been destroyed. */
668 status = PSA_SUCCESS;
669 goto exit;
670 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100671exit:
672 /*
673 * Key attributes may have been returned by psa_get_key_attributes()
674 * thus reset them as required.
675 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100677
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 mbedtls_free(public_key);
679 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100680}
681
682/* We need two keys to exercise key agreement. Exercise the
683 * private key against its own public key. */
684psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
685 psa_algorithm_t alg,
Ryan Everett81630282024-03-12 16:21:12 +0000686 mbedtls_svc_key_id_t key,
687 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100688{
689 psa_key_type_t private_key_type;
690 psa_key_type_t public_key_type;
691 size_t key_bits;
692 uint8_t *public_key = NULL;
693 size_t public_key_length;
694 uint8_t output[1024];
695 size_t output_length;
Paul Elliott66d7bcb2024-11-13 18:27:06 +0000696
697 uint8_t *exported = NULL;
698 size_t exported_size = 0;
699 size_t exported_length = 0;
700
Gilles Peskinee78b0022021-02-13 00:41:11 +0100701 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Paul Elliott66d7bcb2024-11-13 18:27:06 +0000702 psa_key_attributes_t export_attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100703
Paul Elliott2c9d3982024-09-19 15:49:32 +0100704 mbedtls_svc_key_id_t shared_secret_id = MBEDTLS_SVC_KEY_ID_INIT;
705 psa_key_attributes_t shared_secret_attributes = PSA_KEY_ATTRIBUTES_INIT;
706
Ryan Everett81630282024-03-12 16:21:12 +0000707 psa_status_t status = psa_get_key_attributes(key, &attributes);
708 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
709 /* The key has been destroyed. */
710 psa_reset_key_attributes(&attributes);
711 return PSA_SUCCESS;
712 }
713 PSA_ASSERT(status);
714
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 private_key_type = psa_get_key_type(&attributes);
716 key_bits = psa_get_key_bits(&attributes);
717 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
718 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100719 TEST_CALLOC(public_key, public_key_length);
Ryan Everett81630282024-03-12 16:21:12 +0000720 status = psa_export_public_key(key,
721 public_key, public_key_length,
722 &public_key_length);
723 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
724 /* The key has been destroyed. */
725 status = PSA_SUCCESS;
726 goto exit;
727 }
Ryan Everett6de38ac2024-03-14 17:50:39 +0000728 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 status = psa_raw_key_agreement(alg, key,
731 public_key, public_key_length,
732 output, sizeof(output), &output_length);
Ryan Everett81630282024-03-12 16:21:12 +0000733 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
734 /* The key has been destroyed. */
735 status = PSA_SUCCESS;
736 goto exit;
737 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 if (status == PSA_SUCCESS) {
739 TEST_ASSERT(output_length <=
740 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
741 key_bits));
742 TEST_ASSERT(output_length <=
743 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100744 }
745
Paul Elliott2c9d3982024-09-19 15:49:32 +0100746 psa_set_key_type(&shared_secret_attributes, PSA_KEY_TYPE_DERIVE);
747 psa_set_key_usage_flags(&shared_secret_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT);
748
749 status = psa_key_agreement(key, public_key, public_key_length, alg,
750 &shared_secret_attributes, &shared_secret_id);
751
752 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
753 /* The key has been destroyed. */
754 status = PSA_SUCCESS;
Paul Elliott66d7bcb2024-11-13 18:27:06 +0000755 goto exit;
756 } else if (status == PSA_SUCCESS) {
757
758 status = psa_get_key_attributes(shared_secret_id, &export_attributes);
759 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
760 /* The key has been destroyed. */
761 status = PSA_SUCCESS;
762 goto exit;
763 }
764
765 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(psa_get_key_type(&export_attributes),
766 psa_get_key_bits(&export_attributes));
767 TEST_CALLOC(exported, exported_size);
768
769 status = psa_export_key(shared_secret_id, exported, exported_size, &exported_length);
770
771 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
772 /* The key has been destroyed. */
773 status = PSA_SUCCESS;
774 }
775
776 PSA_ASSERT(status);
Paul Elliott2c9d3982024-09-19 15:49:32 +0100777 }
778
Gilles Peskinee78b0022021-02-13 00:41:11 +0100779exit:
780 /*
781 * Key attributes may have been returned by psa_get_key_attributes()
782 * thus reset them as required.
783 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 psa_reset_key_attributes(&attributes);
Paul Elliott66d7bcb2024-11-13 18:27:06 +0000785 psa_reset_key_attributes(&export_attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100786
Paul Elliott2c9d3982024-09-19 15:49:32 +0100787 /* Make sure to reset and free derived key attributes and slot. */
788 psa_reset_key_attributes(&shared_secret_attributes);
789 psa_destroy_key(shared_secret_id);
790
Gilles Peskine449bd832023-01-11 14:50:10 +0100791 mbedtls_free(public_key);
Paul Elliott66d7bcb2024-11-13 18:27:06 +0000792 mbedtls_free(exported);
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100794}
795
Gilles Peskine449bd832023-01-11 14:50:10 +0100796static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
797 psa_key_usage_t usage,
Ryan Everett81630282024-03-12 16:21:12 +0000798 psa_algorithm_t alg,
799 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100800{
801 int ok = 0;
802
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100804 /* We need two keys to exercise key agreement. Exercise the
805 * private key against its own public key. */
Ryan Everett81630282024-03-12 16:21:12 +0000806 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key,
807 key_destroyable));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100808 }
809 ok = 1;
810
811exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100813}
814
Gilles Peskine449bd832023-01-11 14:50:10 +0100815static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
816 psa_key_usage_t usage,
Ryan Everett73e4ea32024-03-12 16:29:55 +0000817 psa_algorithm_t alg,
818 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100819{
820 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200821 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100822 unsigned char output[1];
823 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100824 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200825 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100826
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100828 /* We need two keys to exercise key agreement. Exercise the
829 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
831 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
832 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
833 PSA_ASSERT(psa_key_derivation_input_bytes(
834 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
835 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100836 }
837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
839 PSA_ASSERT(psa_key_derivation_input_bytes(
840 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
841 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200842 }
843
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200844 /* For HKDF_EXPAND input secret may fail as secret size may not match
845 to expected PRK size. In practice it means that key bits must match
846 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200848 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ryan Everett73e4ea32024-03-12 16:29:55 +0000849 psa_status_t status = psa_get_key_attributes(key, &attributes);
850 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
851 /* The key has been destroyed. */
852 ok = 1;
853 }
854 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 size_t key_bits = psa_get_key_bits(&attributes);
856 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200857
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200859 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200861 }
862
Ryan Everett73e4ea32024-03-12 16:29:55 +0000863 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key,
864 key_destroyable),
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200866
Gilles Peskine449bd832023-01-11 14:50:10 +0100867 if (expected_key_agreement_status != PSA_SUCCESS) {
868 return 1;
869 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100870
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
872 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
873 PSA_ASSERT(psa_key_derivation_input_bytes(
874 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
875 input, sizeof(input)));
876 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
877 PSA_ASSERT(psa_key_derivation_input_bytes(
878 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
879 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100880 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
882 output,
883 sizeof(output)));
884 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100885 }
886 ok = 1;
887
888exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100890}
891
892int mbedtls_test_psa_exported_key_sanity_check(
893 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100895{
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
899 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
900 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100901
Ronald Cron64df7382021-07-06 09:23:06 +0200902#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
904 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100905 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100906 size_t len;
907 /* RSAPrivateKey ::= SEQUENCE {
908 * version INTEGER, -- must be 0
909 * modulus INTEGER, -- n
910 * publicExponent INTEGER, -- e
911 * privateExponent INTEGER, -- d
912 * prime1 INTEGER, -- p
913 * prime2 INTEGER, -- q
914 * exponent1 INTEGER, -- d mod (p-1)
915 * exponent2 INTEGER, -- d mod (q-1)
916 * coefficient INTEGER, -- (inverse of q) mod p
917 * }
918 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
920 MBEDTLS_ASN1_SEQUENCE |
921 MBEDTLS_ASN1_CONSTRUCTED), 0);
922 TEST_EQUAL(len, end - p);
923 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100924 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 }
926 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100927 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 }
929 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100930 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100932 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100934 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100936 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100938 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 }
940 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100941 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 }
943 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100944 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 }
946 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100947 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 }
949 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100950 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 }
952 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
955 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200956#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100959 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100961
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
963 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100964
Ronald Cron64df7382021-07-06 09:23:06 +0200965#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
967 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100968 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100969 size_t len;
970 /* RSAPublicKey ::= SEQUENCE {
971 * modulus INTEGER, -- n
972 * publicExponent INTEGER } -- e
973 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
975 MBEDTLS_ASN1_SEQUENCE |
976 MBEDTLS_ASN1_CONSTRUCTED),
977 0);
978 TEST_EQUAL(len, end - p);
979 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100980 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 }
982 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100983 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 }
985 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100986
987
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 TEST_ASSERT(exported_length <=
989 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
990 TEST_ASSERT(exported_length <=
991 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
992 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200993#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100994
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 TEST_ASSERT(exported_length <=
998 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
999 TEST_ASSERT(exported_length <=
1000 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +01001001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +01001003 /* The representation of an ECC Montgomery public key is
1004 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +01001006 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +01001007 /* The representation of an ECC Edwards public key is
1008 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +01001009 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +01001011 /* The representation of an ECC Weierstrass public key is:
1012 * - The byte 0x04;
1013 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
1014 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
1015 * - where m is the bit size associated with the curve.
1016 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
1018 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001019 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +01001020 } else
1021 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +02001022 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +01001023 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
1024 TEST_ASSERT(exported_length <=
1025 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +02001026 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +01001027 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +01001028 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +01001029 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001030
Gilles Peskinecc9db302021-02-14 01:29:52 +01001031#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +01001033 /* Check the parity bits. */
1034 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +01001036 unsigned bit_count = 0;
1037 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 for (m = 1; m <= 0x100; m <<= 1) {
1039 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +01001040 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 }
Gilles Peskinecc9db302021-02-14 01:29:52 +01001042 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +01001044 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001045 }
Gilles Peskinecc9db302021-02-14 01:29:52 +01001046#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +01001047
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001049
1050exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001052}
1053
Gilles Peskine449bd832023-01-11 14:50:10 +01001054static int exercise_export_key(mbedtls_svc_key_id_t key,
Ryan Everettfbf815d2024-03-12 16:32:29 +00001055 psa_key_usage_t usage,
1056 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001057{
1058 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1059 uint8_t *exported = NULL;
1060 size_t exported_size = 0;
1061 size_t exported_length = 0;
1062 int ok = 0;
1063
Ryan Everettfbf815d2024-03-12 16:32:29 +00001064 psa_status_t status = psa_get_key_attributes(key, &attributes);
1065 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1066 /* The key has been destroyed. */
1067 psa_reset_key_attributes(&attributes);
1068 return 1;
1069 }
1070 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001071
1072 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +01001073 psa_get_key_type(&attributes),
1074 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001075 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001076
Ryan Everettfbf815d2024-03-12 16:32:29 +00001077 status = psa_export_key(key, exported, exported_size, &exported_length);
1078 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1079 /* The key has been destroyed. */
1080 ok = 1;
1081 goto exit;
1082 } else if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
1083 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
1084 TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001085 ok = 1;
1086 goto exit;
1087 }
Ryan Everettfbf815d2024-03-12 16:32:29 +00001088 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001089 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001090 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
1091 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001092
1093exit:
1094 /*
1095 * Key attributes may have been returned by psa_get_key_attributes()
1096 * thus reset them as required.
1097 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001098 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001099
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 mbedtls_free(exported);
1101 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001102}
1103
Ryan Everettfbf815d2024-03-12 16:32:29 +00001104static int exercise_export_public_key(mbedtls_svc_key_id_t key,
1105 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001106{
1107 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1108 psa_key_type_t public_type;
1109 uint8_t *exported = NULL;
1110 size_t exported_size = 0;
1111 size_t exported_length = 0;
1112 int ok = 0;
1113
Ryan Everettfbf815d2024-03-12 16:32:29 +00001114 psa_status_t status = psa_get_key_attributes(key, &attributes);
1115 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1116 /* The key has been destroyed. */
1117 psa_reset_key_attributes(&attributes);
1118 return 1;
1119 }
1120 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +01001121 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +01001122 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +01001123 psa_get_key_type(&attributes),
1124 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001125 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001126
Ryan Everettfbf815d2024-03-12 16:32:29 +00001127 status = psa_export_public_key(key, exported,
1128 exported_size, &exported_length);
1129 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1130 /* The key has been destroyed. */
1131 ok = 1;
1132 goto exit;
1133 }
1134 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001135 ok = 1;
1136 goto exit;
1137 }
1138
1139 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 psa_get_key_type(&attributes));
1141 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
1142 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001143 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001144
Ryan Everettfbf815d2024-03-12 16:32:29 +00001145 status = psa_export_public_key(key, exported,
1146 exported_size, &exported_length);
1147 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1148 /* The key has been destroyed. */
1149 ok = 1;
1150 goto exit;
1151 }
1152 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001153 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 public_type, psa_get_key_bits(&attributes),
1155 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001156
1157exit:
1158 /*
1159 * Key attributes may have been returned by psa_get_key_attributes()
1160 * thus reset them as required.
1161 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001163
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 mbedtls_free(exported);
1165 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001166}
1167
Gilles Peskine449bd832023-01-11 14:50:10 +01001168int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
1169 psa_key_usage_t usage,
Ryan Everett0a271fd2024-03-12 16:34:02 +00001170 psa_algorithm_t alg,
1171 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001172{
Gilles Peskine2385f712021-02-14 01:34:21 +01001173 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001174
Ryan Everett0a271fd2024-03-12 16:34:02 +00001175 if (!check_key_attributes_sanity(key, key_destroyable)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 return 0;
1177 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001178
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001180 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 } else if (PSA_ALG_IS_MAC(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001182 ok = exercise_mac_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001183 } else if (PSA_ALG_IS_CIPHER(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001184 ok = exercise_cipher_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 } else if (PSA_ALG_IS_AEAD(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001186 ok = exercise_aead_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001187 } else if (PSA_ALG_IS_SIGN(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001188 ok = exercise_signature_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001189 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001190 ok = exercise_asymmetric_encryption_key(key, usage, alg,
1191 key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001192 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001193 ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001194 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001195 ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001196 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001197 ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001198 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +01001199 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +01001200 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001201
Ryan Everett0a271fd2024-03-12 16:34:02 +00001202 ok = ok && exercise_export_key(key,
1203 usage,
1204 key_destroyable);
1205 ok = ok && exercise_export_public_key(key,
1206 key_destroyable);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001207
Gilles Peskine2385f712021-02-14 01:34:21 +01001208exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001210}
1211
Gilles Peskine449bd832023-01-11 14:50:10 +01001212psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1213 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001214{
Gilles Peskine449bd832023-01-11 14:50:10 +01001215 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1216 if (PSA_ALG_IS_SIGN_HASH(alg)) {
1217 if (PSA_ALG_SIGN_GET_HASH(alg)) {
1218 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1219 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1220 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1221 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1222 }
1223 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1224 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1225 PSA_KEY_USAGE_VERIFY_MESSAGE :
1226 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001227 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001228
Gilles Peskine449bd832023-01-11 14:50:10 +01001229 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1230 PSA_KEY_USAGE_VERIFY_HASH :
1231 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1232 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1233 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1234 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1235 PSA_KEY_USAGE_ENCRYPT :
1236 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1237 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1238 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1239 return PSA_KEY_USAGE_DERIVE;
1240 } else {
1241 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001242 }
1243
1244}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001245
Gilles Peskine34955672024-02-12 14:19:24 +01001246int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1247{
1248 /* Reject algorithms that we know are not supported. Default to
1249 * attempting exercise, so that if an algorithm is missing from this
1250 * function, the result will be a test failure and not silently
1251 * omitting exercise. */
1252#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1253 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1254 return 0;
1255 }
1256#endif
1257#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1258 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1259 return 0;
1260 }
1261#endif
1262#if !defined(PSA_WANT_ALG_RSA_PSS)
1263 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1264 return 0;
1265 }
1266#endif
1267#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1268 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1269 return 0;
1270 }
1271#endif
1272#if !defined(PSA_WANT_ALG_ECDSA)
1273 if (PSA_ALG_IS_ECDSA(alg)) {
1274 return 0;
1275 }
1276#endif
1277#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1278 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1279 return 0;
1280 }
1281#endif
1282#if !defined(PSA_WANT_ALG_ECDH)
1283 if (PSA_ALG_IS_ECDH(alg)) {
1284 return 0;
1285 }
1286#endif
1287 (void) alg;
1288 return 1;
1289}
1290
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001291#if defined(MBEDTLS_PK_C)
1292int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1293 const mbedtls_pk_context *pk)
1294{
1295 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1296 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1297 int ok = 0;
1298
1299 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1300 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1301 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1302
1303 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1304 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1305 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1306
1307 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1308 const uint8_t *pk_public = NULL;
1309 size_t pk_public_length = 0;
1310
1311 switch (pk_type) {
1312#if defined(MBEDTLS_RSA_C)
1313 case MBEDTLS_PK_RSA:
1314 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1315 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1316 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1317 uint8_t *cursor = end;
1318 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1319 pk_public_buffer, &cursor));
1320 pk_public = cursor;
1321 pk_public_length = end - pk_public;
1322 break;
1323#endif
1324
1325#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1326 case MBEDTLS_PK_ECKEY:
1327 case MBEDTLS_PK_ECKEY_DH:
1328 case MBEDTLS_PK_ECDSA:
1329 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1330 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1331 pk_public = pk->pub_raw;
1332 pk_public_length = pk->pub_raw_len;
1333 break;
1334#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1335
Elena Uziunaite8dde3b32024-07-05 12:10:21 +01001336#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001337 case MBEDTLS_PK_ECKEY:
1338 case MBEDTLS_PK_ECKEY_DH:
1339 case MBEDTLS_PK_ECDSA:
1340 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1341 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1342 TEST_EQUAL(mbedtls_ecp_write_public_key(
1343 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1344 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1345 pk_public = pk_public_buffer;
1346 break;
Elena Uziunaite8dde3b32024-07-05 12:10:21 +01001347#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY && !MBEDTLS_PK_USE_PSA_EC_DATA */
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001348
1349#if defined(MBEDTLS_USE_PSA_CRYPTO)
1350 case MBEDTLS_PK_OPAQUE:
1351 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1352 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1353 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1354 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1355 PSA_ASSERT(psa_export_public_key(psa_key,
1356 pk_public_buffer,
1357 sizeof(pk_public_buffer),
1358 &pk_public_length));
1359 pk_public = pk_public_buffer;
1360 break;
1361#endif /* MBEDTLS_USE_PSA_CRYPTO */
1362
1363 default:
1364 TEST_FAIL("pk type not supported");
1365 }
1366
1367 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1368 size_t psa_public_length = 0;
1369 PSA_ASSERT(psa_export_public_key(psa_key,
1370 psa_public, sizeof(psa_public),
1371 &psa_public_length));
1372 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1373 psa_public, psa_public_length);
1374
1375 ok = 1;
1376
1377exit:
1378 psa_reset_key_attributes(&psa_attributes);
1379 psa_reset_key_attributes(&pk_attributes);
1380 return ok;
1381}
1382#endif /* MBEDTLS_PK_C */
1383
David Horstmann0d8287c2024-07-26 18:01:04 +01001384#endif /* MBEDTLS_PSA_CRYPTO_C || MBEDTLS_PSA_CRYPTO_CLIENT */