blob: c7c667f88a15741b70dfb8adb39873c2dc466b28 [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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020028# include <mbedtls/asn1.h>
29# include <psa/crypto.h>
Gilles Peskine66e7b902021-02-12 23:40:58 +010030
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020031# include <test/asn1_helpers.h>
32# include <test/psa_crypto_helpers.h>
Gilles Peskinee78b0022021-02-13 00:41:11 +010033
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020034# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
35static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
Gilles Peskinee78b0022021-02-13 00:41:11 +010036{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020037 return (PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
38 PSA_KEY_LOCATION_LOCAL_STORAGE);
Gilles Peskinee78b0022021-02-13 00:41:11 +010039}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020040# endif
Gilles Peskinee78b0022021-02-13 00:41:11 +010041
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020042static int check_key_attributes_sanity(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +010043{
44 int ok = 0;
45 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
46 psa_key_lifetime_t lifetime;
47 mbedtls_svc_key_id_t id;
48 psa_key_type_t type;
Gilles Peskine6b362e62021-02-15 12:03:16 +010049 size_t bits;
Gilles Peskinee78b0022021-02-13 00:41:11 +010050
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020051 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
52 lifetime = psa_get_key_lifetime(&attributes);
53 id = psa_get_key_id(&attributes);
54 type = psa_get_key_type(&attributes);
55 bits = psa_get_key_bits(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +010056
57 /* Persistence */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020058 if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010059 TEST_ASSERT(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020060 (PSA_KEY_ID_VOLATILE_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
61 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_VOLATILE_MAX));
62 } else {
Gilles Peskinee78b0022021-02-13 00:41:11 +010063 TEST_ASSERT(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020064 (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
65 (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
Gilles Peskinee78b0022021-02-13 00:41:11 +010066 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020067# if defined(MBEDTLS_PSA_CRYPTO_SE_C)
Gilles Peskinee78b0022021-02-13 00:41:11 +010068 /* randomly-generated 64-bit constant, should never appear in test data */
69 psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020070 psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number);
71 if (lifetime_is_dynamic_secure_element(lifetime)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +010072 /* Mbed Crypto currently always exposes the slot number to
73 * applications. This is not mandated by the PSA specification
74 * and may change in future versions. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020075 TEST_EQUAL(status, 0);
76 TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
77 } else {
78 TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +010079 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020080# endif
Gilles Peskinee78b0022021-02-13 00:41:11 +010081
82 /* Type and size */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020083 TEST_ASSERT(type != 0);
84 TEST_ASSERT(bits != 0);
85 TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
86 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type))
87 TEST_ASSERT(bits % 8 == 0);
Gilles Peskinee78b0022021-02-13 00:41:11 +010088
89 /* MAX macros concerning specific key types */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020090 if (PSA_KEY_TYPE_IS_ECC(type))
91 TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
92 else if (PSA_KEY_TYPE_IS_RSA(type))
93 TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
94 TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <=
95 PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
Gilles Peskinee78b0022021-02-13 00:41:11 +010096
97 ok = 1;
98
99exit:
100 /*
101 * Key attributes may have been returned by psa_get_key_attributes()
102 * thus reset them as required.
103 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200104 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100105
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200106 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100107}
108
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200109static int exercise_mac_key(mbedtls_svc_key_id_t key,
110 psa_key_usage_t usage,
111 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100112{
113 psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
114 const unsigned char input[] = "foo";
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200115 unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
116 size_t mac_length = sizeof(mac);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100117
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100118 /* Convert wildcard algorithm to exercisable algorithm */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200119 if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
120 alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100121 }
122
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200123 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
124 PSA_ASSERT(psa_mac_sign_setup(&operation, key, alg));
125 PSA_ASSERT(psa_mac_update(&operation, input, sizeof(input)));
126 PSA_ASSERT(
127 psa_mac_sign_finish(&operation, mac, sizeof(mac), &mac_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100128 }
129
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200130 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
131 psa_status_t verify_status = (usage & PSA_KEY_USAGE_SIGN_HASH ?
132 PSA_SUCCESS :
133 PSA_ERROR_INVALID_SIGNATURE);
134 PSA_ASSERT(psa_mac_verify_setup(&operation, key, alg));
135 PSA_ASSERT(psa_mac_update(&operation, input, sizeof(input)));
136 TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
137 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100138 }
139
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200140 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100141
142exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200143 psa_mac_abort(&operation);
144 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100145}
146
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200147static int exercise_cipher_key(mbedtls_svc_key_id_t key,
148 psa_key_usage_t usage,
149 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100150{
151 psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200152 unsigned char iv[16] = { 0 };
153 size_t iv_length = sizeof(iv);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100154 const unsigned char plaintext[16] = "Hello, world...";
155 unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200156 size_t ciphertext_length = sizeof(ciphertext);
157 unsigned char decrypted[sizeof(ciphertext)];
Gilles Peskinee78b0022021-02-13 00:41:11 +0100158 size_t part_length;
159
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200160 if (usage & PSA_KEY_USAGE_ENCRYPT) {
161 PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
162 PSA_ASSERT(
163 psa_cipher_generate_iv(&operation, iv, sizeof(iv), &iv_length));
164 PSA_ASSERT(psa_cipher_update(&operation, plaintext, sizeof(plaintext),
165 ciphertext, sizeof(ciphertext),
166 &ciphertext_length));
167 PSA_ASSERT(psa_cipher_finish(&operation, ciphertext + ciphertext_length,
168 sizeof(ciphertext) - ciphertext_length,
169 &part_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100170 ciphertext_length += part_length;
171 }
172
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200173 if (usage & PSA_KEY_USAGE_DECRYPT) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100174 psa_status_t status;
175 int maybe_invalid_padding = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200176 if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100177 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200178 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100179 /* This should be PSA_CIPHER_GET_IV_SIZE but the API doesn't
180 * have this macro yet. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200181 iv_length =
182 PSA_BLOCK_CIPHER_BLOCK_LENGTH(psa_get_key_type(&attributes));
183 maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
184 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100185 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200186 PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
187 PSA_ASSERT(psa_cipher_set_iv(&operation, iv, iv_length));
188 PSA_ASSERT(psa_cipher_update(&operation, ciphertext, ciphertext_length,
189 decrypted, sizeof(decrypted),
190 &part_length));
191 status = psa_cipher_finish(&operation, decrypted + part_length,
192 sizeof(decrypted) - part_length,
193 &part_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100194 /* For a stream cipher, all inputs are valid. For a block cipher,
195 * if the input is some aribtrary data rather than an actual
196 ciphertext, a padding error is likely. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200197 if (maybe_invalid_padding)
198 TEST_ASSERT(status == PSA_SUCCESS ||
199 status == PSA_ERROR_INVALID_PADDING);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100200 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200201 PSA_ASSERT(status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100202 }
203
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200204 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100205
206exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200207 psa_cipher_abort(&operation);
208 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100209}
210
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200211static int exercise_aead_key(mbedtls_svc_key_id_t key,
212 psa_key_usage_t usage,
213 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100214{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200215 unsigned char nonce[16] = { 0 };
216 size_t nonce_length = sizeof(nonce);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100217 unsigned char plaintext[16] = "Hello, world...";
218 unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200219 size_t ciphertext_length = sizeof(ciphertext);
220 size_t plaintext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100221
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100222 /* Convert wildcard algorithm to exercisable algorithm */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200223 if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
224 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg,
225 PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
Steven Cooremanfb9cb922021-02-23 14:37:38 +0100226 }
227
Gilles Peskinee78b0022021-02-13 00:41:11 +0100228 /* Default IV length for AES-GCM is 12 bytes */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200229 if (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0) ==
230 PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100231 nonce_length = 12;
232 }
233
Steven Cooremanaaec3412021-02-18 13:30:34 +0100234 /* IV length for CCM needs to be between 7 and 13 bytes */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200235 if (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0) ==
236 PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0)) {
Steven Cooremanaaec3412021-02-18 13:30:34 +0100237 nonce_length = 12;
238 }
239
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200240 if (usage & PSA_KEY_USAGE_ENCRYPT) {
241 PSA_ASSERT(psa_aead_encrypt(key, alg, nonce, nonce_length, NULL, 0,
242 plaintext, sizeof(plaintext), ciphertext,
243 sizeof(ciphertext), &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100244 }
245
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200246 if (usage & PSA_KEY_USAGE_DECRYPT) {
247 psa_status_t verify_status = (usage & PSA_KEY_USAGE_ENCRYPT ?
248 PSA_SUCCESS :
249 PSA_ERROR_INVALID_SIGNATURE);
250 TEST_EQUAL(psa_aead_decrypt(key, alg, nonce, nonce_length, NULL, 0,
251 ciphertext, ciphertext_length, plaintext,
252 sizeof(plaintext), &plaintext_length),
253 verify_status);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100254 }
255
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200256 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100257
258exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200259 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100260}
261
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200262static int exercise_signature_key(mbedtls_svc_key_id_t key,
263 psa_key_usage_t usage,
264 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100265{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200266 if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH)) {
267 unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200268 size_t payload_length = 16;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200269 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
270 size_t signature_length = sizeof(signature);
271 psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200272
273 /* If the policy allows signing with any hash, just pick one. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200274 if (PSA_ALG_IS_HASH_AND_SIGN(alg) && hash_alg == PSA_ALG_ANY_HASH) {
275# if defined(KNOWN_SUPPORTED_HASH_ALG)
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200276 hash_alg = KNOWN_SUPPORTED_HASH_ALG;
277 alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200278# else
279 TEST_ASSERT(!"No hash algorithm for hash-and-sign testing");
280# endif
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200281 }
282
Janos Follath4c0b60e2021-06-14 12:34:30 +0100283 /* Some algorithms require the payload to have the size of
284 * the hash encoded in the algorithm. Use this input size
285 * even for algorithms that allow other input sizes. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200286 if (hash_alg != 0)
287 payload_length = PSA_HASH_LENGTH(hash_alg);
Janos Follath4c0b60e2021-06-14 12:34:30 +0100288
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200289 if (usage & PSA_KEY_USAGE_SIGN_HASH) {
290 PSA_ASSERT(psa_sign_hash(key, alg, payload, payload_length,
291 signature, sizeof(signature),
292 &signature_length));
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200293 }
294
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200295 if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
296 psa_status_t verify_status = (usage & PSA_KEY_USAGE_SIGN_HASH ?
297 PSA_SUCCESS :
298 PSA_ERROR_INVALID_SIGNATURE);
299 TEST_EQUAL(psa_verify_hash(key, alg, payload, payload_length,
300 signature, signature_length),
301 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200302 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100303 }
304
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200305 if (usage & (PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE)) {
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200306 unsigned char message[256] = "Hello, world...";
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200307 unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200308 size_t message_length = 16;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200309 size_t signature_length = sizeof(signature);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100310
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200311 if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
312 PSA_ASSERT(psa_sign_message(key, alg, message, message_length,
313 signature, sizeof(signature),
314 &signature_length));
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200315 }
316
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200317 if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
318 psa_status_t verify_status = (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
319 PSA_SUCCESS :
320 PSA_ERROR_INVALID_SIGNATURE);
321 TEST_EQUAL(psa_verify_message(key, alg, message, message_length,
322 signature, signature_length),
323 verify_status);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200324 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100325 }
326
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200327 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100328
329exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200330 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100331}
332
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200333static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
334 psa_key_usage_t usage,
335 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100336{
337 unsigned char plaintext[256] = "Hello, world...";
338 unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200339 size_t ciphertext_length = sizeof(ciphertext);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100340 size_t plaintext_length = 16;
341
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200342 if (usage & PSA_KEY_USAGE_ENCRYPT) {
343 PSA_ASSERT(psa_asymmetric_encrypt(
344 key, alg, plaintext, plaintext_length, NULL, 0, ciphertext,
345 sizeof(ciphertext), &ciphertext_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100346 }
347
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200348 if (usage & PSA_KEY_USAGE_DECRYPT) {
349 psa_status_t status = psa_asymmetric_decrypt(
350 key, alg, ciphertext, ciphertext_length, NULL, 0, plaintext,
351 sizeof(plaintext), &plaintext_length);
352 TEST_ASSERT(status == PSA_SUCCESS ||
353 ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
354 (status == PSA_ERROR_INVALID_ARGUMENT ||
355 status == PSA_ERROR_INVALID_PADDING)));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100356 }
357
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200358 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100359
360exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200361 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100362}
363
364int mbedtls_test_psa_setup_key_derivation_wrap(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200365 psa_key_derivation_operation_t *operation,
Gilles Peskinee78b0022021-02-13 00:41:11 +0100366 mbedtls_svc_key_id_t key,
367 psa_algorithm_t alg,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200368 const unsigned char *input1,
369 size_t input1_length,
370 const unsigned char *input2,
371 size_t input2_length,
372 size_t capacity)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100373{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200374 PSA_ASSERT(psa_key_derivation_setup(operation, alg));
375 if (PSA_ALG_IS_HKDF(alg)) {
376 PSA_ASSERT(psa_key_derivation_input_bytes(
377 operation, PSA_KEY_DERIVATION_INPUT_SALT, input1, input1_length));
378 PSA_ASSERT(psa_key_derivation_input_key(
379 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key));
380 PSA_ASSERT(psa_key_derivation_input_bytes(
381 operation, PSA_KEY_DERIVATION_INPUT_INFO, input2, input2_length));
382 } else if (PSA_ALG_IS_TLS12_PRF(alg) || PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
383 PSA_ASSERT(psa_key_derivation_input_bytes(
384 operation, PSA_KEY_DERIVATION_INPUT_SEED, input1, input1_length));
385 PSA_ASSERT(psa_key_derivation_input_key(
386 operation, PSA_KEY_DERIVATION_INPUT_SECRET, key));
387 PSA_ASSERT(psa_key_derivation_input_bytes(
388 operation, PSA_KEY_DERIVATION_INPUT_LABEL, input2, input2_length));
389 } else {
390 TEST_ASSERT(!"Key derivation algorithm not supported");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100391 }
392
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200393 if (capacity != SIZE_MAX)
394 PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100395
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200396 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100397
398exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200399 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100400}
401
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200402static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
403 psa_key_usage_t usage,
404 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100405{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200406 psa_key_derivation_operation_t operation =
407 PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100408 unsigned char input1[] = "Input 1";
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200409 size_t input1_length = sizeof(input1);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100410 unsigned char input2[] = "Input 2";
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200411 size_t input2_length = sizeof(input2);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100412 unsigned char output[1];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200413 size_t capacity = sizeof(output);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100414
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200415 if (usage & PSA_KEY_USAGE_DERIVE) {
416 if (!mbedtls_test_psa_setup_key_derivation_wrap(
417 &operation, key, alg, input1, input1_length, input2,
418 input2_length, capacity))
Gilles Peskinee78b0022021-02-13 00:41:11 +0100419 goto exit;
420
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200421 PSA_ASSERT(
422 psa_key_derivation_output_bytes(&operation, output, capacity));
423 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100424 }
425
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200426 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100427
428exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200429 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100430}
431
432/* We need two keys to exercise key agreement. Exercise the
433 * private key against its own public key. */
434psa_status_t mbedtls_test_psa_key_agreement_with_self(
435 psa_key_derivation_operation_t *operation,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200436 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100437{
438 psa_key_type_t private_key_type;
439 psa_key_type_t public_key_type;
440 size_t key_bits;
441 uint8_t *public_key = NULL;
442 size_t public_key_length;
443 /* Return GENERIC_ERROR if something other than the final call to
444 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
445 * but it's good enough: callers will report it as a failed test anyway. */
446 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
447 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
448
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200449 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
450 private_key_type = psa_get_key_type(&attributes);
451 key_bits = psa_get_key_bits(&attributes);
452 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
453 public_key_length =
454 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
455 ASSERT_ALLOC(public_key, public_key_length);
456 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
457 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100458
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200459 status = psa_key_derivation_key_agreement(operation,
460 PSA_KEY_DERIVATION_INPUT_SECRET,
461 key, public_key,
462 public_key_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100463exit:
464 /*
465 * Key attributes may have been returned by psa_get_key_attributes()
466 * thus reset them as required.
467 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200468 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100469
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200470 mbedtls_free(public_key);
471 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100472}
473
474/* We need two keys to exercise key agreement. Exercise the
475 * private key against its own public key. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200476psa_status_t
477mbedtls_test_psa_raw_key_agreement_with_self(psa_algorithm_t alg,
478 mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100479{
480 psa_key_type_t private_key_type;
481 psa_key_type_t public_key_type;
482 size_t key_bits;
483 uint8_t *public_key = NULL;
484 size_t public_key_length;
485 uint8_t output[1024];
486 size_t output_length;
487 /* Return GENERIC_ERROR if something other than the final call to
488 * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
489 * but it's good enough: callers will report it as a failed test anyway. */
490 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
491 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
492
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200493 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
494 private_key_type = psa_get_key_type(&attributes);
495 key_bits = psa_get_key_bits(&attributes);
496 public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
497 public_key_length =
498 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
499 ASSERT_ALLOC(public_key, public_key_length);
500 PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
501 &public_key_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100502
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200503 status = psa_raw_key_agreement(alg, key, public_key, public_key_length,
504 output, sizeof(output), &output_length);
505 if (status == PSA_SUCCESS) {
506 TEST_ASSERT(output_length <= PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(
507 private_key_type, key_bits));
508 TEST_ASSERT(output_length <= PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100509 }
510
Gilles Peskinee78b0022021-02-13 00:41:11 +0100511exit:
512 /*
513 * Key attributes may have been returned by psa_get_key_attributes()
514 * thus reset them as required.
515 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200516 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100517
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200518 mbedtls_free(public_key);
519 return status;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100520}
521
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200522static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
523 psa_key_usage_t usage,
524 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100525{
526 int ok = 0;
527
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200528 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100529 /* We need two keys to exercise key agreement. Exercise the
530 * private key against its own public key. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200531 PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100532 }
533 ok = 1;
534
535exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200536 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100537}
538
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200539static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
540 psa_key_usage_t usage,
541 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100542{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200543 psa_key_derivation_operation_t operation =
544 PSA_KEY_DERIVATION_OPERATION_INIT;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100545 unsigned char output[1];
546 int ok = 0;
547
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200548 if (usage & PSA_KEY_USAGE_DERIVE) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100549 /* We need two keys to exercise key agreement. Exercise the
550 * private key against its own public key. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200551 PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
552 PSA_ASSERT(mbedtls_test_psa_key_agreement_with_self(&operation, key));
553 PSA_ASSERT(psa_key_derivation_output_bytes(&operation, output,
554 sizeof(output)));
555 PSA_ASSERT(psa_key_derivation_abort(&operation));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100556 }
557 ok = 1;
558
559exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200560 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100561}
562
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200563int mbedtls_test_psa_exported_key_sanity_check(psa_key_type_t type,
564 size_t bits,
565 const uint8_t *exported,
566 size_t exported_length)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100567{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200568 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100569
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200570 if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type))
571 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100572 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200573# if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
574 if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
575 uint8_t *p = (uint8_t *)exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100576 const uint8_t *end = exported + exported_length;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100577 size_t len;
578 /* RSAPrivateKey ::= SEQUENCE {
579 * version INTEGER, -- must be 0
580 * modulus INTEGER, -- n
581 * publicExponent INTEGER, -- e
582 * privateExponent INTEGER, -- d
583 * prime1 INTEGER, -- p
584 * prime2 INTEGER, -- q
585 * exponent1 INTEGER, -- d mod (p-1)
586 * exponent2 INTEGER, -- d mod (q-1)
587 * coefficient INTEGER, -- (inverse of q) mod p
588 * }
589 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200590 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
591 MBEDTLS_ASN1_SEQUENCE |
592 MBEDTLS_ASN1_CONSTRUCTED),
593 0);
594 TEST_EQUAL(p + len, end);
595 if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0))
Gilles Peskinee78b0022021-02-13 00:41:11 +0100596 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200597 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1))
Gilles Peskinee78b0022021-02-13 00:41:11 +0100598 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200599 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1))
Gilles Peskinee78b0022021-02-13 00:41:11 +0100600 goto exit;
601 /* Require d to be at least half the size of n. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200602 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1))
Gilles Peskinee78b0022021-02-13 00:41:11 +0100603 goto exit;
604 /* Require p and q to be at most half the size of n, rounded up. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200605 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1))
Gilles Peskinee78b0022021-02-13 00:41:11 +0100606 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200607 if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1))
Gilles Peskinee78b0022021-02-13 00:41:11 +0100608 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200609 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0))
Gilles Peskinee78b0022021-02-13 00:41:11 +0100610 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200611 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0))
Gilles Peskinee78b0022021-02-13 00:41:11 +0100612 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200613 if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0))
Gilles Peskinee78b0022021-02-13 00:41:11 +0100614 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200615 TEST_EQUAL(p, end);
gabor-mezei-armceface22021-01-21 12:26:17 +0100616
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200617 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
618 } else
619# endif /* MBEDTLS_RSA_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100620
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200621# if defined(MBEDTLS_ECP_C)
622 if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100623 /* Just the secret value */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200624 TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
gabor-mezei-armceface22021-01-21 12:26:17 +0100625
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200626 TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
627 } else
628# endif /* MBEDTLS_ECP_C */
Gilles Peskinee78b0022021-02-13 00:41:11 +0100629
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200630# if defined(MBEDTLS_RSA_C)
631 if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
632 uint8_t *p = (uint8_t *)exported;
Gilles Peskine5c2665b2021-02-14 01:22:56 +0100633 const uint8_t *end = exported + exported_length;
Gilles Peskinead557e52021-02-14 01:19:21 +0100634 size_t len;
635 /* RSAPublicKey ::= SEQUENCE {
636 * modulus INTEGER, -- n
637 * publicExponent INTEGER } -- e
638 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200639 TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
640 MBEDTLS_ASN1_SEQUENCE |
641 MBEDTLS_ASN1_CONSTRUCTED),
642 0);
643 TEST_EQUAL(p + len, end);
644 if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1))
Gilles Peskinead557e52021-02-14 01:19:21 +0100645 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200646 if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1))
Gilles Peskinead557e52021-02-14 01:19:21 +0100647 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200648 TEST_EQUAL(p, end);
gabor-mezei-armceface22021-01-21 12:26:17 +0100649
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200650 TEST_ASSERT(exported_length <=
651 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
652 TEST_ASSERT(exported_length <= PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
653 } else
654# endif /* MBEDTLS_RSA_C */
gabor-mezei-armceface22021-01-21 12:26:17 +0100655
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200656# if defined(MBEDTLS_ECP_C)
657 if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100658
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200659 TEST_ASSERT(exported_length <=
660 PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
661 TEST_ASSERT(exported_length <= PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
gabor-mezei-armceface22021-01-21 12:26:17 +0100662
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200663 if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
Gilles Peskinead557e52021-02-14 01:19:21 +0100664 /* The representation of an ECC Montgomery public key is
665 * the raw compressed point */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200666 TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
667 } else {
Gilles Peskinead557e52021-02-14 01:19:21 +0100668 /* The representation of an ECC Weierstrass public key is:
669 * - The byte 0x04;
670 * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
671 * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
672 * - where m is the bit size associated with the curve.
673 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200674 TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
675 TEST_EQUAL(exported[0], 4);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100676 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200677 } else
678# endif /* MBEDTLS_ECP_C */
Gilles Peskinead557e52021-02-14 01:19:21 +0100679
Gilles Peskinead557e52021-02-14 01:19:21 +0100680 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200681 TEST_ASSERT(!"Sanity check not implemented for this key type");
Gilles Peskinead557e52021-02-14 01:19:21 +0100682 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100683
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200684# if defined(MBEDTLS_DES_C)
685 if (type == PSA_KEY_TYPE_DES) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100686 /* Check the parity bits. */
687 unsigned i;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200688 for (i = 0; i < bits / 8; i++) {
Gilles Peskinecc9db302021-02-14 01:29:52 +0100689 unsigned bit_count = 0;
690 unsigned m;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200691 for (m = 1; m <= 0x100; m <<= 1) {
692 if (exported[i] & m)
Gilles Peskinecc9db302021-02-14 01:29:52 +0100693 ++bit_count;
694 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200695 TEST_ASSERT(bit_count % 2 != 0);
Gilles Peskinecc9db302021-02-14 01:29:52 +0100696 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100697 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200698# endif
Gilles Peskinee78b0022021-02-13 00:41:11 +0100699
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200700 return 1;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100701
702exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200703 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100704}
705
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200706static int exercise_export_key(mbedtls_svc_key_id_t key, psa_key_usage_t usage)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100707{
708 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
709 uint8_t *exported = NULL;
710 size_t exported_size = 0;
711 size_t exported_length = 0;
712 int ok = 0;
713
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200714 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100715
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200716 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(psa_get_key_type(&attributes),
717 psa_get_key_bits(&attributes));
718 ASSERT_ALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100719
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200720 if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
721 !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
722 TEST_EQUAL(psa_export_key(key, exported, exported_size,
723 &exported_length),
724 PSA_ERROR_NOT_PERMITTED);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100725 ok = 1;
726 goto exit;
727 }
728
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200729 PSA_ASSERT(psa_export_key(key, exported, exported_size, &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100730 ok = mbedtls_test_psa_exported_key_sanity_check(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200731 psa_get_key_type(&attributes), psa_get_key_bits(&attributes), exported,
732 exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100733
734exit:
735 /*
736 * Key attributes may have been returned by psa_get_key_attributes()
737 * thus reset them as required.
738 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200739 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100740
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200741 mbedtls_free(exported);
742 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100743}
744
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200745static int exercise_export_public_key(mbedtls_svc_key_id_t key)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100746{
747 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
748 psa_key_type_t public_type;
749 uint8_t *exported = NULL;
750 size_t exported_size = 0;
751 size_t exported_length = 0;
752 int ok = 0;
753
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200754 PSA_ASSERT(psa_get_key_attributes(key, &attributes));
755 if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
Gilles Peskinee78b0022021-02-13 00:41:11 +0100756 exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200757 psa_get_key_type(&attributes), psa_get_key_bits(&attributes));
758 ASSERT_ALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100759
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200760 TEST_EQUAL(psa_export_public_key(key, exported, exported_size,
761 &exported_length),
762 PSA_ERROR_INVALID_ARGUMENT);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100763 ok = 1;
764 goto exit;
765 }
766
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200767 public_type =
768 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(&attributes));
769 exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(
770 public_type, psa_get_key_bits(&attributes));
771 ASSERT_ALLOC(exported, exported_size);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100772
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200773 PSA_ASSERT(
774 psa_export_public_key(key, exported, exported_size, &exported_length));
Gilles Peskinee78b0022021-02-13 00:41:11 +0100775 ok = mbedtls_test_psa_exported_key_sanity_check(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200776 public_type, psa_get_key_bits(&attributes), exported, exported_length);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100777
778exit:
779 /*
780 * Key attributes may have been returned by psa_get_key_attributes()
781 * thus reset them as required.
782 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200783 psa_reset_key_attributes(&attributes);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100784
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200785 mbedtls_free(exported);
786 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100787}
788
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200789int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
790 psa_key_usage_t usage,
791 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100792{
Gilles Peskine2385f712021-02-14 01:34:21 +0100793 int ok = 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100794
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200795 if (!check_key_attributes_sanity(key))
796 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100797
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200798 if (alg == 0)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100799 ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200800 else if (PSA_ALG_IS_MAC(alg))
801 ok = exercise_mac_key(key, usage, alg);
802 else if (PSA_ALG_IS_CIPHER(alg))
803 ok = exercise_cipher_key(key, usage, alg);
804 else if (PSA_ALG_IS_AEAD(alg))
805 ok = exercise_aead_key(key, usage, alg);
806 else if (PSA_ALG_IS_SIGN(alg))
807 ok = exercise_signature_key(key, usage, alg);
808 else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg))
809 ok = exercise_asymmetric_encryption_key(key, usage, alg);
810 else if (PSA_ALG_IS_KEY_DERIVATION(alg))
811 ok = exercise_key_derivation_key(key, usage, alg);
812 else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg))
813 ok = exercise_raw_key_agreement_key(key, usage, alg);
814 else if (PSA_ALG_IS_KEY_AGREEMENT(alg))
815 ok = exercise_key_agreement_key(key, usage, alg);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100816 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200817 TEST_ASSERT(!"No code to exercise this category of algorithm");
Gilles Peskinee78b0022021-02-13 00:41:11 +0100818
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200819 ok = ok && exercise_export_key(key, usage);
820 ok = ok && exercise_export_public_key(key);
Gilles Peskinee78b0022021-02-13 00:41:11 +0100821
Gilles Peskine2385f712021-02-14 01:34:21 +0100822exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200823 return ok;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100824}
825
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200826psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
827 psa_algorithm_t alg)
Gilles Peskinee78b0022021-02-13 00:41:11 +0100828{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200829 if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
830 if (PSA_ALG_IS_HASH_AND_SIGN(alg)) {
831 if (PSA_ALG_SIGN_GET_HASH(alg))
832 return (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
833 PSA_KEY_USAGE_VERIFY_HASH |
834 PSA_KEY_USAGE_VERIFY_MESSAGE :
835 PSA_KEY_USAGE_SIGN_HASH |
836 PSA_KEY_USAGE_VERIFY_HASH |
837 PSA_KEY_USAGE_SIGN_MESSAGE |
838 PSA_KEY_USAGE_VERIFY_MESSAGE);
839 } else if (PSA_ALG_IS_SIGN_MESSAGE(alg))
840 return (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
841 PSA_KEY_USAGE_VERIFY_MESSAGE :
842 PSA_KEY_USAGE_SIGN_MESSAGE |
843 PSA_KEY_USAGE_VERIFY_MESSAGE);
gabor-mezei-arm4c6a47a2021-04-26 20:12:17 +0200844
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200845 return (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
846 PSA_KEY_USAGE_VERIFY_HASH :
847 PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
848 } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
849 PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
850 return (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
851 PSA_KEY_USAGE_ENCRYPT :
852 PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
853 } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
854 PSA_ALG_IS_KEY_AGREEMENT(alg)) {
855 return PSA_KEY_USAGE_DERIVE;
856 } else {
857 return 0;
Gilles Peskinee78b0022021-02-13 00:41:11 +0100858 }
Gilles Peskinee78b0022021-02-13 00:41:11 +0100859}
Gilles Peskine66e7b902021-02-12 23:40:58 +0100860
861#endif /* MBEDTLS_PSA_CRYPTO_C */