blob: 71053240cdc862e87f105c2d2ab122a9fb3a9a45 [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 Rodgman7ff79652023-11-03 12:04:52 +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 Stekielb66bc0a2021-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 Peskine1b6c09a2023-01-11 14:52:35 +010024static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
Gilles Peskinee78b0022021-02-13 00:41:11 +010025{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +010047 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010048 TEST_ASSERT(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +010061 psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number);
62 if (lifetime_is_dynamic_secure_element(lifetime)) {
Fredrik Hesse5b673a82021-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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +010096 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +010097
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010098 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +010099}
100
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100124 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100125 psa_status_t verify_status =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100136 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100137
138exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100139 psa_mac_abort(&operation);
140 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100141}
142
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100148 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
Gilles Peskineb5347592022-04-21 11:14:30 +0200149 size_t iv_length;
Gilles Peskine8f3aad22022-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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine8f3aad22022-03-18 18:40:47 +0100161
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine8f3aad22022-03-18 18:40:47 +0100168 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine8f3aad22022-03-18 18:40:47 +0100190 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Case0e7791f2021-12-20 21:14:10 -0800200 * if the input is some arbitrary data rather than an actual
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100210 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100211
212exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100213 psa_cipher_abort(&operation);
214 psa_reset_key_attributes(&attributes);
215 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100216}
217
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100222 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
Gilles Peskine743972c2022-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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100249 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100250 psa_status_t verify_status =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100263 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100264
265exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100266 psa_reset_key_attributes(&attributes);
267 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100268}
269
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100270static int can_sign_or_verify_message(psa_key_usage_t usage,
271 psa_algorithm_t alg)
Gilles Peskine275ecde2022-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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine275ecde2022-03-19 11:15:41 +0100280}
281
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100282static int exercise_signature_key(mbedtls_svc_key_id_t key,
283 psa_key_usage_t usage,
284 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100285{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100286 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH)) {
287 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200288 size_t payload_length = 16;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100289 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
290 size_t signature_length = sizeof(signature);
291 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200292
293 /* If the policy allows signing with any hash, just pick one. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100294 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH) {
Ronald Cronef14af02021-08-31 19:08:55 +0200295 #if defined(KNOWN_MBEDTLS_SUPPORTED_HASH_ALG)
296 hash_alg = KNOWN_MBEDTLS_SUPPORTED_HASH_ALG;
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200297 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
298 #else
Agathiyan Bragadeesh27e29892023-07-14 17:28:27 +0100299 TEST_FAIL("No hash algorithm for hash-and-sign testing");
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200300 #endif
301 }
302
Janos Follath02becd92021-06-14 12:34:30 +0100303 /* Some algorithms require the payload to have the size of
304 * the hash encoded in the algorithm. Use this input size
305 * even for algorithms that allow other input sizes. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100306 if (hash_alg != 0) {
307 payload_length = PSA_HASH_LENGTH(hash_alg);
308 }
Janos Follath02becd92021-06-14 12:34:30 +0100309
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100310 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
311 PSA_ASSERT(psa_sign_hash(key, alg,
312 payload, payload_length,
313 signature, sizeof(signature),
314 &signature_length));
315 }
316
317 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
318 psa_status_t verify_status =
319 (usage & PSA_KEY_USAGE_SIGN_HASH ?
320 PSA_SUCCESS :
321 PSA_ERROR_INVALID_SIGNATURE);
322 TEST_EQUAL(psa_verify_hash(key, alg,
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200323 payload, payload_length,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100324 signature, signature_length),
325 verify_status);
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200326 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100327 }
328
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100329 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200330 unsigned char message[256] = "Hello, world...";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100331 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200332 size_t message_length = 16;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100333 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100334
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100335 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
336 PSA_ASSERT(psa_sign_message(key, alg,
337 message, message_length,
338 signature, sizeof(signature),
339 &signature_length));
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200340 }
341
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100342 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200343 psa_status_t verify_status =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100344 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
345 PSA_SUCCESS :
346 PSA_ERROR_INVALID_SIGNATURE);
347 TEST_EQUAL(psa_verify_message(key, alg,
348 message, message_length,
349 signature, signature_length),
350 verify_status);
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200351 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100352 }
353
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100354 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100355
356exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100357 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100358}
359
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100360static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
361 psa_key_usage_t usage,
362 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100363{
364 unsigned char plaintext[256] = "Hello, world...";
365 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100366 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100367 size_t plaintext_length = 16;
368
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100369 if (usage & PSA_KEY_USAGE_ENCRYPT) {
370 PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
371 plaintext, plaintext_length,
372 NULL, 0,
373 ciphertext, sizeof(ciphertext),
374 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100375 }
376
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100377 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100378 psa_status_t status =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100379 psa_asymmetric_decrypt(key, alg,
380 ciphertext, ciphertext_length,
381 NULL, 0,
382 plaintext, sizeof(plaintext),
383 &plaintext_length);
384 TEST_ASSERT(status == PSA_SUCCESS ||
385 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
386 (status == PSA_ERROR_INVALID_ARGUMENT ||
387 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100388 }
389
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100391
392exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100393 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100394}
395
396int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100397 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100398 mbedtls_svc_key_id_t key,
399 psa_algorithm_t alg,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100400 const unsigned char *input1, size_t input1_length,
401 const unsigned char *input2, size_t input2_length,
402 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100403{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100404 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
405 if (PSA_ALG_IS_HKDF(alg)) {
406 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
407 PSA_KEY_DERIVATION_INPUT_SALT,
408 input1, input1_length));
409 PSA_ASSERT(psa_key_derivation_input_key(operation,
410 PSA_KEY_DERIVATION_INPUT_SECRET,
411 key));
412 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
413 PSA_KEY_DERIVATION_INPUT_INFO,
414 input2,
415 input2_length));
416 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
417 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
418 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
419 PSA_KEY_DERIVATION_INPUT_SEED,
420 input1, input1_length));
421 PSA_ASSERT(psa_key_derivation_input_key(operation,
422 PSA_KEY_DERIVATION_INPUT_SECRET,
423 key));
424 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
425 PSA_KEY_DERIVATION_INPUT_LABEL,
426 input2, input2_length));
427 } else {
Agathiyan Bragadeesh27e29892023-07-14 17:28:27 +0100428 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100429 }
430
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100431 if (capacity != SIZE_MAX) {
432 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
433 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100434
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100435 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100436
437exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100438 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100439}
440
441
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100442static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
443 psa_key_usage_t usage,
444 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100445{
446 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
447 unsigned char input1[] = "Input 1";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100448 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100449 unsigned char input2[] = "Input 2";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100450 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100451 unsigned char output[1];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100452 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100453
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100454 if (usage & PSA_KEY_USAGE_DERIVE) {
455 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
456 input1, input1_length,
457 input2, input2_length,
458 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100459 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100460 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100461
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100462 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
463 output,
464 capacity));
465 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100466 }
467
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100468 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100469
470exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100471 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100472}
473
474/* We need two keys to exercise key agreement. Exercise the
475 * private key against its own public key. */
476psa_status_t mbedtls_test_psa_key_agreement_with_self(
477 psa_key_derivation_operation_t *operation,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100478 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100479{
480 psa_key_type_t private_key_type;
481 psa_key_type_t public_key_type;
482 size_t key_bits;
483 uint8_t *public_key = NULL;
484 size_t public_key_length;
485 /* Return GENERIC_ERROR if something other than the final call to
486 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
487 * but it's good enough: callers will report it as a failed test anyway. */
488 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
489 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
490
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100491 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
492 private_key_type = psa_get_key_type(&attributes);
493 key_bits = psa_get_key_bits(&attributes);
494 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
495 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove30ceb232023-09-04 11:20:19 +0100496 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100497 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
498 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100499
500 status = psa_key_derivation_key_agreement(
501 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100502 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100503exit:
504 /*
505 * Key attributes may have been returned by psa_get_key_attributes()
506 * thus reset them as required.
507 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100508 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100509
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100510 mbedtls_free(public_key);
511 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100512}
513
514/* We need two keys to exercise key agreement. Exercise the
515 * private key against its own public key. */
516psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
517 psa_algorithm_t alg,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100518 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100519{
520 psa_key_type_t private_key_type;
521 psa_key_type_t public_key_type;
522 size_t key_bits;
523 uint8_t *public_key = NULL;
524 size_t public_key_length;
525 uint8_t output[1024];
526 size_t output_length;
527 /* Return GENERIC_ERROR if something other than the final call to
528 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
529 * but it's good enough: callers will report it as a failed test anyway. */
530 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
531 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
532
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100533 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
534 private_key_type = psa_get_key_type(&attributes);
535 key_bits = psa_get_key_bits(&attributes);
536 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
537 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove30ceb232023-09-04 11:20:19 +0100538 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100539 PSA_ASSERT(psa_export_public_key(key,
540 public_key, public_key_length,
541 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100542
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100543 status = psa_raw_key_agreement(alg, key,
544 public_key, public_key_length,
545 output, sizeof(output), &output_length);
546 if (status == PSA_SUCCESS) {
547 TEST_ASSERT(output_length <=
548 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
549 key_bits));
550 TEST_ASSERT(output_length <=
551 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100552 }
553
Gilles Peskinee78b0022021-02-13 00:41:11 +0100554exit:
555 /*
556 * Key attributes may have been returned by psa_get_key_attributes()
557 * thus reset them as required.
558 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100559 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100560
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100561 mbedtls_free(public_key);
562 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100563}
564
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100565static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
566 psa_key_usage_t usage,
567 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100568{
569 int ok = 0;
570
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100571 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100572 /* We need two keys to exercise key agreement. Exercise the
573 * private key against its own public key. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100574 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100575 }
576 ok = 1;
577
578exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100579 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100580}
581
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100582static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
583 psa_key_usage_t usage,
584 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100585{
586 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine9d3706f2022-03-19 16:04:30 +0100587 unsigned char input[1];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100588 unsigned char output[1];
589 int ok = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100590 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100591
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100592 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100593 /* We need two keys to exercise key agreement. Exercise the
594 * private key against its own public key. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100595 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
596 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
597 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
598 PSA_ASSERT(psa_key_derivation_input_bytes(
599 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
600 input, sizeof(input)));
Gilles Peskine9d3706f2022-03-19 16:04:30 +0100601 }
602
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100603 PSA_ASSERT(mbedtls_test_psa_key_agreement_with_self(&operation, key));
Gilles Peskine9d3706f2022-03-19 16:04:30 +0100604
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100605 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
606 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
607 PSA_ASSERT(psa_key_derivation_input_bytes(
608 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
609 input, sizeof(input)));
610 } else if (PSA_ALG_IS_HKDF(kdf_alg)) {
611 PSA_ASSERT(psa_key_derivation_input_bytes(
612 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
613 input, sizeof(input)));
Gilles Peskine9d3706f2022-03-19 16:04:30 +0100614 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100615 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
616 output,
617 sizeof(output)));
618 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100619 }
620 ok = 1;
621
622exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100623 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100624}
625
626int mbedtls_test_psa_exported_key_sanity_check(
627 psa_key_type_t type, size_t bits,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100628 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100629{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100630 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100631
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100632 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
633 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
634 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100635
Ronald Cronfefa4582021-07-06 09:23:06 +0200636#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100637 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
638 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100639 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100640 size_t len;
641 /* RSAPrivateKey ::= SEQUENCE {
642 * version INTEGER, -- must be 0
643 * modulus INTEGER, -- n
644 * publicExponent INTEGER, -- e
645 * privateExponent INTEGER, -- d
646 * prime1 INTEGER, -- p
647 * prime2 INTEGER, -- q
648 * exponent1 INTEGER, -- d mod (p-1)
649 * exponent2 INTEGER, -- d mod (q-1)
650 * coefficient INTEGER, -- (inverse of q) mod p
651 * }
652 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100653 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
654 MBEDTLS_ASN1_SEQUENCE |
655 MBEDTLS_ASN1_CONSTRUCTED), 0);
656 TEST_EQUAL(len, end - p);
657 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100658 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100659 }
660 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100661 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100662 }
663 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100664 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100665 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100666 /* Require d to be at least half the size of n. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100667 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100668 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100669 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100670 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100671 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100672 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100673 }
674 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100675 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100676 }
677 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100678 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100679 }
680 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100681 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100682 }
683 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100684 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100685 }
686 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100687
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100688 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
689 } else
Ronald Cronfefa4582021-07-06 09:23:06 +0200690#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100691
692#if defined(MBEDTLS_ECP_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100693 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100694 /* Just the secret value */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100695 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100696
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100697 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
698 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100699#endif /* MBEDTLS_ECP_C */
700
Ronald Cronfefa4582021-07-06 09:23:06 +0200701#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100702 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
703 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100704 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100705 size_t len;
706 /* RSAPublicKey ::= SEQUENCE {
707 * modulus INTEGER, -- n
708 * publicExponent INTEGER } -- e
709 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100710 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
711 MBEDTLS_ASN1_SEQUENCE |
712 MBEDTLS_ASN1_CONSTRUCTED),
713 0);
714 TEST_EQUAL(len, end - p);
715 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100716 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100717 }
718 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100719 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100720 }
721 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100722
723
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100724 TEST_ASSERT(exported_length <=
725 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
726 TEST_ASSERT(exported_length <=
727 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
728 } else
Ronald Cronfefa4582021-07-06 09:23:06 +0200729#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100730
Gilles Peskinee78b0022021-02-13 00:41:11 +0100731#if defined(MBEDTLS_ECP_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100732 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100733
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100734 TEST_ASSERT(exported_length <=
735 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
736 TEST_ASSERT(exported_length <=
737 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100738
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100739 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100740 /* The representation of an ECC Montgomery public key is
741 * the raw compressed point */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100742 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
743 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100744 /* The representation of an ECC Weierstrass public key is:
745 * - The byte 0x04;
746 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
747 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
748 * - where m is the bit size associated with the curve.
749 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100750 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
751 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100752 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100753 } else
Gilles Peskinead557e52021-02-14 01:19:21 +0100754#endif /* MBEDTLS_ECP_C */
755
Gilles Peskinead557e52021-02-14 01:19:21 +0100756 {
Andrzej Kurek53ad7632022-01-17 15:26:24 +0100757 (void) exported;
Agathiyan Bragadeesh27e29892023-07-14 17:28:27 +0100758 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100759 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100760
Gilles Peskinecc9db302021-02-14 01:29:52 +0100761#if defined(MBEDTLS_DES_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100762 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100763 /* Check the parity bits. */
764 unsigned i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100765 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100766 unsigned bit_count = 0;
767 unsigned m;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100768 for (m = 1; m <= 0x100; m <<= 1) {
769 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100770 ++bit_count;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100771 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100772 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100773 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100774 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100775 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100776#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100777
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100778 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100779
780exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100781 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100782}
783
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100784static int exercise_export_key(mbedtls_svc_key_id_t key,
785 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100786{
787 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
788 uint8_t *exported = NULL;
789 size_t exported_size = 0;
790 size_t exported_length = 0;
791 int ok = 0;
792
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100793 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100794
795 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100796 psa_get_key_type(&attributes),
797 psa_get_key_bits(&attributes));
Tom Cosgrove30ceb232023-09-04 11:20:19 +0100798 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100799
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100800 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
801 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
802 TEST_EQUAL(psa_export_key(key, exported,
803 exported_size, &exported_length),
804 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100805 ok = 1;
806 goto exit;
807 }
808
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100809 PSA_ASSERT(psa_export_key(key,
810 exported, exported_size,
811 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100812 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100813 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
814 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100815
816exit:
817 /*
818 * Key attributes may have been returned by psa_get_key_attributes()
819 * thus reset them as required.
820 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100821 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100822
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100823 mbedtls_free(exported);
824 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100825}
826
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100827static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100828{
829 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
830 psa_key_type_t public_type;
831 uint8_t *exported = NULL;
832 size_t exported_size = 0;
833 size_t exported_length = 0;
834 int ok = 0;
835
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100836 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
837 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100838 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100839 psa_get_key_type(&attributes),
840 psa_get_key_bits(&attributes));
Tom Cosgrove30ceb232023-09-04 11:20:19 +0100841 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100842
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100843 TEST_EQUAL(psa_export_public_key(key, exported,
844 exported_size, &exported_length),
845 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100846 ok = 1;
847 goto exit;
848 }
849
850 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100851 psa_get_key_type(&attributes));
852 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
853 psa_get_key_bits(&attributes));
Tom Cosgrove30ceb232023-09-04 11:20:19 +0100854 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100855
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100856 PSA_ASSERT(psa_export_public_key(key,
857 exported, exported_size,
858 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100859 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100860 public_type, psa_get_key_bits(&attributes),
861 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100862
863exit:
864 /*
865 * Key attributes may have been returned by psa_get_key_attributes()
866 * thus reset them as required.
867 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100868 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100869
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100870 mbedtls_free(exported);
871 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100872}
873
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100874int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
875 psa_key_usage_t usage,
876 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100877{
Gilles Peskine2385f712021-02-14 01:34:21 +0100878 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100879
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100880 if (!check_key_attributes_sanity(key)) {
881 return 0;
882 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100883
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100884 if (alg == 0) {
Shaun Case0e7791f2021-12-20 21:14:10 -0800885 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100886 } else if (PSA_ALG_IS_MAC(alg)) {
887 ok = exercise_mac_key(key, usage, alg);
888 } else if (PSA_ALG_IS_CIPHER(alg)) {
889 ok = exercise_cipher_key(key, usage, alg);
890 } else if (PSA_ALG_IS_AEAD(alg)) {
891 ok = exercise_aead_key(key, usage, alg);
892 } else if (PSA_ALG_IS_SIGN(alg)) {
893 ok = exercise_signature_key(key, usage, alg);
894 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
895 ok = exercise_asymmetric_encryption_key(key, usage, alg);
896 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
897 ok = exercise_key_derivation_key(key, usage, alg);
898 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
899 ok = exercise_raw_key_agreement_key(key, usage, alg);
900 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
901 ok = exercise_key_agreement_key(key, usage, alg);
902 } else {
Agathiyan Bragadeesh27e29892023-07-14 17:28:27 +0100903 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100904 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100905
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100906 ok = ok && exercise_export_key(key, usage);
907 ok = ok && exercise_export_public_key(key);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100908
Gilles Peskine2385f712021-02-14 01:34:21 +0100909exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100910 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100911}
912
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100913psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
914 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100915{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100916 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
917 if (PSA_ALG_IS_SIGN_HASH(alg)) {
918 if (PSA_ALG_SIGN_GET_HASH(alg)) {
919 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
920 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
921 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
922 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
923 }
924 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
925 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
926 PSA_KEY_USAGE_VERIFY_MESSAGE :
927 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm72616972021-05-11 13:29:24 +0200928 }
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200929
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100930 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
931 PSA_KEY_USAGE_VERIFY_HASH :
932 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
933 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
934 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
935 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
936 PSA_KEY_USAGE_ENCRYPT :
937 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
938 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
939 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
940 return PSA_KEY_USAGE_DERIVE;
941 } else {
942 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100943 }
944
945}
Gilles Peskine66e7b902021-02-12 23:40:58 +0100946
947#endif /* MBEDTLS_PSA_CRYPTO_C */