blob: 470073930c8f1ea2b432bb72dafd7c0f3b42f6c3 [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
14#if defined(MBEDTLS_PSA_CRYPTO_C)
15
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,
492 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100493{
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
495 if (PSA_ALG_IS_HKDF(alg)) {
496 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
497 PSA_KEY_DERIVATION_INPUT_SALT,
498 input1, input1_length));
499 PSA_ASSERT(psa_key_derivation_input_key(operation,
500 PSA_KEY_DERIVATION_INPUT_SECRET,
501 key));
502 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
503 PSA_KEY_DERIVATION_INPUT_INFO,
504 input2,
505 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530506 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
507 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
508 PSA_KEY_DERIVATION_INPUT_SALT,
509 input1, input1_length));
510 PSA_ASSERT(psa_key_derivation_input_key(operation,
511 PSA_KEY_DERIVATION_INPUT_SECRET,
512 key));
513 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
514 PSA_ASSERT(psa_key_derivation_input_key(operation,
515 PSA_KEY_DERIVATION_INPUT_SECRET,
516 key));
517 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
518 PSA_KEY_DERIVATION_INPUT_INFO,
519 input2,
520 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
522 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
523 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
524 PSA_KEY_DERIVATION_INPUT_SEED,
525 input1, input1_length));
526 PSA_ASSERT(psa_key_derivation_input_key(operation,
527 PSA_KEY_DERIVATION_INPUT_SECRET,
528 key));
529 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
530 PSA_KEY_DERIVATION_INPUT_LABEL,
531 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530532 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530533 PSA_ASSERT(psa_key_derivation_input_integer(operation,
534 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530535 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530536 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
537 PSA_KEY_DERIVATION_INPUT_SALT,
538 input2,
539 input2_length));
540 PSA_ASSERT(psa_key_derivation_input_key(operation,
541 PSA_KEY_DERIVATION_INPUT_PASSWORD,
542 key));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530543 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
544 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
545 PSA_KEY_DERIVATION_INPUT_SECRET,
546 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100548 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100549 }
550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 if (capacity != SIZE_MAX) {
552 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
553 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100556
557exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100559}
560
561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
563 psa_key_usage_t usage,
564 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100565{
566 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
567 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100569 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100570 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100571 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100573
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 if (usage & PSA_KEY_USAGE_DERIVE) {
575 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
576 input1, input1_length,
577 input2, input2_length,
578 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100579 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100581
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
583 output,
584 capacity));
585 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100586 }
587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100589
590exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100591 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100592}
593
594/* We need two keys to exercise key agreement. Exercise the
595 * private key against its own public key. */
596psa_status_t mbedtls_test_psa_key_agreement_with_self(
597 psa_key_derivation_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100599{
600 psa_key_type_t private_key_type;
601 psa_key_type_t public_key_type;
602 size_t key_bits;
603 uint8_t *public_key = NULL;
604 size_t public_key_length;
605 /* Return GENERIC_ERROR if something other than the final call to
606 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
607 * but it's good enough: callers will report it as a failed test anyway. */
608 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
609 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
610
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
612 private_key_type = psa_get_key_type(&attributes);
613 key_bits = psa_get_key_bits(&attributes);
614 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
615 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100616 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
618 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100619
620 status = psa_key_derivation_key_agreement(
621 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100623exit:
624 /*
625 * Key attributes may have been returned by psa_get_key_attributes()
626 * thus reset them as required.
627 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 mbedtls_free(public_key);
631 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100632}
633
634/* We need two keys to exercise key agreement. Exercise the
635 * private key against its own public key. */
636psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
637 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100639{
640 psa_key_type_t private_key_type;
641 psa_key_type_t public_key_type;
642 size_t key_bits;
643 uint8_t *public_key = NULL;
644 size_t public_key_length;
645 uint8_t output[1024];
646 size_t output_length;
647 /* Return GENERIC_ERROR if something other than the final call to
648 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
649 * but it's good enough: callers will report it as a failed test anyway. */
650 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
651 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
652
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
654 private_key_type = psa_get_key_type(&attributes);
655 key_bits = psa_get_key_bits(&attributes);
656 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
657 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100658 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 PSA_ASSERT(psa_export_public_key(key,
660 public_key, public_key_length,
661 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100662
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 status = psa_raw_key_agreement(alg, key,
664 public_key, public_key_length,
665 output, sizeof(output), &output_length);
666 if (status == PSA_SUCCESS) {
667 TEST_ASSERT(output_length <=
668 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
669 key_bits));
670 TEST_ASSERT(output_length <=
671 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100672 }
673
Gilles Peskinee78b0022021-02-13 00:41:11 +0100674exit:
675 /*
676 * Key attributes may have been returned by psa_get_key_attributes()
677 * thus reset them as required.
678 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100680
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 mbedtls_free(public_key);
682 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100683}
684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
686 psa_key_usage_t usage,
687 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100688{
689 int ok = 0;
690
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100692 /* We need two keys to exercise key agreement. Exercise the
693 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100695 }
696 ok = 1;
697
698exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100700}
701
Gilles Peskine449bd832023-01-11 14:50:10 +0100702static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
703 psa_key_usage_t usage,
704 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100705{
706 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200707 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100708 unsigned char output[1];
709 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200711 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100714 /* We need two keys to exercise key agreement. Exercise the
715 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
717 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
718 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
719 PSA_ASSERT(psa_key_derivation_input_bytes(
720 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
721 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100722 }
723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
725 PSA_ASSERT(psa_key_derivation_input_bytes(
726 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
727 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200728 }
729
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200730 /* For HKDF_EXPAND input secret may fail as secret size may not match
731 to expected PRK size. In practice it means that key bits must match
732 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200734 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
736 size_t key_bits = psa_get_key_bits(&attributes);
737 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200738
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200740 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200742 }
743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
745 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 if (expected_key_agreement_status != PSA_SUCCESS) {
748 return 1;
749 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
752 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
753 PSA_ASSERT(psa_key_derivation_input_bytes(
754 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
755 input, sizeof(input)));
756 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
757 PSA_ASSERT(psa_key_derivation_input_bytes(
758 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
759 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100760 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
762 output,
763 sizeof(output)));
764 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100765 }
766 ok = 1;
767
768exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100770}
771
772int mbedtls_test_psa_exported_key_sanity_check(
773 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100775{
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100777
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
779 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
780 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100781
Ronald Cron64df7382021-07-06 09:23:06 +0200782#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
784 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100785 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100786 size_t len;
787 /* RSAPrivateKey ::= SEQUENCE {
788 * version INTEGER, -- must be 0
789 * modulus INTEGER, -- n
790 * publicExponent INTEGER, -- e
791 * privateExponent INTEGER, -- d
792 * prime1 INTEGER, -- p
793 * prime2 INTEGER, -- q
794 * exponent1 INTEGER, -- d mod (p-1)
795 * exponent2 INTEGER, -- d mod (q-1)
796 * coefficient INTEGER, -- (inverse of q) mod p
797 * }
798 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
800 MBEDTLS_ASN1_SEQUENCE |
801 MBEDTLS_ASN1_CONSTRUCTED), 0);
802 TEST_EQUAL(len, end - p);
803 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100804 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 }
806 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100807 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 }
809 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100810 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100812 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100814 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100816 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100818 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 }
820 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100821 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 }
823 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100824 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 }
826 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100827 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 }
829 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100830 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100831 }
832 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100833
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
835 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200836#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100839 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100841
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
843 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100844
Ronald Cron64df7382021-07-06 09:23:06 +0200845#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
847 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100848 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100849 size_t len;
850 /* RSAPublicKey ::= SEQUENCE {
851 * modulus INTEGER, -- n
852 * publicExponent INTEGER } -- e
853 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
855 MBEDTLS_ASN1_SEQUENCE |
856 MBEDTLS_ASN1_CONSTRUCTED),
857 0);
858 TEST_EQUAL(len, end - p);
859 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100860 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 }
862 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100863 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 }
865 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100866
867
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 TEST_ASSERT(exported_length <=
869 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
870 TEST_ASSERT(exported_length <=
871 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
872 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200873#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100876
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 TEST_ASSERT(exported_length <=
878 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
879 TEST_ASSERT(exported_length <=
880 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100881
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100883 /* The representation of an ECC Montgomery public key is
884 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100886 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100887 /* The representation of an ECC Edwards public key is
888 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100889 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100891 /* The representation of an ECC Weierstrass public key is:
892 * - The byte 0x04;
893 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
894 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
895 * - where m is the bit size associated with the curve.
896 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
898 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100899 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100900 } else
901 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200902 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100903 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
904 TEST_ASSERT(exported_length <=
905 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200906 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100907 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100908 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100909 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100910
Gilles Peskinecc9db302021-02-14 01:29:52 +0100911#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100913 /* Check the parity bits. */
914 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100916 unsigned bit_count = 0;
917 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 for (m = 1; m <= 0x100; m <<= 1) {
919 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100920 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100922 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100924 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100925 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100926#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100927
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100929
930exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100932}
933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934static int exercise_export_key(mbedtls_svc_key_id_t key,
935 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100936{
937 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
938 uint8_t *exported = NULL;
939 size_t exported_size = 0;
940 size_t exported_length = 0;
941 int ok = 0;
942
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100944
945 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 psa_get_key_type(&attributes),
947 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100948 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
951 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
952 TEST_EQUAL(psa_export_key(key, exported,
953 exported_size, &exported_length),
954 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100955 ok = 1;
956 goto exit;
957 }
958
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 PSA_ASSERT(psa_export_key(key,
960 exported, exported_size,
961 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100962 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
964 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100965
966exit:
967 /*
968 * Key attributes may have been returned by psa_get_key_attributes()
969 * thus reset them as required.
970 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100972
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 mbedtls_free(exported);
974 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100975}
976
Gilles Peskine449bd832023-01-11 14:50:10 +0100977static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100978{
979 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
980 psa_key_type_t public_type;
981 uint8_t *exported = NULL;
982 size_t exported_size = 0;
983 size_t exported_length = 0;
984 int ok = 0;
985
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
987 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100988 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 psa_get_key_type(&attributes),
990 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100991 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100992
Gilles Peskine449bd832023-01-11 14:50:10 +0100993 TEST_EQUAL(psa_export_public_key(key, exported,
994 exported_size, &exported_length),
995 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100996 ok = 1;
997 goto exit;
998 }
999
1000 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 psa_get_key_type(&attributes));
1002 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
1003 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +01001004 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 PSA_ASSERT(psa_export_public_key(key,
1007 exported, exported_size,
1008 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +01001009 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 public_type, psa_get_key_bits(&attributes),
1011 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001012
1013exit:
1014 /*
1015 * Key attributes may have been returned by psa_get_key_attributes()
1016 * thus reset them as required.
1017 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 mbedtls_free(exported);
1021 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001022}
1023
Gilles Peskine449bd832023-01-11 14:50:10 +01001024int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
1025 psa_key_usage_t usage,
Ryan Everett0a271fd2024-03-12 16:34:02 +00001026 psa_algorithm_t alg,
1027 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001028{
Gilles Peskine2385f712021-02-14 01:34:21 +01001029 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001030
Ryan Everett0a271fd2024-03-12 16:34:02 +00001031 if (!check_key_attributes_sanity(key, key_destroyable)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 return 0;
1033 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001034
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001036 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 } else if (PSA_ALG_IS_MAC(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001038 ok = exercise_mac_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 } else if (PSA_ALG_IS_CIPHER(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001040 ok = exercise_cipher_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 } else if (PSA_ALG_IS_AEAD(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001042 ok = exercise_aead_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 } else if (PSA_ALG_IS_SIGN(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001044 ok = exercise_signature_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001046 ok = exercise_asymmetric_encryption_key(key, usage, alg,
1047 key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001049 ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001051 ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001053 ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001054 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +01001055 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001057
Ryan Everett0a271fd2024-03-12 16:34:02 +00001058 ok = ok && exercise_export_key(key,
1059 usage,
1060 key_destroyable);
1061 ok = ok && exercise_export_public_key(key,
1062 key_destroyable);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001063
Gilles Peskine2385f712021-02-14 01:34:21 +01001064exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001066}
1067
Gilles Peskine449bd832023-01-11 14:50:10 +01001068psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1069 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001070{
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1072 if (PSA_ALG_IS_SIGN_HASH(alg)) {
1073 if (PSA_ALG_SIGN_GET_HASH(alg)) {
1074 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1075 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1076 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1077 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1078 }
1079 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1080 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1081 PSA_KEY_USAGE_VERIFY_MESSAGE :
1082 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001083 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001084
Gilles Peskine449bd832023-01-11 14:50:10 +01001085 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1086 PSA_KEY_USAGE_VERIFY_HASH :
1087 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1088 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1089 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1090 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1091 PSA_KEY_USAGE_ENCRYPT :
1092 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1093 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1094 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1095 return PSA_KEY_USAGE_DERIVE;
1096 } else {
1097 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001098 }
1099
1100}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001101
Gilles Peskine34955672024-02-12 14:19:24 +01001102int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1103{
1104 /* Reject algorithms that we know are not supported. Default to
1105 * attempting exercise, so that if an algorithm is missing from this
1106 * function, the result will be a test failure and not silently
1107 * omitting exercise. */
1108#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1109 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1110 return 0;
1111 }
1112#endif
1113#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1114 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1115 return 0;
1116 }
1117#endif
1118#if !defined(PSA_WANT_ALG_RSA_PSS)
1119 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1120 return 0;
1121 }
1122#endif
1123#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1124 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1125 return 0;
1126 }
1127#endif
1128#if !defined(PSA_WANT_ALG_ECDSA)
1129 if (PSA_ALG_IS_ECDSA(alg)) {
1130 return 0;
1131 }
1132#endif
1133#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1134 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1135 return 0;
1136 }
1137#endif
1138#if !defined(PSA_WANT_ALG_ECDH)
1139 if (PSA_ALG_IS_ECDH(alg)) {
1140 return 0;
1141 }
1142#endif
1143 (void) alg;
1144 return 1;
1145}
1146
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001147#if defined(MBEDTLS_PK_C)
1148int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1149 const mbedtls_pk_context *pk)
1150{
1151 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1152 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1153 int ok = 0;
1154
1155 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1156 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1157 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1158
1159 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1160 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1161 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1162
1163 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1164 const uint8_t *pk_public = NULL;
1165 size_t pk_public_length = 0;
1166
1167 switch (pk_type) {
1168#if defined(MBEDTLS_RSA_C)
1169 case MBEDTLS_PK_RSA:
1170 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1171 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1172 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1173 uint8_t *cursor = end;
1174 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1175 pk_public_buffer, &cursor));
1176 pk_public = cursor;
1177 pk_public_length = end - pk_public;
1178 break;
1179#endif
1180
1181#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1182 case MBEDTLS_PK_ECKEY:
1183 case MBEDTLS_PK_ECKEY_DH:
1184 case MBEDTLS_PK_ECDSA:
1185 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1186 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1187 pk_public = pk->pub_raw;
1188 pk_public_length = pk->pub_raw_len;
1189 break;
1190#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1191
1192#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1193 case MBEDTLS_PK_ECKEY:
1194 case MBEDTLS_PK_ECKEY_DH:
1195 case MBEDTLS_PK_ECDSA:
1196 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1197 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1198 TEST_EQUAL(mbedtls_ecp_write_public_key(
1199 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1200 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1201 pk_public = pk_public_buffer;
1202 break;
1203#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */
1204
1205#if defined(MBEDTLS_USE_PSA_CRYPTO)
1206 case MBEDTLS_PK_OPAQUE:
1207 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1208 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1209 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1210 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1211 PSA_ASSERT(psa_export_public_key(psa_key,
1212 pk_public_buffer,
1213 sizeof(pk_public_buffer),
1214 &pk_public_length));
1215 pk_public = pk_public_buffer;
1216 break;
1217#endif /* MBEDTLS_USE_PSA_CRYPTO */
1218
1219 default:
1220 TEST_FAIL("pk type not supported");
1221 }
1222
1223 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1224 size_t psa_public_length = 0;
1225 PSA_ASSERT(psa_export_public_key(psa_key,
1226 psa_public, sizeof(psa_public),
1227 &psa_public_length));
1228 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1229 psa_public, psa_public_length);
1230
1231 ok = 1;
1232
1233exit:
1234 psa_reset_key_attributes(&psa_attributes);
1235 psa_reset_key_attributes(&pk_attributes);
1236 return ok;
1237}
1238#endif /* MBEDTLS_PK_C */
1239
Gilles Peskine66e7b902021-02-12 23:40:58 +01001240#endif /* MBEDTLS_PSA_CRYPTO_C */