blob: f8b36e1faaedd34531568843a0bdb6c9498de5e3 [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));
417 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
418 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
419 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
420 PSA_KEY_DERIVATION_INPUT_SEED,
421 input1, input1_length));
422 PSA_ASSERT(psa_key_derivation_input_key(operation,
423 PSA_KEY_DERIVATION_INPUT_SECRET,
424 key));
425 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
426 PSA_KEY_DERIVATION_INPUT_LABEL,
427 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530428 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530429 PSA_ASSERT(psa_key_derivation_input_integer(operation,
430 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530431 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530432 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
433 PSA_KEY_DERIVATION_INPUT_SALT,
434 input2,
435 input2_length));
436 PSA_ASSERT(psa_key_derivation_input_key(operation,
437 PSA_KEY_DERIVATION_INPUT_PASSWORD,
438 key));
Gilles Peskine449bd832023-01-11 14:50:10 +0100439 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100440 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100441 }
442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 if (capacity != SIZE_MAX) {
444 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
445 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100446
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100448
449exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100451}
452
453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
455 psa_key_usage_t usage,
456 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100457{
458 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
459 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100461 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100463 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 if (usage & PSA_KEY_USAGE_DERIVE) {
467 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
468 input1, input1_length,
469 input2, input2_length,
470 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100471 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
475 output,
476 capacity));
477 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100478 }
479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100481
482exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100484}
485
486/* We need two keys to exercise key agreement. Exercise the
487 * private key against its own public key. */
488psa_status_t mbedtls_test_psa_key_agreement_with_self(
489 psa_key_derivation_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100491{
492 psa_key_type_t private_key_type;
493 psa_key_type_t public_key_type;
494 size_t key_bits;
495 uint8_t *public_key = NULL;
496 size_t public_key_length;
497 /* Return GENERIC_ERROR if something other than the final call to
498 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
499 * but it's good enough: callers will report it as a failed test anyway. */
500 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
501 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
504 private_key_type = psa_get_key_type(&attributes);
505 key_bits = psa_get_key_bits(&attributes);
506 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
507 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100508 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
510 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100511
512 status = psa_key_derivation_key_agreement(
513 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100515exit:
516 /*
517 * Key attributes may have been returned by psa_get_key_attributes()
518 * thus reset them as required.
519 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100520 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100521
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 mbedtls_free(public_key);
523 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100524}
525
526/* We need two keys to exercise key agreement. Exercise the
527 * private key against its own public key. */
528psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
529 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100531{
532 psa_key_type_t private_key_type;
533 psa_key_type_t public_key_type;
534 size_t key_bits;
535 uint8_t *public_key = NULL;
536 size_t public_key_length;
537 uint8_t output[1024];
538 size_t output_length;
539 /* Return GENERIC_ERROR if something other than the final call to
540 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
541 * but it's good enough: callers will report it as a failed test anyway. */
542 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
543 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
546 private_key_type = psa_get_key_type(&attributes);
547 key_bits = psa_get_key_bits(&attributes);
548 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
549 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100550 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 PSA_ASSERT(psa_export_public_key(key,
552 public_key, public_key_length,
553 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 status = psa_raw_key_agreement(alg, key,
556 public_key, public_key_length,
557 output, sizeof(output), &output_length);
558 if (status == PSA_SUCCESS) {
559 TEST_ASSERT(output_length <=
560 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
561 key_bits));
562 TEST_ASSERT(output_length <=
563 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100564 }
565
Gilles Peskinee78b0022021-02-13 00:41:11 +0100566exit:
567 /*
568 * Key attributes may have been returned by psa_get_key_attributes()
569 * thus reset them as required.
570 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100572
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 mbedtls_free(public_key);
574 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100575}
576
Gilles Peskine449bd832023-01-11 14:50:10 +0100577static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
578 psa_key_usage_t usage,
579 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100580{
581 int ok = 0;
582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100584 /* We need two keys to exercise key agreement. Exercise the
585 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100587 }
588 ok = 1;
589
590exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100591 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100592}
593
Gilles Peskine449bd832023-01-11 14:50:10 +0100594static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
595 psa_key_usage_t usage,
596 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100597{
598 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200599 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100600 unsigned char output[1];
601 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200603 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100606 /* We need two keys to exercise key agreement. Exercise the
607 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
609 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
610 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
611 PSA_ASSERT(psa_key_derivation_input_bytes(
612 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
613 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100614 }
615
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
617 PSA_ASSERT(psa_key_derivation_input_bytes(
618 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
619 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200620 }
621
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200622 /* For HKDF_EXPAND input secret may fail as secret size may not match
623 to expected PRK size. In practice it means that key bits must match
624 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200626 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
628 size_t key_bits = psa_get_key_bits(&attributes);
629 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200632 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200634 }
635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
637 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 if (expected_key_agreement_status != PSA_SUCCESS) {
640 return 1;
641 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100642
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
644 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
645 PSA_ASSERT(psa_key_derivation_input_bytes(
646 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
647 input, sizeof(input)));
648 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
649 PSA_ASSERT(psa_key_derivation_input_bytes(
650 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
651 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100652 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
654 output,
655 sizeof(output)));
656 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100657 }
658 ok = 1;
659
660exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100662}
663
664int mbedtls_test_psa_exported_key_sanity_check(
665 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100667{
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100669
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
671 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
672 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100673
Ronald Cron64df7382021-07-06 09:23:06 +0200674#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
676 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100677 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100678 size_t len;
679 /* RSAPrivateKey ::= SEQUENCE {
680 * version INTEGER, -- must be 0
681 * modulus INTEGER, -- n
682 * publicExponent INTEGER, -- e
683 * privateExponent INTEGER, -- d
684 * prime1 INTEGER, -- p
685 * prime2 INTEGER, -- q
686 * exponent1 INTEGER, -- d mod (p-1)
687 * exponent2 INTEGER, -- d mod (q-1)
688 * coefficient INTEGER, -- (inverse of q) mod p
689 * }
690 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
692 MBEDTLS_ASN1_SEQUENCE |
693 MBEDTLS_ASN1_CONSTRUCTED), 0);
694 TEST_EQUAL(len, end - p);
695 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100696 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 }
698 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100699 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 }
701 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100702 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100704 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100706 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100708 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100710 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 }
712 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100713 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 }
715 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100716 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 }
718 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100719 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 }
721 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100722 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 }
724 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100725
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
727 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200728#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100731 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100733
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
735 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100736
Ronald Cron64df7382021-07-06 09:23:06 +0200737#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
739 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100740 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100741 size_t len;
742 /* RSAPublicKey ::= SEQUENCE {
743 * modulus INTEGER, -- n
744 * publicExponent INTEGER } -- e
745 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
747 MBEDTLS_ASN1_SEQUENCE |
748 MBEDTLS_ASN1_CONSTRUCTED),
749 0);
750 TEST_EQUAL(len, end - p);
751 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100752 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 }
754 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100755 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 }
757 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100758
759
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 TEST_ASSERT(exported_length <=
761 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
762 TEST_ASSERT(exported_length <=
763 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
764 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200765#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 TEST_ASSERT(exported_length <=
770 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
771 TEST_ASSERT(exported_length <=
772 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100773
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100775 /* The representation of an ECC Montgomery public key is
776 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100778 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100779 /* The representation of an ECC Edwards public key is
780 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100781 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100783 /* The representation of an ECC Weierstrass public key is:
784 * - The byte 0x04;
785 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
786 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
787 * - where m is the bit size associated with the curve.
788 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
790 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100791 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100792 } else
793 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200794 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100795 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
796 TEST_ASSERT(exported_length <=
797 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200798 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100799 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100800 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100801 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100802
Gilles Peskinecc9db302021-02-14 01:29:52 +0100803#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100805 /* Check the parity bits. */
806 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100808 unsigned bit_count = 0;
809 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 for (m = 1; m <= 0x100; m <<= 1) {
811 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100812 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100814 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100816 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100817 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100818#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100819
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100821
822exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100824}
825
Gilles Peskine449bd832023-01-11 14:50:10 +0100826static int exercise_export_key(mbedtls_svc_key_id_t key,
827 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100828{
829 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
830 uint8_t *exported = NULL;
831 size_t exported_size = 0;
832 size_t exported_length = 0;
833 int ok = 0;
834
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100836
837 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 psa_get_key_type(&attributes),
839 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100840 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100841
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
843 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
844 TEST_EQUAL(psa_export_key(key, exported,
845 exported_size, &exported_length),
846 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100847 ok = 1;
848 goto exit;
849 }
850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 PSA_ASSERT(psa_export_key(key,
852 exported, exported_size,
853 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100854 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
856 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100857
858exit:
859 /*
860 * Key attributes may have been returned by psa_get_key_attributes()
861 * thus reset them as required.
862 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100864
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 mbedtls_free(exported);
866 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100867}
868
Gilles Peskine449bd832023-01-11 14:50:10 +0100869static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100870{
871 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
872 psa_key_type_t public_type;
873 uint8_t *exported = NULL;
874 size_t exported_size = 0;
875 size_t exported_length = 0;
876 int ok = 0;
877
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
879 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100880 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 psa_get_key_type(&attributes),
882 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100883 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100884
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 TEST_EQUAL(psa_export_public_key(key, exported,
886 exported_size, &exported_length),
887 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100888 ok = 1;
889 goto exit;
890 }
891
892 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 psa_get_key_type(&attributes));
894 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
895 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100896 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 PSA_ASSERT(psa_export_public_key(key,
899 exported, exported_size,
900 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100901 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 public_type, psa_get_key_bits(&attributes),
903 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100904
905exit:
906 /*
907 * Key attributes may have been returned by psa_get_key_attributes()
908 * thus reset them as required.
909 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100911
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 mbedtls_free(exported);
913 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100914}
915
Gilles Peskine449bd832023-01-11 14:50:10 +0100916int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
917 psa_key_usage_t usage,
918 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100919{
Gilles Peskine2385f712021-02-14 01:34:21 +0100920 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100921
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 if (!check_key_attributes_sanity(key)) {
923 return 0;
924 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100925
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800927 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 } else if (PSA_ALG_IS_MAC(alg)) {
929 ok = exercise_mac_key(key, usage, alg);
930 } else if (PSA_ALG_IS_CIPHER(alg)) {
931 ok = exercise_cipher_key(key, usage, alg);
932 } else if (PSA_ALG_IS_AEAD(alg)) {
933 ok = exercise_aead_key(key, usage, alg);
934 } else if (PSA_ALG_IS_SIGN(alg)) {
935 ok = exercise_signature_key(key, usage, alg);
936 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
937 ok = exercise_asymmetric_encryption_key(key, usage, alg);
938 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
939 ok = exercise_key_derivation_key(key, usage, alg);
940 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
941 ok = exercise_raw_key_agreement_key(key, usage, alg);
942 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
943 ok = exercise_key_agreement_key(key, usage, alg);
944 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100945 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100947
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 ok = ok && exercise_export_key(key, usage);
949 ok = ok && exercise_export_public_key(key);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100950
Gilles Peskine2385f712021-02-14 01:34:21 +0100951exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100953}
954
Gilles Peskine449bd832023-01-11 14:50:10 +0100955psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
956 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100957{
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
959 if (PSA_ALG_IS_SIGN_HASH(alg)) {
960 if (PSA_ALG_SIGN_GET_HASH(alg)) {
961 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
962 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
963 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
964 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
965 }
966 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
967 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
968 PSA_KEY_USAGE_VERIFY_MESSAGE :
969 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +0200970 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200971
Gilles Peskine449bd832023-01-11 14:50:10 +0100972 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
973 PSA_KEY_USAGE_VERIFY_HASH :
974 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
975 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
976 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
977 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
978 PSA_KEY_USAGE_ENCRYPT :
979 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
980 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
981 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
982 return PSA_KEY_USAGE_DERIVE;
983 } else {
984 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100985 }
986
987}
Gilles Peskine66e7b902021-02-12 23:40:58 +0100988
989#endif /* MBEDTLS_PSA_CRYPTO_C */