blob: 62fa4550fa10f1a131c8fdd1bad8c85e7b516619 [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;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100696 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
697
Paul Elliott2c9d3982024-09-19 15:49:32 +0100698 mbedtls_svc_key_id_t shared_secret_id = MBEDTLS_SVC_KEY_ID_INIT;
699 psa_key_attributes_t shared_secret_attributes = PSA_KEY_ATTRIBUTES_INIT;
700
Ryan Everett81630282024-03-12 16:21:12 +0000701 psa_status_t status = psa_get_key_attributes(key, &attributes);
702 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
703 /* The key has been destroyed. */
704 psa_reset_key_attributes(&attributes);
705 return PSA_SUCCESS;
706 }
707 PSA_ASSERT(status);
708
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 private_key_type = psa_get_key_type(&attributes);
710 key_bits = psa_get_key_bits(&attributes);
711 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
712 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100713 TEST_CALLOC(public_key, public_key_length);
Ryan Everett81630282024-03-12 16:21:12 +0000714 status = psa_export_public_key(key,
715 public_key, public_key_length,
716 &public_key_length);
717 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
718 /* The key has been destroyed. */
719 status = PSA_SUCCESS;
720 goto exit;
721 }
Ryan Everett6de38ac2024-03-14 17:50:39 +0000722 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 status = psa_raw_key_agreement(alg, key,
725 public_key, public_key_length,
726 output, sizeof(output), &output_length);
Ryan Everett81630282024-03-12 16:21:12 +0000727 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
728 /* The key has been destroyed. */
729 status = PSA_SUCCESS;
730 goto exit;
731 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 if (status == PSA_SUCCESS) {
733 TEST_ASSERT(output_length <=
734 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
735 key_bits));
736 TEST_ASSERT(output_length <=
737 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100738 }
739
Paul Elliott2c9d3982024-09-19 15:49:32 +0100740 psa_set_key_type(&shared_secret_attributes, PSA_KEY_TYPE_DERIVE);
741 psa_set_key_usage_flags(&shared_secret_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT);
742
743 status = psa_key_agreement(key, public_key, public_key_length, alg,
744 &shared_secret_attributes, &shared_secret_id);
745
746 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
747 /* The key has been destroyed. */
748 status = PSA_SUCCESS;
749 }
750
Gilles Peskinee78b0022021-02-13 00:41:11 +0100751exit:
752 /*
753 * Key attributes may have been returned by psa_get_key_attributes()
754 * thus reset them as required.
755 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100757
Paul Elliott2c9d3982024-09-19 15:49:32 +0100758 /* Make sure to reset and free derived key attributes and slot. */
759 psa_reset_key_attributes(&shared_secret_attributes);
760 psa_destroy_key(shared_secret_id);
761
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 mbedtls_free(public_key);
763 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100764}
765
Gilles Peskine449bd832023-01-11 14:50:10 +0100766static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
767 psa_key_usage_t usage,
Ryan Everett81630282024-03-12 16:21:12 +0000768 psa_algorithm_t alg,
769 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100770{
771 int ok = 0;
772
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100774 /* We need two keys to exercise key agreement. Exercise the
775 * private key against its own public key. */
Ryan Everett81630282024-03-12 16:21:12 +0000776 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key,
777 key_destroyable));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100778 }
779 ok = 1;
780
781exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100783}
784
Gilles Peskine449bd832023-01-11 14:50:10 +0100785static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
786 psa_key_usage_t usage,
Ryan Everett73e4ea32024-03-12 16:29:55 +0000787 psa_algorithm_t alg,
788 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100789{
790 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200791 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100792 unsigned char output[1];
793 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200795 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100796
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100798 /* We need two keys to exercise key agreement. Exercise the
799 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
801 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
802 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
803 PSA_ASSERT(psa_key_derivation_input_bytes(
804 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
805 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100806 }
807
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
809 PSA_ASSERT(psa_key_derivation_input_bytes(
810 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
811 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200812 }
813
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200814 /* For HKDF_EXPAND input secret may fail as secret size may not match
815 to expected PRK size. In practice it means that key bits must match
816 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200818 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ryan Everett73e4ea32024-03-12 16:29:55 +0000819 psa_status_t status = psa_get_key_attributes(key, &attributes);
820 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
821 /* The key has been destroyed. */
822 ok = 1;
823 }
824 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 size_t key_bits = psa_get_key_bits(&attributes);
826 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200827
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200829 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200831 }
832
Ryan Everett73e4ea32024-03-12 16:29:55 +0000833 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key,
834 key_destroyable),
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200836
Gilles Peskine449bd832023-01-11 14:50:10 +0100837 if (expected_key_agreement_status != PSA_SUCCESS) {
838 return 1;
839 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100840
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
842 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
843 PSA_ASSERT(psa_key_derivation_input_bytes(
844 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
845 input, sizeof(input)));
846 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
847 PSA_ASSERT(psa_key_derivation_input_bytes(
848 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
849 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100850 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
852 output,
853 sizeof(output)));
854 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100855 }
856 ok = 1;
857
858exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100860}
861
862int mbedtls_test_psa_exported_key_sanity_check(
863 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100865{
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100867
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
869 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
870 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100871
Ronald Cron64df7382021-07-06 09:23:06 +0200872#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
874 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100875 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100876 size_t len;
877 /* RSAPrivateKey ::= SEQUENCE {
878 * version INTEGER, -- must be 0
879 * modulus INTEGER, -- n
880 * publicExponent INTEGER, -- e
881 * privateExponent INTEGER, -- d
882 * prime1 INTEGER, -- p
883 * prime2 INTEGER, -- q
884 * exponent1 INTEGER, -- d mod (p-1)
885 * exponent2 INTEGER, -- d mod (q-1)
886 * coefficient INTEGER, -- (inverse of q) mod p
887 * }
888 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
890 MBEDTLS_ASN1_SEQUENCE |
891 MBEDTLS_ASN1_CONSTRUCTED), 0);
892 TEST_EQUAL(len, end - p);
893 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
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, bits, bits, 1)) {
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, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100900 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100902 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100904 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100906 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100908 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 }
910 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100911 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 }
913 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100914 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 }
916 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100917 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 }
919 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100920 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 }
922 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100923
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
925 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200926#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100927
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100929 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100931
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
933 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100934
Ronald Cron64df7382021-07-06 09:23:06 +0200935#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
937 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100938 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100939 size_t len;
940 /* RSAPublicKey ::= SEQUENCE {
941 * modulus INTEGER, -- n
942 * publicExponent INTEGER } -- e
943 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
945 MBEDTLS_ASN1_SEQUENCE |
946 MBEDTLS_ASN1_CONSTRUCTED),
947 0);
948 TEST_EQUAL(len, end - p);
949 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100950 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 }
952 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100953 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 }
955 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100956
957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 TEST_ASSERT(exported_length <=
959 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
960 TEST_ASSERT(exported_length <=
961 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
962 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200963#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100964
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100966
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 TEST_ASSERT(exported_length <=
968 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
969 TEST_ASSERT(exported_length <=
970 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100971
Gilles Peskine449bd832023-01-11 14:50:10 +0100972 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100973 /* The representation of an ECC Montgomery public key is
974 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100976 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100977 /* The representation of an ECC Edwards public key is
978 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100979 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100981 /* The representation of an ECC Weierstrass public key is:
982 * - The byte 0x04;
983 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
984 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
985 * - where m is the bit size associated with the curve.
986 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100987 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
988 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100989 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100990 } else
991 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200992 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100993 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
994 TEST_ASSERT(exported_length <=
995 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200996 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100997 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100998 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100999 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001000
Gilles Peskinecc9db302021-02-14 01:29:52 +01001001#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +01001003 /* Check the parity bits. */
1004 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +01001006 unsigned bit_count = 0;
1007 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 for (m = 1; m <= 0x100; m <<= 1) {
1009 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +01001010 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 }
Gilles Peskinecc9db302021-02-14 01:29:52 +01001012 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +01001014 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001015 }
Gilles Peskinecc9db302021-02-14 01:29:52 +01001016#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +01001017
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001019
1020exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001022}
1023
Gilles Peskine449bd832023-01-11 14:50:10 +01001024static int exercise_export_key(mbedtls_svc_key_id_t key,
Ryan Everettfbf815d2024-03-12 16:32:29 +00001025 psa_key_usage_t usage,
1026 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001027{
1028 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1029 uint8_t *exported = NULL;
1030 size_t exported_size = 0;
1031 size_t exported_length = 0;
1032 int ok = 0;
1033
Ryan Everettfbf815d2024-03-12 16:32:29 +00001034 psa_status_t status = psa_get_key_attributes(key, &attributes);
1035 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1036 /* The key has been destroyed. */
1037 psa_reset_key_attributes(&attributes);
1038 return 1;
1039 }
1040 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001041
1042 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 psa_get_key_type(&attributes),
1044 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001045 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001046
Ryan Everettfbf815d2024-03-12 16:32:29 +00001047 status = psa_export_key(key, exported, exported_size, &exported_length);
1048 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1049 /* The key has been destroyed. */
1050 ok = 1;
1051 goto exit;
1052 } else if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
1053 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
1054 TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001055 ok = 1;
1056 goto exit;
1057 }
Ryan Everettfbf815d2024-03-12 16:32:29 +00001058 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001059 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
1061 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001062
1063exit:
1064 /*
1065 * Key attributes may have been returned by psa_get_key_attributes()
1066 * thus reset them as required.
1067 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001068 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001069
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 mbedtls_free(exported);
1071 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001072}
1073
Ryan Everettfbf815d2024-03-12 16:32:29 +00001074static int exercise_export_public_key(mbedtls_svc_key_id_t key,
1075 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001076{
1077 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1078 psa_key_type_t public_type;
1079 uint8_t *exported = NULL;
1080 size_t exported_size = 0;
1081 size_t exported_length = 0;
1082 int ok = 0;
1083
Ryan Everettfbf815d2024-03-12 16:32:29 +00001084 psa_status_t status = psa_get_key_attributes(key, &attributes);
1085 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1086 /* The key has been destroyed. */
1087 psa_reset_key_attributes(&attributes);
1088 return 1;
1089 }
1090 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +01001092 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 psa_get_key_type(&attributes),
1094 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001095 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001096
Ryan Everettfbf815d2024-03-12 16:32:29 +00001097 status = psa_export_public_key(key, exported,
1098 exported_size, &exported_length);
1099 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1100 /* The key has been destroyed. */
1101 ok = 1;
1102 goto exit;
1103 }
1104 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001105 ok = 1;
1106 goto exit;
1107 }
1108
1109 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +01001110 psa_get_key_type(&attributes));
1111 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
1112 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001113 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001114
Ryan Everettfbf815d2024-03-12 16:32:29 +00001115 status = psa_export_public_key(key, exported,
1116 exported_size, &exported_length);
1117 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1118 /* The key has been destroyed. */
1119 ok = 1;
1120 goto exit;
1121 }
1122 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001123 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001124 public_type, psa_get_key_bits(&attributes),
1125 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001126
1127exit:
1128 /*
1129 * Key attributes may have been returned by psa_get_key_attributes()
1130 * thus reset them as required.
1131 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001133
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 mbedtls_free(exported);
1135 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001136}
1137
Gilles Peskine449bd832023-01-11 14:50:10 +01001138int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
1139 psa_key_usage_t usage,
Ryan Everett0a271fd2024-03-12 16:34:02 +00001140 psa_algorithm_t alg,
1141 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001142{
Gilles Peskine2385f712021-02-14 01:34:21 +01001143 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001144
Ryan Everett0a271fd2024-03-12 16:34:02 +00001145 if (!check_key_attributes_sanity(key, key_destroyable)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 return 0;
1147 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001148
Gilles Peskine449bd832023-01-11 14:50:10 +01001149 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001150 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 } else if (PSA_ALG_IS_MAC(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001152 ok = exercise_mac_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001153 } else if (PSA_ALG_IS_CIPHER(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001154 ok = exercise_cipher_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 } else if (PSA_ALG_IS_AEAD(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001156 ok = exercise_aead_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001157 } else if (PSA_ALG_IS_SIGN(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001158 ok = exercise_signature_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001159 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001160 ok = exercise_asymmetric_encryption_key(key, usage, alg,
1161 key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001163 ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001165 ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001166 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001167 ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001168 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +01001169 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001171
Ryan Everett0a271fd2024-03-12 16:34:02 +00001172 ok = ok && exercise_export_key(key,
1173 usage,
1174 key_destroyable);
1175 ok = ok && exercise_export_public_key(key,
1176 key_destroyable);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001177
Gilles Peskine2385f712021-02-14 01:34:21 +01001178exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001180}
1181
Gilles Peskine449bd832023-01-11 14:50:10 +01001182psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1183 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001184{
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1186 if (PSA_ALG_IS_SIGN_HASH(alg)) {
1187 if (PSA_ALG_SIGN_GET_HASH(alg)) {
1188 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1189 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1190 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1191 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1192 }
1193 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1194 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1195 PSA_KEY_USAGE_VERIFY_MESSAGE :
1196 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001197 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001198
Gilles Peskine449bd832023-01-11 14:50:10 +01001199 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1200 PSA_KEY_USAGE_VERIFY_HASH :
1201 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1202 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1203 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1204 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1205 PSA_KEY_USAGE_ENCRYPT :
1206 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1207 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1208 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1209 return PSA_KEY_USAGE_DERIVE;
1210 } else {
1211 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001212 }
1213
1214}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001215
Gilles Peskine34955672024-02-12 14:19:24 +01001216int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1217{
1218 /* Reject algorithms that we know are not supported. Default to
1219 * attempting exercise, so that if an algorithm is missing from this
1220 * function, the result will be a test failure and not silently
1221 * omitting exercise. */
1222#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1223 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1224 return 0;
1225 }
1226#endif
1227#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1228 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1229 return 0;
1230 }
1231#endif
1232#if !defined(PSA_WANT_ALG_RSA_PSS)
1233 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1234 return 0;
1235 }
1236#endif
1237#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1238 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1239 return 0;
1240 }
1241#endif
1242#if !defined(PSA_WANT_ALG_ECDSA)
1243 if (PSA_ALG_IS_ECDSA(alg)) {
1244 return 0;
1245 }
1246#endif
1247#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1248 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1249 return 0;
1250 }
1251#endif
1252#if !defined(PSA_WANT_ALG_ECDH)
1253 if (PSA_ALG_IS_ECDH(alg)) {
1254 return 0;
1255 }
1256#endif
1257 (void) alg;
1258 return 1;
1259}
1260
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001261#if defined(MBEDTLS_PK_C)
1262int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1263 const mbedtls_pk_context *pk)
1264{
1265 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1266 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1267 int ok = 0;
1268
1269 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1270 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1271 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1272
1273 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1274 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1275 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1276
1277 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1278 const uint8_t *pk_public = NULL;
1279 size_t pk_public_length = 0;
1280
1281 switch (pk_type) {
1282#if defined(MBEDTLS_RSA_C)
1283 case MBEDTLS_PK_RSA:
1284 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1285 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1286 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1287 uint8_t *cursor = end;
1288 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1289 pk_public_buffer, &cursor));
1290 pk_public = cursor;
1291 pk_public_length = end - pk_public;
1292 break;
1293#endif
1294
1295#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1296 case MBEDTLS_PK_ECKEY:
1297 case MBEDTLS_PK_ECKEY_DH:
1298 case MBEDTLS_PK_ECDSA:
1299 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1300 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1301 pk_public = pk->pub_raw;
1302 pk_public_length = pk->pub_raw_len;
1303 break;
1304#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1305
Elena Uziunaite8dde3b32024-07-05 12:10:21 +01001306#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001307 case MBEDTLS_PK_ECKEY:
1308 case MBEDTLS_PK_ECKEY_DH:
1309 case MBEDTLS_PK_ECDSA:
1310 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1311 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1312 TEST_EQUAL(mbedtls_ecp_write_public_key(
1313 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1314 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1315 pk_public = pk_public_buffer;
1316 break;
Elena Uziunaite8dde3b32024-07-05 12:10:21 +01001317#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY && !MBEDTLS_PK_USE_PSA_EC_DATA */
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001318
1319#if defined(MBEDTLS_USE_PSA_CRYPTO)
1320 case MBEDTLS_PK_OPAQUE:
1321 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1322 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1323 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1324 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1325 PSA_ASSERT(psa_export_public_key(psa_key,
1326 pk_public_buffer,
1327 sizeof(pk_public_buffer),
1328 &pk_public_length));
1329 pk_public = pk_public_buffer;
1330 break;
1331#endif /* MBEDTLS_USE_PSA_CRYPTO */
1332
1333 default:
1334 TEST_FAIL("pk type not supported");
1335 }
1336
1337 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1338 size_t psa_public_length = 0;
1339 PSA_ASSERT(psa_export_public_key(psa_key,
1340 psa_public, sizeof(psa_public),
1341 &psa_public_length));
1342 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1343 psa_public, psa_public_length);
1344
1345 ok = 1;
1346
1347exit:
1348 psa_reset_key_attributes(&psa_attributes);
1349 psa_reset_key_attributes(&pk_attributes);
1350 return ok;
1351}
1352#endif /* MBEDTLS_PK_C */
1353
David Horstmann0d8287c2024-07-26 18:01:04 +01001354#endif /* MBEDTLS_PSA_CRYPTO_C || MBEDTLS_PSA_CRYPTO_CLIENT */