blob: 7b81052c8c7b0f44aae475e6fcc7199af120a917 [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
Gilles Peskine449bd832023-01-11 14:50:10 +010041static int check_key_attributes_sanity(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +010042{
43 int ok = 0;
44 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
45 psa_key_lifetime_t lifetime;
46 mbedtls_svc_key_id_t id;
47 psa_key_type_t type;
Gilles Peskine6b362e62021-02-15 12:03:16 +010048 size_t bits;
Gilles Peskinee78b0022021-02-13 00:41:11 +010049
Gilles Peskine449bd832023-01-11 14:50:10 +010050 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
51 lifetime = psa_get_key_lifetime(&attributes);
52 id = psa_get_key_id(&attributes);
53 type = psa_get_key_type(&attributes);
54 bits = psa_get_key_bits(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +010055
56 /* Persistence */
Gilles Peskine449bd832023-01-11 14:50:10 +010057 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010058 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010059 (PSA_KEY_ID_VOLATILE_MIN <=
60 MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
61 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
62 PSA_KEY_ID_VOLATILE_MAX));
63 } else {
Gilles Peskinee78b0022021-02-13 00:41:11 +010064 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010065 (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
66 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
Gilles Peskinee78b0022021-02-13 00:41:11 +010067 }
68#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
69 /* randomly-generated 64-bit constant, should never appear in test data */
70 psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
Gilles Peskine449bd832023-01-11 14:50:10 +010071 psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number);
72 if (lifetime_is_dynamic_secure_element(lifetime)) {
Fredrik Hessecc207bc2021-09-28 21:06:08 +020073 /* Mbed TLS currently always exposes the slot number to
Gilles Peskinee78b0022021-02-13 00:41:11 +010074 * applications. This is not mandated by the PSA specification
75 * and may change in future versions. */
Gilles Peskine449bd832023-01-11 14:50:10 +010076 TEST_EQUAL(status, 0);
77 TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
78 } else {
79 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +010080 }
81#endif
82
83 /* Type and size */
Gilles Peskine449bd832023-01-11 14:50:10 +010084 TEST_ASSERT(type != 0);
85 TEST_ASSERT(bits != 0);
86 TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
87 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
88 TEST_ASSERT(bits % 8 == 0);
89 }
Gilles Peskinee78b0022021-02-13 00:41:11 +010090
91 /* MAX macros concerning specific key types */
Gilles Peskine449bd832023-01-11 14:50:10 +010092 if (PSA_KEY_TYPE_IS_ECC(type)) {
93 TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
94 } else if (PSA_KEY_TYPE_IS_RSA(type)) {
95 TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
96 }
97 TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
Gilles Peskinee78b0022021-02-13 00:41:11 +010098
99 ok = 1;
100
101exit:
102 /*
103 * Key attributes may have been returned by psa_get_key_attributes()
104 * thus reset them as required.
105 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100106 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100107
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100109}
110
Gilles Peskine449bd832023-01-11 14:50:10 +0100111static int exercise_mac_key(mbedtls_svc_key_id_t key,
112 psa_key_usage_t usage,
113 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100114{
115 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
116 const unsigned char input[] = "foo";
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
118 size_t mac_length = sizeof(mac);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100119
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100120 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100121 if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
122 alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100123 }
124
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
126 PSA_ASSERT(psa_mac_sign_setup(&operation, key, alg));
127 PSA_ASSERT(psa_mac_update(&operation,
128 input, sizeof(input)));
129 PSA_ASSERT(psa_mac_sign_finish(&operation,
130 mac, sizeof(mac),
131 &mac_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100132 }
133
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100135 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 (usage & PSA_KEY_USAGE_SIGN_HASH ?
137 PSA_SUCCESS :
138 PSA_ERROR_INVALID_SIGNATURE);
139 PSA_ASSERT(psa_mac_verify_setup(&operation, key, alg));
140 PSA_ASSERT(psa_mac_update(&operation,
141 input, sizeof(input)));
142 TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
143 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100144 }
145
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100147
148exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 psa_mac_abort(&operation);
150 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100151}
152
Gilles Peskine449bd832023-01-11 14:50:10 +0100153static int exercise_cipher_key(mbedtls_svc_key_id_t key,
154 psa_key_usage_t usage,
155 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100156{
157 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
Gilles Peskine5eef11a2022-04-21 11:14:30 +0200159 size_t iv_length;
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100160 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
161 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100162 const unsigned char plaintext[16] = "Hello, world...";
163 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100164 size_t ciphertext_length = sizeof(ciphertext);
165 unsigned char decrypted[sizeof(ciphertext)];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100166 size_t part_length;
167
Gilles Peskine449bd832023-01-11 14:50:10 +0100168 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
169 key_type = psa_get_key_type(&attributes);
170 iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100171
Gilles Peskine449bd832023-01-11 14:50:10 +0100172 if (usage & PSA_KEY_USAGE_ENCRYPT) {
173 PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
174 if (iv_length != 0) {
175 PSA_ASSERT(psa_cipher_generate_iv(&operation,
176 iv, sizeof(iv),
177 &iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100178 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 PSA_ASSERT(psa_cipher_update(&operation,
180 plaintext, sizeof(plaintext),
181 ciphertext, sizeof(ciphertext),
182 &ciphertext_length));
183 PSA_ASSERT(psa_cipher_finish(&operation,
184 ciphertext + ciphertext_length,
185 sizeof(ciphertext) - ciphertext_length,
186 &part_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100187 ciphertext_length += part_length;
188 }
189
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100191 psa_status_t status;
192 int maybe_invalid_padding = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
194 maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100195 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
197 if (iv_length != 0) {
198 PSA_ASSERT(psa_cipher_set_iv(&operation,
199 iv, 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 ciphertext, ciphertext_length,
203 decrypted, sizeof(decrypted),
204 &part_length));
205 status = psa_cipher_finish(&operation,
206 decrypted + part_length,
207 sizeof(decrypted) - part_length,
208 &part_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100209 /* For a stream cipher, all inputs are valid. For a block cipher,
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800210 * if the input is some arbitrary data rather than an actual
Gilles Peskine449bd832023-01-11 14:50:10 +0100211 ciphertext, a padding error is likely. */
212 if (maybe_invalid_padding) {
213 TEST_ASSERT(status == PSA_SUCCESS ||
214 status == PSA_ERROR_INVALID_PADDING);
215 } else {
216 PSA_ASSERT(status);
217 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100218 }
219
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100221
222exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 psa_cipher_abort(&operation);
224 psa_reset_key_attributes(&attributes);
225 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100226}
227
Gilles Peskine449bd832023-01-11 14:50:10 +0100228static int exercise_aead_key(mbedtls_svc_key_id_t key,
229 psa_key_usage_t usage,
230 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100231{
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
Gilles Peskine7acb1982022-03-19 11:03:32 +0100233 size_t nonce_length;
234 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
235 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100236 unsigned char plaintext[16] = "Hello, world...";
237 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 size_t ciphertext_length = sizeof(ciphertext);
239 size_t plaintext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100240
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100241 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
243 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100244 }
245
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
247 key_type = psa_get_key_type(&attributes);
248 nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
Steven Cooremanaaec3412021-02-18 13:30:34 +0100249
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 if (usage & PSA_KEY_USAGE_ENCRYPT) {
251 PSA_ASSERT(psa_aead_encrypt(key, alg,
252 nonce, nonce_length,
253 NULL, 0,
254 plaintext, sizeof(plaintext),
255 ciphertext, sizeof(ciphertext),
256 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100257 }
258
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100260 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 (usage & PSA_KEY_USAGE_ENCRYPT ?
262 PSA_SUCCESS :
263 PSA_ERROR_INVALID_SIGNATURE);
264 TEST_EQUAL(psa_aead_decrypt(key, alg,
265 nonce, nonce_length,
266 NULL, 0,
267 ciphertext, ciphertext_length,
268 plaintext, sizeof(plaintext),
269 &plaintext_length),
270 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100271 }
272
Gilles Peskine449bd832023-01-11 14:50:10 +0100273 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100274
275exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100276 psa_reset_key_attributes(&attributes);
277 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100278}
279
Gilles Peskine449bd832023-01-11 14:50:10 +0100280static int can_sign_or_verify_message(psa_key_usage_t usage,
281 psa_algorithm_t alg)
Gilles Peskined586b822022-03-19 11:15:41 +0100282{
283 /* Sign-the-unspecified-hash algorithms can only be used with
284 * {sign,verify}_hash, not with {sign,verify}_message. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
286 return 0;
287 }
288 return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
289 PSA_KEY_USAGE_VERIFY_MESSAGE);
Gilles Peskined586b822022-03-19 11:15:41 +0100290}
291
Gilles Peskine449bd832023-01-11 14:50:10 +0100292static int exercise_signature_key(mbedtls_svc_key_id_t key,
293 psa_key_usage_t usage,
294 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100295{
Gilles Peskine4781bd92024-02-09 17:32:45 +0100296 /* If the policy allows signing with any hash, just pick one. */
297 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
298 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
299 usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
300 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
301#if defined(KNOWN_SUPPORTED_HASH_ALG)
302 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
303 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
304#else
305 TEST_FAIL("No hash algorithm for hash-and-sign testing");
306#endif
307 }
308
oberon-skf7a824b2023-02-15 19:43:30 +0100309 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
310 PSA_ALG_IS_SIGN_HASH(alg)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200312 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
314 size_t signature_length = sizeof(signature);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200315
Janos Follath4c0b60e2021-06-14 12:34:30 +0100316 /* Some algorithms require the payload to have the size of
317 * the hash encoded in the algorithm. Use this input size
318 * even for algorithms that allow other input sizes. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 if (hash_alg != 0) {
320 payload_length = PSA_HASH_LENGTH(hash_alg);
321 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100322
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
324 PSA_ASSERT(psa_sign_hash(key, alg,
325 payload, payload_length,
326 signature, sizeof(signature),
327 &signature_length));
328 }
329
330 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
331 psa_status_t verify_status =
332 (usage & PSA_KEY_USAGE_SIGN_HASH ?
333 PSA_SUCCESS :
334 PSA_ERROR_INVALID_SIGNATURE);
335 TEST_EQUAL(psa_verify_hash(key, alg,
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200336 payload, payload_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 signature, signature_length),
338 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200339 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100340 }
341
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200343 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200345 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100347
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
349 PSA_ASSERT(psa_sign_message(key, alg,
350 message, message_length,
351 signature, sizeof(signature),
352 &signature_length));
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200353 }
354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200356 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
358 PSA_SUCCESS :
359 PSA_ERROR_INVALID_SIGNATURE);
360 TEST_EQUAL(psa_verify_message(key, alg,
361 message, message_length,
362 signature, signature_length),
363 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200364 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100365 }
366
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100368
369exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100371}
372
Gilles Peskine449bd832023-01-11 14:50:10 +0100373static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
374 psa_key_usage_t usage,
375 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100376{
Gilles Peskinef50cd592024-02-15 13:13:26 +0100377 unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100378 "Hello, world...";
Gilles Peskinef50cd592024-02-15 13:13:26 +0100379 unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100380 "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100382 size_t plaintext_length = 16;
383
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 if (usage & PSA_KEY_USAGE_ENCRYPT) {
385 PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
386 plaintext, plaintext_length,
387 NULL, 0,
388 ciphertext, sizeof(ciphertext),
389 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100390 }
391
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100393 psa_status_t status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 psa_asymmetric_decrypt(key, alg,
395 ciphertext, ciphertext_length,
396 NULL, 0,
397 plaintext, sizeof(plaintext),
398 &plaintext_length);
399 TEST_ASSERT(status == PSA_SUCCESS ||
400 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
401 (status == PSA_ERROR_INVALID_ARGUMENT ||
402 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100403 }
404
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100406
407exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100409}
410
411int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100413 mbedtls_svc_key_id_t key,
414 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100415 const unsigned char *input1, size_t input1_length,
416 const unsigned char *input2, size_t input2_length,
417 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100418{
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
420 if (PSA_ALG_IS_HKDF(alg)) {
421 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
422 PSA_KEY_DERIVATION_INPUT_SALT,
423 input1, input1_length));
424 PSA_ASSERT(psa_key_derivation_input_key(operation,
425 PSA_KEY_DERIVATION_INPUT_SECRET,
426 key));
427 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
428 PSA_KEY_DERIVATION_INPUT_INFO,
429 input2,
430 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530431 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
432 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
433 PSA_KEY_DERIVATION_INPUT_SALT,
434 input1, input1_length));
435 PSA_ASSERT(psa_key_derivation_input_key(operation,
436 PSA_KEY_DERIVATION_INPUT_SECRET,
437 key));
438 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
439 PSA_ASSERT(psa_key_derivation_input_key(operation,
440 PSA_KEY_DERIVATION_INPUT_SECRET,
441 key));
442 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
443 PSA_KEY_DERIVATION_INPUT_INFO,
444 input2,
445 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
447 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
448 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
449 PSA_KEY_DERIVATION_INPUT_SEED,
450 input1, input1_length));
451 PSA_ASSERT(psa_key_derivation_input_key(operation,
452 PSA_KEY_DERIVATION_INPUT_SECRET,
453 key));
454 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
455 PSA_KEY_DERIVATION_INPUT_LABEL,
456 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530457 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530458 PSA_ASSERT(psa_key_derivation_input_integer(operation,
459 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530460 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530461 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
462 PSA_KEY_DERIVATION_INPUT_SALT,
463 input2,
464 input2_length));
465 PSA_ASSERT(psa_key_derivation_input_key(operation,
466 PSA_KEY_DERIVATION_INPUT_PASSWORD,
467 key));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530468 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
469 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
470 PSA_KEY_DERIVATION_INPUT_SECRET,
471 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100473 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100474 }
475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 if (capacity != SIZE_MAX) {
477 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
478 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100481
482exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100484}
485
486
Gilles Peskine449bd832023-01-11 14:50:10 +0100487static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
488 psa_key_usage_t usage,
489 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100490{
491 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
492 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100494 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100496 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 if (usage & PSA_KEY_USAGE_DERIVE) {
500 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
501 input1, input1_length,
502 input2, input2_length,
503 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100504 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100506
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
508 output,
509 capacity));
510 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100511 }
512
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100514
515exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100517}
518
519/* We need two keys to exercise key agreement. Exercise the
520 * private key against its own public key. */
521psa_status_t mbedtls_test_psa_key_agreement_with_self(
522 psa_key_derivation_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100523 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100524{
525 psa_key_type_t private_key_type;
526 psa_key_type_t public_key_type;
527 size_t key_bits;
528 uint8_t *public_key = NULL;
529 size_t public_key_length;
530 /* Return GENERIC_ERROR if something other than the final call to
531 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
532 * but it's good enough: callers will report it as a failed test anyway. */
533 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
534 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
535
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
537 private_key_type = psa_get_key_type(&attributes);
538 key_bits = psa_get_key_bits(&attributes);
539 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
540 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100541 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
543 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100544
545 status = psa_key_derivation_key_agreement(
546 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100548exit:
549 /*
550 * Key attributes may have been returned by psa_get_key_attributes()
551 * thus reset them as required.
552 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 mbedtls_free(public_key);
556 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100557}
558
559/* We need two keys to exercise key agreement. Exercise the
560 * private key against its own public key. */
561psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
562 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100564{
565 psa_key_type_t private_key_type;
566 psa_key_type_t public_key_type;
567 size_t key_bits;
568 uint8_t *public_key = NULL;
569 size_t public_key_length;
570 uint8_t output[1024];
571 size_t output_length;
572 /* Return GENERIC_ERROR if something other than the final call to
573 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
574 * but it's good enough: callers will report it as a failed test anyway. */
575 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
576 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
577
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
579 private_key_type = psa_get_key_type(&attributes);
580 key_bits = psa_get_key_bits(&attributes);
581 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
582 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100583 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 PSA_ASSERT(psa_export_public_key(key,
585 public_key, public_key_length,
586 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 status = psa_raw_key_agreement(alg, key,
589 public_key, public_key_length,
590 output, sizeof(output), &output_length);
591 if (status == PSA_SUCCESS) {
592 TEST_ASSERT(output_length <=
593 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
594 key_bits));
595 TEST_ASSERT(output_length <=
596 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100597 }
598
Gilles Peskinee78b0022021-02-13 00:41:11 +0100599exit:
600 /*
601 * Key attributes may have been returned by psa_get_key_attributes()
602 * thus reset them as required.
603 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 mbedtls_free(public_key);
607 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100608}
609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
611 psa_key_usage_t usage,
612 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100613{
614 int ok = 0;
615
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100617 /* We need two keys to exercise key agreement. Exercise the
618 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100620 }
621 ok = 1;
622
623exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100625}
626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
628 psa_key_usage_t usage,
629 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100630{
631 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200632 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100633 unsigned char output[1];
634 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200636 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100637
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(psa_key_derivation_setup(&operation, alg));
642 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
643 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
644 PSA_ASSERT(psa_key_derivation_input_bytes(
645 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
646 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100647 }
648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
650 PSA_ASSERT(psa_key_derivation_input_bytes(
651 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
652 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200653 }
654
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200655 /* For HKDF_EXPAND input secret may fail as secret size may not match
656 to expected PRK size. In practice it means that key bits must match
657 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200659 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
661 size_t key_bits = psa_get_key_bits(&attributes);
662 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200663
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200665 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200667 }
668
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
670 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200671
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 if (expected_key_agreement_status != PSA_SUCCESS) {
673 return 1;
674 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100675
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
677 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
678 PSA_ASSERT(psa_key_derivation_input_bytes(
679 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
680 input, sizeof(input)));
681 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
682 PSA_ASSERT(psa_key_derivation_input_bytes(
683 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
684 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100685 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
687 output,
688 sizeof(output)));
689 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100690 }
691 ok = 1;
692
693exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100695}
696
697int mbedtls_test_psa_exported_key_sanity_check(
698 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100700{
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100702
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
704 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
705 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100706
Ronald Cron64df7382021-07-06 09:23:06 +0200707#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
709 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100710 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100711 size_t len;
712 /* RSAPrivateKey ::= SEQUENCE {
713 * version INTEGER, -- must be 0
714 * modulus INTEGER, -- n
715 * publicExponent INTEGER, -- e
716 * privateExponent INTEGER, -- d
717 * prime1 INTEGER, -- p
718 * prime2 INTEGER, -- q
719 * exponent1 INTEGER, -- d mod (p-1)
720 * exponent2 INTEGER, -- d mod (q-1)
721 * coefficient INTEGER, -- (inverse of q) mod p
722 * }
723 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
725 MBEDTLS_ASN1_SEQUENCE |
726 MBEDTLS_ASN1_CONSTRUCTED), 0);
727 TEST_EQUAL(len, end - p);
728 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100729 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 }
731 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100732 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 }
734 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100735 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100737 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100739 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100741 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100743 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 }
745 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100746 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 }
748 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100749 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 }
751 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100752 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 }
754 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100755 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 }
757 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100758
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
760 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200761#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100762
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100764 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
768 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100769
Ronald Cron64df7382021-07-06 09:23:06 +0200770#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
772 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100773 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100774 size_t len;
775 /* RSAPublicKey ::= SEQUENCE {
776 * modulus INTEGER, -- n
777 * publicExponent INTEGER } -- e
778 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
780 MBEDTLS_ASN1_SEQUENCE |
781 MBEDTLS_ASN1_CONSTRUCTED),
782 0);
783 TEST_EQUAL(len, end - p);
784 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100785 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 }
787 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100788 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 }
790 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100791
792
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 TEST_ASSERT(exported_length <=
794 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
795 TEST_ASSERT(exported_length <=
796 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
797 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200798#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100799
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 TEST_ASSERT(exported_length <=
803 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
804 TEST_ASSERT(exported_length <=
805 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100806
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100808 /* The representation of an ECC Montgomery public key is
809 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100811 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100812 /* The representation of an ECC Edwards public key is
813 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100814 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100816 /* The representation of an ECC Weierstrass public key is:
817 * - The byte 0x04;
818 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
819 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
820 * - where m is the bit size associated with the curve.
821 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
823 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100824 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100825 } else
826 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200827 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100828 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
829 TEST_ASSERT(exported_length <=
830 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200831 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100832 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100833 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100834 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100835
Gilles Peskinecc9db302021-02-14 01:29:52 +0100836#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100837 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100838 /* Check the parity bits. */
839 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100841 unsigned bit_count = 0;
842 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 for (m = 1; m <= 0x100; m <<= 1) {
844 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100845 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100847 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100849 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100850 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100851#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100852
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100854
855exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100857}
858
Gilles Peskine449bd832023-01-11 14:50:10 +0100859static int exercise_export_key(mbedtls_svc_key_id_t key,
860 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100861{
862 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
863 uint8_t *exported = NULL;
864 size_t exported_size = 0;
865 size_t exported_length = 0;
866 int ok = 0;
867
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100869
870 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 psa_get_key_type(&attributes),
872 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100873 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
876 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
877 TEST_EQUAL(psa_export_key(key, exported,
878 exported_size, &exported_length),
879 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100880 ok = 1;
881 goto exit;
882 }
883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 PSA_ASSERT(psa_export_key(key,
885 exported, exported_size,
886 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100887 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
889 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100890
891exit:
892 /*
893 * Key attributes may have been returned by psa_get_key_attributes()
894 * thus reset them as required.
895 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 mbedtls_free(exported);
899 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100900}
901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100903{
904 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
905 psa_key_type_t public_type;
906 uint8_t *exported = NULL;
907 size_t exported_size = 0;
908 size_t exported_length = 0;
909 int ok = 0;
910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
912 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100913 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 psa_get_key_type(&attributes),
915 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100916 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100917
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 TEST_EQUAL(psa_export_public_key(key, exported,
919 exported_size, &exported_length),
920 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100921 ok = 1;
922 goto exit;
923 }
924
925 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 psa_get_key_type(&attributes));
927 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
928 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100929 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100930
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 PSA_ASSERT(psa_export_public_key(key,
932 exported, exported_size,
933 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100934 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 public_type, psa_get_key_bits(&attributes),
936 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100937
938exit:
939 /*
940 * Key attributes may have been returned by psa_get_key_attributes()
941 * thus reset them as required.
942 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100944
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 mbedtls_free(exported);
946 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100947}
948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
950 psa_key_usage_t usage,
951 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100952{
Gilles Peskine2385f712021-02-14 01:34:21 +0100953 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100954
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 if (!check_key_attributes_sanity(key)) {
956 return 0;
957 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100958
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800960 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 } else if (PSA_ALG_IS_MAC(alg)) {
962 ok = exercise_mac_key(key, usage, alg);
963 } else if (PSA_ALG_IS_CIPHER(alg)) {
964 ok = exercise_cipher_key(key, usage, alg);
965 } else if (PSA_ALG_IS_AEAD(alg)) {
966 ok = exercise_aead_key(key, usage, alg);
967 } else if (PSA_ALG_IS_SIGN(alg)) {
968 ok = exercise_signature_key(key, usage, alg);
969 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
970 ok = exercise_asymmetric_encryption_key(key, usage, alg);
971 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
972 ok = exercise_key_derivation_key(key, usage, alg);
973 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
974 ok = exercise_raw_key_agreement_key(key, usage, alg);
975 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
976 ok = exercise_key_agreement_key(key, usage, alg);
977 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100978 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100980
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 ok = ok && exercise_export_key(key, usage);
982 ok = ok && exercise_export_public_key(key);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100983
Gilles Peskine2385f712021-02-14 01:34:21 +0100984exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100986}
987
Gilles Peskine449bd832023-01-11 14:50:10 +0100988psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
989 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100990{
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
992 if (PSA_ALG_IS_SIGN_HASH(alg)) {
993 if (PSA_ALG_SIGN_GET_HASH(alg)) {
994 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
995 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
996 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
997 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
998 }
999 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1000 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1001 PSA_KEY_USAGE_VERIFY_MESSAGE :
1002 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001003 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1006 PSA_KEY_USAGE_VERIFY_HASH :
1007 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1008 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1009 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1010 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1011 PSA_KEY_USAGE_ENCRYPT :
1012 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1013 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1014 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1015 return PSA_KEY_USAGE_DERIVE;
1016 } else {
1017 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001018 }
1019
1020}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001021
Gilles Peskine34955672024-02-12 14:19:24 +01001022int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1023{
1024 /* Reject algorithms that we know are not supported. Default to
1025 * attempting exercise, so that if an algorithm is missing from this
1026 * function, the result will be a test failure and not silently
1027 * omitting exercise. */
1028#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1029 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1030 return 0;
1031 }
1032#endif
1033#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1034 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1035 return 0;
1036 }
1037#endif
1038#if !defined(PSA_WANT_ALG_RSA_PSS)
1039 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1040 return 0;
1041 }
1042#endif
1043#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1044 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1045 return 0;
1046 }
1047#endif
1048#if !defined(PSA_WANT_ALG_ECDSA)
1049 if (PSA_ALG_IS_ECDSA(alg)) {
1050 return 0;
1051 }
1052#endif
1053#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1054 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1055 return 0;
1056 }
1057#endif
1058#if !defined(PSA_WANT_ALG_ECDH)
1059 if (PSA_ALG_IS_ECDH(alg)) {
1060 return 0;
1061 }
1062#endif
1063 (void) alg;
1064 return 1;
1065}
1066
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001067#if defined(MBEDTLS_PK_C)
1068int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1069 const mbedtls_pk_context *pk)
1070{
1071 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1072 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1073 int ok = 0;
1074
1075 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1076 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1077 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1078
1079 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1080 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1081 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1082
1083 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1084 const uint8_t *pk_public = NULL;
1085 size_t pk_public_length = 0;
1086
1087 switch (pk_type) {
1088#if defined(MBEDTLS_RSA_C)
1089 case MBEDTLS_PK_RSA:
1090 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1091 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1092 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1093 uint8_t *cursor = end;
1094 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1095 pk_public_buffer, &cursor));
1096 pk_public = cursor;
1097 pk_public_length = end - pk_public;
1098 break;
1099#endif
1100
1101#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1102 case MBEDTLS_PK_ECKEY:
1103 case MBEDTLS_PK_ECKEY_DH:
1104 case MBEDTLS_PK_ECDSA:
1105 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1106 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1107 pk_public = pk->pub_raw;
1108 pk_public_length = pk->pub_raw_len;
1109 break;
1110#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1111
1112#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1113 case MBEDTLS_PK_ECKEY:
1114 case MBEDTLS_PK_ECKEY_DH:
1115 case MBEDTLS_PK_ECDSA:
1116 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1117 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1118 TEST_EQUAL(mbedtls_ecp_write_public_key(
1119 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1120 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1121 pk_public = pk_public_buffer;
1122 break;
1123#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */
1124
1125#if defined(MBEDTLS_USE_PSA_CRYPTO)
1126 case MBEDTLS_PK_OPAQUE:
1127 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1128 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1129 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1130 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1131 PSA_ASSERT(psa_export_public_key(psa_key,
1132 pk_public_buffer,
1133 sizeof(pk_public_buffer),
1134 &pk_public_length));
1135 pk_public = pk_public_buffer;
1136 break;
1137#endif /* MBEDTLS_USE_PSA_CRYPTO */
1138
1139 default:
1140 TEST_FAIL("pk type not supported");
1141 }
1142
1143 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1144 size_t psa_public_length = 0;
1145 PSA_ASSERT(psa_export_public_key(psa_key,
1146 psa_public, sizeof(psa_public),
1147 &psa_public_length));
1148 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1149 psa_public, psa_public_length);
1150
1151 ok = 1;
1152
1153exit:
1154 psa_reset_key_attributes(&psa_attributes);
1155 psa_reset_key_attributes(&pk_attributes);
1156 return ok;
1157}
1158#endif /* MBEDTLS_PK_C */
1159
Gilles Peskine66e7b902021-02-12 23:40:58 +01001160#endif /* MBEDTLS_PSA_CRYPTO_C */