blob: fde1187e7033e8419428ef19095019c4f9bd47ee [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,
441 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100442{
Gilles Peskinef50cd592024-02-15 13:13:26 +0100443 unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100444 "Hello, world...";
Gilles Peskinef50cd592024-02-15 13:13:26 +0100445 unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100446 "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100448 size_t plaintext_length = 16;
449
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 if (usage & PSA_KEY_USAGE_ENCRYPT) {
451 PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
452 plaintext, plaintext_length,
453 NULL, 0,
454 ciphertext, sizeof(ciphertext),
455 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100456 }
457
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100459 psa_status_t status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 psa_asymmetric_decrypt(key, alg,
461 ciphertext, ciphertext_length,
462 NULL, 0,
463 plaintext, sizeof(plaintext),
464 &plaintext_length);
465 TEST_ASSERT(status == PSA_SUCCESS ||
466 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
467 (status == PSA_ERROR_INVALID_ARGUMENT ||
468 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100469 }
470
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100472
473exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100475}
476
477int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100479 mbedtls_svc_key_id_t key,
480 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 const unsigned char *input1, size_t input1_length,
482 const unsigned char *input2, size_t input2_length,
483 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100484{
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
486 if (PSA_ALG_IS_HKDF(alg)) {
487 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
488 PSA_KEY_DERIVATION_INPUT_SALT,
489 input1, input1_length));
490 PSA_ASSERT(psa_key_derivation_input_key(operation,
491 PSA_KEY_DERIVATION_INPUT_SECRET,
492 key));
493 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
494 PSA_KEY_DERIVATION_INPUT_INFO,
495 input2,
496 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530497 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
498 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
499 PSA_KEY_DERIVATION_INPUT_SALT,
500 input1, input1_length));
501 PSA_ASSERT(psa_key_derivation_input_key(operation,
502 PSA_KEY_DERIVATION_INPUT_SECRET,
503 key));
504 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
505 PSA_ASSERT(psa_key_derivation_input_key(operation,
506 PSA_KEY_DERIVATION_INPUT_SECRET,
507 key));
508 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
509 PSA_KEY_DERIVATION_INPUT_INFO,
510 input2,
511 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
513 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
514 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
515 PSA_KEY_DERIVATION_INPUT_SEED,
516 input1, input1_length));
517 PSA_ASSERT(psa_key_derivation_input_key(operation,
518 PSA_KEY_DERIVATION_INPUT_SECRET,
519 key));
520 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
521 PSA_KEY_DERIVATION_INPUT_LABEL,
522 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530523 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530524 PSA_ASSERT(psa_key_derivation_input_integer(operation,
525 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530526 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530527 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
528 PSA_KEY_DERIVATION_INPUT_SALT,
529 input2,
530 input2_length));
531 PSA_ASSERT(psa_key_derivation_input_key(operation,
532 PSA_KEY_DERIVATION_INPUT_PASSWORD,
533 key));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530534 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
535 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
536 PSA_KEY_DERIVATION_INPUT_SECRET,
537 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100539 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100540 }
541
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 if (capacity != SIZE_MAX) {
543 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
544 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100547
548exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100550}
551
552
Gilles Peskine449bd832023-01-11 14:50:10 +0100553static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
554 psa_key_usage_t usage,
555 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100556{
557 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
558 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100560 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100561 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100562 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100564
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 if (usage & PSA_KEY_USAGE_DERIVE) {
566 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
567 input1, input1_length,
568 input2, input2_length,
569 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100570 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100572
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
574 output,
575 capacity));
576 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100577 }
578
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100580
581exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100583}
584
585/* We need two keys to exercise key agreement. Exercise the
586 * private key against its own public key. */
587psa_status_t mbedtls_test_psa_key_agreement_with_self(
588 psa_key_derivation_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100589 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100590{
591 psa_key_type_t private_key_type;
592 psa_key_type_t public_key_type;
593 size_t key_bits;
594 uint8_t *public_key = NULL;
595 size_t public_key_length;
596 /* Return GENERIC_ERROR if something other than the final call to
597 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
598 * but it's good enough: callers will report it as a failed test anyway. */
599 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
600 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
603 private_key_type = psa_get_key_type(&attributes);
604 key_bits = psa_get_key_bits(&attributes);
605 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
606 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100607 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
609 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100610
611 status = psa_key_derivation_key_agreement(
612 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100614exit:
615 /*
616 * Key attributes may have been returned by psa_get_key_attributes()
617 * thus reset them as required.
618 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100620
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 mbedtls_free(public_key);
622 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100623}
624
625/* We need two keys to exercise key agreement. Exercise the
626 * private key against its own public key. */
627psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
628 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100630{
631 psa_key_type_t private_key_type;
632 psa_key_type_t public_key_type;
633 size_t key_bits;
634 uint8_t *public_key = NULL;
635 size_t public_key_length;
636 uint8_t output[1024];
637 size_t output_length;
638 /* Return GENERIC_ERROR if something other than the final call to
639 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
640 * but it's good enough: callers will report it as a failed test anyway. */
641 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
642 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
645 private_key_type = psa_get_key_type(&attributes);
646 key_bits = psa_get_key_bits(&attributes);
647 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
648 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100649 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 PSA_ASSERT(psa_export_public_key(key,
651 public_key, public_key_length,
652 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100653
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 status = psa_raw_key_agreement(alg, key,
655 public_key, public_key_length,
656 output, sizeof(output), &output_length);
657 if (status == PSA_SUCCESS) {
658 TEST_ASSERT(output_length <=
659 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
660 key_bits));
661 TEST_ASSERT(output_length <=
662 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100663 }
664
Gilles Peskinee78b0022021-02-13 00:41:11 +0100665exit:
666 /*
667 * Key attributes may have been returned by psa_get_key_attributes()
668 * thus reset them as required.
669 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100671
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 mbedtls_free(public_key);
673 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100674}
675
Gilles Peskine449bd832023-01-11 14:50:10 +0100676static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
677 psa_key_usage_t usage,
678 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100679{
680 int ok = 0;
681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100683 /* We need two keys to exercise key agreement. Exercise the
684 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100686 }
687 ok = 1;
688
689exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100691}
692
Gilles Peskine449bd832023-01-11 14:50:10 +0100693static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
694 psa_key_usage_t usage,
695 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100696{
697 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200698 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100699 unsigned char output[1];
700 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200702 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100703
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100705 /* We need two keys to exercise key agreement. Exercise the
706 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
708 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
709 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
710 PSA_ASSERT(psa_key_derivation_input_bytes(
711 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
712 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100713 }
714
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
716 PSA_ASSERT(psa_key_derivation_input_bytes(
717 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
718 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200719 }
720
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200721 /* For HKDF_EXPAND input secret may fail as secret size may not match
722 to expected PRK size. In practice it means that key bits must match
723 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200725 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
727 size_t key_bits = psa_get_key_bits(&attributes);
728 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200731 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200733 }
734
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
736 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200737
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 if (expected_key_agreement_status != PSA_SUCCESS) {
739 return 1;
740 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100741
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
743 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
744 PSA_ASSERT(psa_key_derivation_input_bytes(
745 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
746 input, sizeof(input)));
747 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
748 PSA_ASSERT(psa_key_derivation_input_bytes(
749 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
750 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100751 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
753 output,
754 sizeof(output)));
755 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100756 }
757 ok = 1;
758
759exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100761}
762
763int mbedtls_test_psa_exported_key_sanity_check(
764 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100766{
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
770 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
771 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100772
Ronald Cron64df7382021-07-06 09:23:06 +0200773#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
775 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100776 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100777 size_t len;
778 /* RSAPrivateKey ::= SEQUENCE {
779 * version INTEGER, -- must be 0
780 * modulus INTEGER, -- n
781 * publicExponent INTEGER, -- e
782 * privateExponent INTEGER, -- d
783 * prime1 INTEGER, -- p
784 * prime2 INTEGER, -- q
785 * exponent1 INTEGER, -- d mod (p-1)
786 * exponent2 INTEGER, -- d mod (q-1)
787 * coefficient INTEGER, -- (inverse of q) mod p
788 * }
789 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
791 MBEDTLS_ASN1_SEQUENCE |
792 MBEDTLS_ASN1_CONSTRUCTED), 0);
793 TEST_EQUAL(len, end - p);
794 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100795 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 }
797 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100798 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 }
800 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100801 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100803 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100805 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100807 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100809 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 }
811 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100812 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 }
814 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100815 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100816 }
817 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
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, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100821 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 }
823 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100824
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
826 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200827#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100828
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100830 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100831 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100832
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
834 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100835
Ronald Cron64df7382021-07-06 09:23:06 +0200836#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100837 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
838 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100839 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100840 size_t len;
841 /* RSAPublicKey ::= SEQUENCE {
842 * modulus INTEGER, -- n
843 * publicExponent INTEGER } -- e
844 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
846 MBEDTLS_ASN1_SEQUENCE |
847 MBEDTLS_ASN1_CONSTRUCTED),
848 0);
849 TEST_EQUAL(len, end - p);
850 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100851 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 }
853 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100854 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 }
856 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100857
858
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 TEST_ASSERT(exported_length <=
860 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
861 TEST_ASSERT(exported_length <=
862 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
863 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200864#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100867
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);
gabor-mezei-armceface22021-01-21 12:26:17 +0100872
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100874 /* The representation of an ECC Montgomery public key is
875 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100877 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100878 /* The representation of an ECC Edwards public key is
879 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100880 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100882 /* The representation of an ECC Weierstrass public key is:
883 * - The byte 0x04;
884 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
885 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
886 * - where m is the bit size associated with the curve.
887 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
889 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100890 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100891 } else
892 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200893 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100894 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
895 TEST_ASSERT(exported_length <=
896 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200897 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100898 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100899 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100900 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100901
Gilles Peskinecc9db302021-02-14 01:29:52 +0100902#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100904 /* Check the parity bits. */
905 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100907 unsigned bit_count = 0;
908 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 for (m = 1; m <= 0x100; m <<= 1) {
910 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100911 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100913 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100915 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100916 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100917#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100920
921exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100923}
924
Gilles Peskine449bd832023-01-11 14:50:10 +0100925static int exercise_export_key(mbedtls_svc_key_id_t key,
926 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100927{
928 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
929 uint8_t *exported = NULL;
930 size_t exported_size = 0;
931 size_t exported_length = 0;
932 int ok = 0;
933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100935
936 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 psa_get_key_type(&attributes),
938 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100939 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100940
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
942 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
943 TEST_EQUAL(psa_export_key(key, exported,
944 exported_size, &exported_length),
945 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100946 ok = 1;
947 goto exit;
948 }
949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 PSA_ASSERT(psa_export_key(key,
951 exported, exported_size,
952 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100953 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
955 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100956
957exit:
958 /*
959 * Key attributes may have been returned by psa_get_key_attributes()
960 * thus reset them as required.
961 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100963
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 mbedtls_free(exported);
965 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100966}
967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100969{
970 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
971 psa_key_type_t public_type;
972 uint8_t *exported = NULL;
973 size_t exported_size = 0;
974 size_t exported_length = 0;
975 int ok = 0;
976
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
978 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100979 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 psa_get_key_type(&attributes),
981 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100982 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 TEST_EQUAL(psa_export_public_key(key, exported,
985 exported_size, &exported_length),
986 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100987 ok = 1;
988 goto exit;
989 }
990
991 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 psa_get_key_type(&attributes));
993 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
994 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100995 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 PSA_ASSERT(psa_export_public_key(key,
998 exported, exported_size,
999 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +01001000 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 public_type, psa_get_key_bits(&attributes),
1002 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001003
1004exit:
1005 /*
1006 * Key attributes may have been returned by psa_get_key_attributes()
1007 * thus reset them as required.
1008 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001010
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 mbedtls_free(exported);
1012 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001013}
1014
Gilles Peskine449bd832023-01-11 14:50:10 +01001015int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
1016 psa_key_usage_t usage,
Ryan Everett0a271fd2024-03-12 16:34:02 +00001017 psa_algorithm_t alg,
1018 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001019{
Gilles Peskine2385f712021-02-14 01:34:21 +01001020 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001021
Ryan Everett0a271fd2024-03-12 16:34:02 +00001022 if (!check_key_attributes_sanity(key, key_destroyable)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 return 0;
1024 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001025
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001027 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 } else if (PSA_ALG_IS_MAC(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001029 ok = exercise_mac_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 } else if (PSA_ALG_IS_CIPHER(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001031 ok = exercise_cipher_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 } else if (PSA_ALG_IS_AEAD(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001033 ok = exercise_aead_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 } else if (PSA_ALG_IS_SIGN(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001035 ok = exercise_signature_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001037 ok = exercise_asymmetric_encryption_key(key, usage, alg,
1038 key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001040 ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001042 ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001044 ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +01001046 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001048
Ryan Everett0a271fd2024-03-12 16:34:02 +00001049 ok = ok && exercise_export_key(key,
1050 usage,
1051 key_destroyable);
1052 ok = ok && exercise_export_public_key(key,
1053 key_destroyable);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001054
Gilles Peskine2385f712021-02-14 01:34:21 +01001055exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001057}
1058
Gilles Peskine449bd832023-01-11 14:50:10 +01001059psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1060 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001061{
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1063 if (PSA_ALG_IS_SIGN_HASH(alg)) {
1064 if (PSA_ALG_SIGN_GET_HASH(alg)) {
1065 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1066 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1067 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1068 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1069 }
1070 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1071 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1072 PSA_KEY_USAGE_VERIFY_MESSAGE :
1073 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001074 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001075
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1077 PSA_KEY_USAGE_VERIFY_HASH :
1078 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1079 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1080 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1081 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1082 PSA_KEY_USAGE_ENCRYPT :
1083 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1084 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1085 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1086 return PSA_KEY_USAGE_DERIVE;
1087 } else {
1088 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001089 }
1090
1091}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001092
Gilles Peskine34955672024-02-12 14:19:24 +01001093int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1094{
1095 /* Reject algorithms that we know are not supported. Default to
1096 * attempting exercise, so that if an algorithm is missing from this
1097 * function, the result will be a test failure and not silently
1098 * omitting exercise. */
1099#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1100 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1101 return 0;
1102 }
1103#endif
1104#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1105 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1106 return 0;
1107 }
1108#endif
1109#if !defined(PSA_WANT_ALG_RSA_PSS)
1110 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1111 return 0;
1112 }
1113#endif
1114#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1115 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1116 return 0;
1117 }
1118#endif
1119#if !defined(PSA_WANT_ALG_ECDSA)
1120 if (PSA_ALG_IS_ECDSA(alg)) {
1121 return 0;
1122 }
1123#endif
1124#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1125 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1126 return 0;
1127 }
1128#endif
1129#if !defined(PSA_WANT_ALG_ECDH)
1130 if (PSA_ALG_IS_ECDH(alg)) {
1131 return 0;
1132 }
1133#endif
1134 (void) alg;
1135 return 1;
1136}
1137
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001138#if defined(MBEDTLS_PK_C)
1139int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1140 const mbedtls_pk_context *pk)
1141{
1142 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1143 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1144 int ok = 0;
1145
1146 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1147 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1148 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1149
1150 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1151 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1152 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1153
1154 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1155 const uint8_t *pk_public = NULL;
1156 size_t pk_public_length = 0;
1157
1158 switch (pk_type) {
1159#if defined(MBEDTLS_RSA_C)
1160 case MBEDTLS_PK_RSA:
1161 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1162 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1163 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1164 uint8_t *cursor = end;
1165 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1166 pk_public_buffer, &cursor));
1167 pk_public = cursor;
1168 pk_public_length = end - pk_public;
1169 break;
1170#endif
1171
1172#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1173 case MBEDTLS_PK_ECKEY:
1174 case MBEDTLS_PK_ECKEY_DH:
1175 case MBEDTLS_PK_ECDSA:
1176 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1177 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1178 pk_public = pk->pub_raw;
1179 pk_public_length = pk->pub_raw_len;
1180 break;
1181#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1182
1183#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1184 case MBEDTLS_PK_ECKEY:
1185 case MBEDTLS_PK_ECKEY_DH:
1186 case MBEDTLS_PK_ECDSA:
1187 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1188 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1189 TEST_EQUAL(mbedtls_ecp_write_public_key(
1190 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1191 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1192 pk_public = pk_public_buffer;
1193 break;
1194#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */
1195
1196#if defined(MBEDTLS_USE_PSA_CRYPTO)
1197 case MBEDTLS_PK_OPAQUE:
1198 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1199 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1200 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1201 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1202 PSA_ASSERT(psa_export_public_key(psa_key,
1203 pk_public_buffer,
1204 sizeof(pk_public_buffer),
1205 &pk_public_length));
1206 pk_public = pk_public_buffer;
1207 break;
1208#endif /* MBEDTLS_USE_PSA_CRYPTO */
1209
1210 default:
1211 TEST_FAIL("pk type not supported");
1212 }
1213
1214 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1215 size_t psa_public_length = 0;
1216 PSA_ASSERT(psa_export_public_key(psa_key,
1217 psa_public, sizeof(psa_public),
1218 &psa_public_length));
1219 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1220 psa_public, psa_public_length);
1221
1222 ok = 1;
1223
1224exit:
1225 psa_reset_key_attributes(&psa_attributes);
1226 psa_reset_key_attributes(&pk_attributes);
1227 return ok;
1228}
1229#endif /* MBEDTLS_PK_C */
1230
Gilles Peskine66e7b902021-02-12 23:40:58 +01001231#endif /* MBEDTLS_PSA_CRYPTO_C */