blob: c4488b56f12ced145bad0017d1eac469c9845d74 [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
7 * SPDX-License-Identifier: Apache-2.0
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
10 * not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21
22#include <test/helpers.h>
23#include <test/macros.h>
Gilles Peskinee78b0022021-02-13 00:41:11 +010024#include <test/psa_exercise_key.h>
Gilles Peskine66e7b902021-02-12 23:40:58 +010025
26#if defined(MBEDTLS_PSA_CRYPTO_C)
27
Gilles Peskinee78b0022021-02-13 00:41:11 +010028#include <mbedtls/asn1.h>
Gilles Peskine66e7b902021-02-12 23:40:58 +010029#include <psa/crypto.h>
30
Gilles Peskinee78b0022021-02-13 00:41:11 +010031#include <test/asn1_helpers.h>
Przemyslaw Stekiel53de2622021-11-03 09:35:35 +010032#include <psa_crypto_slot_management.h>
Gilles Peskinee78b0022021-02-13 00:41:11 +010033#include <test/psa_crypto_helpers.h>
34
35#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +010036static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
Gilles Peskinee78b0022021-02-13 00:41:11 +010037{
Gilles Peskine449bd832023-01-11 14:50:10 +010038 return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
39 PSA_KEY_LOCATION_LOCAL_STORAGE;
Gilles Peskinee78b0022021-02-13 00:41:11 +010040}
41#endif
42
Gilles Peskine449bd832023-01-11 14:50:10 +010043static int check_key_attributes_sanity(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +010044{
45 int ok = 0;
46 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
47 psa_key_lifetime_t lifetime;
48 mbedtls_svc_key_id_t id;
49 psa_key_type_t type;
Gilles Peskine6b362e62021-02-15 12:03:16 +010050 size_t bits;
Gilles Peskinee78b0022021-02-13 00:41:11 +010051
Gilles Peskine449bd832023-01-11 14:50:10 +010052 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
53 lifetime = psa_get_key_lifetime(&attributes);
54 id = psa_get_key_id(&attributes);
55 type = psa_get_key_type(&attributes);
56 bits = psa_get_key_bits(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +010057
58 /* Persistence */
Gilles Peskine449bd832023-01-11 14:50:10 +010059 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010060 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010061 (PSA_KEY_ID_VOLATILE_MIN <=
62 MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
63 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
64 PSA_KEY_ID_VOLATILE_MAX));
65 } else {
Gilles Peskinee78b0022021-02-13 00:41:11 +010066 TEST_ASSERT(
Gilles Peskine449bd832023-01-11 14:50:10 +010067 (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
68 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
Gilles Peskinee78b0022021-02-13 00:41:11 +010069 }
70#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
71 /* randomly-generated 64-bit constant, should never appear in test data */
72 psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
Gilles Peskine449bd832023-01-11 14:50:10 +010073 psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number);
74 if (lifetime_is_dynamic_secure_element(lifetime)) {
Fredrik Hessecc207bc2021-09-28 21:06:08 +020075 /* Mbed TLS currently always exposes the slot number to
Gilles Peskinee78b0022021-02-13 00:41:11 +010076 * applications. This is not mandated by the PSA specification
77 * and may change in future versions. */
Gilles Peskine449bd832023-01-11 14:50:10 +010078 TEST_EQUAL(status, 0);
79 TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
80 } else {
81 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +010082 }
83#endif
84
85 /* Type and size */
Gilles Peskine449bd832023-01-11 14:50:10 +010086 TEST_ASSERT(type != 0);
87 TEST_ASSERT(bits != 0);
88 TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
89 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
90 TEST_ASSERT(bits % 8 == 0);
91 }
Gilles Peskinee78b0022021-02-13 00:41:11 +010092
93 /* MAX macros concerning specific key types */
Gilles Peskine449bd832023-01-11 14:50:10 +010094 if (PSA_KEY_TYPE_IS_ECC(type)) {
95 TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
96 } else if (PSA_KEY_TYPE_IS_RSA(type)) {
97 TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
98 }
99 TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100100
101 ok = 1;
102
103exit:
104 /*
105 * Key attributes may have been returned by psa_get_key_attributes()
106 * thus reset them as required.
107 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100109
Gilles Peskine449bd832023-01-11 14:50:10 +0100110 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100111}
112
Gilles Peskine449bd832023-01-11 14:50:10 +0100113static int exercise_mac_key(mbedtls_svc_key_id_t key,
114 psa_key_usage_t usage,
115 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100116{
117 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
118 const unsigned char input[] = "foo";
Gilles Peskine449bd832023-01-11 14:50:10 +0100119 unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
120 size_t mac_length = sizeof(mac);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100121
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100122 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100123 if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
124 alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100125 }
126
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
128 PSA_ASSERT(psa_mac_sign_setup(&operation, key, alg));
129 PSA_ASSERT(psa_mac_update(&operation,
130 input, sizeof(input)));
131 PSA_ASSERT(psa_mac_sign_finish(&operation,
132 mac, sizeof(mac),
133 &mac_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100134 }
135
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100137 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 (usage & PSA_KEY_USAGE_SIGN_HASH ?
139 PSA_SUCCESS :
140 PSA_ERROR_INVALID_SIGNATURE);
141 PSA_ASSERT(psa_mac_verify_setup(&operation, key, alg));
142 PSA_ASSERT(psa_mac_update(&operation,
143 input, sizeof(input)));
144 TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
145 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100146 }
147
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100149
150exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 psa_mac_abort(&operation);
152 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100153}
154
Gilles Peskine449bd832023-01-11 14:50:10 +0100155static int exercise_cipher_key(mbedtls_svc_key_id_t key,
156 psa_key_usage_t usage,
157 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100158{
159 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100160 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
Gilles Peskine5eef11a2022-04-21 11:14:30 +0200161 size_t iv_length;
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100162 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
163 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100164 const unsigned char plaintext[16] = "Hello, world...";
165 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100166 size_t ciphertext_length = sizeof(ciphertext);
167 unsigned char decrypted[sizeof(ciphertext)];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100168 size_t part_length;
169
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
171 key_type = psa_get_key_type(&attributes);
172 iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100173
Gilles Peskine449bd832023-01-11 14:50:10 +0100174 if (usage & PSA_KEY_USAGE_ENCRYPT) {
175 PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
176 if (iv_length != 0) {
177 PSA_ASSERT(psa_cipher_generate_iv(&operation,
178 iv, sizeof(iv),
179 &iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100180 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 PSA_ASSERT(psa_cipher_update(&operation,
182 plaintext, sizeof(plaintext),
183 ciphertext, sizeof(ciphertext),
184 &ciphertext_length));
185 PSA_ASSERT(psa_cipher_finish(&operation,
186 ciphertext + ciphertext_length,
187 sizeof(ciphertext) - ciphertext_length,
188 &part_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100189 ciphertext_length += part_length;
190 }
191
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100193 psa_status_t status;
194 int maybe_invalid_padding = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100195 if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
196 maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100197 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
199 if (iv_length != 0) {
200 PSA_ASSERT(psa_cipher_set_iv(&operation,
201 iv, iv_length));
Gilles Peskinebbf452c2022-03-18 18:40:47 +0100202 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 PSA_ASSERT(psa_cipher_update(&operation,
204 ciphertext, ciphertext_length,
205 decrypted, sizeof(decrypted),
206 &part_length));
207 status = psa_cipher_finish(&operation,
208 decrypted + part_length,
209 sizeof(decrypted) - part_length,
210 &part_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100211 /* For a stream cipher, all inputs are valid. For a block cipher,
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800212 * if the input is some arbitrary data rather than an actual
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 ciphertext, a padding error is likely. */
214 if (maybe_invalid_padding) {
215 TEST_ASSERT(status == PSA_SUCCESS ||
216 status == PSA_ERROR_INVALID_PADDING);
217 } else {
218 PSA_ASSERT(status);
219 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100220 }
221
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100223
224exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 psa_cipher_abort(&operation);
226 psa_reset_key_attributes(&attributes);
227 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100228}
229
Gilles Peskine449bd832023-01-11 14:50:10 +0100230static int exercise_aead_key(mbedtls_svc_key_id_t key,
231 psa_key_usage_t usage,
232 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100233{
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
Gilles Peskine7acb1982022-03-19 11:03:32 +0100235 size_t nonce_length;
236 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
237 psa_key_type_t key_type;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100238 unsigned char plaintext[16] = "Hello, world...";
239 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 size_t ciphertext_length = sizeof(ciphertext);
241 size_t plaintext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100242
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100243 /* Convert wildcard algorithm to exercisable algorithm */
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
245 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100246 }
247
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
249 key_type = psa_get_key_type(&attributes);
250 nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
Steven Cooremanaaec3412021-02-18 13:30:34 +0100251
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 if (usage & PSA_KEY_USAGE_ENCRYPT) {
253 PSA_ASSERT(psa_aead_encrypt(key, alg,
254 nonce, nonce_length,
255 NULL, 0,
256 plaintext, sizeof(plaintext),
257 ciphertext, sizeof(ciphertext),
258 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100259 }
260
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100262 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 (usage & PSA_KEY_USAGE_ENCRYPT ?
264 PSA_SUCCESS :
265 PSA_ERROR_INVALID_SIGNATURE);
266 TEST_EQUAL(psa_aead_decrypt(key, alg,
267 nonce, nonce_length,
268 NULL, 0,
269 ciphertext, ciphertext_length,
270 plaintext, sizeof(plaintext),
271 &plaintext_length),
272 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100273 }
274
Gilles Peskine449bd832023-01-11 14:50:10 +0100275 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100276
277exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 psa_reset_key_attributes(&attributes);
279 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100280}
281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282static int can_sign_or_verify_message(psa_key_usage_t usage,
283 psa_algorithm_t alg)
Gilles Peskined586b822022-03-19 11:15:41 +0100284{
285 /* Sign-the-unspecified-hash algorithms can only be used with
286 * {sign,verify}_hash, not with {sign,verify}_message. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
288 return 0;
289 }
290 return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
291 PSA_KEY_USAGE_VERIFY_MESSAGE);
Gilles Peskined586b822022-03-19 11:15:41 +0100292}
293
Gilles Peskine449bd832023-01-11 14:50:10 +0100294static int exercise_signature_key(mbedtls_svc_key_id_t key,
295 psa_key_usage_t usage,
296 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100297{
oberon-skf7a824b2023-02-15 19:43:30 +0100298 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
299 PSA_ALG_IS_SIGN_HASH(alg)) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200301 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
303 size_t signature_length = sizeof(signature);
304 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200305
306 /* If the policy allows signing with any hash, just pick one. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH) {
Przemek Stekiel8258ea72022-10-19 12:17:19 +0200308 #if defined(KNOWN_SUPPORTED_HASH_ALG)
309 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200310 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
311 #else
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100312 TEST_FAIL("No hash algorithm for hash-and-sign testing");
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200313 #endif
314 }
315
Janos Follath4c0b60e2021-06-14 12:34:30 +0100316 /* Some algorithms require the payload to have the size of
317 * the hash encoded in the algorithm. Use this input size
318 * even for algorithms that allow other input sizes. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 if (hash_alg != 0) {
320 payload_length = PSA_HASH_LENGTH(hash_alg);
321 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100322
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
324 PSA_ASSERT(psa_sign_hash(key, alg,
325 payload, payload_length,
326 signature, sizeof(signature),
327 &signature_length));
328 }
329
330 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
331 psa_status_t verify_status =
332 (usage & PSA_KEY_USAGE_SIGN_HASH ?
333 PSA_SUCCESS :
334 PSA_ERROR_INVALID_SIGNATURE);
335 TEST_EQUAL(psa_verify_hash(key, alg,
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200336 payload, payload_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 signature, signature_length),
338 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200339 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100340 }
341
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200343 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200345 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100347
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
349 PSA_ASSERT(psa_sign_message(key, alg,
350 message, message_length,
351 signature, sizeof(signature),
352 &signature_length));
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200353 }
354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200356 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
358 PSA_SUCCESS :
359 PSA_ERROR_INVALID_SIGNATURE);
360 TEST_EQUAL(psa_verify_message(key, alg,
361 message, message_length,
362 signature, signature_length),
363 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200364 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100365 }
366
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100368
369exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100371}
372
Gilles Peskine449bd832023-01-11 14:50:10 +0100373static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
374 psa_key_usage_t usage,
375 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100376{
377 unsigned char plaintext[256] = "Hello, world...";
378 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100380 size_t plaintext_length = 16;
381
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 if (usage & PSA_KEY_USAGE_ENCRYPT) {
383 PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
384 plaintext, plaintext_length,
385 NULL, 0,
386 ciphertext, sizeof(ciphertext),
387 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100388 }
389
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100391 psa_status_t status =
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 psa_asymmetric_decrypt(key, alg,
393 ciphertext, ciphertext_length,
394 NULL, 0,
395 plaintext, sizeof(plaintext),
396 &plaintext_length);
397 TEST_ASSERT(status == PSA_SUCCESS ||
398 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
399 (status == PSA_ERROR_INVALID_ARGUMENT ||
400 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100401 }
402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100404
405exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100407}
408
409int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100411 mbedtls_svc_key_id_t key,
412 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 const unsigned char *input1, size_t input1_length,
414 const unsigned char *input2, size_t input2_length,
415 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100416{
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
418 if (PSA_ALG_IS_HKDF(alg)) {
419 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
420 PSA_KEY_DERIVATION_INPUT_SALT,
421 input1, input1_length));
422 PSA_ASSERT(psa_key_derivation_input_key(operation,
423 PSA_KEY_DERIVATION_INPUT_SECRET,
424 key));
425 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
426 PSA_KEY_DERIVATION_INPUT_INFO,
427 input2,
428 input2_length));
429 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
430 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
431 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
432 PSA_KEY_DERIVATION_INPUT_SEED,
433 input1, input1_length));
434 PSA_ASSERT(psa_key_derivation_input_key(operation,
435 PSA_KEY_DERIVATION_INPUT_SECRET,
436 key));
437 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
438 PSA_KEY_DERIVATION_INPUT_LABEL,
439 input2, input2_length));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530440 } else if (PSA_ALG_IS_PBKDF2(alg)) {
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530441 PSA_ASSERT(psa_key_derivation_input_integer(operation,
442 PSA_KEY_DERIVATION_INPUT_COST,
Kusumit Ghoderao94d31902023-09-05 19:30:22 +0530443 1U));
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530444 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
445 PSA_KEY_DERIVATION_INPUT_SALT,
446 input2,
447 input2_length));
448 PSA_ASSERT(psa_key_derivation_input_key(operation,
449 PSA_KEY_DERIVATION_INPUT_PASSWORD,
450 key));
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100452 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100453 }
454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 if (capacity != SIZE_MAX) {
456 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
457 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100458
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100460
461exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100463}
464
465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
467 psa_key_usage_t usage,
468 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100469{
470 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
471 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100473 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100475 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 if (usage & PSA_KEY_USAGE_DERIVE) {
479 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
480 input1, input1_length,
481 input2, input2_length,
482 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100483 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100485
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
487 output,
488 capacity));
489 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100490 }
491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100493
494exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100496}
497
498/* We need two keys to exercise key agreement. Exercise the
499 * private key against its own public key. */
500psa_status_t mbedtls_test_psa_key_agreement_with_self(
501 psa_key_derivation_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100503{
504 psa_key_type_t private_key_type;
505 psa_key_type_t public_key_type;
506 size_t key_bits;
507 uint8_t *public_key = NULL;
508 size_t public_key_length;
509 /* Return GENERIC_ERROR if something other than the final call to
510 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
511 * but it's good enough: callers will report it as a failed test anyway. */
512 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
513 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
514
Gilles Peskine449bd832023-01-11 14:50:10 +0100515 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
516 private_key_type = psa_get_key_type(&attributes);
517 key_bits = psa_get_key_bits(&attributes);
518 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
519 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100520 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
522 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100523
524 status = psa_key_derivation_key_agreement(
525 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100527exit:
528 /*
529 * Key attributes may have been returned by psa_get_key_attributes()
530 * thus reset them as required.
531 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 mbedtls_free(public_key);
535 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100536}
537
538/* We need two keys to exercise key agreement. Exercise the
539 * private key against its own public key. */
540psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
541 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100543{
544 psa_key_type_t private_key_type;
545 psa_key_type_t public_key_type;
546 size_t key_bits;
547 uint8_t *public_key = NULL;
548 size_t public_key_length;
549 uint8_t output[1024];
550 size_t output_length;
551 /* Return GENERIC_ERROR if something other than the final call to
552 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
553 * but it's good enough: callers will report it as a failed test anyway. */
554 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
555 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
556
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
558 private_key_type = psa_get_key_type(&attributes);
559 key_bits = psa_get_key_bits(&attributes);
560 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
561 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100562 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 PSA_ASSERT(psa_export_public_key(key,
564 public_key, public_key_length,
565 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100566
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 status = psa_raw_key_agreement(alg, key,
568 public_key, public_key_length,
569 output, sizeof(output), &output_length);
570 if (status == PSA_SUCCESS) {
571 TEST_ASSERT(output_length <=
572 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
573 key_bits));
574 TEST_ASSERT(output_length <=
575 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100576 }
577
Gilles Peskinee78b0022021-02-13 00:41:11 +0100578exit:
579 /*
580 * Key attributes may have been returned by psa_get_key_attributes()
581 * thus reset them as required.
582 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100584
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 mbedtls_free(public_key);
586 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100587}
588
Gilles Peskine449bd832023-01-11 14:50:10 +0100589static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
590 psa_key_usage_t usage,
591 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100592{
593 int ok = 0;
594
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100596 /* We need two keys to exercise key agreement. Exercise the
597 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100599 }
600 ok = 1;
601
602exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100604}
605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
607 psa_key_usage_t usage,
608 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100609{
610 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200611 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100612 unsigned char output[1];
613 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200615 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100618 /* We need two keys to exercise key agreement. Exercise the
619 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
621 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
622 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
623 PSA_ASSERT(psa_key_derivation_input_bytes(
624 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
625 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100626 }
627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
629 PSA_ASSERT(psa_key_derivation_input_bytes(
630 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
631 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200632 }
633
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200634 /* For HKDF_EXPAND input secret may fail as secret size may not match
635 to expected PRK size. In practice it means that key bits must match
636 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200638 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
640 size_t key_bits = psa_get_key_bits(&attributes);
641 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200642
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200644 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200646 }
647
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
649 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200650
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 if (expected_key_agreement_status != PSA_SUCCESS) {
652 return 1;
653 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
656 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
657 PSA_ASSERT(psa_key_derivation_input_bytes(
658 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
659 input, sizeof(input)));
660 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
661 PSA_ASSERT(psa_key_derivation_input_bytes(
662 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
663 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100664 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
666 output,
667 sizeof(output)));
668 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100669 }
670 ok = 1;
671
672exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100674}
675
676int mbedtls_test_psa_exported_key_sanity_check(
677 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100679{
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
683 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
684 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100685
Ronald Cron64df7382021-07-06 09:23:06 +0200686#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
688 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100689 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100690 size_t len;
691 /* RSAPrivateKey ::= SEQUENCE {
692 * version INTEGER, -- must be 0
693 * modulus INTEGER, -- n
694 * publicExponent INTEGER, -- e
695 * privateExponent INTEGER, -- d
696 * prime1 INTEGER, -- p
697 * prime2 INTEGER, -- q
698 * exponent1 INTEGER, -- d mod (p-1)
699 * exponent2 INTEGER, -- d mod (q-1)
700 * coefficient INTEGER, -- (inverse of q) mod p
701 * }
702 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
704 MBEDTLS_ASN1_SEQUENCE |
705 MBEDTLS_ASN1_CONSTRUCTED), 0);
706 TEST_EQUAL(len, end - p);
707 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100708 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 }
710 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100711 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 }
713 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100714 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100716 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100718 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100720 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100722 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 }
724 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100725 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 }
727 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100728 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 }
730 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100731 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 }
733 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100734 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 }
736 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100737
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
739 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200740#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100741
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100743 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100745
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
747 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100748
Ronald Cron64df7382021-07-06 09:23:06 +0200749#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
751 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100752 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100753 size_t len;
754 /* RSAPublicKey ::= SEQUENCE {
755 * modulus INTEGER, -- n
756 * publicExponent INTEGER } -- e
757 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
759 MBEDTLS_ASN1_SEQUENCE |
760 MBEDTLS_ASN1_CONSTRUCTED),
761 0);
762 TEST_EQUAL(len, end - p);
763 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100764 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 }
766 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100767 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 }
769 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100770
771
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 TEST_ASSERT(exported_length <=
773 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
774 TEST_ASSERT(exported_length <=
775 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
776 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200777#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100778
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100780
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 TEST_ASSERT(exported_length <=
782 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
783 TEST_ASSERT(exported_length <=
784 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100785
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100787 /* The representation of an ECC Montgomery public key is
788 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100790 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100791 /* The representation of an ECC Edwards public key is
792 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100793 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100795 /* The representation of an ECC Weierstrass public key is:
796 * - The byte 0x04;
797 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
798 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
799 * - where m is the bit size associated with the curve.
800 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
802 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100803 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100804 } else
805 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200806 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100807 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
808 TEST_ASSERT(exported_length <=
809 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200810 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100811 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100812 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100813 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100814
Gilles Peskinecc9db302021-02-14 01:29:52 +0100815#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100816 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100817 /* Check the parity bits. */
818 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100820 unsigned bit_count = 0;
821 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 for (m = 1; m <= 0x100; m <<= 1) {
823 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100824 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100826 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100828 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100829 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100830#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100831
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100833
834exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100836}
837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838static int exercise_export_key(mbedtls_svc_key_id_t key,
839 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100840{
841 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
842 uint8_t *exported = NULL;
843 size_t exported_size = 0;
844 size_t exported_length = 0;
845 int ok = 0;
846
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100848
849 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 psa_get_key_type(&attributes),
851 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100852 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100853
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
855 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
856 TEST_EQUAL(psa_export_key(key, exported,
857 exported_size, &exported_length),
858 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100859 ok = 1;
860 goto exit;
861 }
862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 PSA_ASSERT(psa_export_key(key,
864 exported, exported_size,
865 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100866 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100867 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
868 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100869
870exit:
871 /*
872 * Key attributes may have been returned by psa_get_key_attributes()
873 * thus reset them as required.
874 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100876
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 mbedtls_free(exported);
878 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100879}
880
Gilles Peskine449bd832023-01-11 14:50:10 +0100881static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100882{
883 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
884 psa_key_type_t public_type;
885 uint8_t *exported = NULL;
886 size_t exported_size = 0;
887 size_t exported_length = 0;
888 int ok = 0;
889
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
891 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100892 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 psa_get_key_type(&attributes),
894 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100895 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100896
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 TEST_EQUAL(psa_export_public_key(key, exported,
898 exported_size, &exported_length),
899 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100900 ok = 1;
901 goto exit;
902 }
903
904 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 psa_get_key_type(&attributes));
906 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
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 PSA_ASSERT(psa_export_public_key(key,
911 exported, exported_size,
912 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100913 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 public_type, psa_get_key_bits(&attributes),
915 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100916
917exit:
918 /*
919 * Key attributes may have been returned by psa_get_key_attributes()
920 * thus reset them as required.
921 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100923
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 mbedtls_free(exported);
925 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100926}
927
Gilles Peskine449bd832023-01-11 14:50:10 +0100928int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
929 psa_key_usage_t usage,
930 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100931{
Gilles Peskine2385f712021-02-14 01:34:21 +0100932 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 if (!check_key_attributes_sanity(key)) {
935 return 0;
936 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100937
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800939 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 } else if (PSA_ALG_IS_MAC(alg)) {
941 ok = exercise_mac_key(key, usage, alg);
942 } else if (PSA_ALG_IS_CIPHER(alg)) {
943 ok = exercise_cipher_key(key, usage, alg);
944 } else if (PSA_ALG_IS_AEAD(alg)) {
945 ok = exercise_aead_key(key, usage, alg);
946 } else if (PSA_ALG_IS_SIGN(alg)) {
947 ok = exercise_signature_key(key, usage, alg);
948 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
949 ok = exercise_asymmetric_encryption_key(key, usage, alg);
950 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
951 ok = exercise_key_derivation_key(key, usage, alg);
952 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
953 ok = exercise_raw_key_agreement_key(key, usage, alg);
954 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
955 ok = exercise_key_agreement_key(key, usage, alg);
956 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100957 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100959
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 ok = ok && exercise_export_key(key, usage);
961 ok = ok && exercise_export_public_key(key);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100962
Gilles Peskine2385f712021-02-14 01:34:21 +0100963exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100965}
966
Gilles Peskine449bd832023-01-11 14:50:10 +0100967psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
968 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100969{
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
971 if (PSA_ALG_IS_SIGN_HASH(alg)) {
972 if (PSA_ALG_SIGN_GET_HASH(alg)) {
973 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
974 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
975 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
976 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
977 }
978 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
979 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
980 PSA_KEY_USAGE_VERIFY_MESSAGE :
981 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +0200982 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
985 PSA_KEY_USAGE_VERIFY_HASH :
986 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
987 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
988 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
989 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
990 PSA_KEY_USAGE_ENCRYPT :
991 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
992 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
993 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
994 return PSA_KEY_USAGE_DERIVE;
995 } else {
996 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100997 }
998
999}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001000
1001#endif /* MBEDTLS_PSA_CRYPTO_C */