blob: b2232764a765526ad595677b558b8e0aae1c9238 [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
Valerio Setti84733902024-06-27 08:05:09 +020014#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
Gilles Peskine66e7b902021-02-12 23:40:58 +010015
Gilles Peskinee78b0022021-02-13 00:41:11 +010016#include <mbedtls/asn1.h>
Gilles Peskine66e7b902021-02-12 23:40:58 +010017#include <psa/crypto.h>
18
Gilles Peskinee78b0022021-02-13 00:41:11 +010019#include <test/asn1_helpers.h>
Przemyslaw Stekiel53de2622021-11-03 09:35:35 +010020#include <psa_crypto_slot_management.h>
Gilles Peskinee78b0022021-02-13 00:41:11 +010021#include <test/psa_crypto_helpers.h>
22
Gilles Peskine6fe8a062024-02-15 17:21:17 +010023#if defined(MBEDTLS_PK_C)
24#include <pk_internal.h>
25#endif
26#if defined(MBEDTLS_ECP_C)
27#include <mbedtls/ecp.h>
28#endif
29#if defined(MBEDTLS_RSA_C)
30#include <rsa_internal.h>
31#endif
32
Gilles Peskinee78b0022021-02-13 00:41:11 +010033#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010034static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
Gilles Peskinee78b0022021-02-13 00:41:11 +010035{
Gilles Peskine449bd832023-01-11 14:50:10 +010036 return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
37 PSA_KEY_LOCATION_LOCAL_STORAGE;
Gilles Peskinee78b0022021-02-13 00:41:11 +010038}
39#endif
40
Ryan Everettf08a93f2024-03-12 16:00:08 +000041static int check_key_attributes_sanity(mbedtls_svc_key_id_t key,
42 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +010043{
44 int ok = 0;
45 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
46 psa_key_lifetime_t lifetime;
47 mbedtls_svc_key_id_t id;
48 psa_key_type_t type;
Gilles Peskine6b362e62021-02-15 12:03:16 +010049 size_t bits;
Ryan Everettf08a93f2024-03-12 16:00:08 +000050 psa_status_t status = psa_get_key_attributes(key, &attributes);
51 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
52 /* The key has been destroyed. */
53 psa_reset_key_attributes(&attributes);
54 return 1;
55 }
56 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +010057 lifetime = psa_get_key_lifetime(&attributes);
58 id = psa_get_key_id(&attributes);
59 type = psa_get_key_type(&attributes);
60 bits = psa_get_key_bits(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +010061
62 /* Persistence */
Gilles Peskine449bd832023-01-11 14:50:10 +010063 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010064 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010065 (PSA_KEY_ID_VOLATILE_MIN <=
66 MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
67 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
68 PSA_KEY_ID_VOLATILE_MAX));
69 } else {
Gilles Peskinee78b0022021-02-13 00:41:11 +010070 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010071 (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
72 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
Gilles Peskinee78b0022021-02-13 00:41:11 +010073 }
74#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Ryan Everettf08a93f2024-03-12 16:00:08 +000075 /* MBEDTLS_PSA_CRYPTO_SE_C does not support thread safety. */
76 if (key_destroyable == 0) {
77 /* randomly-generated 64-bit constant, should never appear in test data */
78 psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
79 status = psa_get_key_slot_number(&attributes, &slot_number);
80 if (lifetime_is_dynamic_secure_element(lifetime)) {
81 /* Mbed TLS currently always exposes the slot number to
82 * applications. This is not mandated by the PSA specification
83 * and may change in future versions. */
84 TEST_EQUAL(status, 0);
85 TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
86 } else {
87 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
88 }
Gilles Peskinee78b0022021-02-13 00:41:11 +010089 }
90#endif
91
92 /* Type and size */
Gilles Peskine449bd832023-01-11 14:50:10 +010093 TEST_ASSERT(type != 0);
94 TEST_ASSERT(bits != 0);
95 TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
96 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
97 TEST_ASSERT(bits % 8 == 0);
98 }
Gilles Peskinee78b0022021-02-13 00:41:11 +010099
100 /* MAX macros concerning specific key types */
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 if (PSA_KEY_TYPE_IS_ECC(type)) {
102 TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
103 } else if (PSA_KEY_TYPE_IS_RSA(type)) {
104 TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
105 }
106 TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100107
108 ok = 1;
109
110exit:
111 /*
112 * Key attributes may have been returned by psa_get_key_attributes()
113 * thus reset them as required.
114 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100116
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100118}
119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120static int exercise_mac_key(mbedtls_svc_key_id_t key,
121 psa_key_usage_t usage,
Ryan Everett77635502024-03-12 16:02:23 +0000122 psa_algorithm_t alg,
123 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100124{
125 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
126 const unsigned char input[] = "foo";
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
128 size_t mac_length = sizeof(mac);
Ryan Everett77635502024-03-12 16:02:23 +0000129 psa_status_t status = PSA_SUCCESS;
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100130 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
132 alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100133 }
134
Gilles Peskine449bd832023-01-11 14:50:10 +0100135 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
Ryan Everett77635502024-03-12 16:02:23 +0000136 status = psa_mac_sign_setup(&operation, key, alg);
137 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
138 /* The key has been destroyed. */
139 PSA_ASSERT(psa_mac_abort(&operation));
140 return 1;
141 }
142 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 PSA_ASSERT(psa_mac_update(&operation,
144 input, sizeof(input)));
145 PSA_ASSERT(psa_mac_sign_finish(&operation,
146 mac, sizeof(mac),
147 &mac_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100148 }
149
Gilles Peskine449bd832023-01-11 14:50:10 +0100150 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100151 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 (usage & PSA_KEY_USAGE_SIGN_HASH ?
153 PSA_SUCCESS :
154 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett77635502024-03-12 16:02:23 +0000155 status = psa_mac_verify_setup(&operation, key, alg);
156 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
157 /* The key has been destroyed. */
158 PSA_ASSERT(psa_mac_abort(&operation));
159 return 1;
160 }
161 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 PSA_ASSERT(psa_mac_update(&operation,
163 input, sizeof(input)));
164 TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
165 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100166 }
167
Gilles Peskine449bd832023-01-11 14:50:10 +0100168 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100169
170exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 psa_mac_abort(&operation);
172 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100173}
174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175static int exercise_cipher_key(mbedtls_svc_key_id_t key,
176 psa_key_usage_t usage,
Ryan Everett70691f32024-03-12 16:04:45 +0000177 psa_algorithm_t alg,
178 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100179{
180 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
Gilles Peskine5eef11a2022-04-21 11:14:30 +0200182 size_t iv_length;
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100183 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
184 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100185 const unsigned char plaintext[16] = "Hello, world...";
186 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 size_t ciphertext_length = sizeof(ciphertext);
188 unsigned char decrypted[sizeof(ciphertext)];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100189 size_t part_length;
Ryan Everett70691f32024-03-12 16:04:45 +0000190 psa_status_t status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100191
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
193 key_type = psa_get_key_type(&attributes);
194 iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everett70691f32024-03-12 16:04:45 +0000197 status = psa_cipher_encrypt_setup(&operation, key, alg);
198 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
199 /* The key has been destroyed. */
200 PSA_ASSERT(psa_cipher_abort(&operation));
201 return 1;
202 }
203 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 if (iv_length != 0) {
205 PSA_ASSERT(psa_cipher_generate_iv(&operation,
206 iv, sizeof(iv),
207 &iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100208 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100209 PSA_ASSERT(psa_cipher_update(&operation,
210 plaintext, sizeof(plaintext),
211 ciphertext, sizeof(ciphertext),
212 &ciphertext_length));
213 PSA_ASSERT(psa_cipher_finish(&operation,
214 ciphertext + ciphertext_length,
215 sizeof(ciphertext) - ciphertext_length,
216 &part_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100217 ciphertext_length += part_length;
218 }
219
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100221 int maybe_invalid_padding = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
223 maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100224 }
Ryan Everett70691f32024-03-12 16:04:45 +0000225 status = psa_cipher_decrypt_setup(&operation, key, alg);
226 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
227 /* The key has been destroyed. */
228 PSA_ASSERT(psa_cipher_abort(&operation));
229 return 1;
230 }
231 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 if (iv_length != 0) {
233 PSA_ASSERT(psa_cipher_set_iv(&operation,
234 iv, iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100235 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 PSA_ASSERT(psa_cipher_update(&operation,
237 ciphertext, ciphertext_length,
238 decrypted, sizeof(decrypted),
239 &part_length));
240 status = psa_cipher_finish(&operation,
241 decrypted + part_length,
242 sizeof(decrypted) - part_length,
243 &part_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100244 /* For a stream cipher, all inputs are valid. For a block cipher,
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800245 * if the input is some arbitrary data rather than an actual
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 ciphertext, a padding error is likely. */
247 if (maybe_invalid_padding) {
248 TEST_ASSERT(status == PSA_SUCCESS ||
249 status == PSA_ERROR_INVALID_PADDING);
250 } else {
251 PSA_ASSERT(status);
252 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100253 }
254
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100256
257exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 psa_cipher_abort(&operation);
259 psa_reset_key_attributes(&attributes);
260 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100261}
262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263static int exercise_aead_key(mbedtls_svc_key_id_t key,
264 psa_key_usage_t usage,
Ryan Everettfbe703d2024-03-12 16:09:25 +0000265 psa_algorithm_t alg,
266 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100267{
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
Gilles Peskine7acb1982022-03-19 11:03:32 +0100269 size_t nonce_length;
270 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
271 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100272 unsigned char plaintext[16] = "Hello, world...";
273 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 size_t ciphertext_length = sizeof(ciphertext);
275 size_t plaintext_length = sizeof(ciphertext);
Ryan Everettfbe703d2024-03-12 16:09:25 +0000276 psa_status_t status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100277
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100278 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
280 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100281 }
282
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
284 key_type = psa_get_key_type(&attributes);
285 nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
Steven Cooremanaaec3412021-02-18 13:30:34 +0100286
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everettfbe703d2024-03-12 16:09:25 +0000288 status = psa_aead_encrypt(key, alg,
289 nonce, nonce_length,
290 NULL, 0,
291 plaintext, sizeof(plaintext),
292 ciphertext, sizeof(ciphertext),
293 &ciphertext_length);
294 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
295 /* The key has been destroyed. */
296 return 1;
297 }
298 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100299 }
300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100302 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 (usage & PSA_KEY_USAGE_ENCRYPT ?
304 PSA_SUCCESS :
305 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everettfbe703d2024-03-12 16:09:25 +0000306 status = psa_aead_decrypt(key, alg,
307 nonce, nonce_length,
308 NULL, 0,
309 ciphertext, ciphertext_length,
310 plaintext, sizeof(plaintext),
311 &plaintext_length);
312 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
313 /* The key has been destroyed. */
314 return 1;
315 }
316 TEST_ASSERT(status == verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100317 }
318
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100320
321exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 psa_reset_key_attributes(&attributes);
323 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100324}
325
Gilles Peskine449bd832023-01-11 14:50:10 +0100326static int can_sign_or_verify_message(psa_key_usage_t usage,
327 psa_algorithm_t alg)
Gilles Peskined586b822022-03-19 11:15:41 +0100328{
329 /* Sign-the-unspecified-hash algorithms can only be used with
330 * {sign,verify}_hash, not with {sign,verify}_message. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
332 return 0;
333 }
334 return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
335 PSA_KEY_USAGE_VERIFY_MESSAGE);
Gilles Peskined586b822022-03-19 11:15:41 +0100336}
337
Gilles Peskine449bd832023-01-11 14:50:10 +0100338static int exercise_signature_key(mbedtls_svc_key_id_t key,
339 psa_key_usage_t usage,
Ryan Everett6edd4082024-03-12 16:11:01 +0000340 psa_algorithm_t alg,
341 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100342{
Gilles Peskine4781bd92024-02-09 17:32:45 +0100343 /* If the policy allows signing with any hash, just pick one. */
344 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
345 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
346 usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
347 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
348#if defined(KNOWN_SUPPORTED_HASH_ALG)
349 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
350 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
351#else
352 TEST_FAIL("No hash algorithm for hash-and-sign testing");
353#endif
354 }
Ryan Everett6edd4082024-03-12 16:11:01 +0000355 psa_status_t status = PSA_SUCCESS;
Gilles Peskine4781bd92024-02-09 17:32:45 +0100356
oberon-skf7a824b2023-02-15 19:43:30 +0100357 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
358 PSA_ALG_IS_SIGN_HASH(alg)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200360 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
362 size_t signature_length = sizeof(signature);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200363
Janos Follath4c0b60e2021-06-14 12:34:30 +0100364 /* Some algorithms require the payload to have the size of
365 * the hash encoded in the algorithm. Use this input size
366 * even for algorithms that allow other input sizes. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 if (hash_alg != 0) {
368 payload_length = PSA_HASH_LENGTH(hash_alg);
369 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100370
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
Ryan Everett6edd4082024-03-12 16:11:01 +0000372 status = psa_sign_hash(key, alg,
373 payload, payload_length,
374 signature, sizeof(signature),
375 &signature_length);
376 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
377 /* The key has been destroyed. */
378 return 1;
379 }
380 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 }
382
383 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
384 psa_status_t verify_status =
385 (usage & PSA_KEY_USAGE_SIGN_HASH ?
386 PSA_SUCCESS :
387 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett6edd4082024-03-12 16:11:01 +0000388 status = psa_verify_hash(key, alg,
389 payload, payload_length,
390 signature, signature_length);
391 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
392 /* The key has been destroyed. */
393 return 1;
394 }
395 TEST_ASSERT(status == verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200396 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100397 }
398
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200400 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200402 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100404
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
Ryan Everett6edd4082024-03-12 16:11:01 +0000406 status = psa_sign_message(key, alg,
407 message, message_length,
408 signature, sizeof(signature),
409 &signature_length);
410 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
411 /* The key has been destroyed. */
412 return 1;
413 }
414 PSA_ASSERT(status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200415 }
416
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200418 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
420 PSA_SUCCESS :
421 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett6edd4082024-03-12 16:11:01 +0000422 status = psa_verify_message(key, alg,
423 message, message_length,
424 signature, signature_length);
425 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
426 /* The key has been destroyed. */
427 return 1;
428 }
429 TEST_ASSERT(status == verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200430 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100431 }
432
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100434
435exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100437}
438
Gilles Peskine449bd832023-01-11 14:50:10 +0100439static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
440 psa_key_usage_t usage,
Ryan Everettd48fc102024-03-12 16:12:41 +0000441 psa_algorithm_t alg,
442 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100443{
Gilles Peskinef50cd592024-02-15 13:13:26 +0100444 unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100445 "Hello, world...";
Gilles Peskinef50cd592024-02-15 13:13:26 +0100446 unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100447 "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100449 size_t plaintext_length = 16;
Ryan Everettd48fc102024-03-12 16:12:41 +0000450 psa_status_t status = PSA_SUCCESS;
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everettd48fc102024-03-12 16:12:41 +0000452 status = psa_asymmetric_encrypt(key, alg,
453 plaintext, plaintext_length,
454 NULL, 0,
455 ciphertext, sizeof(ciphertext),
456 &ciphertext_length);
457 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
458 /* The key has been destroyed. */
459 return 1;
460 }
461 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100462 }
463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 if (usage & PSA_KEY_USAGE_DECRYPT) {
Ryan Everettd48fc102024-03-12 16:12:41 +0000465 status = psa_asymmetric_decrypt(key, alg,
466 ciphertext, ciphertext_length,
467 NULL, 0,
468 plaintext, sizeof(plaintext),
469 &plaintext_length);
470 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
471 /* The key has been destroyed. */
472 return 1;
473 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 TEST_ASSERT(status == PSA_SUCCESS ||
475 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
476 (status == PSA_ERROR_INVALID_ARGUMENT ||
477 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100478 }
479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100481
482exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100484}
485
486int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100488 mbedtls_svc_key_id_t key,
489 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 const unsigned char *input1, size_t input1_length,
491 const unsigned char *input2, size_t input2_length,
Ryan Everettc1cc6682024-03-12 16:17:43 +0000492 size_t capacity, int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100493{
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000495 psa_status_t status = PSA_SUCCESS;
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 if (PSA_ALG_IS_HKDF(alg)) {
497 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
498 PSA_KEY_DERIVATION_INPUT_SALT,
499 input1, input1_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000500 status = psa_key_derivation_input_key(operation,
501 PSA_KEY_DERIVATION_INPUT_SECRET,
502 key);
503 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
504 /* The key has been destroyed. */
505 return 1;
506 }
507 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
509 PSA_KEY_DERIVATION_INPUT_INFO,
510 input2,
511 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530512 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
513 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
514 PSA_KEY_DERIVATION_INPUT_SALT,
515 input1, input1_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000516 status = psa_key_derivation_input_key(operation,
517 PSA_KEY_DERIVATION_INPUT_SECRET,
518 key);
519 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
520 /* The key has been destroyed. */
521 return 1;
522 }
523 PSA_ASSERT(status);
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530524 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
Ryan Everettc1cc6682024-03-12 16:17:43 +0000525 status = psa_key_derivation_input_key(operation,
526 PSA_KEY_DERIVATION_INPUT_SECRET,
527 key);
528 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
529 /* The key has been destroyed. */
530 return 1;
531 }
532 PSA_ASSERT(status);
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530533 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
534 PSA_KEY_DERIVATION_INPUT_INFO,
535 input2,
536 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
538 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
539 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
540 PSA_KEY_DERIVATION_INPUT_SEED,
541 input1, input1_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000542 status = psa_key_derivation_input_key(operation,
543 PSA_KEY_DERIVATION_INPUT_SECRET,
544 key);
545 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
546 /* The key has been destroyed. */
547 return 1;
548 }
549 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
551 PSA_KEY_DERIVATION_INPUT_LABEL,
552 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530553 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530554 PSA_ASSERT(psa_key_derivation_input_integer(operation,
555 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530556 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530557 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
558 PSA_KEY_DERIVATION_INPUT_SALT,
559 input2,
560 input2_length));
Ryan Everettc1cc6682024-03-12 16:17:43 +0000561 status = psa_key_derivation_input_key(operation,
562 PSA_KEY_DERIVATION_INPUT_PASSWORD,
563 key);
564 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
565 /* The key has been destroyed. */
566 return 1;
567 }
568 PSA_ASSERT(status);
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530569 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
570 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
571 PSA_KEY_DERIVATION_INPUT_SECRET,
572 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100574 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100575 }
576
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 if (capacity != SIZE_MAX) {
578 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
579 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100580
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100582
583exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100585}
586
587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
589 psa_key_usage_t usage,
Ryan Everettc1cc6682024-03-12 16:17:43 +0000590 psa_algorithm_t alg,
591 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100592{
593 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
594 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100596 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100597 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100598 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 if (usage & PSA_KEY_USAGE_DERIVE) {
602 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
603 input1, input1_length,
604 input2, input2_length,
Ryan Everettc1cc6682024-03-12 16:17:43 +0000605 capacity, key_destroyable)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100606 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100608
Ryan Everettc1cc6682024-03-12 16:17:43 +0000609 psa_status_t status = psa_key_derivation_output_bytes(&operation,
610 output,
611 capacity);
612 if (key_destroyable && status == PSA_ERROR_BAD_STATE) {
613 /* The key has been destroyed. */
614 PSA_ASSERT(psa_key_derivation_abort(&operation));
615 } else {
616 PSA_ASSERT(status);
617 PSA_ASSERT(psa_key_derivation_abort(&operation));
618 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100619 }
620
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100622
623exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100625}
626
627/* We need two keys to exercise key agreement. Exercise the
628 * private key against its own public key. */
629psa_status_t mbedtls_test_psa_key_agreement_with_self(
630 psa_key_derivation_operation_t *operation,
Ryan Everett73e4ea32024-03-12 16:29:55 +0000631 mbedtls_svc_key_id_t key, int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100632{
633 psa_key_type_t private_key_type;
634 psa_key_type_t public_key_type;
635 size_t key_bits;
636 uint8_t *public_key = NULL;
637 size_t public_key_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100638 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
639
Ryan Everett73e4ea32024-03-12 16:29:55 +0000640 psa_status_t status = psa_get_key_attributes(key, &attributes);
641 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
642 /* The key has been destroyed. */
643 psa_reset_key_attributes(&attributes);
644 return PSA_SUCCESS;
645 }
646 PSA_ASSERT(status);
647
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 private_key_type = psa_get_key_type(&attributes);
649 key_bits = psa_get_key_bits(&attributes);
650 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
651 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100652 TEST_CALLOC(public_key, public_key_length);
Ryan Everett73e4ea32024-03-12 16:29:55 +0000653 status = psa_export_public_key(key, public_key, public_key_length,
654 &public_key_length);
655 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
656 /* The key has been destroyed. */
657 status = PSA_SUCCESS;
658 goto exit;
659 }
660 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100661
662 status = psa_key_derivation_key_agreement(
663 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 public_key, public_key_length);
Ryan Everett73e4ea32024-03-12 16:29:55 +0000665 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
666 /* The key has been destroyed. */
667 status = PSA_SUCCESS;
668 goto exit;
669 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100670exit:
671 /*
672 * Key attributes may have been returned by psa_get_key_attributes()
673 * thus reset them as required.
674 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100676
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 mbedtls_free(public_key);
678 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100679}
680
681/* We need two keys to exercise key agreement. Exercise the
682 * private key against its own public key. */
683psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
684 psa_algorithm_t alg,
Ryan Everett81630282024-03-12 16:21:12 +0000685 mbedtls_svc_key_id_t key,
686 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100687{
688 psa_key_type_t private_key_type;
689 psa_key_type_t public_key_type;
690 size_t key_bits;
691 uint8_t *public_key = NULL;
692 size_t public_key_length;
693 uint8_t output[1024];
694 size_t output_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100695 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
696
Ryan Everett81630282024-03-12 16:21:12 +0000697 psa_status_t status = psa_get_key_attributes(key, &attributes);
698 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
699 /* The key has been destroyed. */
700 psa_reset_key_attributes(&attributes);
701 return PSA_SUCCESS;
702 }
703 PSA_ASSERT(status);
704
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 private_key_type = psa_get_key_type(&attributes);
706 key_bits = psa_get_key_bits(&attributes);
707 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
708 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100709 TEST_CALLOC(public_key, public_key_length);
Ryan Everett81630282024-03-12 16:21:12 +0000710 status = psa_export_public_key(key,
711 public_key, public_key_length,
712 &public_key_length);
713 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
714 /* The key has been destroyed. */
715 status = PSA_SUCCESS;
716 goto exit;
717 }
Ryan Everett6de38ac2024-03-14 17:50:39 +0000718 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100719
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 status = psa_raw_key_agreement(alg, key,
721 public_key, public_key_length,
722 output, sizeof(output), &output_length);
Ryan Everett81630282024-03-12 16:21:12 +0000723 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
724 /* The key has been destroyed. */
725 status = PSA_SUCCESS;
726 goto exit;
727 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 if (status == PSA_SUCCESS) {
729 TEST_ASSERT(output_length <=
730 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
731 key_bits));
732 TEST_ASSERT(output_length <=
733 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100734 }
735
Gilles Peskinee78b0022021-02-13 00:41:11 +0100736exit:
737 /*
738 * Key attributes may have been returned by psa_get_key_attributes()
739 * thus reset them as required.
740 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 mbedtls_free(public_key);
744 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100745}
746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
748 psa_key_usage_t usage,
Ryan Everett81630282024-03-12 16:21:12 +0000749 psa_algorithm_t alg,
750 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100751{
752 int ok = 0;
753
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100755 /* We need two keys to exercise key agreement. Exercise the
756 * private key against its own public key. */
Ryan Everett81630282024-03-12 16:21:12 +0000757 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key,
758 key_destroyable));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100759 }
760 ok = 1;
761
762exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100764}
765
Gilles Peskine449bd832023-01-11 14:50:10 +0100766static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
767 psa_key_usage_t usage,
Ryan Everett73e4ea32024-03-12 16:29:55 +0000768 psa_algorithm_t alg,
769 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100770{
771 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200772 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100773 unsigned char output[1];
774 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200776 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100777
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100779 /* We need two keys to exercise key agreement. Exercise the
780 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
782 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
783 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
784 PSA_ASSERT(psa_key_derivation_input_bytes(
785 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
786 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100787 }
788
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
790 PSA_ASSERT(psa_key_derivation_input_bytes(
791 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
792 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200793 }
794
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200795 /* For HKDF_EXPAND input secret may fail as secret size may not match
796 to expected PRK size. In practice it means that key bits must match
797 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200799 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Ryan Everett73e4ea32024-03-12 16:29:55 +0000800 psa_status_t status = psa_get_key_attributes(key, &attributes);
801 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
802 /* The key has been destroyed. */
803 ok = 1;
804 }
805 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 size_t key_bits = psa_get_key_bits(&attributes);
807 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200808
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200810 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200812 }
813
Ryan Everett73e4ea32024-03-12 16:29:55 +0000814 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key,
815 key_destroyable),
Gilles Peskine449bd832023-01-11 14:50:10 +0100816 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200817
Gilles Peskine449bd832023-01-11 14:50:10 +0100818 if (expected_key_agreement_status != PSA_SUCCESS) {
819 return 1;
820 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100821
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
823 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
824 PSA_ASSERT(psa_key_derivation_input_bytes(
825 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
826 input, sizeof(input)));
827 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
828 PSA_ASSERT(psa_key_derivation_input_bytes(
829 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
830 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100831 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
833 output,
834 sizeof(output)));
835 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100836 }
837 ok = 1;
838
839exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100841}
842
843int mbedtls_test_psa_exported_key_sanity_check(
844 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100846{
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100848
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
850 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
851 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100852
Ronald Cron64df7382021-07-06 09:23:06 +0200853#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
855 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100856 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100857 size_t len;
858 /* RSAPrivateKey ::= SEQUENCE {
859 * version INTEGER, -- must be 0
860 * modulus INTEGER, -- n
861 * publicExponent INTEGER, -- e
862 * privateExponent INTEGER, -- d
863 * prime1 INTEGER, -- p
864 * prime2 INTEGER, -- q
865 * exponent1 INTEGER, -- d mod (p-1)
866 * exponent2 INTEGER, -- d mod (q-1)
867 * coefficient INTEGER, -- (inverse of q) mod p
868 * }
869 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
871 MBEDTLS_ASN1_SEQUENCE |
872 MBEDTLS_ASN1_CONSTRUCTED), 0);
873 TEST_EQUAL(len, end - p);
874 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100875 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 }
877 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
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, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100881 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100883 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100885 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100887 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100889 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 }
891 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, 1, bits / 2 + 1, 0)) {
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 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100904
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
906 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200907#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100908
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100910 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100912
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
914 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100915
Ronald Cron64df7382021-07-06 09:23:06 +0200916#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
918 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100919 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100920 size_t len;
921 /* RSAPublicKey ::= SEQUENCE {
922 * modulus INTEGER, -- n
923 * publicExponent INTEGER } -- e
924 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
926 MBEDTLS_ASN1_SEQUENCE |
927 MBEDTLS_ASN1_CONSTRUCTED),
928 0);
929 TEST_EQUAL(len, end - p);
930 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100931 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 }
933 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100934 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 }
936 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100937
938
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 TEST_ASSERT(exported_length <=
940 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
941 TEST_ASSERT(exported_length <=
942 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
943 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200944#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100945
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100947
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 TEST_ASSERT(exported_length <=
949 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
950 TEST_ASSERT(exported_length <=
951 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100952
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100954 /* The representation of an ECC Montgomery public key is
955 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100957 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100958 /* The representation of an ECC Edwards public key is
959 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100960 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100962 /* The representation of an ECC Weierstrass public key is:
963 * - The byte 0x04;
964 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
965 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
966 * - where m is the bit size associated with the curve.
967 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
969 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100970 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100971 } else
972 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200973 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100974 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
975 TEST_ASSERT(exported_length <=
976 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200977 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100978 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100979 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100980 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100981
Gilles Peskinecc9db302021-02-14 01:29:52 +0100982#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100983 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100984 /* Check the parity bits. */
985 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100987 unsigned bit_count = 0;
988 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 for (m = 1; m <= 0x100; m <<= 1) {
990 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100991 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100993 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100995 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100996 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100997#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100998
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001000
1001exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001003}
1004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005static int exercise_export_key(mbedtls_svc_key_id_t key,
Ryan Everettfbf815d2024-03-12 16:32:29 +00001006 psa_key_usage_t usage,
1007 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001008{
1009 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1010 uint8_t *exported = NULL;
1011 size_t exported_size = 0;
1012 size_t exported_length = 0;
1013 int ok = 0;
1014
Ryan Everettfbf815d2024-03-12 16:32:29 +00001015 psa_status_t status = psa_get_key_attributes(key, &attributes);
1016 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1017 /* The key has been destroyed. */
1018 psa_reset_key_attributes(&attributes);
1019 return 1;
1020 }
1021 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001022
1023 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 psa_get_key_type(&attributes),
1025 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001026 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001027
Ryan Everettfbf815d2024-03-12 16:32:29 +00001028 status = psa_export_key(key, exported, exported_size, &exported_length);
1029 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1030 /* The key has been destroyed. */
1031 ok = 1;
1032 goto exit;
1033 } else if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
1034 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
1035 TEST_EQUAL(status, PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001036 ok = 1;
1037 goto exit;
1038 }
Ryan Everettfbf815d2024-03-12 16:32:29 +00001039 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001040 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
1042 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001043
1044exit:
1045 /*
1046 * Key attributes may have been returned by psa_get_key_attributes()
1047 * thus reset them as required.
1048 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001050
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 mbedtls_free(exported);
1052 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001053}
1054
Ryan Everettfbf815d2024-03-12 16:32:29 +00001055static int exercise_export_public_key(mbedtls_svc_key_id_t key,
1056 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001057{
1058 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1059 psa_key_type_t public_type;
1060 uint8_t *exported = NULL;
1061 size_t exported_size = 0;
1062 size_t exported_length = 0;
1063 int ok = 0;
1064
Ryan Everettfbf815d2024-03-12 16:32:29 +00001065 psa_status_t status = psa_get_key_attributes(key, &attributes);
1066 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1067 /* The key has been destroyed. */
1068 psa_reset_key_attributes(&attributes);
1069 return 1;
1070 }
1071 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +01001072 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +01001073 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 psa_get_key_type(&attributes),
1075 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001076 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001077
Ryan Everettfbf815d2024-03-12 16:32:29 +00001078 status = psa_export_public_key(key, exported,
1079 exported_size, &exported_length);
1080 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1081 /* The key has been destroyed. */
1082 ok = 1;
1083 goto exit;
1084 }
1085 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001086 ok = 1;
1087 goto exit;
1088 }
1089
1090 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 psa_get_key_type(&attributes));
1092 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
1093 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001094 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001095
Ryan Everettfbf815d2024-03-12 16:32:29 +00001096 status = psa_export_public_key(key, exported,
1097 exported_size, &exported_length);
1098 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
1099 /* The key has been destroyed. */
1100 ok = 1;
1101 goto exit;
1102 }
1103 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001104 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001105 public_type, psa_get_key_bits(&attributes),
1106 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001107
1108exit:
1109 /*
1110 * Key attributes may have been returned by psa_get_key_attributes()
1111 * thus reset them as required.
1112 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001113 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001114
Gilles Peskine449bd832023-01-11 14:50:10 +01001115 mbedtls_free(exported);
1116 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001117}
1118
Gilles Peskine449bd832023-01-11 14:50:10 +01001119int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
1120 psa_key_usage_t usage,
Ryan Everett0a271fd2024-03-12 16:34:02 +00001121 psa_algorithm_t alg,
1122 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001123{
Gilles Peskine2385f712021-02-14 01:34:21 +01001124 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001125
Ryan Everett0a271fd2024-03-12 16:34:02 +00001126 if (!check_key_attributes_sanity(key, key_destroyable)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001127 return 0;
1128 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001129
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001131 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 } else if (PSA_ALG_IS_MAC(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001133 ok = exercise_mac_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 } else if (PSA_ALG_IS_CIPHER(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001135 ok = exercise_cipher_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001136 } else if (PSA_ALG_IS_AEAD(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001137 ok = exercise_aead_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 } else if (PSA_ALG_IS_SIGN(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001139 ok = exercise_signature_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001141 ok = exercise_asymmetric_encryption_key(key, usage, alg,
1142 key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001143 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001144 ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001146 ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001147 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001148 ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001149 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +01001150 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001152
Ryan Everett0a271fd2024-03-12 16:34:02 +00001153 ok = ok && exercise_export_key(key,
1154 usage,
1155 key_destroyable);
1156 ok = ok && exercise_export_public_key(key,
1157 key_destroyable);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001158
Gilles Peskine2385f712021-02-14 01:34:21 +01001159exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001161}
1162
Gilles Peskine449bd832023-01-11 14:50:10 +01001163psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1164 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001165{
Gilles Peskine449bd832023-01-11 14:50:10 +01001166 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1167 if (PSA_ALG_IS_SIGN_HASH(alg)) {
1168 if (PSA_ALG_SIGN_GET_HASH(alg)) {
1169 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1170 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1171 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1172 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1173 }
1174 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1175 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1176 PSA_KEY_USAGE_VERIFY_MESSAGE :
1177 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001178 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001179
Gilles Peskine449bd832023-01-11 14:50:10 +01001180 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1181 PSA_KEY_USAGE_VERIFY_HASH :
1182 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1183 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1184 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1185 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1186 PSA_KEY_USAGE_ENCRYPT :
1187 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1188 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1189 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1190 return PSA_KEY_USAGE_DERIVE;
1191 } else {
1192 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001193 }
1194
1195}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001196
Gilles Peskine34955672024-02-12 14:19:24 +01001197int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1198{
1199 /* Reject algorithms that we know are not supported. Default to
1200 * attempting exercise, so that if an algorithm is missing from this
1201 * function, the result will be a test failure and not silently
1202 * omitting exercise. */
1203#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1204 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1205 return 0;
1206 }
1207#endif
1208#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1209 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1210 return 0;
1211 }
1212#endif
1213#if !defined(PSA_WANT_ALG_RSA_PSS)
1214 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1215 return 0;
1216 }
1217#endif
1218#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1219 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1220 return 0;
1221 }
1222#endif
1223#if !defined(PSA_WANT_ALG_ECDSA)
1224 if (PSA_ALG_IS_ECDSA(alg)) {
1225 return 0;
1226 }
1227#endif
1228#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1229 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1230 return 0;
1231 }
1232#endif
1233#if !defined(PSA_WANT_ALG_ECDH)
1234 if (PSA_ALG_IS_ECDH(alg)) {
1235 return 0;
1236 }
1237#endif
1238 (void) alg;
1239 return 1;
1240}
1241
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001242#if defined(MBEDTLS_PK_C)
1243int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1244 const mbedtls_pk_context *pk)
1245{
1246 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1247 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1248 int ok = 0;
1249
1250 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1251 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1252 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1253
1254 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1255 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1256 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1257
1258 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1259 const uint8_t *pk_public = NULL;
1260 size_t pk_public_length = 0;
1261
1262 switch (pk_type) {
1263#if defined(MBEDTLS_RSA_C)
1264 case MBEDTLS_PK_RSA:
1265 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1266 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1267 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1268 uint8_t *cursor = end;
1269 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1270 pk_public_buffer, &cursor));
1271 pk_public = cursor;
1272 pk_public_length = end - pk_public;
1273 break;
1274#endif
1275
1276#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1277 case MBEDTLS_PK_ECKEY:
1278 case MBEDTLS_PK_ECKEY_DH:
1279 case MBEDTLS_PK_ECDSA:
1280 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1281 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1282 pk_public = pk->pub_raw;
1283 pk_public_length = pk->pub_raw_len;
1284 break;
1285#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1286
1287#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1288 case MBEDTLS_PK_ECKEY:
1289 case MBEDTLS_PK_ECKEY_DH:
1290 case MBEDTLS_PK_ECDSA:
1291 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1292 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1293 TEST_EQUAL(mbedtls_ecp_write_public_key(
1294 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1295 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1296 pk_public = pk_public_buffer;
1297 break;
1298#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */
1299
1300#if defined(MBEDTLS_USE_PSA_CRYPTO)
1301 case MBEDTLS_PK_OPAQUE:
1302 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1303 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1304 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1305 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1306 PSA_ASSERT(psa_export_public_key(psa_key,
1307 pk_public_buffer,
1308 sizeof(pk_public_buffer),
1309 &pk_public_length));
1310 pk_public = pk_public_buffer;
1311 break;
1312#endif /* MBEDTLS_USE_PSA_CRYPTO */
1313
1314 default:
1315 TEST_FAIL("pk type not supported");
1316 }
1317
1318 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1319 size_t psa_public_length = 0;
1320 PSA_ASSERT(psa_export_public_key(psa_key,
1321 psa_public, sizeof(psa_public),
1322 &psa_public_length));
1323 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1324 psa_public, psa_public_length);
1325
1326 ok = 1;
1327
1328exit:
1329 psa_reset_key_attributes(&psa_attributes);
1330 psa_reset_key_attributes(&pk_attributes);
1331 return ok;
1332}
1333#endif /* MBEDTLS_PK_C */
1334
Valerio Setti84733902024-06-27 08:05:09 +02001335#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */