blob: 5c821e2f859ff5b70752b7fd8b6c32e42449ab94 [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 Horstmann0d8287c2024-07-26 18:01:04 +010014#if ((MBEDTLS_VERSION_MAJOR < 4) \
15 && defined(MBEDTLS_PSA_CRYPTO_C)) \
David Horstmann34d79ce2024-09-27 15:13:32 +010016 || (MBEDTLS_VERSION_MAJOR >= 4 \
17 && defined(MBEDTLS_PSA_CRYPTO_CLIENT))
Gilles Peskine66e7b902021-02-12 23:40:58 +010018
Gilles Peskinee78b0022021-02-13 00:41:11 +010019#include <mbedtls/asn1.h>
Gilles Peskine66e7b902021-02-12 23:40:58 +010020#include <psa/crypto.h>
21
Gilles Peskinee78b0022021-02-13 00:41:11 +010022#include <test/asn1_helpers.h>
Przemyslaw Stekiel53de2622021-11-03 09:35:35 +010023#include <psa_crypto_slot_management.h>
Gilles Peskinee78b0022021-02-13 00:41:11 +010024#include <test/psa_crypto_helpers.h>
25
Gilles Peskine6fe8a062024-02-15 17:21:17 +010026#if defined(MBEDTLS_PK_C)
27#include <pk_internal.h>
28#endif
29#if defined(MBEDTLS_ECP_C)
30#include <mbedtls/ecp.h>
31#endif
32#if defined(MBEDTLS_RSA_C)
33#include <rsa_internal.h>
34#endif
35
Gilles Peskinee78b0022021-02-13 00:41:11 +010036#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010037static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
Gilles Peskinee78b0022021-02-13 00:41:11 +010038{
Gilles Peskine449bd832023-01-11 14:50:10 +010039 return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
40 PSA_KEY_LOCATION_LOCAL_STORAGE;
Gilles Peskinee78b0022021-02-13 00:41:11 +010041}
42#endif
43
Ryan Everettf08a93f2024-03-12 16:00:08 +000044static int check_key_attributes_sanity(mbedtls_svc_key_id_t key,
45 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +010046{
47 int ok = 0;
48 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
49 psa_key_lifetime_t lifetime;
50 mbedtls_svc_key_id_t id;
51 psa_key_type_t type;
Gilles Peskine6b362e62021-02-15 12:03:16 +010052 size_t bits;
Ryan Everettf08a93f2024-03-12 16:00:08 +000053 psa_status_t status = psa_get_key_attributes(key, &attributes);
54 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
55 /* The key has been destroyed. */
56 psa_reset_key_attributes(&attributes);
57 return 1;
58 }
59 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +010060 lifetime = psa_get_key_lifetime(&attributes);
61 id = psa_get_key_id(&attributes);
62 type = psa_get_key_type(&attributes);
63 bits = psa_get_key_bits(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +010064
65 /* Persistence */
Gilles Peskine449bd832023-01-11 14:50:10 +010066 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010067 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010068 (PSA_KEY_ID_VOLATILE_MIN <=
69 MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
70 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
71 PSA_KEY_ID_VOLATILE_MAX));
72 } else {
Gilles Peskinee78b0022021-02-13 00:41:11 +010073 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010074 (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
75 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
Gilles Peskinee78b0022021-02-13 00:41:11 +010076 }
77#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Ryan Everettf08a93f2024-03-12 16:00:08 +000078 /* MBEDTLS_PSA_CRYPTO_SE_C does not support thread safety. */
79 if (key_destroyable == 0) {
80 /* randomly-generated 64-bit constant, should never appear in test data */
81 psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
82 status = psa_get_key_slot_number(&attributes, &slot_number);
83 if (lifetime_is_dynamic_secure_element(lifetime)) {
84 /* Mbed TLS currently always exposes the slot number to
85 * applications. This is not mandated by the PSA specification
86 * and may change in future versions. */
87 TEST_EQUAL(status, 0);
88 TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
89 } else {
90 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
91 }
Gilles Peskinee78b0022021-02-13 00:41:11 +010092 }
93#endif
94
95 /* Type and size */
Gilles Peskine449bd832023-01-11 14:50:10 +010096 TEST_ASSERT(type != 0);
97 TEST_ASSERT(bits != 0);
98 TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
99 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
100 TEST_ASSERT(bits % 8 == 0);
101 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100102
103 /* MAX macros concerning specific key types */
Gilles Peskine449bd832023-01-11 14:50:10 +0100104 if (PSA_KEY_TYPE_IS_ECC(type)) {
105 TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
106 } else if (PSA_KEY_TYPE_IS_RSA(type)) {
107 TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
108 }
109 TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100110
111 ok = 1;
112
113exit:
114 /*
115 * Key attributes may have been returned by psa_get_key_attributes()
116 * thus reset them as required.
117 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100121}
122
Gilles Peskine449bd832023-01-11 14:50:10 +0100123static int exercise_mac_key(mbedtls_svc_key_id_t key,
124 psa_key_usage_t usage,
Ryan Everett77635502024-03-12 16:02:23 +0000125 psa_algorithm_t alg,
126 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100127{
128 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
129 const unsigned char input[] = "foo";
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
131 size_t mac_length = sizeof(mac);
Ryan Everett77635502024-03-12 16:02:23 +0000132 psa_status_t status = PSA_SUCCESS;
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100133 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
135 alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100136 }
137
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
Ryan Everett77635502024-03-12 16:02:23 +0000139 status = psa_mac_sign_setup(&operation, key, alg);
140 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
141 /* The key has been destroyed. */
142 PSA_ASSERT(psa_mac_abort(&operation));
143 return 1;
144 }
145 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 PSA_ASSERT(psa_mac_update(&operation,
147 input, sizeof(input)));
148 PSA_ASSERT(psa_mac_sign_finish(&operation,
149 mac, sizeof(mac),
150 &mac_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100151 }
152
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100154 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100155 (usage & PSA_KEY_USAGE_SIGN_HASH ?
156 PSA_SUCCESS :
157 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett77635502024-03-12 16:02:23 +0000158 status = psa_mac_verify_setup(&operation, key, alg);
159 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
160 /* The key has been destroyed. */
161 PSA_ASSERT(psa_mac_abort(&operation));
162 return 1;
163 }
164 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100165 PSA_ASSERT(psa_mac_update(&operation,
166 input, sizeof(input)));
167 TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
168 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100169 }
170
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100172
173exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100174 psa_mac_abort(&operation);
175 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100176}
177
Gilles Peskine449bd832023-01-11 14:50:10 +0100178static int exercise_cipher_key(mbedtls_svc_key_id_t key,
179 psa_key_usage_t usage,
Ryan Everett70691f32024-03-12 16:04:45 +0000180 psa_algorithm_t alg,
181 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100182{
183 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100184 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
Gilles Peskine5eef11a2022-04-21 11:14:30 +0200185 size_t iv_length;
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100186 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
187 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100188 const unsigned char plaintext[16] = "Hello, world...";
189 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 size_t ciphertext_length = sizeof(ciphertext);
191 unsigned char decrypted[sizeof(ciphertext)];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100192 size_t part_length;
Ryan Everett70691f32024-03-12 16:04:45 +0000193 psa_status_t status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100194
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
196 key_type = psa_get_key_type(&attributes);
197 iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everett70691f32024-03-12 16:04:45 +0000200 status = psa_cipher_encrypt_setup(&operation, key, alg);
201 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
202 /* The key has been destroyed. */
203 PSA_ASSERT(psa_cipher_abort(&operation));
204 return 1;
205 }
206 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100207 if (iv_length != 0) {
208 PSA_ASSERT(psa_cipher_generate_iv(&operation,
209 iv, sizeof(iv),
210 &iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100211 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 PSA_ASSERT(psa_cipher_update(&operation,
213 plaintext, sizeof(plaintext),
214 ciphertext, sizeof(ciphertext),
215 &ciphertext_length));
216 PSA_ASSERT(psa_cipher_finish(&operation,
217 ciphertext + ciphertext_length,
218 sizeof(ciphertext) - ciphertext_length,
219 &part_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100220 ciphertext_length += part_length;
221 }
222
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100224 int maybe_invalid_padding = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
226 maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100227 }
Ryan Everett70691f32024-03-12 16:04:45 +0000228 status = psa_cipher_decrypt_setup(&operation, key, alg);
229 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
230 /* The key has been destroyed. */
231 PSA_ASSERT(psa_cipher_abort(&operation));
232 return 1;
233 }
234 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 if (iv_length != 0) {
236 PSA_ASSERT(psa_cipher_set_iv(&operation,
237 iv, iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100238 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 PSA_ASSERT(psa_cipher_update(&operation,
240 ciphertext, ciphertext_length,
241 decrypted, sizeof(decrypted),
242 &part_length));
243 status = psa_cipher_finish(&operation,
244 decrypted + part_length,
245 sizeof(decrypted) - part_length,
246 &part_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100247 /* For a stream cipher, all inputs are valid. For a block cipher,
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800248 * if the input is some arbitrary data rather than an actual
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 ciphertext, a padding error is likely. */
250 if (maybe_invalid_padding) {
251 TEST_ASSERT(status == PSA_SUCCESS ||
252 status == PSA_ERROR_INVALID_PADDING);
253 } else {
254 PSA_ASSERT(status);
255 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100256 }
257
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100259
260exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 psa_cipher_abort(&operation);
262 psa_reset_key_attributes(&attributes);
263 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100264}
265
Gilles Peskine449bd832023-01-11 14:50:10 +0100266static int exercise_aead_key(mbedtls_svc_key_id_t key,
267 psa_key_usage_t usage,
Ryan Everettfbe703d2024-03-12 16:09:25 +0000268 psa_algorithm_t alg,
269 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100270{
Gilles Peskine449bd832023-01-11 14:50:10 +0100271 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
Gilles Peskine7acb1982022-03-19 11:03:32 +0100272 size_t nonce_length;
273 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
274 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100275 unsigned char plaintext[16] = "Hello, world...";
276 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100277 size_t ciphertext_length = sizeof(ciphertext);
278 size_t plaintext_length = sizeof(ciphertext);
Ryan Everettfbe703d2024-03-12 16:09:25 +0000279 psa_status_t status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100280
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100281 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100282 if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
283 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100284 }
285
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
287 key_type = psa_get_key_type(&attributes);
288 nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
Steven Cooremanaaec3412021-02-18 13:30:34 +0100289
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everettfbe703d2024-03-12 16:09:25 +0000291 status = psa_aead_encrypt(key, alg,
292 nonce, nonce_length,
293 NULL, 0,
294 plaintext, sizeof(plaintext),
295 ciphertext, sizeof(ciphertext),
296 &ciphertext_length);
297 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
298 /* The key has been destroyed. */
299 return 1;
300 }
301 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100302 }
303
Gilles Peskine449bd832023-01-11 14:50:10 +0100304 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100305 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 (usage & PSA_KEY_USAGE_ENCRYPT ?
307 PSA_SUCCESS :
308 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everettfbe703d2024-03-12 16:09:25 +0000309 status = psa_aead_decrypt(key, alg,
310 nonce, nonce_length,
311 NULL, 0,
312 ciphertext, ciphertext_length,
313 plaintext, sizeof(plaintext),
314 &plaintext_length);
315 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
316 /* The key has been destroyed. */
317 return 1;
318 }
319 TEST_ASSERT(status == verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100320 }
321
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100323
324exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 psa_reset_key_attributes(&attributes);
326 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100327}
328
Gilles Peskine449bd832023-01-11 14:50:10 +0100329static int can_sign_or_verify_message(psa_key_usage_t usage,
330 psa_algorithm_t alg)
Gilles Peskined586b822022-03-19 11:15:41 +0100331{
332 /* Sign-the-unspecified-hash algorithms can only be used with
333 * {sign,verify}_hash, not with {sign,verify}_message. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
335 return 0;
336 }
337 return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
338 PSA_KEY_USAGE_VERIFY_MESSAGE);
Gilles Peskined586b822022-03-19 11:15:41 +0100339}
340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341static int exercise_signature_key(mbedtls_svc_key_id_t key,
342 psa_key_usage_t usage,
Ryan Everett6edd4082024-03-12 16:11:01 +0000343 psa_algorithm_t alg,
344 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100345{
Gilles Peskine4781bd92024-02-09 17:32:45 +0100346 /* If the policy allows signing with any hash, just pick one. */
347 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
348 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
349 usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
350 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
351#if defined(KNOWN_SUPPORTED_HASH_ALG)
352 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
353 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
354#else
355 TEST_FAIL("No hash algorithm for hash-and-sign testing");
356#endif
357 }
Ryan Everett6edd4082024-03-12 16:11:01 +0000358 psa_status_t status = PSA_SUCCESS;
Gilles Peskine4781bd92024-02-09 17:32:45 +0100359
oberon-skf7a824b2023-02-15 19:43:30 +0100360 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
361 PSA_ALG_IS_SIGN_HASH(alg)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200363 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
365 size_t signature_length = sizeof(signature);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200366
Janos Follath4c0b60e2021-06-14 12:34:30 +0100367 /* Some algorithms require the payload to have the size of
368 * the hash encoded in the algorithm. Use this input size
369 * even for algorithms that allow other input sizes. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 if (hash_alg != 0) {
371 payload_length = PSA_HASH_LENGTH(hash_alg);
372 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100373
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
Ryan Everett6edd4082024-03-12 16:11:01 +0000375 status = psa_sign_hash(key, alg,
376 payload, payload_length,
377 signature, sizeof(signature),
378 &signature_length);
379 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
380 /* The key has been destroyed. */
381 return 1;
382 }
383 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 }
385
386 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
387 psa_status_t verify_status =
388 (usage & PSA_KEY_USAGE_SIGN_HASH ?
389 PSA_SUCCESS :
390 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett6edd4082024-03-12 16:11:01 +0000391 status = psa_verify_hash(key, alg,
392 payload, payload_length,
393 signature, signature_length);
394 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
395 /* The key has been destroyed. */
396 return 1;
397 }
398 TEST_ASSERT(status == verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200399 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100400 }
401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200403 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200405 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100407
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
Ryan Everett6edd4082024-03-12 16:11:01 +0000409 status = psa_sign_message(key, alg,
410 message, message_length,
411 signature, sizeof(signature),
412 &signature_length);
413 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
414 /* The key has been destroyed. */
415 return 1;
416 }
417 PSA_ASSERT(status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200418 }
419
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200421 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
423 PSA_SUCCESS :
424 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett6edd4082024-03-12 16:11:01 +0000425 status = psa_verify_message(key, alg,
426 message, message_length,
427 signature, signature_length);
428 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
429 /* The key has been destroyed. */
430 return 1;
431 }
432 TEST_ASSERT(status == verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200433 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100434 }
435
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100437
438exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100439 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100440}
441
Gilles Peskine449bd832023-01-11 14:50:10 +0100442static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
443 psa_key_usage_t usage,
Ryan Everettd48fc102024-03-12 16:12:41 +0000444 psa_algorithm_t alg,
445 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100446{
Gilles Peskinef50cd592024-02-15 13:13:26 +0100447 unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100448 "Hello, world...";
Gilles Peskinef50cd592024-02-15 13:13:26 +0100449 unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100450 "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100452 size_t plaintext_length = 16;
Ryan Everettd48fc102024-03-12 16:12:41 +0000453 psa_status_t status = PSA_SUCCESS;
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everettd48fc102024-03-12 16:12:41 +0000455 status = psa_asymmetric_encrypt(key, alg,
456 plaintext, plaintext_length,
457 NULL, 0,
458 ciphertext, sizeof(ciphertext),
459 &ciphertext_length);
460 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
461 /* The key has been destroyed. */
462 return 1;
463 }
464 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100465 }
466
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 if (usage & PSA_KEY_USAGE_DECRYPT) {
Ryan Everettd48fc102024-03-12 16:12:41 +0000468 status = psa_asymmetric_decrypt(key, alg,
469 ciphertext, ciphertext_length,
470 NULL, 0,
471 plaintext, sizeof(plaintext),
472 &plaintext_length);
473 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
474 /* The key has been destroyed. */
475 return 1;
476 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 TEST_ASSERT(status == PSA_SUCCESS ||
478 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
479 (status == PSA_ERROR_INVALID_ARGUMENT ||
480 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100481 }
482
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100484
485exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100487}
488
489int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100491 mbedtls_svc_key_id_t key,
492 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 const unsigned char *input1, size_t input1_length,
494 const unsigned char *input2, size_t input2_length,
Ryan Everettc1cc6682024-03-12 16:17:43 +0000495 size_t capacity, int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100496{
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000498 psa_status_t status = PSA_SUCCESS;
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 if (PSA_ALG_IS_HKDF(alg)) {
500 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
501 PSA_KEY_DERIVATION_INPUT_SALT,
502 input1, input1_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000503 status = psa_key_derivation_input_key(operation,
504 PSA_KEY_DERIVATION_INPUT_SECRET,
505 key);
506 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
507 /* The key has been destroyed. */
508 return 1;
509 }
510 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
512 PSA_KEY_DERIVATION_INPUT_INFO,
513 input2,
514 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530515 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
516 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
517 PSA_KEY_DERIVATION_INPUT_SALT,
518 input1, input1_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000519 status = psa_key_derivation_input_key(operation,
520 PSA_KEY_DERIVATION_INPUT_SECRET,
521 key);
522 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
523 /* The key has been destroyed. */
524 return 1;
525 }
526 PSA_ASSERT(status);
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530527 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
Ryan Everettc1cc6682024-03-12 16:17:43 +0000528 status = psa_key_derivation_input_key(operation,
529 PSA_KEY_DERIVATION_INPUT_SECRET,
530 key);
531 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
532 /* The key has been destroyed. */
533 return 1;
534 }
535 PSA_ASSERT(status);
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530536 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
537 PSA_KEY_DERIVATION_INPUT_INFO,
538 input2,
539 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
541 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
542 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
543 PSA_KEY_DERIVATION_INPUT_SEED,
544 input1, input1_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000545 status = psa_key_derivation_input_key(operation,
546 PSA_KEY_DERIVATION_INPUT_SECRET,
547 key);
548 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
549 /* The key has been destroyed. */
550 return 1;
551 }
552 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
554 PSA_KEY_DERIVATION_INPUT_LABEL,
555 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530556 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530557 PSA_ASSERT(psa_key_derivation_input_integer(operation,
558 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530559 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530560 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
561 PSA_KEY_DERIVATION_INPUT_SALT,
562 input2,
563 input2_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000564 status = psa_key_derivation_input_key(operation,
565 PSA_KEY_DERIVATION_INPUT_PASSWORD,
566 key);
567 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
568 /* The key has been destroyed. */
569 return 1;
570 }
571 PSA_ASSERT(status);
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530572 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
573 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
574 PSA_KEY_DERIVATION_INPUT_SECRET,
575 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100577 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100578 }
579
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 if (capacity != SIZE_MAX) {
581 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
582 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100583
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100585
586exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100587 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100588}
589
590
Gilles Peskine449bd832023-01-11 14:50:10 +0100591static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
592 psa_key_usage_t usage,
Ryan Everettc1cc6682024-03-12 16:17:43 +0000593 psa_algorithm_t alg,
594 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100595{
596 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
597 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100599 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100601 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 if (usage & PSA_KEY_USAGE_DERIVE) {
605 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
606 input1, input1_length,
607 input2, input2_length,
Ryan Everettc1cc6682024-03-12 16:17:43 +0000608 capacity, key_destroyable)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100609 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100611
Ryan Everettc1cc6682024-03-12 16:17:43 +0000612 psa_status_t status = psa_key_derivation_output_bytes(&operation,
613 output,
614 capacity);
615 if (key_destroyable && status == PSA_ERROR_BAD_STATE) {
616 /* The key has been destroyed. */
617 PSA_ASSERT(psa_key_derivation_abort(&operation));
618 } else {
619 PSA_ASSERT(status);
620 PSA_ASSERT(psa_key_derivation_abort(&operation));
621 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100622 }
623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100625
626exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100628}
629
630/* We need two keys to exercise key agreement. Exercise the
631 * private key against its own public key. */
632psa_status_t mbedtls_test_psa_key_agreement_with_self(
633 psa_key_derivation_operation_t *operation,
Ryan Everett73e4ea32024-03-12 16:29:55 +0000634 mbedtls_svc_key_id_t key, int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100635{
636 psa_key_type_t private_key_type;
637 psa_key_type_t public_key_type;
638 size_t key_bits;
639 uint8_t *public_key = NULL;
640 size_t public_key_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100641 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
642
Ryan Everett73e4ea32024-03-12 16:29:55 +0000643 psa_status_t status = psa_get_key_attributes(key, &attributes);
644 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
645 /* The key has been destroyed. */
646 psa_reset_key_attributes(&attributes);
647 return PSA_SUCCESS;
648 }
649 PSA_ASSERT(status);
650
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 private_key_type = psa_get_key_type(&attributes);
652 key_bits = psa_get_key_bits(&attributes);
653 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
654 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100655 TEST_CALLOC(public_key, public_key_length);
Ryan Everett73e4ea32024-03-12 16:29:55 +0000656 status = psa_export_public_key(key, public_key, public_key_length,
657 &public_key_length);
658 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
659 /* The key has been destroyed. */
660 status = PSA_SUCCESS;
661 goto exit;
662 }
663 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100664
665 status = psa_key_derivation_key_agreement(
666 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 public_key, public_key_length);
Ryan Everett73e4ea32024-03-12 16:29:55 +0000668 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
669 /* The key has been destroyed. */
670 status = PSA_SUCCESS;
671 goto exit;
672 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100673exit:
674 /*
675 * Key attributes may have been returned by psa_get_key_attributes()
676 * thus reset them as required.
677 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100679
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 mbedtls_free(public_key);
681 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100682}
683
684/* We need two keys to exercise key agreement. Exercise the
685 * private key against its own public key. */
686psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
687 psa_algorithm_t alg,
Ryan Everett81630282024-03-12 16:21:12 +0000688 mbedtls_svc_key_id_t key,
689 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100690{
691 psa_key_type_t private_key_type;
692 psa_key_type_t public_key_type;
693 size_t key_bits;
694 uint8_t *public_key = NULL;
695 size_t public_key_length;
696 uint8_t output[1024];
697 size_t output_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100698 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
699
Ryan Everett81630282024-03-12 16:21:12 +0000700 psa_status_t status = psa_get_key_attributes(key, &attributes);
701 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
702 /* The key has been destroyed. */
703 psa_reset_key_attributes(&attributes);
704 return PSA_SUCCESS;
705 }
706 PSA_ASSERT(status);
707
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 private_key_type = psa_get_key_type(&attributes);
709 key_bits = psa_get_key_bits(&attributes);
710 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
711 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100712 TEST_CALLOC(public_key, public_key_length);
Ryan Everett81630282024-03-12 16:21:12 +0000713 status = psa_export_public_key(key,
714 public_key, public_key_length,
715 &public_key_length);
716 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
717 /* The key has been destroyed. */
718 status = PSA_SUCCESS;
719 goto exit;
720 }
Ryan Everett6de38ac2024-03-14 17:50:39 +0000721 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100722
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 status = psa_raw_key_agreement(alg, key,
724 public_key, public_key_length,
725 output, sizeof(output), &output_length);
Ryan Everett81630282024-03-12 16:21:12 +0000726 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
727 /* The key has been destroyed. */
728 status = PSA_SUCCESS;
729 goto exit;
730 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 if (status == PSA_SUCCESS) {
732 TEST_ASSERT(output_length <=
733 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
734 key_bits));
735 TEST_ASSERT(output_length <=
736 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100737 }
738
Gilles Peskinee78b0022021-02-13 00:41:11 +0100739exit:
740 /*
741 * Key attributes may have been returned by psa_get_key_attributes()
742 * thus reset them as required.
743 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100745
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 mbedtls_free(public_key);
747 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100748}
749
Gilles Peskine449bd832023-01-11 14:50:10 +0100750static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
751 psa_key_usage_t usage,
Ryan Everett81630282024-03-12 16:21:12 +0000752 psa_algorithm_t alg,
753 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100754{
755 int ok = 0;
756
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100758 /* We need two keys to exercise key agreement. Exercise the
759 * private key against its own public key. */
Ryan Everett81630282024-03-12 16:21:12 +0000760 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key,
761 key_destroyable));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100762 }
763 ok = 1;
764
765exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100767}
768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
770 psa_key_usage_t usage,
Ryan Everett73e4ea32024-03-12 16:29:55 +0000771 psa_algorithm_t alg,
772 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100773{
774 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200775 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100776 unsigned char output[1];
777 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200779 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100780
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100782 /* We need two keys to exercise key agreement. Exercise the
783 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
785 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
786 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
787 PSA_ASSERT(psa_key_derivation_input_bytes(
788 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
789 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100790 }
791
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
793 PSA_ASSERT(psa_key_derivation_input_bytes(
794 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
795 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200796 }
797
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200798 /* For HKDF_EXPAND input secret may fail as secret size may not match
799 to expected PRK size. In practice it means that key bits must match
800 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200802 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ryan Everett73e4ea32024-03-12 16:29:55 +0000803 psa_status_t status = psa_get_key_attributes(key, &attributes);
804 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
805 /* The key has been destroyed. */
806 ok = 1;
807 }
808 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 size_t key_bits = psa_get_key_bits(&attributes);
810 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200811
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200813 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200815 }
816
Ryan Everett73e4ea32024-03-12 16:29:55 +0000817 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key,
818 key_destroyable),
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200820
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 if (expected_key_agreement_status != PSA_SUCCESS) {
822 return 1;
823 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100824
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
826 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
827 PSA_ASSERT(psa_key_derivation_input_bytes(
828 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
829 input, sizeof(input)));
830 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
831 PSA_ASSERT(psa_key_derivation_input_bytes(
832 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
833 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100834 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
836 output,
837 sizeof(output)));
838 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100839 }
840 ok = 1;
841
842exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100844}
845
846int mbedtls_test_psa_exported_key_sanity_check(
847 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100849{
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100851
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
853 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
854 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100855
Ronald Cron64df7382021-07-06 09:23:06 +0200856#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
858 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100859 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100860 size_t len;
861 /* RSAPrivateKey ::= SEQUENCE {
862 * version INTEGER, -- must be 0
863 * modulus INTEGER, -- n
864 * publicExponent INTEGER, -- e
865 * privateExponent INTEGER, -- d
866 * prime1 INTEGER, -- p
867 * prime2 INTEGER, -- q
868 * exponent1 INTEGER, -- d mod (p-1)
869 * exponent2 INTEGER, -- d mod (q-1)
870 * coefficient INTEGER, -- (inverse of q) mod p
871 * }
872 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
874 MBEDTLS_ASN1_SEQUENCE |
875 MBEDTLS_ASN1_CONSTRUCTED), 0);
876 TEST_EQUAL(len, end - p);
877 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100878 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 }
880 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100881 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 }
883 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100884 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100886 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100888 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100890 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100892 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 }
894 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100895 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 }
897 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100898 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 }
900 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100901 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 }
903 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100904 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 }
906 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
909 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200910#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100911
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100913 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100915
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
917 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100918
Ronald Cron64df7382021-07-06 09:23:06 +0200919#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
921 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100922 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100923 size_t len;
924 /* RSAPublicKey ::= SEQUENCE {
925 * modulus INTEGER, -- n
926 * publicExponent INTEGER } -- e
927 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
929 MBEDTLS_ASN1_SEQUENCE |
930 MBEDTLS_ASN1_CONSTRUCTED),
931 0);
932 TEST_EQUAL(len, end - p);
933 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100934 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 }
936 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100937 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 }
939 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100940
941
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 TEST_ASSERT(exported_length <=
943 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
944 TEST_ASSERT(exported_length <=
945 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
946 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200947#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100950
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 TEST_ASSERT(exported_length <=
952 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
953 TEST_ASSERT(exported_length <=
954 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100955
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100957 /* The representation of an ECC Montgomery public key is
958 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100960 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100961 /* The representation of an ECC Edwards public key is
962 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100963 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100965 /* The representation of an ECC Weierstrass public key is:
966 * - The byte 0x04;
967 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
968 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
969 * - where m is the bit size associated with the curve.
970 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
972 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100973 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100974 } else
975 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200976 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100977 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
978 TEST_ASSERT(exported_length <=
979 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200980 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100981 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100982 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100983 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100984
Gilles Peskinecc9db302021-02-14 01:29:52 +0100985#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100987 /* Check the parity bits. */
988 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100990 unsigned bit_count = 0;
991 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 for (m = 1; m <= 0x100; m <<= 1) {
993 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100994 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100996 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100998 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100999 }
Gilles Peskinecc9db302021-02-14 01:29:52 +01001000#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +01001001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001003
1004exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001006}
1007
Gilles Peskine449bd832023-01-11 14:50:10 +01001008static int exercise_export_key(mbedtls_svc_key_id_t key,
Ryan Everettfbf815d2024-03-12 16:32:29 +00001009 psa_key_usage_t usage,
1010 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001011{
1012 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1013 uint8_t *exported = NULL;
1014 size_t exported_size = 0;
1015 size_t exported_length = 0;
1016 int ok = 0;
1017
Ryan Everettfbf815d2024-03-12 16:32:29 +00001018 psa_status_t status = psa_get_key_attributes(key, &attributes);
1019 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1020 /* The key has been destroyed. */
1021 psa_reset_key_attributes(&attributes);
1022 return 1;
1023 }
1024 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001025
1026 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 psa_get_key_type(&attributes),
1028 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001029 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001030
Ryan Everettfbf815d2024-03-12 16:32:29 +00001031 status = psa_export_key(key, exported, exported_size, &exported_length);
1032 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1033 /* The key has been destroyed. */
1034 ok = 1;
1035 goto exit;
1036 } else if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
1037 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
1038 TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001039 ok = 1;
1040 goto exit;
1041 }
Ryan Everettfbf815d2024-03-12 16:32:29 +00001042 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001043 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
1045 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001046
1047exit:
1048 /*
1049 * Key attributes may have been returned by psa_get_key_attributes()
1050 * thus reset them as required.
1051 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001053
Gilles Peskine449bd832023-01-11 14:50:10 +01001054 mbedtls_free(exported);
1055 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001056}
1057
Ryan Everettfbf815d2024-03-12 16:32:29 +00001058static int exercise_export_public_key(mbedtls_svc_key_id_t key,
1059 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001060{
1061 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1062 psa_key_type_t public_type;
1063 uint8_t *exported = NULL;
1064 size_t exported_size = 0;
1065 size_t exported_length = 0;
1066 int ok = 0;
1067
Ryan Everettfbf815d2024-03-12 16:32:29 +00001068 psa_status_t status = psa_get_key_attributes(key, &attributes);
1069 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1070 /* The key has been destroyed. */
1071 psa_reset_key_attributes(&attributes);
1072 return 1;
1073 }
1074 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +01001076 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +01001077 psa_get_key_type(&attributes),
1078 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001079 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001080
Ryan Everettfbf815d2024-03-12 16:32:29 +00001081 status = psa_export_public_key(key, exported,
1082 exported_size, &exported_length);
1083 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1084 /* The key has been destroyed. */
1085 ok = 1;
1086 goto exit;
1087 }
1088 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001089 ok = 1;
1090 goto exit;
1091 }
1092
1093 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 psa_get_key_type(&attributes));
1095 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
1096 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001097 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001098
Ryan Everettfbf815d2024-03-12 16:32:29 +00001099 status = psa_export_public_key(key, exported,
1100 exported_size, &exported_length);
1101 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1102 /* The key has been destroyed. */
1103 ok = 1;
1104 goto exit;
1105 }
1106 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001107 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 public_type, psa_get_key_bits(&attributes),
1109 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001110
1111exit:
1112 /*
1113 * Key attributes may have been returned by psa_get_key_attributes()
1114 * thus reset them as required.
1115 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001117
Gilles Peskine449bd832023-01-11 14:50:10 +01001118 mbedtls_free(exported);
1119 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001120}
1121
Gilles Peskine449bd832023-01-11 14:50:10 +01001122int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
1123 psa_key_usage_t usage,
Ryan Everett0a271fd2024-03-12 16:34:02 +00001124 psa_algorithm_t alg,
1125 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001126{
Gilles Peskine2385f712021-02-14 01:34:21 +01001127 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001128
Ryan Everett0a271fd2024-03-12 16:34:02 +00001129 if (!check_key_attributes_sanity(key, key_destroyable)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 return 0;
1131 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001132
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001134 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001135 } else if (PSA_ALG_IS_MAC(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001136 ok = exercise_mac_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001137 } else if (PSA_ALG_IS_CIPHER(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001138 ok = exercise_cipher_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 } else if (PSA_ALG_IS_AEAD(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001140 ok = exercise_aead_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 } else if (PSA_ALG_IS_SIGN(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001142 ok = exercise_signature_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001143 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001144 ok = exercise_asymmetric_encryption_key(key, usage, alg,
1145 key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001147 ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001148 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001149 ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001150 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001151 ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001152 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +01001153 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001155
Ryan Everett0a271fd2024-03-12 16:34:02 +00001156 ok = ok && exercise_export_key(key,
1157 usage,
1158 key_destroyable);
1159 ok = ok && exercise_export_public_key(key,
1160 key_destroyable);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001161
Gilles Peskine2385f712021-02-14 01:34:21 +01001162exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001163 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001164}
1165
Gilles Peskine449bd832023-01-11 14:50:10 +01001166psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1167 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001168{
Gilles Peskine449bd832023-01-11 14:50:10 +01001169 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1170 if (PSA_ALG_IS_SIGN_HASH(alg)) {
1171 if (PSA_ALG_SIGN_GET_HASH(alg)) {
1172 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1173 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1174 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1175 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1176 }
1177 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1178 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1179 PSA_KEY_USAGE_VERIFY_MESSAGE :
1180 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001181 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001182
Gilles Peskine449bd832023-01-11 14:50:10 +01001183 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1184 PSA_KEY_USAGE_VERIFY_HASH :
1185 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1186 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1187 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1188 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1189 PSA_KEY_USAGE_ENCRYPT :
1190 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1191 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1192 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1193 return PSA_KEY_USAGE_DERIVE;
1194 } else {
1195 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001196 }
1197
1198}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001199
Gilles Peskine34955672024-02-12 14:19:24 +01001200int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1201{
1202 /* Reject algorithms that we know are not supported. Default to
1203 * attempting exercise, so that if an algorithm is missing from this
1204 * function, the result will be a test failure and not silently
1205 * omitting exercise. */
1206#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1207 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1208 return 0;
1209 }
1210#endif
1211#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1212 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1213 return 0;
1214 }
1215#endif
1216#if !defined(PSA_WANT_ALG_RSA_PSS)
1217 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1218 return 0;
1219 }
1220#endif
1221#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1222 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1223 return 0;
1224 }
1225#endif
1226#if !defined(PSA_WANT_ALG_ECDSA)
1227 if (PSA_ALG_IS_ECDSA(alg)) {
1228 return 0;
1229 }
1230#endif
1231#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1232 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1233 return 0;
1234 }
1235#endif
1236#if !defined(PSA_WANT_ALG_ECDH)
1237 if (PSA_ALG_IS_ECDH(alg)) {
1238 return 0;
1239 }
1240#endif
1241 (void) alg;
1242 return 1;
1243}
1244
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001245#if defined(MBEDTLS_PK_C)
1246int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1247 const mbedtls_pk_context *pk)
1248{
1249 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1250 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1251 int ok = 0;
1252
1253 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1254 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1255 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1256
1257 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1258 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1259 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1260
1261 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1262 const uint8_t *pk_public = NULL;
1263 size_t pk_public_length = 0;
1264
1265 switch (pk_type) {
1266#if defined(MBEDTLS_RSA_C)
1267 case MBEDTLS_PK_RSA:
1268 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1269 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1270 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1271 uint8_t *cursor = end;
1272 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1273 pk_public_buffer, &cursor));
1274 pk_public = cursor;
1275 pk_public_length = end - pk_public;
1276 break;
1277#endif
1278
1279#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1280 case MBEDTLS_PK_ECKEY:
1281 case MBEDTLS_PK_ECKEY_DH:
1282 case MBEDTLS_PK_ECDSA:
1283 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1284 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1285 pk_public = pk->pub_raw;
1286 pk_public_length = pk->pub_raw_len;
1287 break;
1288#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1289
Elena Uziunaite8dde3b32024-07-05 12:10:21 +01001290#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001291 case MBEDTLS_PK_ECKEY:
1292 case MBEDTLS_PK_ECKEY_DH:
1293 case MBEDTLS_PK_ECDSA:
1294 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1295 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1296 TEST_EQUAL(mbedtls_ecp_write_public_key(
1297 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1298 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1299 pk_public = pk_public_buffer;
1300 break;
Elena Uziunaite8dde3b32024-07-05 12:10:21 +01001301#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY && !MBEDTLS_PK_USE_PSA_EC_DATA */
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001302
1303#if defined(MBEDTLS_USE_PSA_CRYPTO)
1304 case MBEDTLS_PK_OPAQUE:
1305 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1306 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1307 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1308 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1309 PSA_ASSERT(psa_export_public_key(psa_key,
1310 pk_public_buffer,
1311 sizeof(pk_public_buffer),
1312 &pk_public_length));
1313 pk_public = pk_public_buffer;
1314 break;
1315#endif /* MBEDTLS_USE_PSA_CRYPTO */
1316
1317 default:
1318 TEST_FAIL("pk type not supported");
1319 }
1320
1321 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1322 size_t psa_public_length = 0;
1323 PSA_ASSERT(psa_export_public_key(psa_key,
1324 psa_public, sizeof(psa_public),
1325 &psa_public_length));
1326 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1327 psa_public, psa_public_length);
1328
1329 ok = 1;
1330
1331exit:
1332 psa_reset_key_attributes(&psa_attributes);
1333 psa_reset_key_attributes(&pk_attributes);
1334 return ok;
1335}
1336#endif /* MBEDTLS_PK_C */
1337
David Horstmann0d8287c2024-07-26 18:01:04 +01001338#endif /* MBEDTLS_PSA_CRYPTO_C || MBEDTLS_PSA_CRYPTO_CLIENT */