blob: 032c4892011e9e2b0c0493f2b722f40a27f6e659 [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 Horstmanna7d2afe2024-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
Ryan Everett81630282024-03-12 16:21:12 +0000698 psa_status_t status = psa_get_key_attributes(key, &attributes);
699 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
700 /* The key has been destroyed. */
701 psa_reset_key_attributes(&attributes);
702 return PSA_SUCCESS;
703 }
704 PSA_ASSERT(status);
705
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 private_key_type = psa_get_key_type(&attributes);
707 key_bits = psa_get_key_bits(&attributes);
708 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
709 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100710 TEST_CALLOC(public_key, public_key_length);
Ryan Everett81630282024-03-12 16:21:12 +0000711 status = psa_export_public_key(key,
712 public_key, public_key_length,
713 &public_key_length);
714 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
715 /* The key has been destroyed. */
716 status = PSA_SUCCESS;
717 goto exit;
718 }
Ryan Everett6de38ac2024-03-14 17:50:39 +0000719 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100720
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 status = psa_raw_key_agreement(alg, key,
722 public_key, public_key_length,
723 output, sizeof(output), &output_length);
Ryan Everett81630282024-03-12 16:21:12 +0000724 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
725 /* The key has been destroyed. */
726 status = PSA_SUCCESS;
727 goto exit;
728 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 if (status == PSA_SUCCESS) {
730 TEST_ASSERT(output_length <=
731 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
732 key_bits));
733 TEST_ASSERT(output_length <=
734 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100735 }
736
Gilles Peskinee78b0022021-02-13 00:41:11 +0100737exit:
738 /*
739 * Key attributes may have been returned by psa_get_key_attributes()
740 * thus reset them as required.
741 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 mbedtls_free(public_key);
745 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100746}
747
Gilles Peskine449bd832023-01-11 14:50:10 +0100748static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
749 psa_key_usage_t usage,
Ryan Everett81630282024-03-12 16:21:12 +0000750 psa_algorithm_t alg,
751 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100752{
753 int ok = 0;
754
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100756 /* We need two keys to exercise key agreement. Exercise the
757 * private key against its own public key. */
Ryan Everett81630282024-03-12 16:21:12 +0000758 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key,
759 key_destroyable));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100760 }
761 ok = 1;
762
763exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100765}
766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
768 psa_key_usage_t usage,
Ryan Everett73e4ea32024-03-12 16:29:55 +0000769 psa_algorithm_t alg,
770 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100771{
772 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200773 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100774 unsigned char output[1];
775 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200777 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100778
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100780 /* We need two keys to exercise key agreement. Exercise the
781 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
783 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
784 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
785 PSA_ASSERT(psa_key_derivation_input_bytes(
786 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
787 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100788 }
789
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
791 PSA_ASSERT(psa_key_derivation_input_bytes(
792 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
793 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200794 }
795
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200796 /* For HKDF_EXPAND input secret may fail as secret size may not match
797 to expected PRK size. In practice it means that key bits must match
798 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200800 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ryan Everett73e4ea32024-03-12 16:29:55 +0000801 psa_status_t status = psa_get_key_attributes(key, &attributes);
802 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
803 /* The key has been destroyed. */
804 ok = 1;
805 }
806 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 size_t key_bits = psa_get_key_bits(&attributes);
808 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200809
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200811 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200813 }
814
Ryan Everett73e4ea32024-03-12 16:29:55 +0000815 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key,
816 key_destroyable),
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200818
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 if (expected_key_agreement_status != PSA_SUCCESS) {
820 return 1;
821 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100822
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
824 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
825 PSA_ASSERT(psa_key_derivation_input_bytes(
826 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
827 input, sizeof(input)));
828 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
829 PSA_ASSERT(psa_key_derivation_input_bytes(
830 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
831 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100832 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
834 output,
835 sizeof(output)));
836 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100837 }
838 ok = 1;
839
840exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100842}
843
844int mbedtls_test_psa_exported_key_sanity_check(
845 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100847{
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100849
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
851 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
852 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100853
Ronald Cron64df7382021-07-06 09:23:06 +0200854#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
856 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100857 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100858 size_t len;
859 /* RSAPrivateKey ::= SEQUENCE {
860 * version INTEGER, -- must be 0
861 * modulus INTEGER, -- n
862 * publicExponent INTEGER, -- e
863 * privateExponent INTEGER, -- d
864 * prime1 INTEGER, -- p
865 * prime2 INTEGER, -- q
866 * exponent1 INTEGER, -- d mod (p-1)
867 * exponent2 INTEGER, -- d mod (q-1)
868 * coefficient INTEGER, -- (inverse of q) mod p
869 * }
870 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
872 MBEDTLS_ASN1_SEQUENCE |
873 MBEDTLS_ASN1_CONSTRUCTED), 0);
874 TEST_EQUAL(len, end - p);
875 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100876 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 }
878 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100879 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 }
881 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100882 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100884 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100886 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100888 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100890 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 }
892 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100893 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 }
895 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100896 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 }
898 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100899 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 }
901 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100902 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 }
904 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
907 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200908#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100909
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100911 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
915 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100916
Ronald Cron64df7382021-07-06 09:23:06 +0200917#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
919 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100920 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100921 size_t len;
922 /* RSAPublicKey ::= SEQUENCE {
923 * modulus INTEGER, -- n
924 * publicExponent INTEGER } -- e
925 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
927 MBEDTLS_ASN1_SEQUENCE |
928 MBEDTLS_ASN1_CONSTRUCTED),
929 0);
930 TEST_EQUAL(len, end - p);
931 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100932 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 }
934 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100935 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 }
937 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100938
939
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 TEST_ASSERT(exported_length <=
941 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
942 TEST_ASSERT(exported_length <=
943 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
944 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200945#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100946
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 TEST_ASSERT(exported_length <=
950 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
951 TEST_ASSERT(exported_length <=
952 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100955 /* The representation of an ECC Montgomery public key is
956 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100958 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100959 /* The representation of an ECC Edwards public key is
960 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100961 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100963 /* The representation of an ECC Weierstrass public key is:
964 * - The byte 0x04;
965 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
966 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
967 * - where m is the bit size associated with the curve.
968 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
970 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100971 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100972 } else
973 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200974 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100975 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
976 TEST_ASSERT(exported_length <=
977 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200978 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100979 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100980 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100981 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100982
Gilles Peskinecc9db302021-02-14 01:29:52 +0100983#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100985 /* Check the parity bits. */
986 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100987 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100988 unsigned bit_count = 0;
989 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 for (m = 1; m <= 0x100; m <<= 1) {
991 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100992 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100993 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100994 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100996 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100997 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100998#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100999
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001001
1002exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001004}
1005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006static int exercise_export_key(mbedtls_svc_key_id_t key,
Ryan Everettfbf815d2024-03-12 16:32:29 +00001007 psa_key_usage_t usage,
1008 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001009{
1010 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1011 uint8_t *exported = NULL;
1012 size_t exported_size = 0;
1013 size_t exported_length = 0;
1014 int ok = 0;
1015
Ryan Everettfbf815d2024-03-12 16:32:29 +00001016 psa_status_t status = psa_get_key_attributes(key, &attributes);
1017 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1018 /* The key has been destroyed. */
1019 psa_reset_key_attributes(&attributes);
1020 return 1;
1021 }
1022 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001023
1024 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 psa_get_key_type(&attributes),
1026 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001027 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001028
Ryan Everettfbf815d2024-03-12 16:32:29 +00001029 status = psa_export_key(key, exported, exported_size, &exported_length);
1030 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1031 /* The key has been destroyed. */
1032 ok = 1;
1033 goto exit;
1034 } else if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
1035 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
1036 TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001037 ok = 1;
1038 goto exit;
1039 }
Ryan Everettfbf815d2024-03-12 16:32:29 +00001040 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001041 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
1043 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001044
1045exit:
1046 /*
1047 * Key attributes may have been returned by psa_get_key_attributes()
1048 * thus reset them as required.
1049 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001051
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 mbedtls_free(exported);
1053 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001054}
1055
Ryan Everettfbf815d2024-03-12 16:32:29 +00001056static int exercise_export_public_key(mbedtls_svc_key_id_t key,
1057 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001058{
1059 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1060 psa_key_type_t public_type;
1061 uint8_t *exported = NULL;
1062 size_t exported_size = 0;
1063 size_t exported_length = 0;
1064 int ok = 0;
1065
Ryan Everettfbf815d2024-03-12 16:32:29 +00001066 psa_status_t status = psa_get_key_attributes(key, &attributes);
1067 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1068 /* The key has been destroyed. */
1069 psa_reset_key_attributes(&attributes);
1070 return 1;
1071 }
1072 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +01001073 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +01001074 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 psa_get_key_type(&attributes),
1076 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001077 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001078
Ryan Everettfbf815d2024-03-12 16:32:29 +00001079 status = psa_export_public_key(key, exported,
1080 exported_size, &exported_length);
1081 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1082 /* The key has been destroyed. */
1083 ok = 1;
1084 goto exit;
1085 }
1086 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001087 ok = 1;
1088 goto exit;
1089 }
1090
1091 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +01001092 psa_get_key_type(&attributes));
1093 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
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 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001105 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 public_type, psa_get_key_bits(&attributes),
1107 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001108
1109exit:
1110 /*
1111 * Key attributes may have been returned by psa_get_key_attributes()
1112 * thus reset them as required.
1113 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001115
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 mbedtls_free(exported);
1117 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001118}
1119
Gilles Peskine449bd832023-01-11 14:50:10 +01001120int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
1121 psa_key_usage_t usage,
Ryan Everett0a271fd2024-03-12 16:34:02 +00001122 psa_algorithm_t alg,
1123 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001124{
Gilles Peskine2385f712021-02-14 01:34:21 +01001125 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001126
Ryan Everett0a271fd2024-03-12 16:34:02 +00001127 if (!check_key_attributes_sanity(key, key_destroyable)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001128 return 0;
1129 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001130
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001132 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 } else if (PSA_ALG_IS_MAC(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001134 ok = exercise_mac_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001135 } else if (PSA_ALG_IS_CIPHER(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001136 ok = exercise_cipher_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001137 } else if (PSA_ALG_IS_AEAD(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001138 ok = exercise_aead_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 } else if (PSA_ALG_IS_SIGN(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001140 ok = exercise_signature_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001142 ok = exercise_asymmetric_encryption_key(key, usage, alg,
1143 key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001144 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001145 ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001147 ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001148 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001149 ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001150 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +01001151 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +01001152 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001153
Ryan Everett0a271fd2024-03-12 16:34:02 +00001154 ok = ok && exercise_export_key(key,
1155 usage,
1156 key_destroyable);
1157 ok = ok && exercise_export_public_key(key,
1158 key_destroyable);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001159
Gilles Peskine2385f712021-02-14 01:34:21 +01001160exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001161 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001162}
1163
Gilles Peskine449bd832023-01-11 14:50:10 +01001164psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1165 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001166{
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1168 if (PSA_ALG_IS_SIGN_HASH(alg)) {
1169 if (PSA_ALG_SIGN_GET_HASH(alg)) {
1170 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1171 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1172 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1173 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1174 }
1175 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1176 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1177 PSA_KEY_USAGE_VERIFY_MESSAGE :
1178 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001179 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001180
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1182 PSA_KEY_USAGE_VERIFY_HASH :
1183 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1184 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1185 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1186 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1187 PSA_KEY_USAGE_ENCRYPT :
1188 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1189 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1190 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1191 return PSA_KEY_USAGE_DERIVE;
1192 } else {
1193 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001194 }
1195
1196}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001197
Gilles Peskine34955672024-02-12 14:19:24 +01001198int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1199{
1200 /* Reject algorithms that we know are not supported. Default to
1201 * attempting exercise, so that if an algorithm is missing from this
1202 * function, the result will be a test failure and not silently
1203 * omitting exercise. */
1204#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1205 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1206 return 0;
1207 }
1208#endif
1209#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1210 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1211 return 0;
1212 }
1213#endif
1214#if !defined(PSA_WANT_ALG_RSA_PSS)
1215 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1216 return 0;
1217 }
1218#endif
1219#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1220 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1221 return 0;
1222 }
1223#endif
1224#if !defined(PSA_WANT_ALG_ECDSA)
1225 if (PSA_ALG_IS_ECDSA(alg)) {
1226 return 0;
1227 }
1228#endif
1229#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1230 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1231 return 0;
1232 }
1233#endif
1234#if !defined(PSA_WANT_ALG_ECDH)
1235 if (PSA_ALG_IS_ECDH(alg)) {
1236 return 0;
1237 }
1238#endif
1239 (void) alg;
1240 return 1;
1241}
1242
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001243#if defined(MBEDTLS_PK_C)
1244int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1245 const mbedtls_pk_context *pk)
1246{
1247 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1248 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1249 int ok = 0;
1250
1251 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1252 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1253 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1254
1255 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1256 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1257 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1258
1259 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1260 const uint8_t *pk_public = NULL;
1261 size_t pk_public_length = 0;
1262
1263 switch (pk_type) {
1264#if defined(MBEDTLS_RSA_C)
1265 case MBEDTLS_PK_RSA:
1266 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1267 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1268 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1269 uint8_t *cursor = end;
1270 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1271 pk_public_buffer, &cursor));
1272 pk_public = cursor;
1273 pk_public_length = end - pk_public;
1274 break;
1275#endif
1276
1277#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1278 case MBEDTLS_PK_ECKEY:
1279 case MBEDTLS_PK_ECKEY_DH:
1280 case MBEDTLS_PK_ECDSA:
1281 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1282 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1283 pk_public = pk->pub_raw;
1284 pk_public_length = pk->pub_raw_len;
1285 break;
1286#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1287
David Horstmann8660e4b2024-09-06 14:55:05 +01001288#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001289 case MBEDTLS_PK_ECKEY:
1290 case MBEDTLS_PK_ECKEY_DH:
1291 case MBEDTLS_PK_ECDSA:
1292 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1293 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1294 TEST_EQUAL(mbedtls_ecp_write_public_key(
1295 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1296 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1297 pk_public = pk_public_buffer;
1298 break;
David Horstmann8660e4b2024-09-06 14:55:05 +01001299#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY && !MBEDTLS_PK_USE_PSA_EC_DATA */
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001300
1301#if defined(MBEDTLS_USE_PSA_CRYPTO)
1302 case MBEDTLS_PK_OPAQUE:
1303 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1304 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1305 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1306 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1307 PSA_ASSERT(psa_export_public_key(psa_key,
1308 pk_public_buffer,
1309 sizeof(pk_public_buffer),
1310 &pk_public_length));
1311 pk_public = pk_public_buffer;
1312 break;
1313#endif /* MBEDTLS_USE_PSA_CRYPTO */
1314
1315 default:
1316 TEST_FAIL("pk type not supported");
1317 }
1318
1319 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1320 size_t psa_public_length = 0;
1321 PSA_ASSERT(psa_export_public_key(psa_key,
1322 psa_public, sizeof(psa_public),
1323 &psa_public_length));
1324 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1325 psa_public, psa_public_length);
1326
1327 ok = 1;
1328
1329exit:
1330 psa_reset_key_attributes(&psa_attributes);
1331 psa_reset_key_attributes(&pk_attributes);
1332 return ok;
1333}
1334#endif /* MBEDTLS_PK_C */
1335
David Horstmann8660e4b2024-09-06 14:55:05 +01001336#endif /* MBEDTLS_PSA_CRYPTO_C || MBEDTLS_PSA_CRYPTO_CLIENT */