blob: c594cee9b6d25838569e6823cac16978e1aabaf4 [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
23#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010024static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
Gilles Peskinee78b0022021-02-13 00:41:11 +010025{
Gilles Peskine449bd832023-01-11 14:50:10 +010026 return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
27 PSA_KEY_LOCATION_LOCAL_STORAGE;
Gilles Peskinee78b0022021-02-13 00:41:11 +010028}
29#endif
30
Gilles Peskine449bd832023-01-11 14:50:10 +010031static int check_key_attributes_sanity(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +010032{
33 int ok = 0;
34 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
35 psa_key_lifetime_t lifetime;
36 mbedtls_svc_key_id_t id;
37 psa_key_type_t type;
Gilles Peskine6b362e62021-02-15 12:03:16 +010038 size_t bits;
Gilles Peskinee78b0022021-02-13 00:41:11 +010039
Gilles Peskine449bd832023-01-11 14:50:10 +010040 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
41 lifetime = psa_get_key_lifetime(&attributes);
42 id = psa_get_key_id(&attributes);
43 type = psa_get_key_type(&attributes);
44 bits = psa_get_key_bits(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +010045
46 /* Persistence */
Gilles Peskine449bd832023-01-11 14:50:10 +010047 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010048 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010049 (PSA_KEY_ID_VOLATILE_MIN <=
50 MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
51 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
52 PSA_KEY_ID_VOLATILE_MAX));
53 } else {
Gilles Peskinee78b0022021-02-13 00:41:11 +010054 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010055 (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
56 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
Gilles Peskinee78b0022021-02-13 00:41:11 +010057 }
58#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
59 /* randomly-generated 64-bit constant, should never appear in test data */
60 psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
Gilles Peskine449bd832023-01-11 14:50:10 +010061 psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number);
62 if (lifetime_is_dynamic_secure_element(lifetime)) {
Fredrik Hessecc207bc2021-09-28 21:06:08 +020063 /* Mbed TLS currently always exposes the slot number to
Gilles Peskinee78b0022021-02-13 00:41:11 +010064 * applications. This is not mandated by the PSA specification
65 * and may change in future versions. */
Gilles Peskine449bd832023-01-11 14:50:10 +010066 TEST_EQUAL(status, 0);
67 TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
68 } else {
69 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +010070 }
71#endif
72
73 /* Type and size */
Gilles Peskine449bd832023-01-11 14:50:10 +010074 TEST_ASSERT(type != 0);
75 TEST_ASSERT(bits != 0);
76 TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
77 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
78 TEST_ASSERT(bits % 8 == 0);
79 }
Gilles Peskinee78b0022021-02-13 00:41:11 +010080
81 /* MAX macros concerning specific key types */
Gilles Peskine449bd832023-01-11 14:50:10 +010082 if (PSA_KEY_TYPE_IS_ECC(type)) {
83 TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
84 } else if (PSA_KEY_TYPE_IS_RSA(type)) {
85 TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
86 }
87 TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
Gilles Peskinee78b0022021-02-13 00:41:11 +010088
89 ok = 1;
90
91exit:
92 /*
93 * Key attributes may have been returned by psa_get_key_attributes()
94 * thus reset them as required.
95 */
Gilles Peskine449bd832023-01-11 14:50:10 +010096 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +010097
Gilles Peskine449bd832023-01-11 14:50:10 +010098 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +010099}
100
Gilles Peskine449bd832023-01-11 14:50:10 +0100101static int exercise_mac_key(mbedtls_svc_key_id_t key,
102 psa_key_usage_t usage,
103 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100104{
105 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
106 const unsigned char input[] = "foo";
Gilles Peskine449bd832023-01-11 14:50:10 +0100107 unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
108 size_t mac_length = sizeof(mac);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100109
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100110 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
112 alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100113 }
114
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
116 PSA_ASSERT(psa_mac_sign_setup(&operation, key, alg));
117 PSA_ASSERT(psa_mac_update(&operation,
118 input, sizeof(input)));
119 PSA_ASSERT(psa_mac_sign_finish(&operation,
120 mac, sizeof(mac),
121 &mac_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100122 }
123
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100125 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 (usage & PSA_KEY_USAGE_SIGN_HASH ?
127 PSA_SUCCESS :
128 PSA_ERROR_INVALID_SIGNATURE);
129 PSA_ASSERT(psa_mac_verify_setup(&operation, key, alg));
130 PSA_ASSERT(psa_mac_update(&operation,
131 input, sizeof(input)));
132 TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
133 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100134 }
135
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100137
138exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 psa_mac_abort(&operation);
140 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100141}
142
Gilles Peskine449bd832023-01-11 14:50:10 +0100143static int exercise_cipher_key(mbedtls_svc_key_id_t key,
144 psa_key_usage_t usage,
145 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100146{
147 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
Gilles Peskine5eef11a2022-04-21 11:14:30 +0200149 size_t iv_length;
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100150 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
151 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100152 const unsigned char plaintext[16] = "Hello, world...";
153 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 size_t ciphertext_length = sizeof(ciphertext);
155 unsigned char decrypted[sizeof(ciphertext)];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100156 size_t part_length;
157
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
159 key_type = psa_get_key_type(&attributes);
160 iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100161
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 if (usage & PSA_KEY_USAGE_ENCRYPT) {
163 PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
164 if (iv_length != 0) {
165 PSA_ASSERT(psa_cipher_generate_iv(&operation,
166 iv, sizeof(iv),
167 &iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100168 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 PSA_ASSERT(psa_cipher_update(&operation,
170 plaintext, sizeof(plaintext),
171 ciphertext, sizeof(ciphertext),
172 &ciphertext_length));
173 PSA_ASSERT(psa_cipher_finish(&operation,
174 ciphertext + ciphertext_length,
175 sizeof(ciphertext) - ciphertext_length,
176 &part_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100177 ciphertext_length += part_length;
178 }
179
Gilles Peskine449bd832023-01-11 14:50:10 +0100180 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100181 psa_status_t status;
182 int maybe_invalid_padding = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
184 maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100185 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
187 if (iv_length != 0) {
188 PSA_ASSERT(psa_cipher_set_iv(&operation,
189 iv, iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100190 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 PSA_ASSERT(psa_cipher_update(&operation,
192 ciphertext, ciphertext_length,
193 decrypted, sizeof(decrypted),
194 &part_length));
195 status = psa_cipher_finish(&operation,
196 decrypted + part_length,
197 sizeof(decrypted) - part_length,
198 &part_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100199 /* For a stream cipher, all inputs are valid. For a block cipher,
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800200 * if the input is some arbitrary data rather than an actual
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 ciphertext, a padding error is likely. */
202 if (maybe_invalid_padding) {
203 TEST_ASSERT(status == PSA_SUCCESS ||
204 status == PSA_ERROR_INVALID_PADDING);
205 } else {
206 PSA_ASSERT(status);
207 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100208 }
209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100211
212exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 psa_cipher_abort(&operation);
214 psa_reset_key_attributes(&attributes);
215 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100216}
217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218static int exercise_aead_key(mbedtls_svc_key_id_t key,
219 psa_key_usage_t usage,
220 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100221{
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
Gilles Peskine7acb1982022-03-19 11:03:32 +0100223 size_t nonce_length;
224 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
225 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100226 unsigned char plaintext[16] = "Hello, world...";
227 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 size_t ciphertext_length = sizeof(ciphertext);
229 size_t plaintext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100230
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100231 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
233 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100234 }
235
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
237 key_type = psa_get_key_type(&attributes);
238 nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
Steven Cooremanaaec3412021-02-18 13:30:34 +0100239
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 if (usage & PSA_KEY_USAGE_ENCRYPT) {
241 PSA_ASSERT(psa_aead_encrypt(key, alg,
242 nonce, nonce_length,
243 NULL, 0,
244 plaintext, sizeof(plaintext),
245 ciphertext, sizeof(ciphertext),
246 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100247 }
248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100250 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 (usage & PSA_KEY_USAGE_ENCRYPT ?
252 PSA_SUCCESS :
253 PSA_ERROR_INVALID_SIGNATURE);
254 TEST_EQUAL(psa_aead_decrypt(key, alg,
255 nonce, nonce_length,
256 NULL, 0,
257 ciphertext, ciphertext_length,
258 plaintext, sizeof(plaintext),
259 &plaintext_length),
260 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100261 }
262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100264
265exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 psa_reset_key_attributes(&attributes);
267 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100268}
269
Gilles Peskine449bd832023-01-11 14:50:10 +0100270static int can_sign_or_verify_message(psa_key_usage_t usage,
271 psa_algorithm_t alg)
Gilles Peskined586b822022-03-19 11:15:41 +0100272{
273 /* Sign-the-unspecified-hash algorithms can only be used with
274 * {sign,verify}_hash, not with {sign,verify}_message. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100275 if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
276 return 0;
277 }
278 return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
279 PSA_KEY_USAGE_VERIFY_MESSAGE);
Gilles Peskined586b822022-03-19 11:15:41 +0100280}
281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282static int exercise_signature_key(mbedtls_svc_key_id_t key,
283 psa_key_usage_t usage,
284 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100285{
Gilles Peskine4781bd92024-02-09 17:32:45 +0100286 /* If the policy allows signing with any hash, just pick one. */
287 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
288 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
289 usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
290 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
291#if defined(KNOWN_SUPPORTED_HASH_ALG)
292 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
293 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
294#else
295 TEST_FAIL("No hash algorithm for hash-and-sign testing");
296#endif
297 }
298
oberon-skf7a824b2023-02-15 19:43:30 +0100299 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
300 PSA_ALG_IS_SIGN_HASH(alg)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200302 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
304 size_t signature_length = sizeof(signature);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200305
Janos Follath4c0b60e2021-06-14 12:34:30 +0100306 /* Some algorithms require the payload to have the size of
307 * the hash encoded in the algorithm. Use this input size
308 * even for algorithms that allow other input sizes. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 if (hash_alg != 0) {
310 payload_length = PSA_HASH_LENGTH(hash_alg);
311 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
314 PSA_ASSERT(psa_sign_hash(key, alg,
315 payload, payload_length,
316 signature, sizeof(signature),
317 &signature_length));
318 }
319
320 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
321 psa_status_t verify_status =
322 (usage & PSA_KEY_USAGE_SIGN_HASH ?
323 PSA_SUCCESS :
324 PSA_ERROR_INVALID_SIGNATURE);
325 TEST_EQUAL(psa_verify_hash(key, alg,
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200326 payload, payload_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 signature, signature_length),
328 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200329 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100330 }
331
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200333 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200335 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100337
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
339 PSA_ASSERT(psa_sign_message(key, alg,
340 message, message_length,
341 signature, sizeof(signature),
342 &signature_length));
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200343 }
344
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200346 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
348 PSA_SUCCESS :
349 PSA_ERROR_INVALID_SIGNATURE);
350 TEST_EQUAL(psa_verify_message(key, alg,
351 message, message_length,
352 signature, signature_length),
353 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200354 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100355 }
356
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100358
359exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100361}
362
Gilles Peskine449bd832023-01-11 14:50:10 +0100363static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
364 psa_key_usage_t usage,
365 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100366{
367 unsigned char plaintext[256] = "Hello, world...";
368 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100370 size_t plaintext_length = 16;
371
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 if (usage & PSA_KEY_USAGE_ENCRYPT) {
373 PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
374 plaintext, plaintext_length,
375 NULL, 0,
376 ciphertext, sizeof(ciphertext),
377 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100378 }
379
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100381 psa_status_t status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 psa_asymmetric_decrypt(key, alg,
383 ciphertext, ciphertext_length,
384 NULL, 0,
385 plaintext, sizeof(plaintext),
386 &plaintext_length);
387 TEST_ASSERT(status == PSA_SUCCESS ||
388 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
389 (status == PSA_ERROR_INVALID_ARGUMENT ||
390 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100391 }
392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100394
395exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100397}
398
399int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100401 mbedtls_svc_key_id_t key,
402 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 const unsigned char *input1, size_t input1_length,
404 const unsigned char *input2, size_t input2_length,
405 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100406{
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
408 if (PSA_ALG_IS_HKDF(alg)) {
409 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
410 PSA_KEY_DERIVATION_INPUT_SALT,
411 input1, input1_length));
412 PSA_ASSERT(psa_key_derivation_input_key(operation,
413 PSA_KEY_DERIVATION_INPUT_SECRET,
414 key));
415 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
416 PSA_KEY_DERIVATION_INPUT_INFO,
417 input2,
418 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530419 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
420 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
421 PSA_KEY_DERIVATION_INPUT_SALT,
422 input1, input1_length));
423 PSA_ASSERT(psa_key_derivation_input_key(operation,
424 PSA_KEY_DERIVATION_INPUT_SECRET,
425 key));
426 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
427 PSA_ASSERT(psa_key_derivation_input_key(operation,
428 PSA_KEY_DERIVATION_INPUT_SECRET,
429 key));
430 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
431 PSA_KEY_DERIVATION_INPUT_INFO,
432 input2,
433 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100434 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
435 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
436 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
437 PSA_KEY_DERIVATION_INPUT_SEED,
438 input1, input1_length));
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_LABEL,
444 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530445 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530446 PSA_ASSERT(psa_key_derivation_input_integer(operation,
447 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530448 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530449 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
450 PSA_KEY_DERIVATION_INPUT_SALT,
451 input2,
452 input2_length));
453 PSA_ASSERT(psa_key_derivation_input_key(operation,
454 PSA_KEY_DERIVATION_INPUT_PASSWORD,
455 key));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530456 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
457 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
458 PSA_KEY_DERIVATION_INPUT_SECRET,
459 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100461 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100462 }
463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 if (capacity != SIZE_MAX) {
465 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
466 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100467
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100469
470exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100472}
473
474
Gilles Peskine449bd832023-01-11 14:50:10 +0100475static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
476 psa_key_usage_t usage,
477 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100478{
479 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
480 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100482 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100484 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100486
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 if (usage & PSA_KEY_USAGE_DERIVE) {
488 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
489 input1, input1_length,
490 input2, input2_length,
491 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100492 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100494
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
496 output,
497 capacity));
498 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100499 }
500
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100502
503exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100505}
506
507/* We need two keys to exercise key agreement. Exercise the
508 * private key against its own public key. */
509psa_status_t mbedtls_test_psa_key_agreement_with_self(
510 psa_key_derivation_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100512{
513 psa_key_type_t private_key_type;
514 psa_key_type_t public_key_type;
515 size_t key_bits;
516 uint8_t *public_key = NULL;
517 size_t public_key_length;
518 /* Return GENERIC_ERROR if something other than the final call to
519 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
520 * but it's good enough: callers will report it as a failed test anyway. */
521 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
522 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
523
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
525 private_key_type = psa_get_key_type(&attributes);
526 key_bits = psa_get_key_bits(&attributes);
527 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
528 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100529 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
531 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100532
533 status = psa_key_derivation_key_agreement(
534 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100536exit:
537 /*
538 * Key attributes may have been returned by psa_get_key_attributes()
539 * thus reset them as required.
540 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100542
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 mbedtls_free(public_key);
544 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100545}
546
547/* We need two keys to exercise key agreement. Exercise the
548 * private key against its own public key. */
549psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
550 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100552{
553 psa_key_type_t private_key_type;
554 psa_key_type_t public_key_type;
555 size_t key_bits;
556 uint8_t *public_key = NULL;
557 size_t public_key_length;
558 uint8_t output[1024];
559 size_t output_length;
560 /* Return GENERIC_ERROR if something other than the final call to
561 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
562 * but it's good enough: callers will report it as a failed test anyway. */
563 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
564 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
565
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
567 private_key_type = psa_get_key_type(&attributes);
568 key_bits = psa_get_key_bits(&attributes);
569 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
570 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100571 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 PSA_ASSERT(psa_export_public_key(key,
573 public_key, public_key_length,
574 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100575
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 status = psa_raw_key_agreement(alg, key,
577 public_key, public_key_length,
578 output, sizeof(output), &output_length);
579 if (status == PSA_SUCCESS) {
580 TEST_ASSERT(output_length <=
581 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
582 key_bits));
583 TEST_ASSERT(output_length <=
584 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100585 }
586
Gilles Peskinee78b0022021-02-13 00:41:11 +0100587exit:
588 /*
589 * Key attributes may have been returned by psa_get_key_attributes()
590 * thus reset them as required.
591 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100592 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100593
Gilles Peskine449bd832023-01-11 14:50:10 +0100594 mbedtls_free(public_key);
595 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100596}
597
Gilles Peskine449bd832023-01-11 14:50:10 +0100598static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
599 psa_key_usage_t usage,
600 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100601{
602 int ok = 0;
603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100605 /* We need two keys to exercise key agreement. Exercise the
606 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100608 }
609 ok = 1;
610
611exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100613}
614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
616 psa_key_usage_t usage,
617 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100618{
619 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200620 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100621 unsigned char output[1];
622 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200624 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100627 /* We need two keys to exercise key agreement. Exercise the
628 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
630 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
631 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
632 PSA_ASSERT(psa_key_derivation_input_bytes(
633 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
634 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100635 }
636
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
638 PSA_ASSERT(psa_key_derivation_input_bytes(
639 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
640 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200641 }
642
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200643 /* For HKDF_EXPAND input secret may fail as secret size may not match
644 to expected PRK size. In practice it means that key bits must match
645 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200647 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
649 size_t key_bits = psa_get_key_bits(&attributes);
650 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200651
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200653 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200655 }
656
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
658 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200659
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 if (expected_key_agreement_status != PSA_SUCCESS) {
661 return 1;
662 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100663
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 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_LABEL,
668 input, sizeof(input)));
669 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
670 PSA_ASSERT(psa_key_derivation_input_bytes(
671 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
672 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100673 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
675 output,
676 sizeof(output)));
677 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100678 }
679 ok = 1;
680
681exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100683}
684
685int mbedtls_test_psa_exported_key_sanity_check(
686 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100688{
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100690
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
692 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
693 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100694
Ronald Cron64df7382021-07-06 09:23:06 +0200695#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
697 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100698 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100699 size_t len;
700 /* RSAPrivateKey ::= SEQUENCE {
701 * version INTEGER, -- must be 0
702 * modulus INTEGER, -- n
703 * publicExponent INTEGER, -- e
704 * privateExponent INTEGER, -- d
705 * prime1 INTEGER, -- p
706 * prime2 INTEGER, -- q
707 * exponent1 INTEGER, -- d mod (p-1)
708 * exponent2 INTEGER, -- d mod (q-1)
709 * coefficient INTEGER, -- (inverse of q) mod p
710 * }
711 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
713 MBEDTLS_ASN1_SEQUENCE |
714 MBEDTLS_ASN1_CONSTRUCTED), 0);
715 TEST_EQUAL(len, end - p);
716 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100717 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 }
719 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100720 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 }
722 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100723 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100725 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100727 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100729 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100731 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 }
733 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100734 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 }
736 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100737 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 }
739 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100740 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 }
742 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100743 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 }
745 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
748 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200749#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100752 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100754
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
756 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100757
Ronald Cron64df7382021-07-06 09:23:06 +0200758#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
760 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100761 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100762 size_t len;
763 /* RSAPublicKey ::= SEQUENCE {
764 * modulus INTEGER, -- n
765 * publicExponent INTEGER } -- e
766 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
768 MBEDTLS_ASN1_SEQUENCE |
769 MBEDTLS_ASN1_CONSTRUCTED),
770 0);
771 TEST_EQUAL(len, end - p);
772 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100773 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 }
775 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100776 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 }
778 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100779
780
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 TEST_ASSERT(exported_length <=
782 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
783 TEST_ASSERT(exported_length <=
784 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
785 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200786#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100787
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100789
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 TEST_ASSERT(exported_length <=
791 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
792 TEST_ASSERT(exported_length <=
793 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100794
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100796 /* The representation of an ECC Montgomery public key is
797 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100799 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100800 /* The representation of an ECC Edwards public key is
801 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100802 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100804 /* The representation of an ECC Weierstrass public key is:
805 * - The byte 0x04;
806 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
807 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
808 * - where m is the bit size associated with the curve.
809 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
811 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100812 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100813 } else
814 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200815 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100816 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
817 TEST_ASSERT(exported_length <=
818 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200819 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100820 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100821 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100822 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100823
Gilles Peskinecc9db302021-02-14 01:29:52 +0100824#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100826 /* Check the parity bits. */
827 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100829 unsigned bit_count = 0;
830 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100831 for (m = 1; m <= 0x100; m <<= 1) {
832 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100833 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100835 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100837 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100838 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100839#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100840
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100842
843exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100845}
846
Gilles Peskine449bd832023-01-11 14:50:10 +0100847static int exercise_export_key(mbedtls_svc_key_id_t key,
848 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100849{
850 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
851 uint8_t *exported = NULL;
852 size_t exported_size = 0;
853 size_t exported_length = 0;
854 int ok = 0;
855
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100857
858 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 psa_get_key_type(&attributes),
860 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100861 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
864 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
865 TEST_EQUAL(psa_export_key(key, exported,
866 exported_size, &exported_length),
867 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100868 ok = 1;
869 goto exit;
870 }
871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 PSA_ASSERT(psa_export_key(key,
873 exported, exported_size,
874 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100875 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
877 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100878
879exit:
880 /*
881 * Key attributes may have been returned by psa_get_key_attributes()
882 * thus reset them as required.
883 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100885
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 mbedtls_free(exported);
887 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100888}
889
Gilles Peskine449bd832023-01-11 14:50:10 +0100890static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100891{
892 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
893 psa_key_type_t public_type;
894 uint8_t *exported = NULL;
895 size_t exported_size = 0;
896 size_t exported_length = 0;
897 int ok = 0;
898
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
900 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100901 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 psa_get_key_type(&attributes),
903 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100904 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 TEST_EQUAL(psa_export_public_key(key, exported,
907 exported_size, &exported_length),
908 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100909 ok = 1;
910 goto exit;
911 }
912
913 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 psa_get_key_type(&attributes));
915 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
916 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100917 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 PSA_ASSERT(psa_export_public_key(key,
920 exported, exported_size,
921 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100922 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 public_type, psa_get_key_bits(&attributes),
924 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100925
926exit:
927 /*
928 * Key attributes may have been returned by psa_get_key_attributes()
929 * thus reset them as required.
930 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100932
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 mbedtls_free(exported);
934 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100935}
936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
938 psa_key_usage_t usage,
939 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100940{
Gilles Peskine2385f712021-02-14 01:34:21 +0100941 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100942
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 if (!check_key_attributes_sanity(key)) {
944 return 0;
945 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100946
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800948 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 } else if (PSA_ALG_IS_MAC(alg)) {
950 ok = exercise_mac_key(key, usage, alg);
951 } else if (PSA_ALG_IS_CIPHER(alg)) {
952 ok = exercise_cipher_key(key, usage, alg);
953 } else if (PSA_ALG_IS_AEAD(alg)) {
954 ok = exercise_aead_key(key, usage, alg);
955 } else if (PSA_ALG_IS_SIGN(alg)) {
956 ok = exercise_signature_key(key, usage, alg);
957 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
958 ok = exercise_asymmetric_encryption_key(key, usage, alg);
959 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
960 ok = exercise_key_derivation_key(key, usage, alg);
961 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
962 ok = exercise_raw_key_agreement_key(key, usage, alg);
963 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
964 ok = exercise_key_agreement_key(key, usage, alg);
965 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100966 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100968
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 ok = ok && exercise_export_key(key, usage);
970 ok = ok && exercise_export_public_key(key);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100971
Gilles Peskine2385f712021-02-14 01:34:21 +0100972exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100974}
975
Gilles Peskine449bd832023-01-11 14:50:10 +0100976psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
977 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100978{
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
980 if (PSA_ALG_IS_SIGN_HASH(alg)) {
981 if (PSA_ALG_SIGN_GET_HASH(alg)) {
982 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
983 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
984 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
985 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
986 }
987 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
988 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
989 PSA_KEY_USAGE_VERIFY_MESSAGE :
990 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +0200991 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200992
Gilles Peskine449bd832023-01-11 14:50:10 +0100993 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
994 PSA_KEY_USAGE_VERIFY_HASH :
995 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
996 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
997 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
998 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
999 PSA_KEY_USAGE_ENCRYPT :
1000 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1001 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1002 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1003 return PSA_KEY_USAGE_DERIVE;
1004 } else {
1005 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001006 }
1007
1008}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001009
1010#endif /* MBEDTLS_PSA_CRYPTO_C */