blob: dc5b2bf00701b14916eab100e475439f25d69a08 [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,
177 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100178{
179 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100180 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
Gilles Peskine5eef11a2022-04-21 11:14:30 +0200181 size_t iv_length;
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100182 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
183 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100184 const unsigned char plaintext[16] = "Hello, world...";
185 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 size_t ciphertext_length = sizeof(ciphertext);
187 unsigned char decrypted[sizeof(ciphertext)];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100188 size_t part_length;
189
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
191 key_type = psa_get_key_type(&attributes);
192 iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 if (usage & PSA_KEY_USAGE_ENCRYPT) {
195 PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
196 if (iv_length != 0) {
197 PSA_ASSERT(psa_cipher_generate_iv(&operation,
198 iv, sizeof(iv),
199 &iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100200 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 PSA_ASSERT(psa_cipher_update(&operation,
202 plaintext, sizeof(plaintext),
203 ciphertext, sizeof(ciphertext),
204 &ciphertext_length));
205 PSA_ASSERT(psa_cipher_finish(&operation,
206 ciphertext + ciphertext_length,
207 sizeof(ciphertext) - ciphertext_length,
208 &part_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100209 ciphertext_length += part_length;
210 }
211
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100213 psa_status_t status;
214 int maybe_invalid_padding = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
216 maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100217 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
219 if (iv_length != 0) {
220 PSA_ASSERT(psa_cipher_set_iv(&operation,
221 iv, iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100222 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 PSA_ASSERT(psa_cipher_update(&operation,
224 ciphertext, ciphertext_length,
225 decrypted, sizeof(decrypted),
226 &part_length));
227 status = psa_cipher_finish(&operation,
228 decrypted + part_length,
229 sizeof(decrypted) - part_length,
230 &part_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100231 /* For a stream cipher, all inputs are valid. For a block cipher,
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800232 * if the input is some arbitrary data rather than an actual
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 ciphertext, a padding error is likely. */
234 if (maybe_invalid_padding) {
235 TEST_ASSERT(status == PSA_SUCCESS ||
236 status == PSA_ERROR_INVALID_PADDING);
237 } else {
238 PSA_ASSERT(status);
239 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100240 }
241
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100243
244exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 psa_cipher_abort(&operation);
246 psa_reset_key_attributes(&attributes);
247 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100248}
249
Gilles Peskine449bd832023-01-11 14:50:10 +0100250static int exercise_aead_key(mbedtls_svc_key_id_t key,
251 psa_key_usage_t usage,
252 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100253{
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
Gilles Peskine7acb1982022-03-19 11:03:32 +0100255 size_t nonce_length;
256 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
257 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100258 unsigned char plaintext[16] = "Hello, world...";
259 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 size_t ciphertext_length = sizeof(ciphertext);
261 size_t plaintext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100262
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100263 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
265 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100266 }
267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
269 key_type = psa_get_key_type(&attributes);
270 nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
Steven Cooremanaaec3412021-02-18 13:30:34 +0100271
Gilles Peskine449bd832023-01-11 14:50:10 +0100272 if (usage & PSA_KEY_USAGE_ENCRYPT) {
273 PSA_ASSERT(psa_aead_encrypt(key, alg,
274 nonce, nonce_length,
275 NULL, 0,
276 plaintext, sizeof(plaintext),
277 ciphertext, sizeof(ciphertext),
278 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100279 }
280
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100282 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 (usage & PSA_KEY_USAGE_ENCRYPT ?
284 PSA_SUCCESS :
285 PSA_ERROR_INVALID_SIGNATURE);
286 TEST_EQUAL(psa_aead_decrypt(key, alg,
287 nonce, nonce_length,
288 NULL, 0,
289 ciphertext, ciphertext_length,
290 plaintext, sizeof(plaintext),
291 &plaintext_length),
292 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100293 }
294
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100296
297exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 psa_reset_key_attributes(&attributes);
299 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100300}
301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302static int can_sign_or_verify_message(psa_key_usage_t usage,
303 psa_algorithm_t alg)
Gilles Peskined586b822022-03-19 11:15:41 +0100304{
305 /* Sign-the-unspecified-hash algorithms can only be used with
306 * {sign,verify}_hash, not with {sign,verify}_message. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
308 return 0;
309 }
310 return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
311 PSA_KEY_USAGE_VERIFY_MESSAGE);
Gilles Peskined586b822022-03-19 11:15:41 +0100312}
313
Gilles Peskine449bd832023-01-11 14:50:10 +0100314static int exercise_signature_key(mbedtls_svc_key_id_t key,
315 psa_key_usage_t usage,
316 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100317{
Gilles Peskine4781bd92024-02-09 17:32:45 +0100318 /* If the policy allows signing with any hash, just pick one. */
319 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
320 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
321 usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
322 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
323#if defined(KNOWN_SUPPORTED_HASH_ALG)
324 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
325 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
326#else
327 TEST_FAIL("No hash algorithm for hash-and-sign testing");
328#endif
329 }
330
oberon-skf7a824b2023-02-15 19:43:30 +0100331 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
332 PSA_ALG_IS_SIGN_HASH(alg)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200334 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
336 size_t signature_length = sizeof(signature);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200337
Janos Follath4c0b60e2021-06-14 12:34:30 +0100338 /* Some algorithms require the payload to have the size of
339 * the hash encoded in the algorithm. Use this input size
340 * even for algorithms that allow other input sizes. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 if (hash_alg != 0) {
342 payload_length = PSA_HASH_LENGTH(hash_alg);
343 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100344
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
346 PSA_ASSERT(psa_sign_hash(key, alg,
347 payload, payload_length,
348 signature, sizeof(signature),
349 &signature_length));
350 }
351
352 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
353 psa_status_t verify_status =
354 (usage & PSA_KEY_USAGE_SIGN_HASH ?
355 PSA_SUCCESS :
356 PSA_ERROR_INVALID_SIGNATURE);
357 TEST_EQUAL(psa_verify_hash(key, alg,
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200358 payload, payload_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 signature, signature_length),
360 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200361 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100362 }
363
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200365 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200367 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100369
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
371 PSA_ASSERT(psa_sign_message(key, alg,
372 message, message_length,
373 signature, sizeof(signature),
374 &signature_length));
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200375 }
376
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200378 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
380 PSA_SUCCESS :
381 PSA_ERROR_INVALID_SIGNATURE);
382 TEST_EQUAL(psa_verify_message(key, alg,
383 message, message_length,
384 signature, signature_length),
385 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200386 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100387 }
388
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100390
391exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100393}
394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
396 psa_key_usage_t usage,
397 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100398{
Gilles Peskinef50cd592024-02-15 13:13:26 +0100399 unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100400 "Hello, world...";
Gilles Peskinef50cd592024-02-15 13:13:26 +0100401 unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100402 "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100404 size_t plaintext_length = 16;
405
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 if (usage & PSA_KEY_USAGE_ENCRYPT) {
407 PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
408 plaintext, plaintext_length,
409 NULL, 0,
410 ciphertext, sizeof(ciphertext),
411 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100412 }
413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100415 psa_status_t status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 psa_asymmetric_decrypt(key, alg,
417 ciphertext, ciphertext_length,
418 NULL, 0,
419 plaintext, sizeof(plaintext),
420 &plaintext_length);
421 TEST_ASSERT(status == PSA_SUCCESS ||
422 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
423 (status == PSA_ERROR_INVALID_ARGUMENT ||
424 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100425 }
426
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100428
429exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100431}
432
433int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100434 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100435 mbedtls_svc_key_id_t key,
436 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 const unsigned char *input1, size_t input1_length,
438 const unsigned char *input2, size_t input2_length,
439 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100440{
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
442 if (PSA_ALG_IS_HKDF(alg)) {
443 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
444 PSA_KEY_DERIVATION_INPUT_SALT,
445 input1, input1_length));
446 PSA_ASSERT(psa_key_derivation_input_key(operation,
447 PSA_KEY_DERIVATION_INPUT_SECRET,
448 key));
449 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
450 PSA_KEY_DERIVATION_INPUT_INFO,
451 input2,
452 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530453 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
454 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
455 PSA_KEY_DERIVATION_INPUT_SALT,
456 input1, input1_length));
457 PSA_ASSERT(psa_key_derivation_input_key(operation,
458 PSA_KEY_DERIVATION_INPUT_SECRET,
459 key));
460 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
461 PSA_ASSERT(psa_key_derivation_input_key(operation,
462 PSA_KEY_DERIVATION_INPUT_SECRET,
463 key));
464 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
465 PSA_KEY_DERIVATION_INPUT_INFO,
466 input2,
467 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
469 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
470 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
471 PSA_KEY_DERIVATION_INPUT_SEED,
472 input1, input1_length));
473 PSA_ASSERT(psa_key_derivation_input_key(operation,
474 PSA_KEY_DERIVATION_INPUT_SECRET,
475 key));
476 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
477 PSA_KEY_DERIVATION_INPUT_LABEL,
478 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530479 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530480 PSA_ASSERT(psa_key_derivation_input_integer(operation,
481 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530482 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530483 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
484 PSA_KEY_DERIVATION_INPUT_SALT,
485 input2,
486 input2_length));
487 PSA_ASSERT(psa_key_derivation_input_key(operation,
488 PSA_KEY_DERIVATION_INPUT_PASSWORD,
489 key));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530490 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
491 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
492 PSA_KEY_DERIVATION_INPUT_SECRET,
493 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100495 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100496 }
497
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 if (capacity != SIZE_MAX) {
499 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
500 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100501
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100503
504exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100506}
507
508
Gilles Peskine449bd832023-01-11 14:50:10 +0100509static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
510 psa_key_usage_t usage,
511 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100512{
513 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
514 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100515 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100516 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100518 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100520
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 if (usage & PSA_KEY_USAGE_DERIVE) {
522 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
523 input1, input1_length,
524 input2, input2_length,
525 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100526 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100528
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
530 output,
531 capacity));
532 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100533 }
534
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100536
537exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100539}
540
541/* We need two keys to exercise key agreement. Exercise the
542 * private key against its own public key. */
543psa_status_t mbedtls_test_psa_key_agreement_with_self(
544 psa_key_derivation_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100546{
547 psa_key_type_t private_key_type;
548 psa_key_type_t public_key_type;
549 size_t key_bits;
550 uint8_t *public_key = NULL;
551 size_t public_key_length;
552 /* Return GENERIC_ERROR if something other than the final call to
553 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
554 * but it's good enough: callers will report it as a failed test anyway. */
555 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
556 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
559 private_key_type = psa_get_key_type(&attributes);
560 key_bits = psa_get_key_bits(&attributes);
561 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
562 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100563 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
565 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100566
567 status = psa_key_derivation_key_agreement(
568 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100570exit:
571 /*
572 * Key attributes may have been returned by psa_get_key_attributes()
573 * thus reset them as required.
574 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100576
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 mbedtls_free(public_key);
578 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100579}
580
581/* We need two keys to exercise key agreement. Exercise the
582 * private key against its own public key. */
583psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
584 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100586{
587 psa_key_type_t private_key_type;
588 psa_key_type_t public_key_type;
589 size_t key_bits;
590 uint8_t *public_key = NULL;
591 size_t public_key_length;
592 uint8_t output[1024];
593 size_t output_length;
594 /* Return GENERIC_ERROR if something other than the final call to
595 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
596 * but it's good enough: callers will report it as a failed test anyway. */
597 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
598 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
599
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
601 private_key_type = psa_get_key_type(&attributes);
602 key_bits = psa_get_key_bits(&attributes);
603 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
604 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100605 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 PSA_ASSERT(psa_export_public_key(key,
607 public_key, public_key_length,
608 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 status = psa_raw_key_agreement(alg, key,
611 public_key, public_key_length,
612 output, sizeof(output), &output_length);
613 if (status == PSA_SUCCESS) {
614 TEST_ASSERT(output_length <=
615 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
616 key_bits));
617 TEST_ASSERT(output_length <=
618 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100619 }
620
Gilles Peskinee78b0022021-02-13 00:41:11 +0100621exit:
622 /*
623 * Key attributes may have been returned by psa_get_key_attributes()
624 * thus reset them as required.
625 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 mbedtls_free(public_key);
629 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100630}
631
Gilles Peskine449bd832023-01-11 14:50:10 +0100632static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
633 psa_key_usage_t usage,
634 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100635{
636 int ok = 0;
637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100639 /* We need two keys to exercise key agreement. Exercise the
640 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100642 }
643 ok = 1;
644
645exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100647}
648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
650 psa_key_usage_t usage,
651 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100652{
653 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200654 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100655 unsigned char output[1];
656 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200658 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100659
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100661 /* We need two keys to exercise key agreement. Exercise the
662 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
664 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
665 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
666 PSA_ASSERT(psa_key_derivation_input_bytes(
667 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
668 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100669 }
670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
672 PSA_ASSERT(psa_key_derivation_input_bytes(
673 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
674 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200675 }
676
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200677 /* For HKDF_EXPAND input secret may fail as secret size may not match
678 to expected PRK size. In practice it means that key bits must match
679 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200681 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
683 size_t key_bits = psa_get_key_bits(&attributes);
684 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200685
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200687 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200689 }
690
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
692 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 if (expected_key_agreement_status != PSA_SUCCESS) {
695 return 1;
696 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100697
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
699 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
700 PSA_ASSERT(psa_key_derivation_input_bytes(
701 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
702 input, sizeof(input)));
703 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
704 PSA_ASSERT(psa_key_derivation_input_bytes(
705 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
706 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100707 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
709 output,
710 sizeof(output)));
711 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100712 }
713 ok = 1;
714
715exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100717}
718
719int mbedtls_test_psa_exported_key_sanity_check(
720 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100722{
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100724
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
726 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
727 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100728
Ronald Cron64df7382021-07-06 09:23:06 +0200729#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
731 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100732 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100733 size_t len;
734 /* RSAPrivateKey ::= SEQUENCE {
735 * version INTEGER, -- must be 0
736 * modulus INTEGER, -- n
737 * publicExponent INTEGER, -- e
738 * privateExponent INTEGER, -- d
739 * prime1 INTEGER, -- p
740 * prime2 INTEGER, -- q
741 * exponent1 INTEGER, -- d mod (p-1)
742 * exponent2 INTEGER, -- d mod (q-1)
743 * coefficient INTEGER, -- (inverse of q) mod p
744 * }
745 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
747 MBEDTLS_ASN1_SEQUENCE |
748 MBEDTLS_ASN1_CONSTRUCTED), 0);
749 TEST_EQUAL(len, end - p);
750 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100751 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 }
753 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100754 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 }
756 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100757 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100759 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100761 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100763 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100765 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 }
767 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100768 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 }
770 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100771 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 }
773 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100774 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 }
776 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100777 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 }
779 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100780
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
782 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200783#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100784
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100786 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100787 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100788
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
790 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100791
Ronald Cron64df7382021-07-06 09:23:06 +0200792#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
794 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100795 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100796 size_t len;
797 /* RSAPublicKey ::= SEQUENCE {
798 * modulus INTEGER, -- n
799 * publicExponent INTEGER } -- e
800 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
802 MBEDTLS_ASN1_SEQUENCE |
803 MBEDTLS_ASN1_CONSTRUCTED),
804 0);
805 TEST_EQUAL(len, end - p);
806 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100807 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 }
809 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100810 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 }
812 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100813
814
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 TEST_ASSERT(exported_length <=
816 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
817 TEST_ASSERT(exported_length <=
818 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
819 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200820#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100821
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100823
Gilles Peskine449bd832023-01-11 14:50:10 +0100824 TEST_ASSERT(exported_length <=
825 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
826 TEST_ASSERT(exported_length <=
827 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100828
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100830 /* The representation of an ECC Montgomery public key is
831 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100833 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100834 /* The representation of an ECC Edwards public key is
835 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100836 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100837 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100838 /* The representation of an ECC Weierstrass public key is:
839 * - The byte 0x04;
840 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
841 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
842 * - where m is the bit size associated with the curve.
843 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
845 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100846 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100847 } else
848 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200849 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100850 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
851 TEST_ASSERT(exported_length <=
852 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200853 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100854 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100855 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100856 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100857
Gilles Peskinecc9db302021-02-14 01:29:52 +0100858#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100860 /* Check the parity bits. */
861 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100863 unsigned bit_count = 0;
864 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 for (m = 1; m <= 0x100; m <<= 1) {
866 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100867 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100869 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100871 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100872 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100873#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100876
877exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100879}
880
Gilles Peskine449bd832023-01-11 14:50:10 +0100881static int exercise_export_key(mbedtls_svc_key_id_t key,
882 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100883{
884 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
885 uint8_t *exported = NULL;
886 size_t exported_size = 0;
887 size_t exported_length = 0;
888 int ok = 0;
889
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100891
892 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 psa_get_key_type(&attributes),
894 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100895 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100896
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
898 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
899 TEST_EQUAL(psa_export_key(key, exported,
900 exported_size, &exported_length),
901 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100902 ok = 1;
903 goto exit;
904 }
905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 PSA_ASSERT(psa_export_key(key,
907 exported, exported_size,
908 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100909 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
911 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100912
913exit:
914 /*
915 * Key attributes may have been returned by psa_get_key_attributes()
916 * thus reset them as required.
917 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100919
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 mbedtls_free(exported);
921 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100922}
923
Gilles Peskine449bd832023-01-11 14:50:10 +0100924static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100925{
926 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
927 psa_key_type_t public_type;
928 uint8_t *exported = NULL;
929 size_t exported_size = 0;
930 size_t exported_length = 0;
931 int ok = 0;
932
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
934 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100935 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 psa_get_key_type(&attributes),
937 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100938 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100939
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 TEST_EQUAL(psa_export_public_key(key, exported,
941 exported_size, &exported_length),
942 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100943 ok = 1;
944 goto exit;
945 }
946
947 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 psa_get_key_type(&attributes));
949 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
950 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100951 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100952
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 PSA_ASSERT(psa_export_public_key(key,
954 exported, exported_size,
955 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100956 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 public_type, psa_get_key_bits(&attributes),
958 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100959
960exit:
961 /*
962 * Key attributes may have been returned by psa_get_key_attributes()
963 * thus reset them as required.
964 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100966
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 mbedtls_free(exported);
968 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100969}
970
Gilles Peskine449bd832023-01-11 14:50:10 +0100971int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
972 psa_key_usage_t usage,
Ryan Everett0a271fd2024-03-12 16:34:02 +0000973 psa_algorithm_t alg,
974 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100975{
Gilles Peskine2385f712021-02-14 01:34:21 +0100976 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100977
Ryan Everett0a271fd2024-03-12 16:34:02 +0000978 if (!check_key_attributes_sanity(key, key_destroyable)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 return 0;
980 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100981
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800983 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 } else if (PSA_ALG_IS_MAC(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000985 ok = exercise_mac_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 } else if (PSA_ALG_IS_CIPHER(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000987 ok = exercise_cipher_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 } else if (PSA_ALG_IS_AEAD(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000989 ok = exercise_aead_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 } else if (PSA_ALG_IS_SIGN(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000991 ok = exercise_signature_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000993 ok = exercise_asymmetric_encryption_key(key, usage, alg,
994 key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000996 ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000998 ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001000 ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +01001002 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001004
Ryan Everett0a271fd2024-03-12 16:34:02 +00001005 ok = ok && exercise_export_key(key,
1006 usage,
1007 key_destroyable);
1008 ok = ok && exercise_export_public_key(key,
1009 key_destroyable);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001010
Gilles Peskine2385f712021-02-14 01:34:21 +01001011exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001013}
1014
Gilles Peskine449bd832023-01-11 14:50:10 +01001015psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1016 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001017{
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1019 if (PSA_ALG_IS_SIGN_HASH(alg)) {
1020 if (PSA_ALG_SIGN_GET_HASH(alg)) {
1021 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1022 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1023 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1024 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1025 }
1026 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1027 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1028 PSA_KEY_USAGE_VERIFY_MESSAGE :
1029 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001030 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001031
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1033 PSA_KEY_USAGE_VERIFY_HASH :
1034 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1035 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1036 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1037 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1038 PSA_KEY_USAGE_ENCRYPT :
1039 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1040 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1041 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1042 return PSA_KEY_USAGE_DERIVE;
1043 } else {
1044 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001045 }
1046
1047}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001048
Gilles Peskine34955672024-02-12 14:19:24 +01001049int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1050{
1051 /* Reject algorithms that we know are not supported. Default to
1052 * attempting exercise, so that if an algorithm is missing from this
1053 * function, the result will be a test failure and not silently
1054 * omitting exercise. */
1055#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1056 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1057 return 0;
1058 }
1059#endif
1060#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1061 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1062 return 0;
1063 }
1064#endif
1065#if !defined(PSA_WANT_ALG_RSA_PSS)
1066 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1067 return 0;
1068 }
1069#endif
1070#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1071 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1072 return 0;
1073 }
1074#endif
1075#if !defined(PSA_WANT_ALG_ECDSA)
1076 if (PSA_ALG_IS_ECDSA(alg)) {
1077 return 0;
1078 }
1079#endif
1080#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1081 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1082 return 0;
1083 }
1084#endif
1085#if !defined(PSA_WANT_ALG_ECDH)
1086 if (PSA_ALG_IS_ECDH(alg)) {
1087 return 0;
1088 }
1089#endif
1090 (void) alg;
1091 return 1;
1092}
1093
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001094#if defined(MBEDTLS_PK_C)
1095int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1096 const mbedtls_pk_context *pk)
1097{
1098 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1099 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1100 int ok = 0;
1101
1102 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1103 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1104 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1105
1106 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1107 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1108 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1109
1110 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1111 const uint8_t *pk_public = NULL;
1112 size_t pk_public_length = 0;
1113
1114 switch (pk_type) {
1115#if defined(MBEDTLS_RSA_C)
1116 case MBEDTLS_PK_RSA:
1117 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1118 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1119 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1120 uint8_t *cursor = end;
1121 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1122 pk_public_buffer, &cursor));
1123 pk_public = cursor;
1124 pk_public_length = end - pk_public;
1125 break;
1126#endif
1127
1128#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1129 case MBEDTLS_PK_ECKEY:
1130 case MBEDTLS_PK_ECKEY_DH:
1131 case MBEDTLS_PK_ECDSA:
1132 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1133 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1134 pk_public = pk->pub_raw;
1135 pk_public_length = pk->pub_raw_len;
1136 break;
1137#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1138
1139#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1140 case MBEDTLS_PK_ECKEY:
1141 case MBEDTLS_PK_ECKEY_DH:
1142 case MBEDTLS_PK_ECDSA:
1143 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1144 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1145 TEST_EQUAL(mbedtls_ecp_write_public_key(
1146 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1147 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1148 pk_public = pk_public_buffer;
1149 break;
1150#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */
1151
1152#if defined(MBEDTLS_USE_PSA_CRYPTO)
1153 case MBEDTLS_PK_OPAQUE:
1154 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1155 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1156 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1157 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1158 PSA_ASSERT(psa_export_public_key(psa_key,
1159 pk_public_buffer,
1160 sizeof(pk_public_buffer),
1161 &pk_public_length));
1162 pk_public = pk_public_buffer;
1163 break;
1164#endif /* MBEDTLS_USE_PSA_CRYPTO */
1165
1166 default:
1167 TEST_FAIL("pk type not supported");
1168 }
1169
1170 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1171 size_t psa_public_length = 0;
1172 PSA_ASSERT(psa_export_public_key(psa_key,
1173 psa_public, sizeof(psa_public),
1174 &psa_public_length));
1175 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1176 psa_public, psa_public_length);
1177
1178 ok = 1;
1179
1180exit:
1181 psa_reset_key_attributes(&psa_attributes);
1182 psa_reset_key_attributes(&pk_attributes);
1183 return ok;
1184}
1185#endif /* MBEDTLS_PK_C */
1186
Gilles Peskine66e7b902021-02-12 23:40:58 +01001187#endif /* MBEDTLS_PSA_CRYPTO_C */