blob: 89434bfdcf585330ce49c8b742677b374a6881aa [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,
340 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100341{
Gilles Peskine4781bd92024-02-09 17:32:45 +0100342 /* If the policy allows signing with any hash, just pick one. */
343 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
344 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
345 usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
346 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
347#if defined(KNOWN_SUPPORTED_HASH_ALG)
348 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
349 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
350#else
351 TEST_FAIL("No hash algorithm for hash-and-sign testing");
352#endif
353 }
354
oberon-skf7a824b2023-02-15 19:43:30 +0100355 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
356 PSA_ALG_IS_SIGN_HASH(alg)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200358 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
360 size_t signature_length = sizeof(signature);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200361
Janos Follath4c0b60e2021-06-14 12:34:30 +0100362 /* Some algorithms require the payload to have the size of
363 * the hash encoded in the algorithm. Use this input size
364 * even for algorithms that allow other input sizes. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 if (hash_alg != 0) {
366 payload_length = PSA_HASH_LENGTH(hash_alg);
367 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100368
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
370 PSA_ASSERT(psa_sign_hash(key, alg,
371 payload, payload_length,
372 signature, sizeof(signature),
373 &signature_length));
374 }
375
376 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
377 psa_status_t verify_status =
378 (usage & PSA_KEY_USAGE_SIGN_HASH ?
379 PSA_SUCCESS :
380 PSA_ERROR_INVALID_SIGNATURE);
381 TEST_EQUAL(psa_verify_hash(key, alg,
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200382 payload, payload_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 signature, signature_length),
384 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200385 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100386 }
387
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200389 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200391 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100393
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
395 PSA_ASSERT(psa_sign_message(key, alg,
396 message, message_length,
397 signature, sizeof(signature),
398 &signature_length));
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200399 }
400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200402 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
404 PSA_SUCCESS :
405 PSA_ERROR_INVALID_SIGNATURE);
406 TEST_EQUAL(psa_verify_message(key, alg,
407 message, message_length,
408 signature, signature_length),
409 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200410 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100411 }
412
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100414
415exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100417}
418
Gilles Peskine449bd832023-01-11 14:50:10 +0100419static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
420 psa_key_usage_t usage,
421 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100422{
Gilles Peskinef50cd592024-02-15 13:13:26 +0100423 unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100424 "Hello, world...";
Gilles Peskinef50cd592024-02-15 13:13:26 +0100425 unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100426 "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100428 size_t plaintext_length = 16;
429
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 if (usage & PSA_KEY_USAGE_ENCRYPT) {
431 PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
432 plaintext, plaintext_length,
433 NULL, 0,
434 ciphertext, sizeof(ciphertext),
435 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100436 }
437
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100439 psa_status_t status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 psa_asymmetric_decrypt(key, alg,
441 ciphertext, ciphertext_length,
442 NULL, 0,
443 plaintext, sizeof(plaintext),
444 &plaintext_length);
445 TEST_ASSERT(status == PSA_SUCCESS ||
446 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
447 (status == PSA_ERROR_INVALID_ARGUMENT ||
448 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100449 }
450
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100452
453exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100455}
456
457int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100459 mbedtls_svc_key_id_t key,
460 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 const unsigned char *input1, size_t input1_length,
462 const unsigned char *input2, size_t input2_length,
463 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100464{
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
466 if (PSA_ALG_IS_HKDF(alg)) {
467 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
468 PSA_KEY_DERIVATION_INPUT_SALT,
469 input1, input1_length));
470 PSA_ASSERT(psa_key_derivation_input_key(operation,
471 PSA_KEY_DERIVATION_INPUT_SECRET,
472 key));
473 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
474 PSA_KEY_DERIVATION_INPUT_INFO,
475 input2,
476 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530477 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
478 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
479 PSA_KEY_DERIVATION_INPUT_SALT,
480 input1, input1_length));
481 PSA_ASSERT(psa_key_derivation_input_key(operation,
482 PSA_KEY_DERIVATION_INPUT_SECRET,
483 key));
484 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
485 PSA_ASSERT(psa_key_derivation_input_key(operation,
486 PSA_KEY_DERIVATION_INPUT_SECRET,
487 key));
488 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
489 PSA_KEY_DERIVATION_INPUT_INFO,
490 input2,
491 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
493 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
494 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
495 PSA_KEY_DERIVATION_INPUT_SEED,
496 input1, input1_length));
497 PSA_ASSERT(psa_key_derivation_input_key(operation,
498 PSA_KEY_DERIVATION_INPUT_SECRET,
499 key));
500 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
501 PSA_KEY_DERIVATION_INPUT_LABEL,
502 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530503 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530504 PSA_ASSERT(psa_key_derivation_input_integer(operation,
505 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530506 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530507 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
508 PSA_KEY_DERIVATION_INPUT_SALT,
509 input2,
510 input2_length));
511 PSA_ASSERT(psa_key_derivation_input_key(operation,
512 PSA_KEY_DERIVATION_INPUT_PASSWORD,
513 key));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530514 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
515 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
516 PSA_KEY_DERIVATION_INPUT_SECRET,
517 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100519 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100520 }
521
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 if (capacity != SIZE_MAX) {
523 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
524 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100525
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100527
528exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100530}
531
532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
534 psa_key_usage_t usage,
535 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100536{
537 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
538 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100540 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100542 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 if (usage & PSA_KEY_USAGE_DERIVE) {
546 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
547 input1, input1_length,
548 input2, input2_length,
549 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100550 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100552
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
554 output,
555 capacity));
556 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100557 }
558
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100560
561exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100563}
564
565/* We need two keys to exercise key agreement. Exercise the
566 * private key against its own public key. */
567psa_status_t mbedtls_test_psa_key_agreement_with_self(
568 psa_key_derivation_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100570{
571 psa_key_type_t private_key_type;
572 psa_key_type_t public_key_type;
573 size_t key_bits;
574 uint8_t *public_key = NULL;
575 size_t public_key_length;
576 /* Return GENERIC_ERROR if something other than the final call to
577 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
578 * but it's good enough: callers will report it as a failed test anyway. */
579 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
580 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
581
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
583 private_key_type = psa_get_key_type(&attributes);
584 key_bits = psa_get_key_bits(&attributes);
585 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
586 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100587 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
589 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100590
591 status = psa_key_derivation_key_agreement(
592 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100593 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100594exit:
595 /*
596 * Key attributes may have been returned by psa_get_key_attributes()
597 * thus reset them as required.
598 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 mbedtls_free(public_key);
602 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100603}
604
605/* We need two keys to exercise key agreement. Exercise the
606 * private key against its own public key. */
607psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
608 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100610{
611 psa_key_type_t private_key_type;
612 psa_key_type_t public_key_type;
613 size_t key_bits;
614 uint8_t *public_key = NULL;
615 size_t public_key_length;
616 uint8_t output[1024];
617 size_t output_length;
618 /* Return GENERIC_ERROR if something other than the final call to
619 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
620 * but it's good enough: callers will report it as a failed test anyway. */
621 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
622 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
625 private_key_type = psa_get_key_type(&attributes);
626 key_bits = psa_get_key_bits(&attributes);
627 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
628 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100629 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 PSA_ASSERT(psa_export_public_key(key,
631 public_key, public_key_length,
632 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 status = psa_raw_key_agreement(alg, key,
635 public_key, public_key_length,
636 output, sizeof(output), &output_length);
637 if (status == PSA_SUCCESS) {
638 TEST_ASSERT(output_length <=
639 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
640 key_bits));
641 TEST_ASSERT(output_length <=
642 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100643 }
644
Gilles Peskinee78b0022021-02-13 00:41:11 +0100645exit:
646 /*
647 * Key attributes may have been returned by psa_get_key_attributes()
648 * thus reset them as required.
649 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100651
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 mbedtls_free(public_key);
653 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100654}
655
Gilles Peskine449bd832023-01-11 14:50:10 +0100656static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
657 psa_key_usage_t usage,
658 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100659{
660 int ok = 0;
661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100663 /* We need two keys to exercise key agreement. Exercise the
664 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100666 }
667 ok = 1;
668
669exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100671}
672
Gilles Peskine449bd832023-01-11 14:50:10 +0100673static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
674 psa_key_usage_t usage,
675 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100676{
677 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200678 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100679 unsigned char output[1];
680 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200682 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100683
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100685 /* We need two keys to exercise key agreement. Exercise the
686 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
688 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
689 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
690 PSA_ASSERT(psa_key_derivation_input_bytes(
691 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
692 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100693 }
694
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
696 PSA_ASSERT(psa_key_derivation_input_bytes(
697 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
698 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200699 }
700
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200701 /* For HKDF_EXPAND input secret may fail as secret size may not match
702 to expected PRK size. In practice it means that key bits must match
703 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200705 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
707 size_t key_bits = psa_get_key_bits(&attributes);
708 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200709
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200711 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200713 }
714
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
716 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200717
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 if (expected_key_agreement_status != PSA_SUCCESS) {
719 return 1;
720 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100721
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
723 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
724 PSA_ASSERT(psa_key_derivation_input_bytes(
725 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
726 input, sizeof(input)));
727 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
728 PSA_ASSERT(psa_key_derivation_input_bytes(
729 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
730 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100731 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
733 output,
734 sizeof(output)));
735 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100736 }
737 ok = 1;
738
739exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100741}
742
743int mbedtls_test_psa_exported_key_sanity_check(
744 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100746{
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
750 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
751 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100752
Ronald Cron64df7382021-07-06 09:23:06 +0200753#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
755 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100756 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100757 size_t len;
758 /* RSAPrivateKey ::= SEQUENCE {
759 * version INTEGER, -- must be 0
760 * modulus INTEGER, -- n
761 * publicExponent INTEGER, -- e
762 * privateExponent INTEGER, -- d
763 * prime1 INTEGER, -- p
764 * prime2 INTEGER, -- q
765 * exponent1 INTEGER, -- d mod (p-1)
766 * exponent2 INTEGER, -- d mod (q-1)
767 * coefficient INTEGER, -- (inverse of q) mod p
768 * }
769 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
771 MBEDTLS_ASN1_SEQUENCE |
772 MBEDTLS_ASN1_CONSTRUCTED), 0);
773 TEST_EQUAL(len, end - p);
774 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100775 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 }
777 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100778 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 }
780 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100781 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100783 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100785 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100787 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100789 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 }
791 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100792 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 }
794 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 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, 1, bits / 2 + 1, 0)) {
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, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100801 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 }
803 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100804
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
806 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200807#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100808
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100810 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100812
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
814 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100815
Ronald Cron64df7382021-07-06 09:23:06 +0200816#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
818 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100819 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100820 size_t len;
821 /* RSAPublicKey ::= SEQUENCE {
822 * modulus INTEGER, -- n
823 * publicExponent INTEGER } -- e
824 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
826 MBEDTLS_ASN1_SEQUENCE |
827 MBEDTLS_ASN1_CONSTRUCTED),
828 0);
829 TEST_EQUAL(len, end - p);
830 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100831 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 }
833 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100834 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 }
836 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100837
838
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 TEST_ASSERT(exported_length <=
840 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
841 TEST_ASSERT(exported_length <=
842 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
843 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200844#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100845
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100847
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 TEST_ASSERT(exported_length <=
849 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
850 TEST_ASSERT(exported_length <=
851 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100852
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100854 /* The representation of an ECC Montgomery public key is
855 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100857 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100858 /* The representation of an ECC Edwards public key is
859 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100860 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100862 /* The representation of an ECC Weierstrass public key is:
863 * - The byte 0x04;
864 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
865 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
866 * - where m is the bit size associated with the curve.
867 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
869 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100870 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100871 } else
872 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200873 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100874 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
875 TEST_ASSERT(exported_length <=
876 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200877 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100878 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100879 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100880 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100881
Gilles Peskinecc9db302021-02-14 01:29:52 +0100882#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100884 /* Check the parity bits. */
885 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100887 unsigned bit_count = 0;
888 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 for (m = 1; m <= 0x100; m <<= 1) {
890 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100891 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100893 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100895 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100896 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100897#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100898
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100900
901exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100903}
904
Gilles Peskine449bd832023-01-11 14:50:10 +0100905static int exercise_export_key(mbedtls_svc_key_id_t key,
906 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100907{
908 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
909 uint8_t *exported = NULL;
910 size_t exported_size = 0;
911 size_t exported_length = 0;
912 int ok = 0;
913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100915
916 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 psa_get_key_type(&attributes),
918 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100919 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100920
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
922 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
923 TEST_EQUAL(psa_export_key(key, exported,
924 exported_size, &exported_length),
925 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100926 ok = 1;
927 goto exit;
928 }
929
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 PSA_ASSERT(psa_export_key(key,
931 exported, exported_size,
932 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100933 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
935 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100936
937exit:
938 /*
939 * Key attributes may have been returned by psa_get_key_attributes()
940 * thus reset them as required.
941 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 mbedtls_free(exported);
945 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100946}
947
Gilles Peskine449bd832023-01-11 14:50:10 +0100948static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100949{
950 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
951 psa_key_type_t public_type;
952 uint8_t *exported = NULL;
953 size_t exported_size = 0;
954 size_t exported_length = 0;
955 int ok = 0;
956
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
958 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100959 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 psa_get_key_type(&attributes),
961 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100962 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100963
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 TEST_EQUAL(psa_export_public_key(key, exported,
965 exported_size, &exported_length),
966 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100967 ok = 1;
968 goto exit;
969 }
970
971 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +0100972 psa_get_key_type(&attributes));
973 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
974 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100975 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100976
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 PSA_ASSERT(psa_export_public_key(key,
978 exported, exported_size,
979 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100980 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 public_type, psa_get_key_bits(&attributes),
982 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100983
984exit:
985 /*
986 * Key attributes may have been returned by psa_get_key_attributes()
987 * thus reset them as required.
988 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 mbedtls_free(exported);
992 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100993}
994
Gilles Peskine449bd832023-01-11 14:50:10 +0100995int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
996 psa_key_usage_t usage,
Ryan Everett0a271fd2024-03-12 16:34:02 +0000997 psa_algorithm_t alg,
998 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100999{
Gilles Peskine2385f712021-02-14 01:34:21 +01001000 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001001
Ryan Everett0a271fd2024-03-12 16:34:02 +00001002 if (!check_key_attributes_sanity(key, key_destroyable)) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 return 0;
1004 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001007 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 } else if (PSA_ALG_IS_MAC(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001009 ok = exercise_mac_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 } else if (PSA_ALG_IS_CIPHER(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001011 ok = exercise_cipher_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 } else if (PSA_ALG_IS_AEAD(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001013 ok = exercise_aead_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 } else if (PSA_ALG_IS_SIGN(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001015 ok = exercise_signature_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001017 ok = exercise_asymmetric_encryption_key(key, usage, alg,
1018 key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001020 ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001022 ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001024 ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +01001026 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001028
Ryan Everett0a271fd2024-03-12 16:34:02 +00001029 ok = ok && exercise_export_key(key,
1030 usage,
1031 key_destroyable);
1032 ok = ok && exercise_export_public_key(key,
1033 key_destroyable);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001034
Gilles Peskine2385f712021-02-14 01:34:21 +01001035exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001037}
1038
Gilles Peskine449bd832023-01-11 14:50:10 +01001039psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1040 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001041{
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1043 if (PSA_ALG_IS_SIGN_HASH(alg)) {
1044 if (PSA_ALG_SIGN_GET_HASH(alg)) {
1045 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1046 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1047 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1048 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1049 }
1050 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1051 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1052 PSA_KEY_USAGE_VERIFY_MESSAGE :
1053 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001054 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001055
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1057 PSA_KEY_USAGE_VERIFY_HASH :
1058 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1059 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1060 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1061 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1062 PSA_KEY_USAGE_ENCRYPT :
1063 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1064 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1065 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1066 return PSA_KEY_USAGE_DERIVE;
1067 } else {
1068 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001069 }
1070
1071}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001072
Gilles Peskine34955672024-02-12 14:19:24 +01001073int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1074{
1075 /* Reject algorithms that we know are not supported. Default to
1076 * attempting exercise, so that if an algorithm is missing from this
1077 * function, the result will be a test failure and not silently
1078 * omitting exercise. */
1079#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1080 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1081 return 0;
1082 }
1083#endif
1084#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1085 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1086 return 0;
1087 }
1088#endif
1089#if !defined(PSA_WANT_ALG_RSA_PSS)
1090 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1091 return 0;
1092 }
1093#endif
1094#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1095 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1096 return 0;
1097 }
1098#endif
1099#if !defined(PSA_WANT_ALG_ECDSA)
1100 if (PSA_ALG_IS_ECDSA(alg)) {
1101 return 0;
1102 }
1103#endif
1104#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1105 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1106 return 0;
1107 }
1108#endif
1109#if !defined(PSA_WANT_ALG_ECDH)
1110 if (PSA_ALG_IS_ECDH(alg)) {
1111 return 0;
1112 }
1113#endif
1114 (void) alg;
1115 return 1;
1116}
1117
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001118#if defined(MBEDTLS_PK_C)
1119int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1120 const mbedtls_pk_context *pk)
1121{
1122 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1123 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1124 int ok = 0;
1125
1126 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1127 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1128 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1129
1130 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1131 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1132 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1133
1134 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1135 const uint8_t *pk_public = NULL;
1136 size_t pk_public_length = 0;
1137
1138 switch (pk_type) {
1139#if defined(MBEDTLS_RSA_C)
1140 case MBEDTLS_PK_RSA:
1141 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1142 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1143 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1144 uint8_t *cursor = end;
1145 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1146 pk_public_buffer, &cursor));
1147 pk_public = cursor;
1148 pk_public_length = end - pk_public;
1149 break;
1150#endif
1151
1152#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1153 case MBEDTLS_PK_ECKEY:
1154 case MBEDTLS_PK_ECKEY_DH:
1155 case MBEDTLS_PK_ECDSA:
1156 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1157 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1158 pk_public = pk->pub_raw;
1159 pk_public_length = pk->pub_raw_len;
1160 break;
1161#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1162
1163#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1164 case MBEDTLS_PK_ECKEY:
1165 case MBEDTLS_PK_ECKEY_DH:
1166 case MBEDTLS_PK_ECDSA:
1167 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1168 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1169 TEST_EQUAL(mbedtls_ecp_write_public_key(
1170 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1171 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1172 pk_public = pk_public_buffer;
1173 break;
1174#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */
1175
1176#if defined(MBEDTLS_USE_PSA_CRYPTO)
1177 case MBEDTLS_PK_OPAQUE:
1178 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1179 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1180 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1181 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1182 PSA_ASSERT(psa_export_public_key(psa_key,
1183 pk_public_buffer,
1184 sizeof(pk_public_buffer),
1185 &pk_public_length));
1186 pk_public = pk_public_buffer;
1187 break;
1188#endif /* MBEDTLS_USE_PSA_CRYPTO */
1189
1190 default:
1191 TEST_FAIL("pk type not supported");
1192 }
1193
1194 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1195 size_t psa_public_length = 0;
1196 PSA_ASSERT(psa_export_public_key(psa_key,
1197 psa_public, sizeof(psa_public),
1198 &psa_public_length));
1199 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1200 psa_public, psa_public_length);
1201
1202 ok = 1;
1203
1204exit:
1205 psa_reset_key_attributes(&psa_attributes);
1206 psa_reset_key_attributes(&pk_attributes);
1207 return ok;
1208}
1209#endif /* MBEDTLS_PK_C */
1210
Gilles Peskine66e7b902021-02-12 23:40:58 +01001211#endif /* MBEDTLS_PSA_CRYPTO_C */