blob: 2656deb4375edf257530c8c3c145f6f894e6d7ff [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)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010075 /* Mbed Crypto currently always exposes the slot number to
76 * 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{
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH)) {
299 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200300 size_t payload_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +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-arm4c6a47a2021-04-26 20:12:17 +0200304
305 /* If the policy allows signing with any hash, just pick one. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH) {
Przemek Stekiel8258ea72022-10-19 12:17:19 +0200307 #if defined(KNOWN_SUPPORTED_HASH_ALG)
308 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200309 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
310 #else
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 TEST_ASSERT(!"No hash algorithm for hash-and-sign testing");
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200312 #endif
313 }
314
Janos Follath4c0b60e2021-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 Peskine449bd832023-01-11 14:50:10 +0100318 if (hash_alg != 0) {
319 payload_length = PSA_HASH_LENGTH(hash_alg);
320 }
Janos Follath4c0b60e2021-06-14 12:34:30 +0100321
Gilles Peskine449bd832023-01-11 14:50:10 +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-arm4c6a47a2021-04-26 20:12:17 +0200335 payload, payload_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 signature, signature_length),
337 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200338 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100339 }
340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 if (can_sign_or_verify_message(usage, alg)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200342 unsigned char message[256] = "Hello, world...";
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200344 size_t message_length = 16;
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100346
Gilles Peskine449bd832023-01-11 14:50:10 +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-arm4c6a47a2021-04-26 20:12:17 +0200352 }
353
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200355 psa_status_t verify_status =
Gilles Peskine449bd832023-01-11 14:50:10 +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-arm4c6a47a2021-04-26 20:12:17 +0200363 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100364 }
365
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100367
368exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100370}
371
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100378 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100379 size_t plaintext_length = 16;
380
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100389 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100390 psa_status_t status =
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100402 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100403
404exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100406}
407
408int mbedtls_test_psa_setup_key_derivation_wrap(
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 {
440 TEST_ASSERT(!"Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100441 }
442
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100447 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100448
449exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100451}
452
453
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100460 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100461 unsigned char input2[] = "Input 2";
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100463 unsigned char output[1];
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100465
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100472 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100473
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100480 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100481
482exit:
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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);
508 ASSERT_ALLOC(public_key, public_key_length);
509 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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100520 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100521
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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);
550 ASSERT_ALLOC(public_key, public_key_length);
551 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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100571 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100572
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 mbedtls_free(public_key);
574 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100575}
576
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100591 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100592}
593
Gilles Peskine449bd832023-01-11 14:50:10 +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;
Gabor Mezeidc3f3bb2022-07-01 15:06:34 +0200599 unsigned char input[1] = { 0 };
Gilles Peskinee78b0022021-02-13 00:41:11 +0100600 unsigned char output[1];
601 int ok = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200603 psa_status_t expected_key_agreement_status = PSA_SUCCESS;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100606 /* We need two keys to exercise key agreement. Exercise the
607 * private key against its own public key. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
609 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
610 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
611 PSA_ASSERT(psa_key_derivation_input_bytes(
612 &operation, PSA_KEY_DERIVATION_INPUT_SEED,
613 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100614 }
615
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
617 PSA_ASSERT(psa_key_derivation_input_bytes(
618 &operation, PSA_KEY_DERIVATION_INPUT_SALT,
619 input, sizeof(input)));
Przemek Stekield8987452022-06-14 11:41:52 +0200620 }
621
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200622 /* For HKDF_EXPAND input secret may fail as secret size may not match
623 to expected PRK size. In practice it means that key bits must match
624 hash length. Otherwise test should fail with INVALID_ARGUMENT. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200626 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
628 size_t key_bits = psa_get_key_bits(&attributes);
629 psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200632 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 }
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200634 }
635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
637 expected_key_agreement_status);
Przemek Stekiel6c9fd612022-06-14 14:41:42 +0200638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 if (expected_key_agreement_status != PSA_SUCCESS) {
640 return 1;
641 }
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100642
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
644 PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
645 PSA_ASSERT(psa_key_derivation_input_bytes(
646 &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
647 input, sizeof(input)));
648 } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
649 PSA_ASSERT(psa_key_derivation_input_bytes(
650 &operation, PSA_KEY_DERIVATION_INPUT_INFO,
651 input, sizeof(input)));
Gilles Peskineaa3449d2022-03-19 16:04:30 +0100652 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
654 output,
655 sizeof(output)));
656 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100657 }
658 ok = 1;
659
660exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100662}
663
664int mbedtls_test_psa_exported_key_sanity_check(
665 psa_key_type_t type, size_t bits,
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 const uint8_t *exported, size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100667{
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100669
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
671 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
672 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100673
Ronald Cron64df7382021-07-06 09:23:06 +0200674#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
676 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100677 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100678 size_t len;
679 /* RSAPrivateKey ::= SEQUENCE {
680 * version INTEGER, -- must be 0
681 * modulus INTEGER, -- n
682 * publicExponent INTEGER, -- e
683 * privateExponent INTEGER, -- d
684 * prime1 INTEGER, -- p
685 * prime2 INTEGER, -- q
686 * exponent1 INTEGER, -- d mod (p-1)
687 * exponent2 INTEGER, -- d mod (q-1)
688 * coefficient INTEGER, -- (inverse of q) mod p
689 * }
690 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
692 MBEDTLS_ASN1_SEQUENCE |
693 MBEDTLS_ASN1_CONSTRUCTED), 0);
694 TEST_EQUAL(len, end - p);
695 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100696 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 }
698 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100699 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 }
701 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100702 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100704 /* Require d to be at least half the size of n. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100706 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100708 /* Require p and q to be at most half the size of n, rounded up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100710 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 }
712 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100713 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 }
715 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100716 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 }
718 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100719 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 }
721 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100722 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 }
724 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100725
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
727 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200728#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100731 /* Just the secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100733
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
735 } else
Gilles Peskinee78b0022021-02-13 00:41:11 +0100736
Ronald Cron64df7382021-07-06 09:23:06 +0200737#if defined(MBEDTLS_ASN1_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
739 uint8_t *p = (uint8_t *) exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100740 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100741 size_t len;
742 /* RSAPublicKey ::= SEQUENCE {
743 * modulus INTEGER, -- n
744 * publicExponent INTEGER } -- e
745 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
747 MBEDTLS_ASN1_SEQUENCE |
748 MBEDTLS_ASN1_CONSTRUCTED),
749 0);
750 TEST_EQUAL(len, end - p);
751 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100752 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 }
754 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100755 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 }
757 TEST_EQUAL(p - end, 0);
gabor-mezei-armceface22021-01-21 12:26:17 +0100758
759
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 TEST_ASSERT(exported_length <=
761 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
762 TEST_ASSERT(exported_length <=
763 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
764 } else
Ronald Cron64df7382021-07-06 09:23:06 +0200765#endif /* MBEDTLS_ASN1_PARSE_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
gabor-mezei-armceface22021-01-21 12:26:17 +0100768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 TEST_ASSERT(exported_length <=
770 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
771 TEST_ASSERT(exported_length <=
772 PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100773
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100775 /* The representation of an ECC Montgomery public key is
776 * the raw compressed point */
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
Stephan Koch6eb73112023-03-03 17:48:40 +0100778 } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
oberon-sk6d501732023-02-13 12:13:20 +0100779 /* The representation of an ECC Edwards public key is
780 * the raw compressed point */
Stephan Koch6eb73112023-03-03 17:48:40 +0100781 TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100783 /* The representation of an ECC Weierstrass public key is:
784 * - The byte 0x04;
785 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
786 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
787 * - where m is the bit size associated with the curve.
788 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
790 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100791 }
Valerio Setti2dbc3062023-04-13 12:19:57 +0200792 } else {
Andrzej Kurek57d2f132022-01-17 15:26:24 +0100793 (void) exported;
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 TEST_ASSERT(!"Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100795 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100796
Gilles Peskinecc9db302021-02-14 01:29:52 +0100797#if defined(MBEDTLS_DES_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100799 /* Check the parity bits. */
800 unsigned i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100802 unsigned bit_count = 0;
803 unsigned m;
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 for (m = 1; m <= 0x100; m <<= 1) {
805 if (exported[i] & m) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100806 ++bit_count;
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100808 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100810 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100811 }
Gilles Peskinecc9db302021-02-14 01:29:52 +0100812#endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100813
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100815
816exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100818}
819
Gilles Peskine449bd832023-01-11 14:50:10 +0100820static int exercise_export_key(mbedtls_svc_key_id_t key,
821 psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100822{
823 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
824 uint8_t *exported = NULL;
825 size_t exported_size = 0;
826 size_t exported_length = 0;
827 int ok = 0;
828
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100830
831 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 psa_get_key_type(&attributes),
833 psa_get_key_bits(&attributes));
834 ASSERT_ALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100835
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
837 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
838 TEST_EQUAL(psa_export_key(key, exported,
839 exported_size, &exported_length),
840 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100841 ok = 1;
842 goto exit;
843 }
844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 PSA_ASSERT(psa_export_key(key,
846 exported, exported_size,
847 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100848 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
850 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100851
852exit:
853 /*
854 * Key attributes may have been returned by psa_get_key_attributes()
855 * thus reset them as required.
856 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100858
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 mbedtls_free(exported);
860 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100861}
862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100864{
865 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
866 psa_key_type_t public_type;
867 uint8_t *exported = NULL;
868 size_t exported_size = 0;
869 size_t exported_length = 0;
870 int ok = 0;
871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
873 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100874 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 psa_get_key_type(&attributes),
876 psa_get_key_bits(&attributes));
877 ASSERT_ALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100878
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 TEST_EQUAL(psa_export_public_key(key, exported,
880 exported_size, &exported_length),
881 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100882 ok = 1;
883 goto exit;
884 }
885
886 public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 psa_get_key_type(&attributes));
888 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
889 psa_get_key_bits(&attributes));
890 ASSERT_ALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100891
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 PSA_ASSERT(psa_export_public_key(key,
893 exported, exported_size,
894 &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100895 ok = mbedtls_test_psa_exported_key_sanity_check(
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 public_type, psa_get_key_bits(&attributes),
897 exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100898
899exit:
900 /*
901 * Key attributes may have been returned by psa_get_key_attributes()
902 * thus reset them as required.
903 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 mbedtls_free(exported);
907 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100908}
909
Gilles Peskine449bd832023-01-11 14:50:10 +0100910int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
911 psa_key_usage_t usage,
912 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100913{
Gilles Peskine2385f712021-02-14 01:34:21 +0100914 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100915
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 if (!check_key_attributes_sanity(key)) {
917 return 0;
918 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100919
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 if (alg == 0) {
Shaun Case8b0ecbc2021-12-20 21:14:10 -0800921 ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 } else if (PSA_ALG_IS_MAC(alg)) {
923 ok = exercise_mac_key(key, usage, alg);
924 } else if (PSA_ALG_IS_CIPHER(alg)) {
925 ok = exercise_cipher_key(key, usage, alg);
926 } else if (PSA_ALG_IS_AEAD(alg)) {
927 ok = exercise_aead_key(key, usage, alg);
928 } else if (PSA_ALG_IS_SIGN(alg)) {
929 ok = exercise_signature_key(key, usage, alg);
930 } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
931 ok = exercise_asymmetric_encryption_key(key, usage, alg);
932 } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
933 ok = exercise_key_derivation_key(key, usage, alg);
934 } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
935 ok = exercise_raw_key_agreement_key(key, usage, alg);
936 } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
937 ok = exercise_key_agreement_key(key, usage, alg);
938 } else {
939 TEST_ASSERT(!"No code to exercise this category of algorithm");
940 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100941
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 ok = ok && exercise_export_key(key, usage);
943 ok = ok && exercise_export_public_key(key);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100944
Gilles Peskine2385f712021-02-14 01:34:21 +0100945exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100947}
948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
950 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100951{
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
953 if (PSA_ALG_IS_SIGN_HASH(alg)) {
954 if (PSA_ALG_SIGN_GET_HASH(alg)) {
955 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
956 PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
957 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
958 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
959 }
960 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
961 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
962 PSA_KEY_USAGE_VERIFY_MESSAGE :
963 PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
gabor-mezei-arm041887b2021-05-11 13:29:24 +0200964 }
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200965
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
967 PSA_KEY_USAGE_VERIFY_HASH :
968 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
969 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
970 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
971 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
972 PSA_KEY_USAGE_ENCRYPT :
973 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
974 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
975 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
976 return PSA_KEY_USAGE_DERIVE;
977 } else {
978 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100979 }
980
981}
Gilles Peskine66e7b902021-02-12 23:40:58 +0100982
983#endif /* MBEDTLS_PSA_CRYPTO_C */