blob: 83359771c1973771f99f11cbcf3837ab5d9202fe [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)) {
441 data_t input_cost = { (unsigned char *) input1, (uint32_t) input1_length };
442 PSA_ASSERT(psa_key_derivation_input_integer(operation,
443 PSA_KEY_DERIVATION_INPUT_COST,
444 parse_binary_string(&input_cost)));
445 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
446 PSA_KEY_DERIVATION_INPUT_SALT,
447 input2,
448 input2_length));
449 PSA_ASSERT(psa_key_derivation_input_key(operation,
450 PSA_KEY_DERIVATION_INPUT_PASSWORD,
451 key));
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100453 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100454 }
455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 if (capacity != SIZE_MAX) {
457 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
458 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100461
462exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100464}
465
466
Gilles Peskine449bd832023-01-11 14:50:10 +0100467static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
468 psa_key_usage_t usage,
469 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100470{
471 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
472 unsigned char input1[] = "Input 1";
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100474 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100475 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100476 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100478
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 if (usage & PSA_KEY_USAGE_DERIVE) {
480 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
481 input1, input1_length,
482 input2, input2_length,
483 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100484 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100486
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
488 output,
489 capacity));
490 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100491 }
492
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100494
495exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100497}
498
499/* We need two keys to exercise key agreement. Exercise the
500 * private key against its own public key. */
501psa_status_t mbedtls_test_psa_key_agreement_with_self(
502 psa_key_derivation_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100504{
505 psa_key_type_t private_key_type;
506 psa_key_type_t public_key_type;
507 size_t key_bits;
508 uint8_t *public_key = NULL;
509 size_t public_key_length;
510 /* Return GENERIC_ERROR if something other than the final call to
511 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
512 * but it's good enough: callers will report it as a failed test anyway. */
513 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
514 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
515
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
517 private_key_type = psa_get_key_type(&attributes);
518 key_bits = psa_get_key_bits(&attributes);
519 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
520 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100521 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
523 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100524
525 status = psa_key_derivation_key_agreement(
526 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100528exit:
529 /*
530 * Key attributes may have been returned by psa_get_key_attributes()
531 * thus reset them as required.
532 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100534
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 mbedtls_free(public_key);
536 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100537}
538
539/* We need two keys to exercise key agreement. Exercise the
540 * private key against its own public key. */
541psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
542 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100544{
545 psa_key_type_t private_key_type;
546 psa_key_type_t public_key_type;
547 size_t key_bits;
548 uint8_t *public_key = NULL;
549 size_t public_key_length;
550 uint8_t output[1024];
551 size_t output_length;
552 /* Return GENERIC_ERROR if something other than the final call to
553 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
554 * but it's good enough: callers will report it as a failed test anyway. */
555 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
556 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
559 private_key_type = psa_get_key_type(&attributes);
560 key_bits = psa_get_key_bits(&attributes);
561 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
562 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100563 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 PSA_ASSERT(psa_export_public_key(key,
565 public_key, public_key_length,
566 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100567
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 status = psa_raw_key_agreement(alg, key,
569 public_key, public_key_length,
570 output, sizeof(output), &output_length);
571 if (status == PSA_SUCCESS) {
572 TEST_ASSERT(output_length <=
573 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
574 key_bits));
575 TEST_ASSERT(output_length <=
576 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100577 }
578
Gilles Peskinee78b0022021-02-13 00:41:11 +0100579exit:
580 /*
581 * Key attributes may have been returned by psa_get_key_attributes()
582 * thus reset them as required.
583 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100585
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 mbedtls_free(public_key);
587 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100588}
589
Gilles Peskine449bd832023-01-11 14:50:10 +0100590static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
591 psa_key_usage_t usage,
592 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100593{
594 int ok = 0;
595
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100597 /* We need two keys to exercise key agreement. Exercise the
598 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100600 }
601 ok = 1;
602
603exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100605}
606
Gilles Peskine449bd832023-01-11 14:50:10 +0100607static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
608 psa_key_usage_t usage,
609 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100610{
611 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200612 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100613 unsigned char output[1];
614 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200616 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100617
Gilles Peskine449bd832023-01-11 14:50:10 +0100618 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100619 /* We need two keys to exercise key agreement. Exercise the
620 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
622 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
623 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
624 PSA_ASSERT(psa_key_derivation_input_bytes(
625 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
626 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100627 }
628
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
630 PSA_ASSERT(psa_key_derivation_input_bytes(
631 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
632 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200633 }
634
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200635 /* For HKDF_EXPAND input secret may fail as secret size may not match
636 to expected PRK size. In practice it means that key bits must match
637 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200639 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
641 size_t key_bits = psa_get_key_bits(&attributes);
642 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200645 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200647 }
648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
650 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200651
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 if (expected_key_agreement_status != PSA_SUCCESS) {
653 return 1;
654 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100655
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
657 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
658 PSA_ASSERT(psa_key_derivation_input_bytes(
659 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
660 input, sizeof(input)));
661 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
662 PSA_ASSERT(psa_key_derivation_input_bytes(
663 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
664 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100665 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
667 output,
668 sizeof(output)));
669 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100670 }
671 ok = 1;
672
673exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100675}
676
677int mbedtls_test_psa_exported_key_sanity_check(
678 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100680{
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100682
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
684 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
685 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100686
Ronald Cron64df7382021-07-06 09:23:06 +0200687#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
689 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100690 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100691 size_t len;
692 /* RSAPrivateKey ::= SEQUENCE {
693 * version INTEGER, -- must be 0
694 * modulus INTEGER, -- n
695 * publicExponent INTEGER, -- e
696 * privateExponent INTEGER, -- d
697 * prime1 INTEGER, -- p
698 * prime2 INTEGER, -- q
699 * exponent1 INTEGER, -- d mod (p-1)
700 * exponent2 INTEGER, -- d mod (q-1)
701 * coefficient INTEGER, -- (inverse of q) mod p
702 * }
703 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
705 MBEDTLS_ASN1_SEQUENCE |
706 MBEDTLS_ASN1_CONSTRUCTED), 0);
707 TEST_EQUAL(len, end - p);
708 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100709 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 }
711 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100712 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 }
714 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100715 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100717 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100719 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100721 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100723 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 }
725 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100726 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100727 }
728 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100729 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 }
731 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100732 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 }
734 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100735 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 }
737 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100738
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
740 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200741#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100744 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
748 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100749
Ronald Cron64df7382021-07-06 09:23:06 +0200750#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
752 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100753 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100754 size_t len;
755 /* RSAPublicKey ::= SEQUENCE {
756 * modulus INTEGER, -- n
757 * publicExponent INTEGER } -- e
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),
762 0);
763 TEST_EQUAL(len, end - p);
764 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100765 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 }
767 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100768 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 }
770 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100771
772
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 TEST_ASSERT(exported_length <=
774 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
775 TEST_ASSERT(exported_length <=
776 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
777 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200778#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100781
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 TEST_ASSERT(exported_length <=
783 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
784 TEST_ASSERT(exported_length <=
785 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100786
Gilles Peskine449bd832023-01-11 14:50:10 +0100787 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100788 /* The representation of an ECC Montgomery public key is
789 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100791 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100792 /* The representation of an ECC Edwards public key is
793 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100794 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100796 /* The representation of an ECC Weierstrass public key is:
797 * - The byte 0x04;
798 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
799 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
800 * - where m is the bit size associated with the curve.
801 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
803 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100804 }
Przemek Stekiel7cf26df2022-12-01 15:09:40 +0100805 } else
806 if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
Przemek Stekiel4c0da512023-04-27 13:04:20 +0200807 TEST_ASSERT(exported_length ==
Przemek Stekiel654bef02022-12-15 13:28:02 +0100808 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
809 TEST_ASSERT(exported_length <=
810 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
Valerio Setti2dbc3062023-04-13 12:19:57 +0200811 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100812 (void) exported;
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100813 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100814 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100815
Gilles Peskinecc9db302021-02-14 01:29:52 +0100816#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100818 /* Check the parity bits. */
819 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100821 unsigned bit_count = 0;
822 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 for (m = 1; m <= 0x100; m <<= 1) {
824 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100825 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100827 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100829 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100830 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100831#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100832
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100834
835exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100837}
838
Gilles Peskine449bd832023-01-11 14:50:10 +0100839static int exercise_export_key(mbedtls_svc_key_id_t key,
840 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100841{
842 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
843 uint8_t *exported = NULL;
844 size_t exported_size = 0;
845 size_t exported_length = 0;
846 int ok = 0;
847
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100849
850 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 psa_get_key_type(&attributes),
852 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100853 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100854
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
856 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
857 TEST_EQUAL(psa_export_key(key, exported,
858 exported_size, &exported_length),
859 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100860 ok = 1;
861 goto exit;
862 }
863
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 PSA_ASSERT(psa_export_key(key,
865 exported, exported_size,
866 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100867 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
869 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100870
871exit:
872 /*
873 * Key attributes may have been returned by psa_get_key_attributes()
874 * thus reset them as required.
875 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100877
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 mbedtls_free(exported);
879 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100880}
881
Gilles Peskine449bd832023-01-11 14:50:10 +0100882static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100883{
884 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
885 psa_key_type_t public_type;
886 uint8_t *exported = NULL;
887 size_t exported_size = 0;
888 size_t exported_length = 0;
889 int ok = 0;
890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
892 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100893 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 psa_get_key_type(&attributes),
895 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100896 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 TEST_EQUAL(psa_export_public_key(key, exported,
899 exported_size, &exported_length),
900 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100901 ok = 1;
902 goto exit;
903 }
904
905 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 psa_get_key_type(&attributes));
907 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
908 psa_get_key_bits(&attributes));
Tom Cosgrove05b2a872023-07-21 11:31:13 +0100909 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 PSA_ASSERT(psa_export_public_key(key,
912 exported, exported_size,
913 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100914 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 public_type, psa_get_key_bits(&attributes),
916 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100917
918exit:
919 /*
920 * Key attributes may have been returned by psa_get_key_attributes()
921 * thus reset them as required.
922 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100924
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 mbedtls_free(exported);
926 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100927}
928
Gilles Peskine449bd832023-01-11 14:50:10 +0100929int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
930 psa_key_usage_t usage,
931 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100932{
Gilles Peskine2385f712021-02-14 01:34:21 +0100933 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100934
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 if (!check_key_attributes_sanity(key)) {
936 return 0;
937 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100938
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800940 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 } else if (PSA_ALG_IS_MAC(alg)) {
942 ok = exercise_mac_key(key, usage, alg);
943 } else if (PSA_ALG_IS_CIPHER(alg)) {
944 ok = exercise_cipher_key(key, usage, alg);
945 } else if (PSA_ALG_IS_AEAD(alg)) {
946 ok = exercise_aead_key(key, usage, alg);
947 } else if (PSA_ALG_IS_SIGN(alg)) {
948 ok = exercise_signature_key(key, usage, alg);
949 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
950 ok = exercise_asymmetric_encryption_key(key, usage, alg);
951 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
952 ok = exercise_key_derivation_key(key, usage, alg);
953 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
954 ok = exercise_raw_key_agreement_key(key, usage, alg);
955 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
956 ok = exercise_key_agreement_key(key, usage, alg);
957 } else {
Agathiyan Bragadeeshdc28a5a2023-07-18 11:45:28 +0100958 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100960
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 ok = ok && exercise_export_key(key, usage);
962 ok = ok && exercise_export_public_key(key);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100963
Gilles Peskine2385f712021-02-14 01:34:21 +0100964exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100966}
967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
969 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100970{
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
972 if (PSA_ALG_IS_SIGN_HASH(alg)) {
973 if (PSA_ALG_SIGN_GET_HASH(alg)) {
974 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
975 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
976 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
977 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
978 }
979 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
980 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
981 PSA_KEY_USAGE_VERIFY_MESSAGE :
982 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +0200983 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200984
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
986 PSA_KEY_USAGE_VERIFY_HASH :
987 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
988 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
989 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
990 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
991 PSA_KEY_USAGE_ENCRYPT :
992 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
993 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
994 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
995 return PSA_KEY_USAGE_DERIVE;
996 } else {
997 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100998 }
999
1000}
Gilles Peskine66e7b902021-02-12 23:40:58 +01001001
1002#endif /* MBEDTLS_PSA_CRYPTO_C */