blob: ff0d1c0a6333f534a4f40cfa956c65f2f932e049 [file] [log] [blame]
Gilles Peskine66e7b902021-02-12 23:40:58 +01001/** Code to exercise a PSA key object, i.e. validate that it seems well-formed
2 * and can do what it is supposed to do.
3 */
4
5/*
6 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00007 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Gilles Peskine66e7b902021-02-12 23:40:58 +01008 */
9
10#include <test/helpers.h>
11#include <test/macros.h>
Gilles Peskinee78b0022021-02-13 00:41:11 +010012#include <test/psa_exercise_key.h>
Gilles Peskine66e7b902021-02-12 23:40:58 +010013
14#if defined(MBEDTLS_PSA_CRYPTO_C)
15
Gilles Peskinee78b0022021-02-13 00:41:11 +010016#include <mbedtls/asn1.h>
Gilles Peskine66e7b902021-02-12 23:40:58 +010017#include <psa/crypto.h>
18
Gilles Peskinee78b0022021-02-13 00:41:11 +010019#include <test/asn1_helpers.h>
Przemyslaw Stekiel53de2622021-11-03 09:35:35 +010020#include <psa_crypto_slot_management.h>
Gilles Peskinee78b0022021-02-13 00:41:11 +010021#include <test/psa_crypto_helpers.h>
22
Gilles Peskine6fe8a062024-02-15 17:21:17 +010023#if defined(MBEDTLS_PK_C)
24#include <pk_internal.h>
25#endif
26#if defined(MBEDTLS_ECP_C)
27#include <mbedtls/ecp.h>
28#endif
29#if defined(MBEDTLS_RSA_C)
30#include <rsa_internal.h>
31#endif
32
Gilles Peskinee78b0022021-02-13 00:41:11 +010033#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010034static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
Gilles Peskinee78b0022021-02-13 00:41:11 +010035{
Gilles Peskine449bd832023-01-11 14:50:10 +010036 return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
37 PSA_KEY_LOCATION_LOCAL_STORAGE;
Gilles Peskinee78b0022021-02-13 00:41:11 +010038}
39#endif
40
Ryan Everettf08a93f2024-03-12 16:00:08 +000041static int check_key_attributes_sanity(mbedtls_svc_key_id_t key,
42 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +010043{
44 int ok = 0;
45 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
46 psa_key_lifetime_t lifetime;
47 mbedtls_svc_key_id_t id;
48 psa_key_type_t type;
Gilles Peskine6b362e62021-02-15 12:03:16 +010049 size_t bits;
Ryan Everettf08a93f2024-03-12 16:00:08 +000050 psa_status_t status = psa_get_key_attributes(key, &attributes);
51 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
52 /* The key has been destroyed. */
53 psa_reset_key_attributes(&attributes);
54 return 1;
55 }
56 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +010057 lifetime = psa_get_key_lifetime(&attributes);
58 id = psa_get_key_id(&attributes);
59 type = psa_get_key_type(&attributes);
60 bits = psa_get_key_bits(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +010061
62 /* Persistence */
Gilles Peskine449bd832023-01-11 14:50:10 +010063 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010064 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010065 (PSA_KEY_ID_VOLATILE_MIN <=
66 MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
67 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
68 PSA_KEY_ID_VOLATILE_MAX));
69 } else {
Gilles Peskinee78b0022021-02-13 00:41:11 +010070 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010071 (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
72 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
Gilles Peskinee78b0022021-02-13 00:41:11 +010073 }
74#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Ryan Everettf08a93f2024-03-12 16:00:08 +000075 /* MBEDTLS_PSA_CRYPTO_SE_C does not support thread safety. */
76 if (key_destroyable == 0) {
77 /* randomly-generated 64-bit constant, should never appear in test data */
78 psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
79 status = psa_get_key_slot_number(&attributes, &slot_number);
80 if (lifetime_is_dynamic_secure_element(lifetime)) {
81 /* Mbed TLS currently always exposes the slot number to
82 * applications. This is not mandated by the PSA specification
83 * and may change in future versions. */
84 TEST_EQUAL(status, 0);
85 TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
86 } else {
87 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
88 }
Gilles Peskinee78b0022021-02-13 00:41:11 +010089 }
90#endif
91
92 /* Type and size */
Gilles Peskine449bd832023-01-11 14:50:10 +010093 TEST_ASSERT(type != 0);
94 TEST_ASSERT(bits != 0);
95 TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
96 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
97 TEST_ASSERT(bits % 8 == 0);
98 }
Gilles Peskinee78b0022021-02-13 00:41:11 +010099
100 /* MAX macros concerning specific key types */
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 if (PSA_KEY_TYPE_IS_ECC(type)) {
102 TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
103 } else if (PSA_KEY_TYPE_IS_RSA(type)) {
104 TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
105 }
106 TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100107
108 ok = 1;
109
110exit:
111 /*
112 * Key attributes may have been returned by psa_get_key_attributes()
113 * thus reset them as required.
114 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100116
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100118}
119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120static int exercise_mac_key(mbedtls_svc_key_id_t key,
121 psa_key_usage_t usage,
Ryan Everett77635502024-03-12 16:02:23 +0000122 psa_algorithm_t alg,
123 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100124{
125 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
126 const unsigned char input[] = "foo";
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
128 size_t mac_length = sizeof(mac);
Ryan Everett77635502024-03-12 16:02:23 +0000129 psa_status_t status = PSA_SUCCESS;
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100130 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
132 alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100133 }
134
Gilles Peskine449bd832023-01-11 14:50:10 +0100135 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
Ryan Everett77635502024-03-12 16:02:23 +0000136 status = psa_mac_sign_setup(&operation, key, alg);
137 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
138 /* The key has been destroyed. */
139 PSA_ASSERT(psa_mac_abort(&operation));
140 return 1;
141 }
142 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 PSA_ASSERT(psa_mac_update(&operation,
144 input, sizeof(input)));
145 PSA_ASSERT(psa_mac_sign_finish(&operation,
146 mac, sizeof(mac),
147 &mac_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100148 }
149
Gilles Peskine449bd832023-01-11 14:50:10 +0100150 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100151 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 (usage & PSA_KEY_USAGE_SIGN_HASH ?
153 PSA_SUCCESS :
154 PSA_ERROR_INVALID_SIGNATURE);
Ryan Everett77635502024-03-12 16:02:23 +0000155 status = psa_mac_verify_setup(&operation, key, alg);
156 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
157 /* The key has been destroyed. */
158 PSA_ASSERT(psa_mac_abort(&operation));
159 return 1;
160 }
161 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 PSA_ASSERT(psa_mac_update(&operation,
163 input, sizeof(input)));
164 TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
165 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100166 }
167
Gilles Peskine449bd832023-01-11 14:50:10 +0100168 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100169
170exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 psa_mac_abort(&operation);
172 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100173}
174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175static int exercise_cipher_key(mbedtls_svc_key_id_t key,
176 psa_key_usage_t usage,
Ryan Everett70691f32024-03-12 16:04:45 +0000177 psa_algorithm_t alg,
178 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100179{
180 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
Gilles Peskine5eef11a2022-04-21 11:14:30 +0200182 size_t iv_length;
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100183 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
184 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100185 const unsigned char plaintext[16] = "Hello, world...";
186 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 size_t ciphertext_length = sizeof(ciphertext);
188 unsigned char decrypted[sizeof(ciphertext)];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100189 size_t part_length;
Ryan Everett70691f32024-03-12 16:04:45 +0000190 psa_status_t status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100191
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
193 key_type = psa_get_key_type(&attributes);
194 iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 if (usage & PSA_KEY_USAGE_ENCRYPT) {
Ryan Everett70691f32024-03-12 16:04:45 +0000197 status = psa_cipher_encrypt_setup(&operation, key, alg);
198 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
199 /* The key has been destroyed. */
200 PSA_ASSERT(psa_cipher_abort(&operation));
201 return 1;
202 }
203 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 if (iv_length != 0) {
205 PSA_ASSERT(psa_cipher_generate_iv(&operation,
206 iv, sizeof(iv),
207 &iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100208 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100209 PSA_ASSERT(psa_cipher_update(&operation,
210 plaintext, sizeof(plaintext),
211 ciphertext, sizeof(ciphertext),
212 &ciphertext_length));
213 PSA_ASSERT(psa_cipher_finish(&operation,
214 ciphertext + ciphertext_length,
215 sizeof(ciphertext) - ciphertext_length,
216 &part_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100217 ciphertext_length += part_length;
218 }
219
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100221 int maybe_invalid_padding = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
223 maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100224 }
Ryan Everett70691f32024-03-12 16:04:45 +0000225 status = psa_cipher_decrypt_setup(&operation, key, alg);
226 if (key_destroyable && status == PSA_ERROR_INVALID_HANDLE) {
227 /* The key has been destroyed. */
228 PSA_ASSERT(psa_cipher_abort(&operation));
229 return 1;
230 }
231 PSA_ASSERT(status);
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 if (iv_length != 0) {
233 PSA_ASSERT(psa_cipher_set_iv(&operation,
234 iv, iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100235 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 PSA_ASSERT(psa_cipher_update(&operation,
237 ciphertext, ciphertext_length,
238 decrypted, sizeof(decrypted),
239 &part_length));
240 status = psa_cipher_finish(&operation,
241 decrypted + part_length,
242 sizeof(decrypted) - part_length,
243 &part_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100244 /* For a stream cipher, all inputs are valid. For a block cipher,
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800245 * if the input is some arbitrary data rather than an actual
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 ciphertext, a padding error is likely. */
247 if (maybe_invalid_padding) {
248 TEST_ASSERT(status == PSA_SUCCESS ||
249 status == PSA_ERROR_INVALID_PADDING);
250 } else {
251 PSA_ASSERT(status);
252 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100253 }
254
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100256
257exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 psa_cipher_abort(&operation);
259 psa_reset_key_attributes(&attributes);
260 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100261}
262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263static int exercise_aead_key(mbedtls_svc_key_id_t key,
264 psa_key_usage_t usage,
265 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100266{
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
Gilles Peskine7acb1982022-03-19 11:03:32 +0100268 size_t nonce_length;
269 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
270 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100271 unsigned char plaintext[16] = "Hello, world...";
272 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100273 size_t ciphertext_length = sizeof(ciphertext);
274 size_t plaintext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100275
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100276 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100277 if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
278 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100279 }
280
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
282 key_type = psa_get_key_type(&attributes);
283 nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
Steven Cooremanaaec3412021-02-18 13:30:34 +0100284
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 if (usage & PSA_KEY_USAGE_ENCRYPT) {
286 PSA_ASSERT(psa_aead_encrypt(key, alg,
287 nonce, nonce_length,
288 NULL, 0,
289 plaintext, sizeof(plaintext),
290 ciphertext, sizeof(ciphertext),
291 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100292 }
293
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100295 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 (usage & PSA_KEY_USAGE_ENCRYPT ?
297 PSA_SUCCESS :
298 PSA_ERROR_INVALID_SIGNATURE);
299 TEST_EQUAL(psa_aead_decrypt(key, alg,
300 nonce, nonce_length,
301 NULL, 0,
302 ciphertext, ciphertext_length,
303 plaintext, sizeof(plaintext),
304 &plaintext_length),
305 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100306 }
307
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100309
310exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 psa_reset_key_attributes(&attributes);
312 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100313}
314
Gilles Peskine449bd832023-01-11 14:50:10 +0100315static int can_sign_or_verify_message(psa_key_usage_t usage,
316 psa_algorithm_t alg)
Gilles Peskined586b822022-03-19 11:15:41 +0100317{
318 /* Sign-the-unspecified-hash algorithms can only be used with
319 * {sign,verify}_hash, not with {sign,verify}_message. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
321 return 0;
322 }
323 return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
324 PSA_KEY_USAGE_VERIFY_MESSAGE);
Gilles Peskined586b822022-03-19 11:15:41 +0100325}
326
Gilles Peskine449bd832023-01-11 14:50:10 +0100327static int exercise_signature_key(mbedtls_svc_key_id_t key,
328 psa_key_usage_t usage,
329 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100330{
Gilles Peskine4781bd92024-02-09 17:32:45 +0100331 /* If the policy allows signing with any hash, just pick one. */
332 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
333 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH &&
334 usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
335 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
336#if defined(KNOWN_SUPPORTED_HASH_ALG)
337 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
338 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
339#else
340 TEST_FAIL("No hash algorithm for hash-and-sign testing");
341#endif
342 }
343
oberon-skf7a824b2023-02-15 19:43:30 +0100344 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
345 PSA_ALG_IS_SIGN_HASH(alg)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200347 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
349 size_t signature_length = sizeof(signature);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200350
Janos Follath4c0b60e2021-06-14 12:34:30 +0100351 /* Some algorithms require the payload to have the size of
352 * the hash encoded in the algorithm. Use this input size
353 * even for algorithms that allow other input sizes. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 if (hash_alg != 0) {
355 payload_length = PSA_HASH_LENGTH(hash_alg);
356 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100357
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
359 PSA_ASSERT(psa_sign_hash(key, alg,
360 payload, payload_length,
361 signature, sizeof(signature),
362 &signature_length));
363 }
364
365 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
366 psa_status_t verify_status =
367 (usage & PSA_KEY_USAGE_SIGN_HASH ?
368 PSA_SUCCESS :
369 PSA_ERROR_INVALID_SIGNATURE);
370 TEST_EQUAL(psa_verify_hash(key, alg,
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200371 payload, payload_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 signature, signature_length),
373 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200374 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100375 }
376
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200378 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200380 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100382
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
384 PSA_ASSERT(psa_sign_message(key, alg,
385 message, message_length,
386 signature, sizeof(signature),
387 &signature_length));
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200388 }
389
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200391 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
393 PSA_SUCCESS :
394 PSA_ERROR_INVALID_SIGNATURE);
395 TEST_EQUAL(psa_verify_message(key, alg,
396 message, message_length,
397 signature, signature_length),
398 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200399 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100400 }
401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100403
404exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100406}
407
Gilles Peskine449bd832023-01-11 14:50:10 +0100408static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
409 psa_key_usage_t usage,
410 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100411{
Gilles Peskinef50cd592024-02-15 13:13:26 +0100412 unsigned char plaintext[PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100413 "Hello, world...";
Gilles Peskinef50cd592024-02-15 13:13:26 +0100414 unsigned char ciphertext[PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE] =
Gilles Peskinefdb809e2024-02-09 19:22:30 +0100415 "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100417 size_t plaintext_length = 16;
418
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 if (usage & PSA_KEY_USAGE_ENCRYPT) {
420 PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
421 plaintext, plaintext_length,
422 NULL, 0,
423 ciphertext, sizeof(ciphertext),
424 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100425 }
426
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100428 psa_status_t status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 psa_asymmetric_decrypt(key, alg,
430 ciphertext, ciphertext_length,
431 NULL, 0,
432 plaintext, sizeof(plaintext),
433 &plaintext_length);
434 TEST_ASSERT(status == PSA_SUCCESS ||
435 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
436 (status == PSA_ERROR_INVALID_ARGUMENT ||
437 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100438 }
439
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100441
442exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100444}
445
446int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100448 mbedtls_svc_key_id_t key,
449 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 const unsigned char *input1, size_t input1_length,
451 const unsigned char *input2, size_t input2_length,
452 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100453{
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
455 if (PSA_ALG_IS_HKDF(alg)) {
456 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
457 PSA_KEY_DERIVATION_INPUT_SALT,
458 input1, input1_length));
459 PSA_ASSERT(psa_key_derivation_input_key(operation,
460 PSA_KEY_DERIVATION_INPUT_SECRET,
461 key));
462 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
463 PSA_KEY_DERIVATION_INPUT_INFO,
464 input2,
465 input2_length));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530466 } else if (PSA_ALG_IS_HKDF_EXTRACT(alg)) {
467 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
468 PSA_KEY_DERIVATION_INPUT_SALT,
469 input1, input1_length));
470 PSA_ASSERT(psa_key_derivation_input_key(operation,
471 PSA_KEY_DERIVATION_INPUT_SECRET,
472 key));
473 } else if (PSA_ALG_IS_HKDF_EXPAND(alg)) {
474 PSA_ASSERT(psa_key_derivation_input_key(operation,
475 PSA_KEY_DERIVATION_INPUT_SECRET,
476 key));
477 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
478 PSA_KEY_DERIVATION_INPUT_INFO,
479 input2,
480 input2_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
482 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
483 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
484 PSA_KEY_DERIVATION_INPUT_SEED,
485 input1, input1_length));
486 PSA_ASSERT(psa_key_derivation_input_key(operation,
487 PSA_KEY_DERIVATION_INPUT_SECRET,
488 key));
489 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
490 PSA_KEY_DERIVATION_INPUT_LABEL,
491 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530492 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530493 PSA_ASSERT(psa_key_derivation_input_integer(operation,
494 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530495 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530496 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
497 PSA_KEY_DERIVATION_INPUT_SALT,
498 input2,
499 input2_length));
500 PSA_ASSERT(psa_key_derivation_input_key(operation,
501 PSA_KEY_DERIVATION_INPUT_PASSWORD,
502 key));
Kusumit Ghoderao2c4264b2023-12-01 16:41:26 +0530503 } else if (alg == PSA_ALG_TLS12_ECJPAKE_TO_PMS) {
504 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
505 PSA_KEY_DERIVATION_INPUT_SECRET,
506 input1, input1_length));
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100508 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100509 }
510
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 if (capacity != SIZE_MAX) {
512 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
513 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100514
Gilles Peskine449bd832023-01-11 14:50:10 +0100515 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100516
517exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100519}
520
521
Gilles Peskine449bd832023-01-11 14:50:10 +0100522static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
523 psa_key_usage_t usage,
524 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100525{
526 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
527 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100528 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100529 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100531 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 if (usage & PSA_KEY_USAGE_DERIVE) {
535 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
536 input1, input1_length,
537 input2, input2_length,
538 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100539 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100541
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
543 output,
544 capacity));
545 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100546 }
547
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100549
550exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100552}
553
554/* We need two keys to exercise key agreement. Exercise the
555 * private key against its own public key. */
556psa_status_t mbedtls_test_psa_key_agreement_with_self(
557 psa_key_derivation_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100559{
560 psa_key_type_t private_key_type;
561 psa_key_type_t public_key_type;
562 size_t key_bits;
563 uint8_t *public_key = NULL;
564 size_t public_key_length;
565 /* Return GENERIC_ERROR if something other than the final call to
566 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
567 * but it's good enough: callers will report it as a failed test anyway. */
568 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
569 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
570
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
572 private_key_type = psa_get_key_type(&attributes);
573 key_bits = psa_get_key_bits(&attributes);
574 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
575 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100576 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
578 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100579
580 status = psa_key_derivation_key_agreement(
581 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100583exit:
584 /*
585 * Key attributes may have been returned by psa_get_key_attributes()
586 * thus reset them as required.
587 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100589
Gilles Peskine449bd832023-01-11 14:50:10 +0100590 mbedtls_free(public_key);
591 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100592}
593
594/* We need two keys to exercise key agreement. Exercise the
595 * private key against its own public key. */
596psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
597 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100599{
600 psa_key_type_t private_key_type;
601 psa_key_type_t public_key_type;
602 size_t key_bits;
603 uint8_t *public_key = NULL;
604 size_t public_key_length;
605 uint8_t output[1024];
606 size_t output_length;
607 /* Return GENERIC_ERROR if something other than the final call to
608 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
609 * but it's good enough: callers will report it as a failed test anyway. */
610 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
611 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
614 private_key_type = psa_get_key_type(&attributes);
615 key_bits = psa_get_key_bits(&attributes);
616 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
617 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100618 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 PSA_ASSERT(psa_export_public_key(key,
620 public_key, public_key_length,
621 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100622
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 status = psa_raw_key_agreement(alg, key,
624 public_key, public_key_length,
625 output, sizeof(output), &output_length);
626 if (status == PSA_SUCCESS) {
627 TEST_ASSERT(output_length <=
628 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
629 key_bits));
630 TEST_ASSERT(output_length <=
631 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100632 }
633
Gilles Peskinee78b0022021-02-13 00:41:11 +0100634exit:
635 /*
636 * Key attributes may have been returned by psa_get_key_attributes()
637 * thus reset them as required.
638 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 mbedtls_free(public_key);
642 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100643}
644
Gilles Peskine449bd832023-01-11 14:50:10 +0100645static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
646 psa_key_usage_t usage,
647 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100648{
649 int ok = 0;
650
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100652 /* We need two keys to exercise key agreement. Exercise the
653 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100655 }
656 ok = 1;
657
658exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100660}
661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
663 psa_key_usage_t usage,
664 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100665{
666 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200667 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100668 unsigned char output[1];
669 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200671 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100672
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100674 /* We need two keys to exercise key agreement. Exercise the
675 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
677 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
678 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
679 PSA_ASSERT(psa_key_derivation_input_bytes(
680 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
681 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100682 }
683
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
685 PSA_ASSERT(psa_key_derivation_input_bytes(
686 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
687 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200688 }
689
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200690 /* For HKDF_EXPAND input secret may fail as secret size may not match
691 to expected PRK size. In practice it means that key bits must match
692 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200694 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
696 size_t key_bits = psa_get_key_bits(&attributes);
697 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200700 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200702 }
703
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
705 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200706
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 if (expected_key_agreement_status != PSA_SUCCESS) {
708 return 1;
709 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100710
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
712 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
713 PSA_ASSERT(psa_key_derivation_input_bytes(
714 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
715 input, sizeof(input)));
716 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
717 PSA_ASSERT(psa_key_derivation_input_bytes(
718 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
719 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100720 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
722 output,
723 sizeof(output)));
724 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100725 }
726 ok = 1;
727
728exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100730}
731
732int mbedtls_test_psa_exported_key_sanity_check(
733 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100735{
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100737
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
739 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
740 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100741
Ronald Cron64df7382021-07-06 09:23:06 +0200742#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
744 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100745 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100746 size_t len;
747 /* RSAPrivateKey ::= SEQUENCE {
748 * version INTEGER, -- must be 0
749 * modulus INTEGER, -- n
750 * publicExponent INTEGER, -- e
751 * privateExponent INTEGER, -- d
752 * prime1 INTEGER, -- p
753 * prime2 INTEGER, -- q
754 * exponent1 INTEGER, -- d mod (p-1)
755 * exponent2 INTEGER, -- d mod (q-1)
756 * coefficient INTEGER, -- (inverse of q) mod p
757 * }
758 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
760 MBEDTLS_ASN1_SEQUENCE |
761 MBEDTLS_ASN1_CONSTRUCTED), 0);
762 TEST_EQUAL(len, end - p);
763 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100764 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 }
766 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100767 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 }
769 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100770 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100772 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100774 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100776 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100778 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 }
780 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100781 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 }
783 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100784 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 }
786 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100787 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 }
789 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100790 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100791 }
792 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100793
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
795 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200796#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100797
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100799 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
803 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100804
Ronald Cron64df7382021-07-06 09:23:06 +0200805#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
807 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100808 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100809 size_t len;
810 /* RSAPublicKey ::= SEQUENCE {
811 * modulus INTEGER, -- n
812 * publicExponent INTEGER } -- e
813 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
815 MBEDTLS_ASN1_SEQUENCE |
816 MBEDTLS_ASN1_CONSTRUCTED),
817 0);
818 TEST_EQUAL(len, end - p);
819 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100820 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 }
822 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100823 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100824 }
825 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100826
827
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 TEST_ASSERT(exported_length <=
829 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
830 TEST_ASSERT(exported_length <=
831 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
832 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200833#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100834
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100836
Gilles Peskine449bd832023-01-11 14:50:10 +0100837 TEST_ASSERT(exported_length <=
838 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
839 TEST_ASSERT(exported_length <=
840 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100841
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100843 /* The representation of an ECC Montgomery public key is
844 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100846 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100847 /* The representation of an ECC Edwards public key is
848 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100849 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100851 /* The representation of an ECC Weierstrass public key is:
852 * - The byte 0x04;
853 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
854 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
855 * - where m is the bit size associated with the curve.
856 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
858 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100859 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100860 } else
861 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200862 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100863 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
864 TEST_ASSERT(exported_length <=
865 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200866 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100867 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100868 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100869 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100870
Gilles Peskinecc9db302021-02-14 01:29:52 +0100871#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100873 /* Check the parity bits. */
874 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100876 unsigned bit_count = 0;
877 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 for (m = 1; m <= 0x100; m <<= 1) {
879 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100880 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100882 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100884 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100885 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100886#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100887
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100889
890exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100892}
893
Gilles Peskine449bd832023-01-11 14:50:10 +0100894static int exercise_export_key(mbedtls_svc_key_id_t key,
895 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100896{
897 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
898 uint8_t *exported = NULL;
899 size_t exported_size = 0;
900 size_t exported_length = 0;
901 int ok = 0;
902
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100904
905 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 psa_get_key_type(&attributes),
907 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100908 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100909
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
911 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
912 TEST_EQUAL(psa_export_key(key, exported,
913 exported_size, &exported_length),
914 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100915 ok = 1;
916 goto exit;
917 }
918
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 PSA_ASSERT(psa_export_key(key,
920 exported, exported_size,
921 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100922 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
924 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100925
926exit:
927 /*
928 * Key attributes may have been returned by psa_get_key_attributes()
929 * thus reset them as required.
930 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100932
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 mbedtls_free(exported);
934 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100935}
936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100938{
939 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
940 psa_key_type_t public_type;
941 uint8_t *exported = NULL;
942 size_t exported_size = 0;
943 size_t exported_length = 0;
944 int ok = 0;
945
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
947 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100948 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 psa_get_key_type(&attributes),
950 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100951 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100952
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 TEST_EQUAL(psa_export_public_key(key, exported,
954 exported_size, &exported_length),
955 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100956 ok = 1;
957 goto exit;
958 }
959
960 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 psa_get_key_type(&attributes));
962 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
963 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100964 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100965
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 PSA_ASSERT(psa_export_public_key(key,
967 exported, exported_size,
968 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100969 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 public_type, psa_get_key_bits(&attributes),
971 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100972
973exit:
974 /*
975 * Key attributes may have been returned by psa_get_key_attributes()
976 * thus reset them as required.
977 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100978 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100979
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 mbedtls_free(exported);
981 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100982}
983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
985 psa_key_usage_t usage,
Ryan Everett0a271fd2024-03-12 16:34:02 +0000986 psa_algorithm_t alg,
987 int key_destroyable)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100988{
Gilles Peskine2385f712021-02-14 01:34:21 +0100989 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100990
Ryan Everett0a271fd2024-03-12 16:34:02 +0000991 if (!check_key_attributes_sanity(key, key_destroyable)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 return 0;
993 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100994
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800996 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 } else if (PSA_ALG_IS_MAC(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +0000998 ok = exercise_mac_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 } else if (PSA_ALG_IS_CIPHER(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001000 ok = exercise_cipher_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 } else if (PSA_ALG_IS_AEAD(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001002 ok = exercise_aead_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 } else if (PSA_ALG_IS_SIGN(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001004 ok = exercise_signature_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001006 ok = exercise_asymmetric_encryption_key(key, usage, alg,
1007 key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001009 ok = exercise_key_derivation_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001011 ok = exercise_raw_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
Ryan Everett0a271fd2024-03-12 16:34:02 +00001013 ok = exercise_key_agreement_key(key, usage, alg, key_destroyable);
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +01001015 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 }
Gilles Peskinee78b0022021-02-13 00:41:11 +01001017
Ryan Everett0a271fd2024-03-12 16:34:02 +00001018 ok = ok && exercise_export_key(key,
1019 usage,
1020 key_destroyable);
1021 ok = ok && exercise_export_public_key(key,
1022 key_destroyable);
Gilles Peskinee78b0022021-02-13 00:41:11 +01001023
Gilles Peskine2385f712021-02-14 01:34:21 +01001024exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001026}
1027
Gilles Peskine449bd832023-01-11 14:50:10 +01001028psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
1029 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +01001030{
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
1032 if (PSA_ALG_IS_SIGN_HASH(alg)) {
1033 if (PSA_ALG_SIGN_GET_HASH(alg)) {
1034 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1035 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
1036 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
1037 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
1038 }
1039 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
1040 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1041 PSA_KEY_USAGE_VERIFY_MESSAGE :
1042 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +02001043 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +02001044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1046 PSA_KEY_USAGE_VERIFY_HASH :
1047 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
1048 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
1049 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
1050 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
1051 PSA_KEY_USAGE_ENCRYPT :
1052 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
1053 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
1054 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
1055 return PSA_KEY_USAGE_DERIVE;
1056 } else {
1057 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +01001058 }
1059
1060}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001061
Gilles Peskine34955672024-02-12 14:19:24 +01001062int mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg)
1063{
1064 /* Reject algorithms that we know are not supported. Default to
1065 * attempting exercise, so that if an algorithm is missing from this
1066 * function, the result will be a test failure and not silently
1067 * omitting exercise. */
1068#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
1069 if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) {
1070 return 0;
1071 }
1072#endif
1073#if !defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
1074 if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
1075 return 0;
1076 }
1077#endif
1078#if !defined(PSA_WANT_ALG_RSA_PSS)
1079 if (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg)) {
1080 return 0;
1081 }
1082#endif
1083#if !defined(PSA_WANT_ALG_RSA_PSS_ANY_SALT)
1084 if (PSA_ALG_IS_RSA_PSS_ANY_SALT(alg)) {
1085 return 0;
1086 }
1087#endif
1088#if !defined(PSA_WANT_ALG_ECDSA)
1089 if (PSA_ALG_IS_ECDSA(alg)) {
1090 return 0;
1091 }
1092#endif
1093#if !defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
1094 if (PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
1095 return 0;
1096 }
1097#endif
1098#if !defined(PSA_WANT_ALG_ECDH)
1099 if (PSA_ALG_IS_ECDH(alg)) {
1100 return 0;
1101 }
1102#endif
1103 (void) alg;
1104 return 1;
1105}
1106
Gilles Peskine6fe8a062024-02-15 17:21:17 +01001107#if defined(MBEDTLS_PK_C)
1108int mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key,
1109 const mbedtls_pk_context *pk)
1110{
1111 psa_key_attributes_t psa_attributes = PSA_KEY_ATTRIBUTES_INIT;
1112 psa_key_attributes_t pk_attributes = PSA_KEY_ATTRIBUTES_INIT;
1113 int ok = 0;
1114
1115 PSA_ASSERT(psa_get_key_attributes(psa_key, &psa_attributes));
1116 psa_key_type_t psa_type = psa_get_key_type(&psa_attributes);
1117 mbedtls_pk_type_t pk_type = mbedtls_pk_get_type(pk);
1118
1119 TEST_ASSERT(PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_type) ||
1120 PSA_KEY_TYPE_IS_KEY_PAIR(psa_type));
1121 TEST_EQUAL(psa_get_key_bits(&psa_attributes), mbedtls_pk_get_bitlen(pk));
1122
1123 uint8_t pk_public_buffer[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1124 const uint8_t *pk_public = NULL;
1125 size_t pk_public_length = 0;
1126
1127 switch (pk_type) {
1128#if defined(MBEDTLS_RSA_C)
1129 case MBEDTLS_PK_RSA:
1130 TEST_ASSERT(PSA_KEY_TYPE_IS_RSA(psa_type));
1131 const mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
1132 uint8_t *const end = pk_public_buffer + sizeof(pk_public_buffer);
1133 uint8_t *cursor = end;
1134 TEST_LE_U(1, mbedtls_rsa_write_pubkey(rsa,
1135 pk_public_buffer, &cursor));
1136 pk_public = cursor;
1137 pk_public_length = end - pk_public;
1138 break;
1139#endif
1140
1141#if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1142 case MBEDTLS_PK_ECKEY:
1143 case MBEDTLS_PK_ECKEY_DH:
1144 case MBEDTLS_PK_ECDSA:
1145 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_type));
1146 TEST_EQUAL(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_type), pk->ec_family);
1147 pk_public = pk->pub_raw;
1148 pk_public_length = pk->pub_raw_len;
1149 break;
1150#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
1151
1152#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) && !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
1153 case MBEDTLS_PK_ECKEY:
1154 case MBEDTLS_PK_ECKEY_DH:
1155 case MBEDTLS_PK_ECDSA:
1156 TEST_ASSERT(PSA_KEY_TYPE_IS_ECC(psa_get_key_type(&psa_attributes)));
1157 const mbedtls_ecp_keypair *ec = mbedtls_pk_ec_ro(*pk);
1158 TEST_EQUAL(mbedtls_ecp_write_public_key(
1159 ec, MBEDTLS_ECP_PF_UNCOMPRESSED, &pk_public_length,
1160 pk_public_buffer, sizeof(pk_public_buffer)), 0);
1161 pk_public = pk_public_buffer;
1162 break;
1163#endif /* MBEDTLS_PK_HAVE_ECC_KEYS && !MBEDTLS_PK_USE_PSA_EC_DATA */
1164
1165#if defined(MBEDTLS_USE_PSA_CRYPTO)
1166 case MBEDTLS_PK_OPAQUE:
1167 PSA_ASSERT(psa_get_key_attributes(pk->priv_id, &pk_attributes));
1168 psa_key_type_t pk_psa_type = psa_get_key_type(&pk_attributes);
1169 TEST_EQUAL(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_type),
1170 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(pk_psa_type));
1171 PSA_ASSERT(psa_export_public_key(psa_key,
1172 pk_public_buffer,
1173 sizeof(pk_public_buffer),
1174 &pk_public_length));
1175 pk_public = pk_public_buffer;
1176 break;
1177#endif /* MBEDTLS_USE_PSA_CRYPTO */
1178
1179 default:
1180 TEST_FAIL("pk type not supported");
1181 }
1182
1183 uint8_t psa_public[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
1184 size_t psa_public_length = 0;
1185 PSA_ASSERT(psa_export_public_key(psa_key,
1186 psa_public, sizeof(psa_public),
1187 &psa_public_length));
1188 TEST_MEMORY_COMPARE(pk_public, pk_public_length,
1189 psa_public, psa_public_length);
1190
1191 ok = 1;
1192
1193exit:
1194 psa_reset_key_attributes(&psa_attributes);
1195 psa_reset_key_attributes(&pk_attributes);
1196 return ok;
1197}
1198#endif /* MBEDTLS_PK_C */
1199
Gilles Peskine66e7b902021-02-12 23:40:58 +01001200#endif /* MBEDTLS_PSA_CRYPTO_C */