blob: 560b7113d12a4e064a831385597c2ac3d8aa2fd8 [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{
oberon-skf7a824b2023-02-15 19:43:30 +0100286 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
287 PSA_ALG_IS_SIGN_HASH(alg)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200289 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
291 size_t signature_length = sizeof(signature);
292 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200293
294 /* If the policy allows signing with any hash, just pick one. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH) {
Przemek Stekiel8258ea72022-10-19 12:17:19 +0200296 #if defined(KNOWN_SUPPORTED_HASH_ALG)
297 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200298 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
299 #else
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100300 TEST_FAIL("No hash algorithm for hash-and-sign testing");
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200301 #endif
302 }
303
Janos Follath4c0b60e2021-06-14 12:34:30 +0100304 /* Some algorithms require the payload to have the size of
305 * the hash encoded in the algorithm. Use this input size
306 * even for algorithms that allow other input sizes. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 if (hash_alg != 0) {
308 payload_length = PSA_HASH_LENGTH(hash_alg);
309 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100310
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
312 PSA_ASSERT(psa_sign_hash(key, alg,
313 payload, payload_length,
314 signature, sizeof(signature),
315 &signature_length));
316 }
317
318 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
319 psa_status_t verify_status =
320 (usage & PSA_KEY_USAGE_SIGN_HASH ?
321 PSA_SUCCESS :
322 PSA_ERROR_INVALID_SIGNATURE);
323 TEST_EQUAL(psa_verify_hash(key, alg,
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200324 payload, payload_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 signature, signature_length),
326 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200327 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100328 }
329
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200331 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200333 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
337 PSA_ASSERT(psa_sign_message(key, alg,
338 message, message_length,
339 signature, sizeof(signature),
340 &signature_length));
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200341 }
342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200344 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
346 PSA_SUCCESS :
347 PSA_ERROR_INVALID_SIGNATURE);
348 TEST_EQUAL(psa_verify_message(key, alg,
349 message, message_length,
350 signature, signature_length),
351 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200352 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100353 }
354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100356
357exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100359}
360
Gilles Peskine449bd832023-01-11 14:50:10 +0100361static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
362 psa_key_usage_t usage,
363 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100364{
365 unsigned char plaintext[256] = "Hello, world...";
366 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100368 size_t plaintext_length = 16;
369
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 if (usage & PSA_KEY_USAGE_ENCRYPT) {
371 PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
372 plaintext, plaintext_length,
373 NULL, 0,
374 ciphertext, sizeof(ciphertext),
375 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100376 }
377
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100379 psa_status_t status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 psa_asymmetric_decrypt(key, alg,
381 ciphertext, ciphertext_length,
382 NULL, 0,
383 plaintext, sizeof(plaintext),
384 &plaintext_length);
385 TEST_ASSERT(status == PSA_SUCCESS ||
386 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
387 (status == PSA_ERROR_INVALID_ARGUMENT ||
388 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100389 }
390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100392
393exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100395}
396
397int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100399 mbedtls_svc_key_id_t key,
400 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 const unsigned char *input1, size_t input1_length,
402 const unsigned char *input2, size_t input2_length,
403 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100404{
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
406 if (PSA_ALG_IS_HKDF(alg)) {
407 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
408 PSA_KEY_DERIVATION_INPUT_SALT,
409 input1, input1_length));
410 PSA_ASSERT(psa_key_derivation_input_key(operation,
411 PSA_KEY_DERIVATION_INPUT_SECRET,
412 key));
413 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
414 PSA_KEY_DERIVATION_INPUT_INFO,
415 input2,
416 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530417 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
418 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
419 PSA_KEY_DERIVATION_INPUT_SALT,
420 input1, input1_length));
421 PSA_ASSERT(psa_key_derivation_input_key(operation,
422 PSA_KEY_DERIVATION_INPUT_SECRET,
423 key));
424 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
425 PSA_ASSERT(psa_key_derivation_input_key(operation,
426 PSA_KEY_DERIVATION_INPUT_SECRET,
427 key));
428 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
429 PSA_KEY_DERIVATION_INPUT_INFO,
430 input2,
431 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
433 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
434 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
435 PSA_KEY_DERIVATION_INPUT_SEED,
436 input1, input1_length));
437 PSA_ASSERT(psa_key_derivation_input_key(operation,
438 PSA_KEY_DERIVATION_INPUT_SECRET,
439 key));
440 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
441 PSA_KEY_DERIVATION_INPUT_LABEL,
442 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530443 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530444 PSA_ASSERT(psa_key_derivation_input_integer(operation,
445 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530446 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530447 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
448 PSA_KEY_DERIVATION_INPUT_SALT,
449 input2,
450 input2_length));
451 PSA_ASSERT(psa_key_derivation_input_key(operation,
452 PSA_KEY_DERIVATION_INPUT_PASSWORD,
453 key));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530454 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
455 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
456 PSA_KEY_DERIVATION_INPUT_SECRET,
457 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100459 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100460 }
461
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 if (capacity != SIZE_MAX) {
463 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
464 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100467
468exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100470}
471
472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
474 psa_key_usage_t usage,
475 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100476{
477 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
478 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100480 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100482 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 if (usage & PSA_KEY_USAGE_DERIVE) {
486 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
487 input1, input1_length,
488 input2, input2_length,
489 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100490 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100492
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
494 output,
495 capacity));
496 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100497 }
498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100500
501exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100503}
504
505/* We need two keys to exercise key agreement. Exercise the
506 * private key against its own public key. */
507psa_status_t mbedtls_test_psa_key_agreement_with_self(
508 psa_key_derivation_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100510{
511 psa_key_type_t private_key_type;
512 psa_key_type_t public_key_type;
513 size_t key_bits;
514 uint8_t *public_key = NULL;
515 size_t public_key_length;
516 /* Return GENERIC_ERROR if something other than the final call to
517 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
518 * but it's good enough: callers will report it as a failed test anyway. */
519 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
520 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
521
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
523 private_key_type = psa_get_key_type(&attributes);
524 key_bits = psa_get_key_bits(&attributes);
525 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
526 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100527 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100528 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
529 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100530
531 status = psa_key_derivation_key_agreement(
532 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100534exit:
535 /*
536 * Key attributes may have been returned by psa_get_key_attributes()
537 * thus reset them as required.
538 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100540
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 mbedtls_free(public_key);
542 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100543}
544
545/* We need two keys to exercise key agreement. Exercise the
546 * private key against its own public key. */
547psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
548 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100550{
551 psa_key_type_t private_key_type;
552 psa_key_type_t public_key_type;
553 size_t key_bits;
554 uint8_t *public_key = NULL;
555 size_t public_key_length;
556 uint8_t output[1024];
557 size_t output_length;
558 /* Return GENERIC_ERROR if something other than the final call to
559 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
560 * but it's good enough: callers will report it as a failed test anyway. */
561 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
562 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
563
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
565 private_key_type = psa_get_key_type(&attributes);
566 key_bits = psa_get_key_bits(&attributes);
567 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
568 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100569 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100570 PSA_ASSERT(psa_export_public_key(key,
571 public_key, public_key_length,
572 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100573
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 status = psa_raw_key_agreement(alg, key,
575 public_key, public_key_length,
576 output, sizeof(output), &output_length);
577 if (status == PSA_SUCCESS) {
578 TEST_ASSERT(output_length <=
579 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
580 key_bits));
581 TEST_ASSERT(output_length <=
582 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100583 }
584
Gilles Peskinee78b0022021-02-13 00:41:11 +0100585exit:
586 /*
587 * Key attributes may have been returned by psa_get_key_attributes()
588 * thus reset them as required.
589 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100590 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100591
Gilles Peskine449bd832023-01-11 14:50:10 +0100592 mbedtls_free(public_key);
593 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100594}
595
Gilles Peskine449bd832023-01-11 14:50:10 +0100596static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
597 psa_key_usage_t usage,
598 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100599{
600 int ok = 0;
601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100603 /* We need two keys to exercise key agreement. Exercise the
604 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100606 }
607 ok = 1;
608
609exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100611}
612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
614 psa_key_usage_t usage,
615 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100616{
617 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200618 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100619 unsigned char output[1];
620 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200622 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100625 /* We need two keys to exercise key agreement. Exercise the
626 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
628 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
629 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
630 PSA_ASSERT(psa_key_derivation_input_bytes(
631 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
632 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100633 }
634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
636 PSA_ASSERT(psa_key_derivation_input_bytes(
637 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
638 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200639 }
640
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200641 /* For HKDF_EXPAND input secret may fail as secret size may not match
642 to expected PRK size. In practice it means that key bits must match
643 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200645 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
647 size_t key_bits = psa_get_key_bits(&attributes);
648 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200649
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200651 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200653 }
654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
656 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200657
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 if (expected_key_agreement_status != PSA_SUCCESS) {
659 return 1;
660 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
663 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
664 PSA_ASSERT(psa_key_derivation_input_bytes(
665 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
666 input, sizeof(input)));
667 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
668 PSA_ASSERT(psa_key_derivation_input_bytes(
669 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
670 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100671 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
673 output,
674 sizeof(output)));
675 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100676 }
677 ok = 1;
678
679exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100681}
682
683int mbedtls_test_psa_exported_key_sanity_check(
684 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100686{
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100688
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
690 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
691 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100692
Ronald Cron64df7382021-07-06 09:23:06 +0200693#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
695 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100696 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100697 size_t len;
698 /* RSAPrivateKey ::= SEQUENCE {
699 * version INTEGER, -- must be 0
700 * modulus INTEGER, -- n
701 * publicExponent INTEGER, -- e
702 * privateExponent INTEGER, -- d
703 * prime1 INTEGER, -- p
704 * prime2 INTEGER, -- q
705 * exponent1 INTEGER, -- d mod (p-1)
706 * exponent2 INTEGER, -- d mod (q-1)
707 * coefficient INTEGER, -- (inverse of q) mod p
708 * }
709 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
711 MBEDTLS_ASN1_SEQUENCE |
712 MBEDTLS_ASN1_CONSTRUCTED), 0);
713 TEST_EQUAL(len, end - p);
714 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100715 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 }
717 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100718 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 }
720 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100721 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100723 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100725 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100727 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
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 / 2, bits / 2 + 1, 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, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100735 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 }
737 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100738 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 }
740 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100741 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 }
743 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100744
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
746 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200747#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100750 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100752
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
754 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100755
Ronald Cron64df7382021-07-06 09:23:06 +0200756#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
758 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100759 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100760 size_t len;
761 /* RSAPublicKey ::= SEQUENCE {
762 * modulus INTEGER, -- n
763 * publicExponent INTEGER } -- e
764 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
766 MBEDTLS_ASN1_SEQUENCE |
767 MBEDTLS_ASN1_CONSTRUCTED),
768 0);
769 TEST_EQUAL(len, end - p);
770 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100771 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 }
773 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100774 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 }
776 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100777
778
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 TEST_ASSERT(exported_length <=
780 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
781 TEST_ASSERT(exported_length <=
782 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
783 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200784#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100785
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100787
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 TEST_ASSERT(exported_length <=
789 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
790 TEST_ASSERT(exported_length <=
791 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100792
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100794 /* The representation of an ECC Montgomery public key is
795 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100797 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100798 /* The representation of an ECC Edwards public key is
799 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100800 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100802 /* The representation of an ECC Weierstrass public key is:
803 * - The byte 0x04;
804 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
805 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
806 * - where m is the bit size associated with the curve.
807 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
809 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100810 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100811 } else
812 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200813 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100814 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
815 TEST_ASSERT(exported_length <=
816 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200817 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100818 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100819 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100820 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100821
Gilles Peskinecc9db302021-02-14 01:29:52 +0100822#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100824 /* Check the parity bits. */
825 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100827 unsigned bit_count = 0;
828 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 for (m = 1; m <= 0x100; m <<= 1) {
830 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100831 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100833 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100835 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100836 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100837#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100838
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100840
841exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100843}
844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845static int exercise_export_key(mbedtls_svc_key_id_t key,
846 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100847{
848 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
849 uint8_t *exported = NULL;
850 size_t exported_size = 0;
851 size_t exported_length = 0;
852 int ok = 0;
853
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100855
856 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 psa_get_key_type(&attributes),
858 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100859 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100860
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
862 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
863 TEST_EQUAL(psa_export_key(key, exported,
864 exported_size, &exported_length),
865 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100866 ok = 1;
867 goto exit;
868 }
869
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 PSA_ASSERT(psa_export_key(key,
871 exported, exported_size,
872 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100873 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
875 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100876
877exit:
878 /*
879 * Key attributes may have been returned by psa_get_key_attributes()
880 * thus reset them as required.
881 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 mbedtls_free(exported);
885 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100886}
887
Gilles Peskine449bd832023-01-11 14:50:10 +0100888static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100889{
890 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
891 psa_key_type_t public_type;
892 uint8_t *exported = NULL;
893 size_t exported_size = 0;
894 size_t exported_length = 0;
895 int ok = 0;
896
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
898 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100899 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 psa_get_key_type(&attributes),
901 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100902 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 TEST_EQUAL(psa_export_public_key(key, exported,
905 exported_size, &exported_length),
906 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100907 ok = 1;
908 goto exit;
909 }
910
911 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 psa_get_key_type(&attributes));
913 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
914 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100915 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100916
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 PSA_ASSERT(psa_export_public_key(key,
918 exported, exported_size,
919 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100920 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 public_type, psa_get_key_bits(&attributes),
922 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100923
924exit:
925 /*
926 * Key attributes may have been returned by psa_get_key_attributes()
927 * thus reset them as required.
928 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100930
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 mbedtls_free(exported);
932 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100933}
934
Gilles Peskine449bd832023-01-11 14:50:10 +0100935int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
936 psa_key_usage_t usage,
937 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100938{
Gilles Peskine2385f712021-02-14 01:34:21 +0100939 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100940
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 if (!check_key_attributes_sanity(key)) {
942 return 0;
943 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100944
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800946 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 } else if (PSA_ALG_IS_MAC(alg)) {
948 ok = exercise_mac_key(key, usage, alg);
949 } else if (PSA_ALG_IS_CIPHER(alg)) {
950 ok = exercise_cipher_key(key, usage, alg);
951 } else if (PSA_ALG_IS_AEAD(alg)) {
952 ok = exercise_aead_key(key, usage, alg);
953 } else if (PSA_ALG_IS_SIGN(alg)) {
954 ok = exercise_signature_key(key, usage, alg);
955 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
956 ok = exercise_asymmetric_encryption_key(key, usage, alg);
957 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
958 ok = exercise_key_derivation_key(key, usage, alg);
959 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
960 ok = exercise_raw_key_agreement_key(key, usage, alg);
961 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
962 ok = exercise_key_agreement_key(key, usage, alg);
963 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100964 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100966
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 ok = ok && exercise_export_key(key, usage);
968 ok = ok && exercise_export_public_key(key);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100969
Gilles Peskine2385f712021-02-14 01:34:21 +0100970exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100972}
973
Gilles Peskine449bd832023-01-11 14:50:10 +0100974psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
975 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100976{
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
978 if (PSA_ALG_IS_SIGN_HASH(alg)) {
979 if (PSA_ALG_SIGN_GET_HASH(alg)) {
980 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
981 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
982 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
983 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
984 }
985 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
986 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
987 PSA_KEY_USAGE_VERIFY_MESSAGE :
988 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +0200989 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
992 PSA_KEY_USAGE_VERIFY_HASH :
993 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
994 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
995 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
996 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
997 PSA_KEY_USAGE_ENCRYPT :
998 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
999 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1000 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1001 return PSA_KEY_USAGE_DERIVE;
1002 } else {
1003 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001004 }
1005
1006}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001007
1008#endif /* MBEDTLS_PSA_CRYPTO_C */