blob: 7c70fa85c8975745a36f29314354cd6fe05b582f [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 Stekielb66bc0a2021-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 Peskine1b6c09a2023-01-11 14:52:35 +010036static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
Gilles Peskinee78b0022021-02-13 00:41:11 +010037{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +010059 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010060 TEST_ASSERT(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +010073 psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number);
74 if (lifetime_is_dynamic_secure_element(lifetime)) {
Fredrik Hesse5b673a82021-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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100108 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100109
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100110 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100111}
112
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100136 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100137 psa_status_t verify_status =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100148 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100149
150exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100151 psa_mac_abort(&operation);
152 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100153}
154
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100160 unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
Gilles Peskineb5347592022-04-21 11:14:30 +0200161 size_t iv_length;
Gilles Peskine8f3aad22022-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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine8f3aad22022-03-18 18:40:47 +0100173
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine8f3aad22022-03-18 18:40:47 +0100180 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine8f3aad22022-03-18 18:40:47 +0100202 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Case0e7791f2021-12-20 21:14:10 -0800212 * if the input is some arbitrary data rather than an actual
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100222 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100223
224exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100225 psa_cipher_abort(&operation);
226 psa_reset_key_attributes(&attributes);
227 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100228}
229
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100234 unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
Gilles Peskine743972c2022-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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100261 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100262 psa_status_t verify_status =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100275 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100276
277exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100278 psa_reset_key_attributes(&attributes);
279 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100280}
281
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100282static int can_sign_or_verify_message(psa_key_usage_t usage,
283 psa_algorithm_t alg)
Gilles Peskine275ecde2022-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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine275ecde2022-03-19 11:15:41 +0100292}
293
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100298 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH)) {
299 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200300 size_t payload_length = 16;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100301 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
302 size_t signature_length = sizeof(signature);
303 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200304
305 /* If the policy allows signing with any hash, just pick one. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100306 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH) {
Ronald Cronef14af02021-08-31 19:08:55 +0200307 #if defined(KNOWN_MBEDTLS_SUPPORTED_HASH_ALG)
308 hash_alg = KNOWN_MBEDTLS_SUPPORTED_HASH_ALG;
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200309 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
310 #else
Agathiyan Bragadeesh27e29892023-07-14 17:28:27 +0100311 TEST_FAIL("No hash algorithm for hash-and-sign testing");
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200312 #endif
313 }
314
Janos Follath02becd92021-06-14 12:34:30 +0100315 /* Some algorithms require the payload to have the size of
316 * the hash encoded in the algorithm. Use this input size
317 * even for algorithms that allow other input sizes. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100318 if (hash_alg != 0) {
319 payload_length = PSA_HASH_LENGTH(hash_alg);
320 }
Janos Follath02becd92021-06-14 12:34:30 +0100321
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100322 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
323 PSA_ASSERT(psa_sign_hash(key, alg,
324 payload, payload_length,
325 signature, sizeof(signature),
326 &signature_length));
327 }
328
329 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
330 psa_status_t verify_status =
331 (usage & PSA_KEY_USAGE_SIGN_HASH ?
332 PSA_SUCCESS :
333 PSA_ERROR_INVALID_SIGNATURE);
334 TEST_EQUAL(psa_verify_hash(key, alg,
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200335 payload, payload_length,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100336 signature, signature_length),
337 verify_status);
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200338 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100339 }
340
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100341 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200342 unsigned char message[256] = "Hello, world...";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100343 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200344 size_t message_length = 16;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100345 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100346
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100347 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
348 PSA_ASSERT(psa_sign_message(key, alg,
349 message, message_length,
350 signature, sizeof(signature),
351 &signature_length));
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200352 }
353
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100354 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200355 psa_status_t verify_status =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100356 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
357 PSA_SUCCESS :
358 PSA_ERROR_INVALID_SIGNATURE);
359 TEST_EQUAL(psa_verify_message(key, alg,
360 message, message_length,
361 signature, signature_length),
362 verify_status);
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200363 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100364 }
365
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100366 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100367
368exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100369 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100370}
371
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100372static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
373 psa_key_usage_t usage,
374 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100375{
376 unsigned char plaintext[256] = "Hello, world...";
377 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100378 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100379 size_t plaintext_length = 16;
380
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100381 if (usage & PSA_KEY_USAGE_ENCRYPT) {
382 PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
383 plaintext, plaintext_length,
384 NULL, 0,
385 ciphertext, sizeof(ciphertext),
386 &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100387 }
388
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100389 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100390 psa_status_t status =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100391 psa_asymmetric_decrypt(key, alg,
392 ciphertext, ciphertext_length,
393 NULL, 0,
394 plaintext, sizeof(plaintext),
395 &plaintext_length);
396 TEST_ASSERT(status == PSA_SUCCESS ||
397 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
398 (status == PSA_ERROR_INVALID_ARGUMENT ||
399 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100400 }
401
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100402 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100403
404exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100405 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100406}
407
408int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100409 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100410 mbedtls_svc_key_id_t key,
411 psa_algorithm_t alg,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100412 const unsigned char *input1, size_t input1_length,
413 const unsigned char *input2, size_t input2_length,
414 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100415{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100416 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
417 if (PSA_ALG_IS_HKDF(alg)) {
418 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
419 PSA_KEY_DERIVATION_INPUT_SALT,
420 input1, input1_length));
421 PSA_ASSERT(psa_key_derivation_input_key(operation,
422 PSA_KEY_DERIVATION_INPUT_SECRET,
423 key));
424 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
425 PSA_KEY_DERIVATION_INPUT_INFO,
426 input2,
427 input2_length));
428 } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
429 PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
430 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
431 PSA_KEY_DERIVATION_INPUT_SEED,
432 input1, input1_length));
433 PSA_ASSERT(psa_key_derivation_input_key(operation,
434 PSA_KEY_DERIVATION_INPUT_SECRET,
435 key));
436 PSA_ASSERT(psa_key_derivation_input_bytes(operation,
437 PSA_KEY_DERIVATION_INPUT_LABEL,
438 input2, input2_length));
439 } else {
Agathiyan Bragadeesh27e29892023-07-14 17:28:27 +0100440 TEST_FAIL("Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100441 }
442
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100443 if (capacity != SIZE_MAX) {
444 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
445 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100446
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100447 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100448
449exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100450 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100451}
452
453
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100454static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
455 psa_key_usage_t usage,
456 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100457{
458 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
459 unsigned char input1[] = "Input 1";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100460 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100461 unsigned char input2[] = "Input 2";
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100462 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100463 unsigned char output[1];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100464 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100465
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100466 if (usage & PSA_KEY_USAGE_DERIVE) {
467 if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
468 input1, input1_length,
469 input2, input2_length,
470 capacity)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100471 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100472 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100473
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100474 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
475 output,
476 capacity));
477 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100478 }
479
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100480 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100481
482exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100483 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100484}
485
486/* We need two keys to exercise key agreement. Exercise the
487 * private key against its own public key. */
488psa_status_t mbedtls_test_psa_key_agreement_with_self(
489 psa_key_derivation_operation_t *operation,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100490 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100491{
492 psa_key_type_t private_key_type;
493 psa_key_type_t public_key_type;
494 size_t key_bits;
495 uint8_t *public_key = NULL;
496 size_t public_key_length;
497 /* Return GENERIC_ERROR if something other than the final call to
498 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
499 * but it's good enough: callers will report it as a failed test anyway. */
500 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
501 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
502
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100503 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
504 private_key_type = psa_get_key_type(&attributes);
505 key_bits = psa_get_key_bits(&attributes);
506 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
507 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove30ceb232023-09-04 11:20:19 +0100508 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100509 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
510 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100511
512 status = psa_key_derivation_key_agreement(
513 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100514 public_key, public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100515exit:
516 /*
517 * Key attributes may have been returned by psa_get_key_attributes()
518 * thus reset them as required.
519 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100520 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100521
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100522 mbedtls_free(public_key);
523 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100524}
525
526/* We need two keys to exercise key agreement. Exercise the
527 * private key against its own public key. */
528psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
529 psa_algorithm_t alg,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100530 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100531{
532 psa_key_type_t private_key_type;
533 psa_key_type_t public_key_type;
534 size_t key_bits;
535 uint8_t *public_key = NULL;
536 size_t public_key_length;
537 uint8_t output[1024];
538 size_t output_length;
539 /* Return GENERIC_ERROR if something other than the final call to
540 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
541 * but it's good enough: callers will report it as a failed test anyway. */
542 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
543 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
544
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100545 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
546 private_key_type = psa_get_key_type(&attributes);
547 key_bits = psa_get_key_bits(&attributes);
548 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
549 public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
Tom Cosgrove30ceb232023-09-04 11:20:19 +0100550 TEST_CALLOC(public_key, public_key_length);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100551 PSA_ASSERT(psa_export_public_key(key,
552 public_key, public_key_length,
553 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100554
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100555 status = psa_raw_key_agreement(alg, key,
556 public_key, public_key_length,
557 output, sizeof(output), &output_length);
558 if (status == PSA_SUCCESS) {
559 TEST_ASSERT(output_length <=
560 PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
561 key_bits));
562 TEST_ASSERT(output_length <=
563 PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100564 }
565
Gilles Peskinee78b0022021-02-13 00:41:11 +0100566exit:
567 /*
568 * Key attributes may have been returned by psa_get_key_attributes()
569 * thus reset them as required.
570 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100571 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100572
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100573 mbedtls_free(public_key);
574 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100575}
576
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100577static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
578 psa_key_usage_t usage,
579 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100580{
581 int ok = 0;
582
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100583 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100584 /* We need two keys to exercise key agreement. Exercise the
585 * private key against its own public key. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100586 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100587 }
588 ok = 1;
589
590exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100591 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100592}
593
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100594static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
595 psa_key_usage_t usage,
596 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100597{
598 psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskine9d3706f2022-03-19 16:04:30 +0100599 unsigned char input[1];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100600 unsigned char output[1];
601 int ok = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100602 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100603
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100604 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100605 /* We need two keys to exercise key agreement. Exercise the
606 * private key against its own public key. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100607 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
608 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
609 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
610 PSA_ASSERT(psa_key_derivation_input_bytes(
611 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
612 input, sizeof(input)));
Gilles Peskine9d3706f2022-03-19 16:04:30 +0100613 }
614
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100615 PSA_ASSERT(mbedtls_test_psa_key_agreement_with_self(&operation, key));
Gilles Peskine9d3706f2022-03-19 16:04:30 +0100616
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100617 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
618 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
619 PSA_ASSERT(psa_key_derivation_input_bytes(
620 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
621 input, sizeof(input)));
622 } else if (PSA_ALG_IS_HKDF(kdf_alg)) {
623 PSA_ASSERT(psa_key_derivation_input_bytes(
624 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
625 input, sizeof(input)));
Gilles Peskine9d3706f2022-03-19 16:04:30 +0100626 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100627 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
628 output,
629 sizeof(output)));
630 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100631 }
632 ok = 1;
633
634exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100635 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100636}
637
638int mbedtls_test_psa_exported_key_sanity_check(
639 psa_key_type_t type, size_t bits,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100640 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100641{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100642 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100643
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100644 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
645 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
646 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100647
Ronald Cronfefa4582021-07-06 09:23:06 +0200648#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100649 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
650 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100651 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100652 size_t len;
653 /* RSAPrivateKey ::= SEQUENCE {
654 * version INTEGER, -- must be 0
655 * modulus INTEGER, -- n
656 * publicExponent INTEGER, -- e
657 * privateExponent INTEGER, -- d
658 * prime1 INTEGER, -- p
659 * prime2 INTEGER, -- q
660 * exponent1 INTEGER, -- d mod (p-1)
661 * exponent2 INTEGER, -- d mod (q-1)
662 * coefficient INTEGER, -- (inverse of q) mod p
663 * }
664 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100665 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
666 MBEDTLS_ASN1_SEQUENCE |
667 MBEDTLS_ASN1_CONSTRUCTED), 0);
668 TEST_EQUAL(len, end - p);
669 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100670 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100671 }
672 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100673 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100674 }
675 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100676 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100677 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100678 /* Require d to be at least half the size of n. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100679 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100680 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100681 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100682 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100683 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100684 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100685 }
686 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100687 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100688 }
689 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100690 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100691 }
692 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100693 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100694 }
695 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100696 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100697 }
698 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100699
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100700 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
701 } else
Ronald Cronfefa4582021-07-06 09:23:06 +0200702#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100703
704#if defined(MBEDTLS_ECP_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100705 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100706 /* Just the secret value */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100707 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100708
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100709 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
710 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100711#endif /* MBEDTLS_ECP_C */
712
Ronald Cronfefa4582021-07-06 09:23:06 +0200713#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100714 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
715 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100716 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100717 size_t len;
718 /* RSAPublicKey ::= SEQUENCE {
719 * modulus INTEGER, -- n
720 * publicExponent INTEGER } -- e
721 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100722 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
723 MBEDTLS_ASN1_SEQUENCE |
724 MBEDTLS_ASN1_CONSTRUCTED),
725 0);
726 TEST_EQUAL(len, end - p);
727 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100728 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100729 }
730 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100731 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100732 }
733 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100734
735
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100736 TEST_ASSERT(exported_length <=
737 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
738 TEST_ASSERT(exported_length <=
739 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
740 } else
Ronald Cronfefa4582021-07-06 09:23:06 +0200741#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100742
Gilles Peskinee78b0022021-02-13 00:41:11 +0100743#if defined(MBEDTLS_ECP_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100744 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100745
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100746 TEST_ASSERT(exported_length <=
747 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
748 TEST_ASSERT(exported_length <=
749 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100750
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100751 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100752 /* The representation of an ECC Montgomery public key is
753 * the raw compressed point */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100754 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
755 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100756 /* The representation of an ECC Weierstrass public key is:
757 * - The byte 0x04;
758 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
759 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
760 * - where m is the bit size associated with the curve.
761 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100762 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
763 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100764 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100765 } else
Gilles Peskinead557e52021-02-14 01:19:21 +0100766#endif /* MBEDTLS_ECP_C */
767
Gilles Peskinead557e52021-02-14 01:19:21 +0100768 {
Andrzej Kurek53ad7632022-01-17 15:26:24 +0100769 (void) exported;
Agathiyan Bragadeesh27e29892023-07-14 17:28:27 +0100770 TEST_FAIL("Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100771 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100772
Gilles Peskinecc9db302021-02-14 01:29:52 +0100773#if defined(MBEDTLS_DES_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100774 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100775 /* Check the parity bits. */
776 unsigned i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100777 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100778 unsigned bit_count = 0;
779 unsigned m;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100780 for (m = 1; m <= 0x100; m <<= 1) {
781 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100782 ++bit_count;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100783 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100784 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100785 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100786 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100787 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100788#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100789
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100790 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100791
792exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100793 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100794}
795
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100796static int exercise_export_key(mbedtls_svc_key_id_t key,
797 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100798{
799 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
800 uint8_t *exported = NULL;
801 size_t exported_size = 0;
802 size_t exported_length = 0;
803 int ok = 0;
804
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100805 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100806
807 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100808 psa_get_key_type(&attributes),
809 psa_get_key_bits(&attributes));
Tom Cosgrove30ceb232023-09-04 11:20:19 +0100810 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100811
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100812 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
813 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
814 TEST_EQUAL(psa_export_key(key, exported,
815 exported_size, &exported_length),
816 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100817 ok = 1;
818 goto exit;
819 }
820
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100821 PSA_ASSERT(psa_export_key(key,
822 exported, exported_size,
823 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100824 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100825 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
826 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100827
828exit:
829 /*
830 * Key attributes may have been returned by psa_get_key_attributes()
831 * thus reset them as required.
832 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100833 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100834
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100835 mbedtls_free(exported);
836 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100837}
838
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100839static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100840{
841 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
842 psa_key_type_t public_type;
843 uint8_t *exported = NULL;
844 size_t exported_size = 0;
845 size_t exported_length = 0;
846 int ok = 0;
847
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100848 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
849 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100850 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100851 psa_get_key_type(&attributes),
852 psa_get_key_bits(&attributes));
Tom Cosgrove30ceb232023-09-04 11:20:19 +0100853 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100854
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100855 TEST_EQUAL(psa_export_public_key(key, exported,
856 exported_size, &exported_length),
857 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100858 ok = 1;
859 goto exit;
860 }
861
862 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100863 psa_get_key_type(&attributes));
864 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
865 psa_get_key_bits(&attributes));
Tom Cosgrove30ceb232023-09-04 11:20:19 +0100866 TEST_CALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100867
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100868 PSA_ASSERT(psa_export_public_key(key,
869 exported, exported_size,
870 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100871 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100872 public_type, psa_get_key_bits(&attributes),
873 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100874
875exit:
876 /*
877 * Key attributes may have been returned by psa_get_key_attributes()
878 * thus reset them as required.
879 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100880 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100881
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100882 mbedtls_free(exported);
883 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100884}
885
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100886int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
887 psa_key_usage_t usage,
888 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100889{
Gilles Peskine2385f712021-02-14 01:34:21 +0100890 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100891
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100892 if (!check_key_attributes_sanity(key)) {
893 return 0;
894 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100895
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100896 if (alg == 0) {
Shaun Case0e7791f2021-12-20 21:14:10 -0800897 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100898 } else if (PSA_ALG_IS_MAC(alg)) {
899 ok = exercise_mac_key(key, usage, alg);
900 } else if (PSA_ALG_IS_CIPHER(alg)) {
901 ok = exercise_cipher_key(key, usage, alg);
902 } else if (PSA_ALG_IS_AEAD(alg)) {
903 ok = exercise_aead_key(key, usage, alg);
904 } else if (PSA_ALG_IS_SIGN(alg)) {
905 ok = exercise_signature_key(key, usage, alg);
906 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
907 ok = exercise_asymmetric_encryption_key(key, usage, alg);
908 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
909 ok = exercise_key_derivation_key(key, usage, alg);
910 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
911 ok = exercise_raw_key_agreement_key(key, usage, alg);
912 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
913 ok = exercise_key_agreement_key(key, usage, alg);
914 } else {
Agathiyan Bragadeesh27e29892023-07-14 17:28:27 +0100915 TEST_FAIL("No code to exercise this category of algorithm");
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100916 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100917
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100918 ok = ok && exercise_export_key(key, usage);
919 ok = ok && exercise_export_public_key(key);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100920
Gilles Peskine2385f712021-02-14 01:34:21 +0100921exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100922 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100923}
924
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100925psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
926 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100927{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100928 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
929 if (PSA_ALG_IS_SIGN_HASH(alg)) {
930 if (PSA_ALG_SIGN_GET_HASH(alg)) {
931 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
932 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
933 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
934 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
935 }
936 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
937 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
938 PSA_KEY_USAGE_VERIFY_MESSAGE :
939 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm72616972021-05-11 13:29:24 +0200940 }
gabor-mezei-arm7a74c132021-04-26 20:12:17 +0200941
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100942 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
943 PSA_KEY_USAGE_VERIFY_HASH :
944 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
945 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
946 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
947 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
948 PSA_KEY_USAGE_ENCRYPT :
949 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
950 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
951 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
952 return PSA_KEY_USAGE_DERIVE;
953 } else {
954 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100955 }
956
957}
Gilles Peskine66e7b902021-02-12 23:40:58 +0100958
959#endif /* MBEDTLS_PSA_CRYPTO_C */