xref: /aosp_15_r20/external/mbedtls/tests/src/psa_exercise_key.c (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1*62c56f98SSadaf Ebrahimi /** Code to exercise a PSA key object, i.e. validate that it seems well-formed
2*62c56f98SSadaf Ebrahimi  * and can do what it is supposed to do.
3*62c56f98SSadaf Ebrahimi  */
4*62c56f98SSadaf Ebrahimi 
5*62c56f98SSadaf Ebrahimi /*
6*62c56f98SSadaf Ebrahimi  *  Copyright The Mbed TLS Contributors
7*62c56f98SSadaf Ebrahimi  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
8*62c56f98SSadaf Ebrahimi  */
9*62c56f98SSadaf Ebrahimi 
10*62c56f98SSadaf Ebrahimi #include <test/helpers.h>
11*62c56f98SSadaf Ebrahimi #include <test/macros.h>
12*62c56f98SSadaf Ebrahimi #include <test/psa_exercise_key.h>
13*62c56f98SSadaf Ebrahimi 
14*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_CRYPTO_C)
15*62c56f98SSadaf Ebrahimi 
16*62c56f98SSadaf Ebrahimi #include <mbedtls/asn1.h>
17*62c56f98SSadaf Ebrahimi #include <psa/crypto.h>
18*62c56f98SSadaf Ebrahimi 
19*62c56f98SSadaf Ebrahimi #include <test/asn1_helpers.h>
20*62c56f98SSadaf Ebrahimi #include <psa_crypto_slot_management.h>
21*62c56f98SSadaf Ebrahimi #include <test/psa_crypto_helpers.h>
22*62c56f98SSadaf Ebrahimi 
23*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)24*62c56f98SSadaf Ebrahimi static int lifetime_is_dynamic_secure_element(psa_key_lifetime_t lifetime)
25*62c56f98SSadaf Ebrahimi {
26*62c56f98SSadaf Ebrahimi     return PSA_KEY_LIFETIME_GET_LOCATION(lifetime) !=
27*62c56f98SSadaf Ebrahimi            PSA_KEY_LOCATION_LOCAL_STORAGE;
28*62c56f98SSadaf Ebrahimi }
29*62c56f98SSadaf Ebrahimi #endif
30*62c56f98SSadaf Ebrahimi 
check_key_attributes_sanity(mbedtls_svc_key_id_t key)31*62c56f98SSadaf Ebrahimi static int check_key_attributes_sanity(mbedtls_svc_key_id_t key)
32*62c56f98SSadaf Ebrahimi {
33*62c56f98SSadaf Ebrahimi     int ok = 0;
34*62c56f98SSadaf Ebrahimi     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
35*62c56f98SSadaf Ebrahimi     psa_key_lifetime_t lifetime;
36*62c56f98SSadaf Ebrahimi     mbedtls_svc_key_id_t id;
37*62c56f98SSadaf Ebrahimi     psa_key_type_t type;
38*62c56f98SSadaf Ebrahimi     size_t bits;
39*62c56f98SSadaf Ebrahimi 
40*62c56f98SSadaf Ebrahimi     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
41*62c56f98SSadaf Ebrahimi     lifetime = psa_get_key_lifetime(&attributes);
42*62c56f98SSadaf Ebrahimi     id = psa_get_key_id(&attributes);
43*62c56f98SSadaf Ebrahimi     type = psa_get_key_type(&attributes);
44*62c56f98SSadaf Ebrahimi     bits = psa_get_key_bits(&attributes);
45*62c56f98SSadaf Ebrahimi 
46*62c56f98SSadaf Ebrahimi     /* Persistence */
47*62c56f98SSadaf Ebrahimi     if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
48*62c56f98SSadaf Ebrahimi         TEST_ASSERT(
49*62c56f98SSadaf Ebrahimi             (PSA_KEY_ID_VOLATILE_MIN <=
50*62c56f98SSadaf Ebrahimi              MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
51*62c56f98SSadaf Ebrahimi             (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <=
52*62c56f98SSadaf Ebrahimi              PSA_KEY_ID_VOLATILE_MAX));
53*62c56f98SSadaf Ebrahimi     } else {
54*62c56f98SSadaf Ebrahimi         TEST_ASSERT(
55*62c56f98SSadaf Ebrahimi             (PSA_KEY_ID_USER_MIN <= MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id)) &&
56*62c56f98SSadaf Ebrahimi             (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) <= PSA_KEY_ID_USER_MAX));
57*62c56f98SSadaf Ebrahimi     }
58*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
59*62c56f98SSadaf Ebrahimi     /* randomly-generated 64-bit constant, should never appear in test data */
60*62c56f98SSadaf Ebrahimi     psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
61*62c56f98SSadaf Ebrahimi     psa_status_t status = psa_get_key_slot_number(&attributes, &slot_number);
62*62c56f98SSadaf Ebrahimi     if (lifetime_is_dynamic_secure_element(lifetime)) {
63*62c56f98SSadaf Ebrahimi         /* Mbed TLS currently always exposes the slot number to
64*62c56f98SSadaf Ebrahimi          * applications. This is not mandated by the PSA specification
65*62c56f98SSadaf Ebrahimi          * and may change in future versions. */
66*62c56f98SSadaf Ebrahimi         TEST_EQUAL(status, 0);
67*62c56f98SSadaf Ebrahimi         TEST_ASSERT(slot_number != 0xec94d4a5058a1a21);
68*62c56f98SSadaf Ebrahimi     } else {
69*62c56f98SSadaf Ebrahimi         TEST_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT);
70*62c56f98SSadaf Ebrahimi     }
71*62c56f98SSadaf Ebrahimi #endif
72*62c56f98SSadaf Ebrahimi 
73*62c56f98SSadaf Ebrahimi     /* Type and size */
74*62c56f98SSadaf Ebrahimi     TEST_ASSERT(type != 0);
75*62c56f98SSadaf Ebrahimi     TEST_ASSERT(bits != 0);
76*62c56f98SSadaf Ebrahimi     TEST_ASSERT(bits <= PSA_MAX_KEY_BITS);
77*62c56f98SSadaf Ebrahimi     if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
78*62c56f98SSadaf Ebrahimi         TEST_ASSERT(bits % 8 == 0);
79*62c56f98SSadaf Ebrahimi     }
80*62c56f98SSadaf Ebrahimi 
81*62c56f98SSadaf Ebrahimi     /* MAX macros concerning specific key types */
82*62c56f98SSadaf Ebrahimi     if (PSA_KEY_TYPE_IS_ECC(type)) {
83*62c56f98SSadaf Ebrahimi         TEST_ASSERT(bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS);
84*62c56f98SSadaf Ebrahimi     } else if (PSA_KEY_TYPE_IS_RSA(type)) {
85*62c56f98SSadaf Ebrahimi         TEST_ASSERT(bits <= PSA_VENDOR_RSA_MAX_KEY_BITS);
86*62c56f98SSadaf Ebrahimi     }
87*62c56f98SSadaf Ebrahimi     TEST_ASSERT(PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) <= PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE);
88*62c56f98SSadaf Ebrahimi 
89*62c56f98SSadaf Ebrahimi     ok = 1;
90*62c56f98SSadaf Ebrahimi 
91*62c56f98SSadaf Ebrahimi exit:
92*62c56f98SSadaf Ebrahimi     /*
93*62c56f98SSadaf Ebrahimi      * Key attributes may have been returned by psa_get_key_attributes()
94*62c56f98SSadaf Ebrahimi      * thus reset them as required.
95*62c56f98SSadaf Ebrahimi      */
96*62c56f98SSadaf Ebrahimi     psa_reset_key_attributes(&attributes);
97*62c56f98SSadaf Ebrahimi 
98*62c56f98SSadaf Ebrahimi     return ok;
99*62c56f98SSadaf Ebrahimi }
100*62c56f98SSadaf Ebrahimi 
exercise_mac_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)101*62c56f98SSadaf Ebrahimi static int exercise_mac_key(mbedtls_svc_key_id_t key,
102*62c56f98SSadaf Ebrahimi                             psa_key_usage_t usage,
103*62c56f98SSadaf Ebrahimi                             psa_algorithm_t alg)
104*62c56f98SSadaf Ebrahimi {
105*62c56f98SSadaf Ebrahimi     psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
106*62c56f98SSadaf Ebrahimi     const unsigned char input[] = "foo";
107*62c56f98SSadaf Ebrahimi     unsigned char mac[PSA_MAC_MAX_SIZE] = { 0 };
108*62c56f98SSadaf Ebrahimi     size_t mac_length = sizeof(mac);
109*62c56f98SSadaf Ebrahimi 
110*62c56f98SSadaf Ebrahimi     /* Convert wildcard algorithm to exercisable algorithm */
111*62c56f98SSadaf Ebrahimi     if (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) {
112*62c56f98SSadaf Ebrahimi         alg = PSA_ALG_TRUNCATED_MAC(alg, PSA_MAC_TRUNCATED_LENGTH(alg));
113*62c56f98SSadaf Ebrahimi     }
114*62c56f98SSadaf Ebrahimi 
115*62c56f98SSadaf Ebrahimi     if (usage & PSA_KEY_USAGE_SIGN_HASH) {
116*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_mac_sign_setup(&operation, key, alg));
117*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_mac_update(&operation,
118*62c56f98SSadaf Ebrahimi                                   input, sizeof(input)));
119*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_mac_sign_finish(&operation,
120*62c56f98SSadaf Ebrahimi                                        mac, sizeof(mac),
121*62c56f98SSadaf Ebrahimi                                        &mac_length));
122*62c56f98SSadaf Ebrahimi     }
123*62c56f98SSadaf Ebrahimi 
124*62c56f98SSadaf Ebrahimi     if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
125*62c56f98SSadaf Ebrahimi         psa_status_t verify_status =
126*62c56f98SSadaf Ebrahimi             (usage & PSA_KEY_USAGE_SIGN_HASH ?
127*62c56f98SSadaf Ebrahimi              PSA_SUCCESS :
128*62c56f98SSadaf Ebrahimi              PSA_ERROR_INVALID_SIGNATURE);
129*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_mac_verify_setup(&operation, key, alg));
130*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_mac_update(&operation,
131*62c56f98SSadaf Ebrahimi                                   input, sizeof(input)));
132*62c56f98SSadaf Ebrahimi         TEST_EQUAL(psa_mac_verify_finish(&operation, mac, mac_length),
133*62c56f98SSadaf Ebrahimi                    verify_status);
134*62c56f98SSadaf Ebrahimi     }
135*62c56f98SSadaf Ebrahimi 
136*62c56f98SSadaf Ebrahimi     return 1;
137*62c56f98SSadaf Ebrahimi 
138*62c56f98SSadaf Ebrahimi exit:
139*62c56f98SSadaf Ebrahimi     psa_mac_abort(&operation);
140*62c56f98SSadaf Ebrahimi     return 0;
141*62c56f98SSadaf Ebrahimi }
142*62c56f98SSadaf Ebrahimi 
exercise_cipher_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)143*62c56f98SSadaf Ebrahimi static int exercise_cipher_key(mbedtls_svc_key_id_t key,
144*62c56f98SSadaf Ebrahimi                                psa_key_usage_t usage,
145*62c56f98SSadaf Ebrahimi                                psa_algorithm_t alg)
146*62c56f98SSadaf Ebrahimi {
147*62c56f98SSadaf Ebrahimi     psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
148*62c56f98SSadaf Ebrahimi     unsigned char iv[PSA_CIPHER_IV_MAX_SIZE] = { 0 };
149*62c56f98SSadaf Ebrahimi     size_t iv_length;
150*62c56f98SSadaf Ebrahimi     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
151*62c56f98SSadaf Ebrahimi     psa_key_type_t key_type;
152*62c56f98SSadaf Ebrahimi     const unsigned char plaintext[16] = "Hello, world...";
153*62c56f98SSadaf Ebrahimi     unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
154*62c56f98SSadaf Ebrahimi     size_t ciphertext_length = sizeof(ciphertext);
155*62c56f98SSadaf Ebrahimi     unsigned char decrypted[sizeof(ciphertext)];
156*62c56f98SSadaf Ebrahimi     size_t part_length;
157*62c56f98SSadaf Ebrahimi 
158*62c56f98SSadaf Ebrahimi     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
159*62c56f98SSadaf Ebrahimi     key_type = psa_get_key_type(&attributes);
160*62c56f98SSadaf Ebrahimi     iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
161*62c56f98SSadaf Ebrahimi 
162*62c56f98SSadaf Ebrahimi     if (usage & PSA_KEY_USAGE_ENCRYPT) {
163*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
164*62c56f98SSadaf Ebrahimi         if (iv_length != 0) {
165*62c56f98SSadaf Ebrahimi             PSA_ASSERT(psa_cipher_generate_iv(&operation,
166*62c56f98SSadaf Ebrahimi                                               iv, sizeof(iv),
167*62c56f98SSadaf Ebrahimi                                               &iv_length));
168*62c56f98SSadaf Ebrahimi         }
169*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_cipher_update(&operation,
170*62c56f98SSadaf Ebrahimi                                      plaintext, sizeof(plaintext),
171*62c56f98SSadaf Ebrahimi                                      ciphertext, sizeof(ciphertext),
172*62c56f98SSadaf Ebrahimi                                      &ciphertext_length));
173*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_cipher_finish(&operation,
174*62c56f98SSadaf Ebrahimi                                      ciphertext + ciphertext_length,
175*62c56f98SSadaf Ebrahimi                                      sizeof(ciphertext) - ciphertext_length,
176*62c56f98SSadaf Ebrahimi                                      &part_length));
177*62c56f98SSadaf Ebrahimi         ciphertext_length += part_length;
178*62c56f98SSadaf Ebrahimi     }
179*62c56f98SSadaf Ebrahimi 
180*62c56f98SSadaf Ebrahimi     if (usage & PSA_KEY_USAGE_DECRYPT) {
181*62c56f98SSadaf Ebrahimi         psa_status_t status;
182*62c56f98SSadaf Ebrahimi         int maybe_invalid_padding = 0;
183*62c56f98SSadaf Ebrahimi         if (!(usage & PSA_KEY_USAGE_ENCRYPT)) {
184*62c56f98SSadaf Ebrahimi             maybe_invalid_padding = !PSA_ALG_IS_STREAM_CIPHER(alg);
185*62c56f98SSadaf Ebrahimi         }
186*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
187*62c56f98SSadaf Ebrahimi         if (iv_length != 0) {
188*62c56f98SSadaf Ebrahimi             PSA_ASSERT(psa_cipher_set_iv(&operation,
189*62c56f98SSadaf Ebrahimi                                          iv, iv_length));
190*62c56f98SSadaf Ebrahimi         }
191*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_cipher_update(&operation,
192*62c56f98SSadaf Ebrahimi                                      ciphertext, ciphertext_length,
193*62c56f98SSadaf Ebrahimi                                      decrypted, sizeof(decrypted),
194*62c56f98SSadaf Ebrahimi                                      &part_length));
195*62c56f98SSadaf Ebrahimi         status = psa_cipher_finish(&operation,
196*62c56f98SSadaf Ebrahimi                                    decrypted + part_length,
197*62c56f98SSadaf Ebrahimi                                    sizeof(decrypted) - part_length,
198*62c56f98SSadaf Ebrahimi                                    &part_length);
199*62c56f98SSadaf Ebrahimi         /* For a stream cipher, all inputs are valid. For a block cipher,
200*62c56f98SSadaf Ebrahimi          * if the input is some arbitrary data rather than an actual
201*62c56f98SSadaf Ebrahimi            ciphertext, a padding error is likely.  */
202*62c56f98SSadaf Ebrahimi         if (maybe_invalid_padding) {
203*62c56f98SSadaf Ebrahimi             TEST_ASSERT(status == PSA_SUCCESS ||
204*62c56f98SSadaf Ebrahimi                         status == PSA_ERROR_INVALID_PADDING);
205*62c56f98SSadaf Ebrahimi         } else {
206*62c56f98SSadaf Ebrahimi             PSA_ASSERT(status);
207*62c56f98SSadaf Ebrahimi         }
208*62c56f98SSadaf Ebrahimi     }
209*62c56f98SSadaf Ebrahimi 
210*62c56f98SSadaf Ebrahimi     return 1;
211*62c56f98SSadaf Ebrahimi 
212*62c56f98SSadaf Ebrahimi exit:
213*62c56f98SSadaf Ebrahimi     psa_cipher_abort(&operation);
214*62c56f98SSadaf Ebrahimi     psa_reset_key_attributes(&attributes);
215*62c56f98SSadaf Ebrahimi     return 0;
216*62c56f98SSadaf Ebrahimi }
217*62c56f98SSadaf Ebrahimi 
exercise_aead_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)218*62c56f98SSadaf Ebrahimi static int exercise_aead_key(mbedtls_svc_key_id_t key,
219*62c56f98SSadaf Ebrahimi                              psa_key_usage_t usage,
220*62c56f98SSadaf Ebrahimi                              psa_algorithm_t alg)
221*62c56f98SSadaf Ebrahimi {
222*62c56f98SSadaf Ebrahimi     unsigned char nonce[PSA_AEAD_NONCE_MAX_SIZE] = { 0 };
223*62c56f98SSadaf Ebrahimi     size_t nonce_length;
224*62c56f98SSadaf Ebrahimi     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
225*62c56f98SSadaf Ebrahimi     psa_key_type_t key_type;
226*62c56f98SSadaf Ebrahimi     unsigned char plaintext[16] = "Hello, world...";
227*62c56f98SSadaf Ebrahimi     unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
228*62c56f98SSadaf Ebrahimi     size_t ciphertext_length = sizeof(ciphertext);
229*62c56f98SSadaf Ebrahimi     size_t plaintext_length = sizeof(ciphertext);
230*62c56f98SSadaf Ebrahimi 
231*62c56f98SSadaf Ebrahimi     /* Convert wildcard algorithm to exercisable algorithm */
232*62c56f98SSadaf Ebrahimi     if (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) {
233*62c56f98SSadaf Ebrahimi         alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, PSA_ALG_AEAD_GET_TAG_LENGTH(alg));
234*62c56f98SSadaf Ebrahimi     }
235*62c56f98SSadaf Ebrahimi 
236*62c56f98SSadaf Ebrahimi     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
237*62c56f98SSadaf Ebrahimi     key_type = psa_get_key_type(&attributes);
238*62c56f98SSadaf Ebrahimi     nonce_length = PSA_AEAD_NONCE_LENGTH(key_type, alg);
239*62c56f98SSadaf Ebrahimi 
240*62c56f98SSadaf Ebrahimi     if (usage & PSA_KEY_USAGE_ENCRYPT) {
241*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_aead_encrypt(key, alg,
242*62c56f98SSadaf Ebrahimi                                     nonce, nonce_length,
243*62c56f98SSadaf Ebrahimi                                     NULL, 0,
244*62c56f98SSadaf Ebrahimi                                     plaintext, sizeof(plaintext),
245*62c56f98SSadaf Ebrahimi                                     ciphertext, sizeof(ciphertext),
246*62c56f98SSadaf Ebrahimi                                     &ciphertext_length));
247*62c56f98SSadaf Ebrahimi     }
248*62c56f98SSadaf Ebrahimi 
249*62c56f98SSadaf Ebrahimi     if (usage & PSA_KEY_USAGE_DECRYPT) {
250*62c56f98SSadaf Ebrahimi         psa_status_t verify_status =
251*62c56f98SSadaf Ebrahimi             (usage & PSA_KEY_USAGE_ENCRYPT ?
252*62c56f98SSadaf Ebrahimi              PSA_SUCCESS :
253*62c56f98SSadaf Ebrahimi              PSA_ERROR_INVALID_SIGNATURE);
254*62c56f98SSadaf Ebrahimi         TEST_EQUAL(psa_aead_decrypt(key, alg,
255*62c56f98SSadaf Ebrahimi                                     nonce, nonce_length,
256*62c56f98SSadaf Ebrahimi                                     NULL, 0,
257*62c56f98SSadaf Ebrahimi                                     ciphertext, ciphertext_length,
258*62c56f98SSadaf Ebrahimi                                     plaintext, sizeof(plaintext),
259*62c56f98SSadaf Ebrahimi                                     &plaintext_length),
260*62c56f98SSadaf Ebrahimi                    verify_status);
261*62c56f98SSadaf Ebrahimi     }
262*62c56f98SSadaf Ebrahimi 
263*62c56f98SSadaf Ebrahimi     return 1;
264*62c56f98SSadaf Ebrahimi 
265*62c56f98SSadaf Ebrahimi exit:
266*62c56f98SSadaf Ebrahimi     psa_reset_key_attributes(&attributes);
267*62c56f98SSadaf Ebrahimi     return 0;
268*62c56f98SSadaf Ebrahimi }
269*62c56f98SSadaf Ebrahimi 
can_sign_or_verify_message(psa_key_usage_t usage,psa_algorithm_t alg)270*62c56f98SSadaf Ebrahimi static int can_sign_or_verify_message(psa_key_usage_t usage,
271*62c56f98SSadaf Ebrahimi                                       psa_algorithm_t alg)
272*62c56f98SSadaf Ebrahimi {
273*62c56f98SSadaf Ebrahimi     /* Sign-the-unspecified-hash algorithms can only be used with
274*62c56f98SSadaf Ebrahimi      * {sign,verify}_hash, not with {sign,verify}_message. */
275*62c56f98SSadaf Ebrahimi     if (alg == PSA_ALG_ECDSA_ANY || alg == PSA_ALG_RSA_PKCS1V15_SIGN_RAW) {
276*62c56f98SSadaf Ebrahimi         return 0;
277*62c56f98SSadaf Ebrahimi     }
278*62c56f98SSadaf Ebrahimi     return usage & (PSA_KEY_USAGE_SIGN_MESSAGE |
279*62c56f98SSadaf Ebrahimi                     PSA_KEY_USAGE_VERIFY_MESSAGE);
280*62c56f98SSadaf Ebrahimi }
281*62c56f98SSadaf Ebrahimi 
exercise_signature_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)282*62c56f98SSadaf Ebrahimi static int exercise_signature_key(mbedtls_svc_key_id_t key,
283*62c56f98SSadaf Ebrahimi                                   psa_key_usage_t usage,
284*62c56f98SSadaf Ebrahimi                                   psa_algorithm_t alg)
285*62c56f98SSadaf Ebrahimi {
286*62c56f98SSadaf Ebrahimi     if (usage & (PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH) &&
287*62c56f98SSadaf Ebrahimi         PSA_ALG_IS_SIGN_HASH(alg)) {
288*62c56f98SSadaf Ebrahimi         unsigned char payload[PSA_HASH_MAX_SIZE] = { 1 };
289*62c56f98SSadaf Ebrahimi         size_t payload_length = 16;
290*62c56f98SSadaf Ebrahimi         unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
291*62c56f98SSadaf Ebrahimi         size_t signature_length = sizeof(signature);
292*62c56f98SSadaf Ebrahimi         psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
293*62c56f98SSadaf Ebrahimi 
294*62c56f98SSadaf Ebrahimi         /* If the policy allows signing with any hash, just pick one. */
295*62c56f98SSadaf Ebrahimi         if (PSA_ALG_IS_SIGN_HASH(alg) && hash_alg == PSA_ALG_ANY_HASH) {
296*62c56f98SSadaf Ebrahimi     #if defined(KNOWN_SUPPORTED_HASH_ALG)
297*62c56f98SSadaf Ebrahimi             hash_alg = KNOWN_SUPPORTED_HASH_ALG;
298*62c56f98SSadaf Ebrahimi             alg ^= PSA_ALG_ANY_HASH ^ hash_alg;
299*62c56f98SSadaf Ebrahimi     #else
300*62c56f98SSadaf Ebrahimi             TEST_FAIL("No hash algorithm for hash-and-sign testing");
301*62c56f98SSadaf Ebrahimi     #endif
302*62c56f98SSadaf Ebrahimi         }
303*62c56f98SSadaf Ebrahimi 
304*62c56f98SSadaf Ebrahimi         /* Some algorithms require the payload to have the size of
305*62c56f98SSadaf Ebrahimi          * the hash encoded in the algorithm. Use this input size
306*62c56f98SSadaf Ebrahimi          * even for algorithms that allow other input sizes. */
307*62c56f98SSadaf Ebrahimi         if (hash_alg != 0) {
308*62c56f98SSadaf Ebrahimi             payload_length = PSA_HASH_LENGTH(hash_alg);
309*62c56f98SSadaf Ebrahimi         }
310*62c56f98SSadaf Ebrahimi 
311*62c56f98SSadaf Ebrahimi         if (usage & PSA_KEY_USAGE_SIGN_HASH) {
312*62c56f98SSadaf Ebrahimi             PSA_ASSERT(psa_sign_hash(key, alg,
313*62c56f98SSadaf Ebrahimi                                      payload, payload_length,
314*62c56f98SSadaf Ebrahimi                                      signature, sizeof(signature),
315*62c56f98SSadaf Ebrahimi                                      &signature_length));
316*62c56f98SSadaf Ebrahimi         }
317*62c56f98SSadaf Ebrahimi 
318*62c56f98SSadaf Ebrahimi         if (usage & PSA_KEY_USAGE_VERIFY_HASH) {
319*62c56f98SSadaf Ebrahimi             psa_status_t verify_status =
320*62c56f98SSadaf Ebrahimi                 (usage & PSA_KEY_USAGE_SIGN_HASH ?
321*62c56f98SSadaf Ebrahimi                  PSA_SUCCESS :
322*62c56f98SSadaf Ebrahimi                  PSA_ERROR_INVALID_SIGNATURE);
323*62c56f98SSadaf Ebrahimi             TEST_EQUAL(psa_verify_hash(key, alg,
324*62c56f98SSadaf Ebrahimi                                        payload, payload_length,
325*62c56f98SSadaf Ebrahimi                                        signature, signature_length),
326*62c56f98SSadaf Ebrahimi                        verify_status);
327*62c56f98SSadaf Ebrahimi         }
328*62c56f98SSadaf Ebrahimi     }
329*62c56f98SSadaf Ebrahimi 
330*62c56f98SSadaf Ebrahimi     if (can_sign_or_verify_message(usage, alg)) {
331*62c56f98SSadaf Ebrahimi         unsigned char message[256] = "Hello, world...";
332*62c56f98SSadaf Ebrahimi         unsigned char signature[PSA_SIGNATURE_MAX_SIZE] = { 0 };
333*62c56f98SSadaf Ebrahimi         size_t message_length = 16;
334*62c56f98SSadaf Ebrahimi         size_t signature_length = sizeof(signature);
335*62c56f98SSadaf Ebrahimi 
336*62c56f98SSadaf Ebrahimi         if (usage & PSA_KEY_USAGE_SIGN_MESSAGE) {
337*62c56f98SSadaf Ebrahimi             PSA_ASSERT(psa_sign_message(key, alg,
338*62c56f98SSadaf Ebrahimi                                         message, message_length,
339*62c56f98SSadaf Ebrahimi                                         signature, sizeof(signature),
340*62c56f98SSadaf Ebrahimi                                         &signature_length));
341*62c56f98SSadaf Ebrahimi         }
342*62c56f98SSadaf Ebrahimi 
343*62c56f98SSadaf Ebrahimi         if (usage & PSA_KEY_USAGE_VERIFY_MESSAGE) {
344*62c56f98SSadaf Ebrahimi             psa_status_t verify_status =
345*62c56f98SSadaf Ebrahimi                 (usage & PSA_KEY_USAGE_SIGN_MESSAGE ?
346*62c56f98SSadaf Ebrahimi                  PSA_SUCCESS :
347*62c56f98SSadaf Ebrahimi                  PSA_ERROR_INVALID_SIGNATURE);
348*62c56f98SSadaf Ebrahimi             TEST_EQUAL(psa_verify_message(key, alg,
349*62c56f98SSadaf Ebrahimi                                           message, message_length,
350*62c56f98SSadaf Ebrahimi                                           signature, signature_length),
351*62c56f98SSadaf Ebrahimi                        verify_status);
352*62c56f98SSadaf Ebrahimi         }
353*62c56f98SSadaf Ebrahimi     }
354*62c56f98SSadaf Ebrahimi 
355*62c56f98SSadaf Ebrahimi     return 1;
356*62c56f98SSadaf Ebrahimi 
357*62c56f98SSadaf Ebrahimi exit:
358*62c56f98SSadaf Ebrahimi     return 0;
359*62c56f98SSadaf Ebrahimi }
360*62c56f98SSadaf Ebrahimi 
exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)361*62c56f98SSadaf Ebrahimi static int exercise_asymmetric_encryption_key(mbedtls_svc_key_id_t key,
362*62c56f98SSadaf Ebrahimi                                               psa_key_usage_t usage,
363*62c56f98SSadaf Ebrahimi                                               psa_algorithm_t alg)
364*62c56f98SSadaf Ebrahimi {
365*62c56f98SSadaf Ebrahimi     unsigned char plaintext[256] = "Hello, world...";
366*62c56f98SSadaf Ebrahimi     unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
367*62c56f98SSadaf Ebrahimi     size_t ciphertext_length = sizeof(ciphertext);
368*62c56f98SSadaf Ebrahimi     size_t plaintext_length = 16;
369*62c56f98SSadaf Ebrahimi 
370*62c56f98SSadaf Ebrahimi     if (usage & PSA_KEY_USAGE_ENCRYPT) {
371*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_asymmetric_encrypt(key, alg,
372*62c56f98SSadaf Ebrahimi                                           plaintext, plaintext_length,
373*62c56f98SSadaf Ebrahimi                                           NULL, 0,
374*62c56f98SSadaf Ebrahimi                                           ciphertext, sizeof(ciphertext),
375*62c56f98SSadaf Ebrahimi                                           &ciphertext_length));
376*62c56f98SSadaf Ebrahimi     }
377*62c56f98SSadaf Ebrahimi 
378*62c56f98SSadaf Ebrahimi     if (usage & PSA_KEY_USAGE_DECRYPT) {
379*62c56f98SSadaf Ebrahimi         psa_status_t status =
380*62c56f98SSadaf Ebrahimi             psa_asymmetric_decrypt(key, alg,
381*62c56f98SSadaf Ebrahimi                                    ciphertext, ciphertext_length,
382*62c56f98SSadaf Ebrahimi                                    NULL, 0,
383*62c56f98SSadaf Ebrahimi                                    plaintext, sizeof(plaintext),
384*62c56f98SSadaf Ebrahimi                                    &plaintext_length);
385*62c56f98SSadaf Ebrahimi         TEST_ASSERT(status == PSA_SUCCESS ||
386*62c56f98SSadaf Ebrahimi                     ((usage & PSA_KEY_USAGE_ENCRYPT) == 0 &&
387*62c56f98SSadaf Ebrahimi                      (status == PSA_ERROR_INVALID_ARGUMENT ||
388*62c56f98SSadaf Ebrahimi                       status == PSA_ERROR_INVALID_PADDING)));
389*62c56f98SSadaf Ebrahimi     }
390*62c56f98SSadaf Ebrahimi 
391*62c56f98SSadaf Ebrahimi     return 1;
392*62c56f98SSadaf Ebrahimi 
393*62c56f98SSadaf Ebrahimi exit:
394*62c56f98SSadaf Ebrahimi     return 0;
395*62c56f98SSadaf Ebrahimi }
396*62c56f98SSadaf Ebrahimi 
mbedtls_test_psa_setup_key_derivation_wrap(psa_key_derivation_operation_t * operation,mbedtls_svc_key_id_t key,psa_algorithm_t alg,const unsigned char * input1,size_t input1_length,const unsigned char * input2,size_t input2_length,size_t capacity)397*62c56f98SSadaf Ebrahimi int mbedtls_test_psa_setup_key_derivation_wrap(
398*62c56f98SSadaf Ebrahimi     psa_key_derivation_operation_t *operation,
399*62c56f98SSadaf Ebrahimi     mbedtls_svc_key_id_t key,
400*62c56f98SSadaf Ebrahimi     psa_algorithm_t alg,
401*62c56f98SSadaf Ebrahimi     const unsigned char *input1, size_t input1_length,
402*62c56f98SSadaf Ebrahimi     const unsigned char *input2, size_t input2_length,
403*62c56f98SSadaf Ebrahimi     size_t capacity)
404*62c56f98SSadaf Ebrahimi {
405*62c56f98SSadaf Ebrahimi     PSA_ASSERT(psa_key_derivation_setup(operation, alg));
406*62c56f98SSadaf Ebrahimi     if (PSA_ALG_IS_HKDF(alg)) {
407*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
408*62c56f98SSadaf Ebrahimi                                                   PSA_KEY_DERIVATION_INPUT_SALT,
409*62c56f98SSadaf Ebrahimi                                                   input1, input1_length));
410*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_input_key(operation,
411*62c56f98SSadaf Ebrahimi                                                 PSA_KEY_DERIVATION_INPUT_SECRET,
412*62c56f98SSadaf Ebrahimi                                                 key));
413*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
414*62c56f98SSadaf Ebrahimi                                                   PSA_KEY_DERIVATION_INPUT_INFO,
415*62c56f98SSadaf Ebrahimi                                                   input2,
416*62c56f98SSadaf Ebrahimi                                                   input2_length));
417*62c56f98SSadaf Ebrahimi     } else if (PSA_ALG_IS_TLS12_PRF(alg) ||
418*62c56f98SSadaf Ebrahimi                PSA_ALG_IS_TLS12_PSK_TO_MS(alg)) {
419*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
420*62c56f98SSadaf Ebrahimi                                                   PSA_KEY_DERIVATION_INPUT_SEED,
421*62c56f98SSadaf Ebrahimi                                                   input1, input1_length));
422*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_input_key(operation,
423*62c56f98SSadaf Ebrahimi                                                 PSA_KEY_DERIVATION_INPUT_SECRET,
424*62c56f98SSadaf Ebrahimi                                                 key));
425*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
426*62c56f98SSadaf Ebrahimi                                                   PSA_KEY_DERIVATION_INPUT_LABEL,
427*62c56f98SSadaf Ebrahimi                                                   input2, input2_length));
428*62c56f98SSadaf Ebrahimi     } else if (PSA_ALG_IS_PBKDF2(alg)) {
429*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_input_integer(operation,
430*62c56f98SSadaf Ebrahimi                                                     PSA_KEY_DERIVATION_INPUT_COST,
431*62c56f98SSadaf Ebrahimi                                                     1U));
432*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_input_bytes(operation,
433*62c56f98SSadaf Ebrahimi                                                   PSA_KEY_DERIVATION_INPUT_SALT,
434*62c56f98SSadaf Ebrahimi                                                   input2,
435*62c56f98SSadaf Ebrahimi                                                   input2_length));
436*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_input_key(operation,
437*62c56f98SSadaf Ebrahimi                                                 PSA_KEY_DERIVATION_INPUT_PASSWORD,
438*62c56f98SSadaf Ebrahimi                                                 key));
439*62c56f98SSadaf Ebrahimi     } else {
440*62c56f98SSadaf Ebrahimi         TEST_FAIL("Key derivation algorithm not supported");
441*62c56f98SSadaf Ebrahimi     }
442*62c56f98SSadaf Ebrahimi 
443*62c56f98SSadaf Ebrahimi     if (capacity != SIZE_MAX) {
444*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_set_capacity(operation, capacity));
445*62c56f98SSadaf Ebrahimi     }
446*62c56f98SSadaf Ebrahimi 
447*62c56f98SSadaf Ebrahimi     return 1;
448*62c56f98SSadaf Ebrahimi 
449*62c56f98SSadaf Ebrahimi exit:
450*62c56f98SSadaf Ebrahimi     return 0;
451*62c56f98SSadaf Ebrahimi }
452*62c56f98SSadaf Ebrahimi 
453*62c56f98SSadaf Ebrahimi 
exercise_key_derivation_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)454*62c56f98SSadaf Ebrahimi static int exercise_key_derivation_key(mbedtls_svc_key_id_t key,
455*62c56f98SSadaf Ebrahimi                                        psa_key_usage_t usage,
456*62c56f98SSadaf Ebrahimi                                        psa_algorithm_t alg)
457*62c56f98SSadaf Ebrahimi {
458*62c56f98SSadaf Ebrahimi     psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
459*62c56f98SSadaf Ebrahimi     unsigned char input1[] = "Input 1";
460*62c56f98SSadaf Ebrahimi     size_t input1_length = sizeof(input1);
461*62c56f98SSadaf Ebrahimi     unsigned char input2[] = "Input 2";
462*62c56f98SSadaf Ebrahimi     size_t input2_length = sizeof(input2);
463*62c56f98SSadaf Ebrahimi     unsigned char output[1];
464*62c56f98SSadaf Ebrahimi     size_t capacity = sizeof(output);
465*62c56f98SSadaf Ebrahimi 
466*62c56f98SSadaf Ebrahimi     if (usage & PSA_KEY_USAGE_DERIVE) {
467*62c56f98SSadaf Ebrahimi         if (!mbedtls_test_psa_setup_key_derivation_wrap(&operation, key, alg,
468*62c56f98SSadaf Ebrahimi                                                         input1, input1_length,
469*62c56f98SSadaf Ebrahimi                                                         input2, input2_length,
470*62c56f98SSadaf Ebrahimi                                                         capacity)) {
471*62c56f98SSadaf Ebrahimi             goto exit;
472*62c56f98SSadaf Ebrahimi         }
473*62c56f98SSadaf Ebrahimi 
474*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
475*62c56f98SSadaf Ebrahimi                                                    output,
476*62c56f98SSadaf Ebrahimi                                                    capacity));
477*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_abort(&operation));
478*62c56f98SSadaf Ebrahimi     }
479*62c56f98SSadaf Ebrahimi 
480*62c56f98SSadaf Ebrahimi     return 1;
481*62c56f98SSadaf Ebrahimi 
482*62c56f98SSadaf Ebrahimi exit:
483*62c56f98SSadaf Ebrahimi     return 0;
484*62c56f98SSadaf Ebrahimi }
485*62c56f98SSadaf Ebrahimi 
486*62c56f98SSadaf Ebrahimi /* We need two keys to exercise key agreement. Exercise the
487*62c56f98SSadaf Ebrahimi  * private key against its own public key. */
mbedtls_test_psa_key_agreement_with_self(psa_key_derivation_operation_t * operation,mbedtls_svc_key_id_t key)488*62c56f98SSadaf Ebrahimi psa_status_t mbedtls_test_psa_key_agreement_with_self(
489*62c56f98SSadaf Ebrahimi     psa_key_derivation_operation_t *operation,
490*62c56f98SSadaf Ebrahimi     mbedtls_svc_key_id_t key)
491*62c56f98SSadaf Ebrahimi {
492*62c56f98SSadaf Ebrahimi     psa_key_type_t private_key_type;
493*62c56f98SSadaf Ebrahimi     psa_key_type_t public_key_type;
494*62c56f98SSadaf Ebrahimi     size_t key_bits;
495*62c56f98SSadaf Ebrahimi     uint8_t *public_key = NULL;
496*62c56f98SSadaf Ebrahimi     size_t public_key_length;
497*62c56f98SSadaf Ebrahimi     /* Return GENERIC_ERROR if something other than the final call to
498*62c56f98SSadaf Ebrahimi      * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
499*62c56f98SSadaf Ebrahimi      * but it's good enough: callers will report it as a failed test anyway. */
500*62c56f98SSadaf Ebrahimi     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
501*62c56f98SSadaf Ebrahimi     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
502*62c56f98SSadaf Ebrahimi 
503*62c56f98SSadaf Ebrahimi     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
504*62c56f98SSadaf Ebrahimi     private_key_type = psa_get_key_type(&attributes);
505*62c56f98SSadaf Ebrahimi     key_bits = psa_get_key_bits(&attributes);
506*62c56f98SSadaf Ebrahimi     public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
507*62c56f98SSadaf Ebrahimi     public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
508*62c56f98SSadaf Ebrahimi     TEST_CALLOC(public_key, public_key_length);
509*62c56f98SSadaf Ebrahimi     PSA_ASSERT(psa_export_public_key(key, public_key, public_key_length,
510*62c56f98SSadaf Ebrahimi                                      &public_key_length));
511*62c56f98SSadaf Ebrahimi 
512*62c56f98SSadaf Ebrahimi     status = psa_key_derivation_key_agreement(
513*62c56f98SSadaf Ebrahimi         operation, PSA_KEY_DERIVATION_INPUT_SECRET, key,
514*62c56f98SSadaf Ebrahimi         public_key, public_key_length);
515*62c56f98SSadaf Ebrahimi exit:
516*62c56f98SSadaf Ebrahimi     /*
517*62c56f98SSadaf Ebrahimi      * Key attributes may have been returned by psa_get_key_attributes()
518*62c56f98SSadaf Ebrahimi      * thus reset them as required.
519*62c56f98SSadaf Ebrahimi      */
520*62c56f98SSadaf Ebrahimi     psa_reset_key_attributes(&attributes);
521*62c56f98SSadaf Ebrahimi 
522*62c56f98SSadaf Ebrahimi     mbedtls_free(public_key);
523*62c56f98SSadaf Ebrahimi     return status;
524*62c56f98SSadaf Ebrahimi }
525*62c56f98SSadaf Ebrahimi 
526*62c56f98SSadaf Ebrahimi /* We need two keys to exercise key agreement. Exercise the
527*62c56f98SSadaf Ebrahimi  * private key against its own public key. */
mbedtls_test_psa_raw_key_agreement_with_self(psa_algorithm_t alg,mbedtls_svc_key_id_t key)528*62c56f98SSadaf Ebrahimi psa_status_t mbedtls_test_psa_raw_key_agreement_with_self(
529*62c56f98SSadaf Ebrahimi     psa_algorithm_t alg,
530*62c56f98SSadaf Ebrahimi     mbedtls_svc_key_id_t key)
531*62c56f98SSadaf Ebrahimi {
532*62c56f98SSadaf Ebrahimi     psa_key_type_t private_key_type;
533*62c56f98SSadaf Ebrahimi     psa_key_type_t public_key_type;
534*62c56f98SSadaf Ebrahimi     size_t key_bits;
535*62c56f98SSadaf Ebrahimi     uint8_t *public_key = NULL;
536*62c56f98SSadaf Ebrahimi     size_t public_key_length;
537*62c56f98SSadaf Ebrahimi     uint8_t output[1024];
538*62c56f98SSadaf Ebrahimi     size_t output_length;
539*62c56f98SSadaf Ebrahimi     /* Return GENERIC_ERROR if something other than the final call to
540*62c56f98SSadaf Ebrahimi      * psa_key_derivation_key_agreement fails. This isn't fully satisfactory,
541*62c56f98SSadaf Ebrahimi      * but it's good enough: callers will report it as a failed test anyway. */
542*62c56f98SSadaf Ebrahimi     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
543*62c56f98SSadaf Ebrahimi     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
544*62c56f98SSadaf Ebrahimi 
545*62c56f98SSadaf Ebrahimi     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
546*62c56f98SSadaf Ebrahimi     private_key_type = psa_get_key_type(&attributes);
547*62c56f98SSadaf Ebrahimi     key_bits = psa_get_key_bits(&attributes);
548*62c56f98SSadaf Ebrahimi     public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(private_key_type);
549*62c56f98SSadaf Ebrahimi     public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_key_type, key_bits);
550*62c56f98SSadaf Ebrahimi     TEST_CALLOC(public_key, public_key_length);
551*62c56f98SSadaf Ebrahimi     PSA_ASSERT(psa_export_public_key(key,
552*62c56f98SSadaf Ebrahimi                                      public_key, public_key_length,
553*62c56f98SSadaf Ebrahimi                                      &public_key_length));
554*62c56f98SSadaf Ebrahimi 
555*62c56f98SSadaf Ebrahimi     status = psa_raw_key_agreement(alg, key,
556*62c56f98SSadaf Ebrahimi                                    public_key, public_key_length,
557*62c56f98SSadaf Ebrahimi                                    output, sizeof(output), &output_length);
558*62c56f98SSadaf Ebrahimi     if (status == PSA_SUCCESS) {
559*62c56f98SSadaf Ebrahimi         TEST_ASSERT(output_length <=
560*62c56f98SSadaf Ebrahimi                     PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(private_key_type,
561*62c56f98SSadaf Ebrahimi                                                       key_bits));
562*62c56f98SSadaf Ebrahimi         TEST_ASSERT(output_length <=
563*62c56f98SSadaf Ebrahimi                     PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
564*62c56f98SSadaf Ebrahimi     }
565*62c56f98SSadaf Ebrahimi 
566*62c56f98SSadaf Ebrahimi exit:
567*62c56f98SSadaf Ebrahimi     /*
568*62c56f98SSadaf Ebrahimi      * Key attributes may have been returned by psa_get_key_attributes()
569*62c56f98SSadaf Ebrahimi      * thus reset them as required.
570*62c56f98SSadaf Ebrahimi      */
571*62c56f98SSadaf Ebrahimi     psa_reset_key_attributes(&attributes);
572*62c56f98SSadaf Ebrahimi 
573*62c56f98SSadaf Ebrahimi     mbedtls_free(public_key);
574*62c56f98SSadaf Ebrahimi     return status;
575*62c56f98SSadaf Ebrahimi }
576*62c56f98SSadaf Ebrahimi 
exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)577*62c56f98SSadaf Ebrahimi static int exercise_raw_key_agreement_key(mbedtls_svc_key_id_t key,
578*62c56f98SSadaf Ebrahimi                                           psa_key_usage_t usage,
579*62c56f98SSadaf Ebrahimi                                           psa_algorithm_t alg)
580*62c56f98SSadaf Ebrahimi {
581*62c56f98SSadaf Ebrahimi     int ok = 0;
582*62c56f98SSadaf Ebrahimi 
583*62c56f98SSadaf Ebrahimi     if (usage & PSA_KEY_USAGE_DERIVE) {
584*62c56f98SSadaf Ebrahimi         /* We need two keys to exercise key agreement. Exercise the
585*62c56f98SSadaf Ebrahimi          * private key against its own public key. */
586*62c56f98SSadaf Ebrahimi         PSA_ASSERT(mbedtls_test_psa_raw_key_agreement_with_self(alg, key));
587*62c56f98SSadaf Ebrahimi     }
588*62c56f98SSadaf Ebrahimi     ok = 1;
589*62c56f98SSadaf Ebrahimi 
590*62c56f98SSadaf Ebrahimi exit:
591*62c56f98SSadaf Ebrahimi     return ok;
592*62c56f98SSadaf Ebrahimi }
593*62c56f98SSadaf Ebrahimi 
exercise_key_agreement_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)594*62c56f98SSadaf Ebrahimi static int exercise_key_agreement_key(mbedtls_svc_key_id_t key,
595*62c56f98SSadaf Ebrahimi                                       psa_key_usage_t usage,
596*62c56f98SSadaf Ebrahimi                                       psa_algorithm_t alg)
597*62c56f98SSadaf Ebrahimi {
598*62c56f98SSadaf Ebrahimi     psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
599*62c56f98SSadaf Ebrahimi     unsigned char input[1] = { 0 };
600*62c56f98SSadaf Ebrahimi     unsigned char output[1];
601*62c56f98SSadaf Ebrahimi     int ok = 0;
602*62c56f98SSadaf Ebrahimi     psa_algorithm_t kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
603*62c56f98SSadaf Ebrahimi     psa_status_t expected_key_agreement_status = PSA_SUCCESS;
604*62c56f98SSadaf Ebrahimi 
605*62c56f98SSadaf Ebrahimi     if (usage & PSA_KEY_USAGE_DERIVE) {
606*62c56f98SSadaf Ebrahimi         /* We need two keys to exercise key agreement. Exercise the
607*62c56f98SSadaf Ebrahimi          * private key against its own public key. */
608*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_setup(&operation, alg));
609*62c56f98SSadaf Ebrahimi         if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
610*62c56f98SSadaf Ebrahimi             PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
611*62c56f98SSadaf Ebrahimi             PSA_ASSERT(psa_key_derivation_input_bytes(
612*62c56f98SSadaf Ebrahimi                            &operation, PSA_KEY_DERIVATION_INPUT_SEED,
613*62c56f98SSadaf Ebrahimi                            input, sizeof(input)));
614*62c56f98SSadaf Ebrahimi         }
615*62c56f98SSadaf Ebrahimi 
616*62c56f98SSadaf Ebrahimi         if (PSA_ALG_IS_HKDF_EXTRACT(kdf_alg)) {
617*62c56f98SSadaf Ebrahimi             PSA_ASSERT(psa_key_derivation_input_bytes(
618*62c56f98SSadaf Ebrahimi                            &operation, PSA_KEY_DERIVATION_INPUT_SALT,
619*62c56f98SSadaf Ebrahimi                            input, sizeof(input)));
620*62c56f98SSadaf Ebrahimi         }
621*62c56f98SSadaf Ebrahimi 
622*62c56f98SSadaf Ebrahimi         /* For HKDF_EXPAND input secret may fail as secret size may not match
623*62c56f98SSadaf Ebrahimi            to expected PRK size. In practice it means that key bits must match
624*62c56f98SSadaf Ebrahimi            hash length. Otherwise test should fail with INVALID_ARGUMENT. */
625*62c56f98SSadaf Ebrahimi         if (PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
626*62c56f98SSadaf Ebrahimi             psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
627*62c56f98SSadaf Ebrahimi             PSA_ASSERT(psa_get_key_attributes(key, &attributes));
628*62c56f98SSadaf Ebrahimi             size_t key_bits = psa_get_key_bits(&attributes);
629*62c56f98SSadaf Ebrahimi             psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH(kdf_alg);
630*62c56f98SSadaf Ebrahimi 
631*62c56f98SSadaf Ebrahimi             if (PSA_BITS_TO_BYTES(key_bits) != PSA_HASH_LENGTH(hash_alg)) {
632*62c56f98SSadaf Ebrahimi                 expected_key_agreement_status = PSA_ERROR_INVALID_ARGUMENT;
633*62c56f98SSadaf Ebrahimi             }
634*62c56f98SSadaf Ebrahimi         }
635*62c56f98SSadaf Ebrahimi 
636*62c56f98SSadaf Ebrahimi         TEST_EQUAL(mbedtls_test_psa_key_agreement_with_self(&operation, key),
637*62c56f98SSadaf Ebrahimi                    expected_key_agreement_status);
638*62c56f98SSadaf Ebrahimi 
639*62c56f98SSadaf Ebrahimi         if (expected_key_agreement_status != PSA_SUCCESS) {
640*62c56f98SSadaf Ebrahimi             return 1;
641*62c56f98SSadaf Ebrahimi         }
642*62c56f98SSadaf Ebrahimi 
643*62c56f98SSadaf Ebrahimi         if (PSA_ALG_IS_TLS12_PRF(kdf_alg) ||
644*62c56f98SSadaf Ebrahimi             PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) {
645*62c56f98SSadaf Ebrahimi             PSA_ASSERT(psa_key_derivation_input_bytes(
646*62c56f98SSadaf Ebrahimi                            &operation, PSA_KEY_DERIVATION_INPUT_LABEL,
647*62c56f98SSadaf Ebrahimi                            input, sizeof(input)));
648*62c56f98SSadaf Ebrahimi         } else if (PSA_ALG_IS_HKDF(kdf_alg) || PSA_ALG_IS_HKDF_EXPAND(kdf_alg)) {
649*62c56f98SSadaf Ebrahimi             PSA_ASSERT(psa_key_derivation_input_bytes(
650*62c56f98SSadaf Ebrahimi                            &operation, PSA_KEY_DERIVATION_INPUT_INFO,
651*62c56f98SSadaf Ebrahimi                            input, sizeof(input)));
652*62c56f98SSadaf Ebrahimi         }
653*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_output_bytes(&operation,
654*62c56f98SSadaf Ebrahimi                                                    output,
655*62c56f98SSadaf Ebrahimi                                                    sizeof(output)));
656*62c56f98SSadaf Ebrahimi         PSA_ASSERT(psa_key_derivation_abort(&operation));
657*62c56f98SSadaf Ebrahimi     }
658*62c56f98SSadaf Ebrahimi     ok = 1;
659*62c56f98SSadaf Ebrahimi 
660*62c56f98SSadaf Ebrahimi exit:
661*62c56f98SSadaf Ebrahimi     return ok;
662*62c56f98SSadaf Ebrahimi }
663*62c56f98SSadaf Ebrahimi 
mbedtls_test_psa_exported_key_sanity_check(psa_key_type_t type,size_t bits,const uint8_t * exported,size_t exported_length)664*62c56f98SSadaf Ebrahimi int mbedtls_test_psa_exported_key_sanity_check(
665*62c56f98SSadaf Ebrahimi     psa_key_type_t type, size_t bits,
666*62c56f98SSadaf Ebrahimi     const uint8_t *exported, size_t exported_length)
667*62c56f98SSadaf Ebrahimi {
668*62c56f98SSadaf Ebrahimi     TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE(type, bits));
669*62c56f98SSadaf Ebrahimi 
670*62c56f98SSadaf Ebrahimi     if (PSA_KEY_TYPE_IS_UNSTRUCTURED(type)) {
671*62c56f98SSadaf Ebrahimi         TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
672*62c56f98SSadaf Ebrahimi     } else
673*62c56f98SSadaf Ebrahimi 
674*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_ASN1_PARSE_C)
675*62c56f98SSadaf Ebrahimi     if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) {
676*62c56f98SSadaf Ebrahimi         uint8_t *p = (uint8_t *) exported;
677*62c56f98SSadaf Ebrahimi         const uint8_t *end = exported + exported_length;
678*62c56f98SSadaf Ebrahimi         size_t len;
679*62c56f98SSadaf Ebrahimi         /*   RSAPrivateKey ::= SEQUENCE {
680*62c56f98SSadaf Ebrahimi          *       version             INTEGER,  -- must be 0
681*62c56f98SSadaf Ebrahimi          *       modulus             INTEGER,  -- n
682*62c56f98SSadaf Ebrahimi          *       publicExponent      INTEGER,  -- e
683*62c56f98SSadaf Ebrahimi          *       privateExponent     INTEGER,  -- d
684*62c56f98SSadaf Ebrahimi          *       prime1              INTEGER,  -- p
685*62c56f98SSadaf Ebrahimi          *       prime2              INTEGER,  -- q
686*62c56f98SSadaf Ebrahimi          *       exponent1           INTEGER,  -- d mod (p-1)
687*62c56f98SSadaf Ebrahimi          *       exponent2           INTEGER,  -- d mod (q-1)
688*62c56f98SSadaf Ebrahimi          *       coefficient         INTEGER,  -- (inverse of q) mod p
689*62c56f98SSadaf Ebrahimi          *   }
690*62c56f98SSadaf Ebrahimi          */
691*62c56f98SSadaf Ebrahimi         TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
692*62c56f98SSadaf Ebrahimi                                         MBEDTLS_ASN1_SEQUENCE |
693*62c56f98SSadaf Ebrahimi                                         MBEDTLS_ASN1_CONSTRUCTED), 0);
694*62c56f98SSadaf Ebrahimi         TEST_EQUAL(len, end - p);
695*62c56f98SSadaf Ebrahimi         if (!mbedtls_test_asn1_skip_integer(&p, end, 0, 0, 0)) {
696*62c56f98SSadaf Ebrahimi             goto exit;
697*62c56f98SSadaf Ebrahimi         }
698*62c56f98SSadaf Ebrahimi         if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
699*62c56f98SSadaf Ebrahimi             goto exit;
700*62c56f98SSadaf Ebrahimi         }
701*62c56f98SSadaf Ebrahimi         if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
702*62c56f98SSadaf Ebrahimi             goto exit;
703*62c56f98SSadaf Ebrahimi         }
704*62c56f98SSadaf Ebrahimi         /* Require d to be at least half the size of n. */
705*62c56f98SSadaf Ebrahimi         if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits, 1)) {
706*62c56f98SSadaf Ebrahimi             goto exit;
707*62c56f98SSadaf Ebrahimi         }
708*62c56f98SSadaf Ebrahimi         /* Require p and q to be at most half the size of n, rounded up. */
709*62c56f98SSadaf Ebrahimi         if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
710*62c56f98SSadaf Ebrahimi             goto exit;
711*62c56f98SSadaf Ebrahimi         }
712*62c56f98SSadaf Ebrahimi         if (!mbedtls_test_asn1_skip_integer(&p, end, bits / 2, bits / 2 + 1, 1)) {
713*62c56f98SSadaf Ebrahimi             goto exit;
714*62c56f98SSadaf Ebrahimi         }
715*62c56f98SSadaf Ebrahimi         if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
716*62c56f98SSadaf Ebrahimi             goto exit;
717*62c56f98SSadaf Ebrahimi         }
718*62c56f98SSadaf Ebrahimi         if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
719*62c56f98SSadaf Ebrahimi             goto exit;
720*62c56f98SSadaf Ebrahimi         }
721*62c56f98SSadaf Ebrahimi         if (!mbedtls_test_asn1_skip_integer(&p, end, 1, bits / 2 + 1, 0)) {
722*62c56f98SSadaf Ebrahimi             goto exit;
723*62c56f98SSadaf Ebrahimi         }
724*62c56f98SSadaf Ebrahimi         TEST_EQUAL(p - end, 0);
725*62c56f98SSadaf Ebrahimi 
726*62c56f98SSadaf Ebrahimi         TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
727*62c56f98SSadaf Ebrahimi     } else
728*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_ASN1_PARSE_C */
729*62c56f98SSadaf Ebrahimi 
730*62c56f98SSadaf Ebrahimi     if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type)) {
731*62c56f98SSadaf Ebrahimi         /* Just the secret value */
732*62c56f98SSadaf Ebrahimi         TEST_EQUAL(exported_length, PSA_BITS_TO_BYTES(bits));
733*62c56f98SSadaf Ebrahimi 
734*62c56f98SSadaf Ebrahimi         TEST_ASSERT(exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE);
735*62c56f98SSadaf Ebrahimi     } else
736*62c56f98SSadaf Ebrahimi 
737*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_ASN1_PARSE_C)
738*62c56f98SSadaf Ebrahimi     if (type == PSA_KEY_TYPE_RSA_PUBLIC_KEY) {
739*62c56f98SSadaf Ebrahimi         uint8_t *p = (uint8_t *) exported;
740*62c56f98SSadaf Ebrahimi         const uint8_t *end = exported + exported_length;
741*62c56f98SSadaf Ebrahimi         size_t len;
742*62c56f98SSadaf Ebrahimi         /*   RSAPublicKey ::= SEQUENCE {
743*62c56f98SSadaf Ebrahimi          *      modulus            INTEGER,    -- n
744*62c56f98SSadaf Ebrahimi          *      publicExponent     INTEGER  }  -- e
745*62c56f98SSadaf Ebrahimi          */
746*62c56f98SSadaf Ebrahimi         TEST_EQUAL(mbedtls_asn1_get_tag(&p, end, &len,
747*62c56f98SSadaf Ebrahimi                                         MBEDTLS_ASN1_SEQUENCE |
748*62c56f98SSadaf Ebrahimi                                         MBEDTLS_ASN1_CONSTRUCTED),
749*62c56f98SSadaf Ebrahimi                    0);
750*62c56f98SSadaf Ebrahimi         TEST_EQUAL(len, end - p);
751*62c56f98SSadaf Ebrahimi         if (!mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)) {
752*62c56f98SSadaf Ebrahimi             goto exit;
753*62c56f98SSadaf Ebrahimi         }
754*62c56f98SSadaf Ebrahimi         if (!mbedtls_test_asn1_skip_integer(&p, end, 2, bits, 1)) {
755*62c56f98SSadaf Ebrahimi             goto exit;
756*62c56f98SSadaf Ebrahimi         }
757*62c56f98SSadaf Ebrahimi         TEST_EQUAL(p - end, 0);
758*62c56f98SSadaf Ebrahimi 
759*62c56f98SSadaf Ebrahimi 
760*62c56f98SSadaf Ebrahimi         TEST_ASSERT(exported_length <=
761*62c56f98SSadaf Ebrahimi                     PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
762*62c56f98SSadaf Ebrahimi         TEST_ASSERT(exported_length <=
763*62c56f98SSadaf Ebrahimi                     PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
764*62c56f98SSadaf Ebrahimi     } else
765*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_ASN1_PARSE_C */
766*62c56f98SSadaf Ebrahimi 
767*62c56f98SSadaf Ebrahimi     if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)) {
768*62c56f98SSadaf Ebrahimi 
769*62c56f98SSadaf Ebrahimi         TEST_ASSERT(exported_length <=
770*62c56f98SSadaf Ebrahimi                     PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
771*62c56f98SSadaf Ebrahimi         TEST_ASSERT(exported_length <=
772*62c56f98SSadaf Ebrahimi                     PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
773*62c56f98SSadaf Ebrahimi 
774*62c56f98SSadaf Ebrahimi         if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_MONTGOMERY) {
775*62c56f98SSadaf Ebrahimi             /* The representation of an ECC Montgomery public key is
776*62c56f98SSadaf Ebrahimi              * the raw compressed point */
777*62c56f98SSadaf Ebrahimi             TEST_EQUAL(PSA_BITS_TO_BYTES(bits), exported_length);
778*62c56f98SSadaf Ebrahimi         } else if (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS) {
779*62c56f98SSadaf Ebrahimi             /* The representation of an ECC Edwards public key is
780*62c56f98SSadaf Ebrahimi              * the raw compressed point */
781*62c56f98SSadaf Ebrahimi             TEST_EQUAL(PSA_BITS_TO_BYTES(bits + 1), exported_length);
782*62c56f98SSadaf Ebrahimi         } else {
783*62c56f98SSadaf Ebrahimi             /* The representation of an ECC Weierstrass public key is:
784*62c56f98SSadaf Ebrahimi              *      - The byte 0x04;
785*62c56f98SSadaf Ebrahimi              *      - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
786*62c56f98SSadaf Ebrahimi              *      - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
787*62c56f98SSadaf Ebrahimi              *      - where m is the bit size associated with the curve.
788*62c56f98SSadaf Ebrahimi              */
789*62c56f98SSadaf Ebrahimi             TEST_EQUAL(1 + 2 * PSA_BITS_TO_BYTES(bits), exported_length);
790*62c56f98SSadaf Ebrahimi             TEST_EQUAL(exported[0], 4);
791*62c56f98SSadaf Ebrahimi         }
792*62c56f98SSadaf Ebrahimi     } else
793*62c56f98SSadaf Ebrahimi     if (PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) || PSA_KEY_TYPE_IS_DH_KEY_PAIR(type)) {
794*62c56f98SSadaf Ebrahimi         TEST_ASSERT(exported_length ==
795*62c56f98SSadaf Ebrahimi                     PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(type, bits));
796*62c56f98SSadaf Ebrahimi         TEST_ASSERT(exported_length <=
797*62c56f98SSadaf Ebrahimi                     PSA_EXPORT_PUBLIC_KEY_MAX_SIZE);
798*62c56f98SSadaf Ebrahimi     } else {
799*62c56f98SSadaf Ebrahimi         (void) exported;
800*62c56f98SSadaf Ebrahimi         TEST_FAIL("Sanity check not implemented for this key type");
801*62c56f98SSadaf Ebrahimi     }
802*62c56f98SSadaf Ebrahimi 
803*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_DES_C)
804*62c56f98SSadaf Ebrahimi     if (type == PSA_KEY_TYPE_DES) {
805*62c56f98SSadaf Ebrahimi         /* Check the parity bits. */
806*62c56f98SSadaf Ebrahimi         unsigned i;
807*62c56f98SSadaf Ebrahimi         for (i = 0; i < bits / 8; i++) {
808*62c56f98SSadaf Ebrahimi             unsigned bit_count = 0;
809*62c56f98SSadaf Ebrahimi             unsigned m;
810*62c56f98SSadaf Ebrahimi             for (m = 1; m <= 0x100; m <<= 1) {
811*62c56f98SSadaf Ebrahimi                 if (exported[i] & m) {
812*62c56f98SSadaf Ebrahimi                     ++bit_count;
813*62c56f98SSadaf Ebrahimi                 }
814*62c56f98SSadaf Ebrahimi             }
815*62c56f98SSadaf Ebrahimi             TEST_ASSERT(bit_count % 2 != 0);
816*62c56f98SSadaf Ebrahimi         }
817*62c56f98SSadaf Ebrahimi     }
818*62c56f98SSadaf Ebrahimi #endif
819*62c56f98SSadaf Ebrahimi 
820*62c56f98SSadaf Ebrahimi     return 1;
821*62c56f98SSadaf Ebrahimi 
822*62c56f98SSadaf Ebrahimi exit:
823*62c56f98SSadaf Ebrahimi     return 0;
824*62c56f98SSadaf Ebrahimi }
825*62c56f98SSadaf Ebrahimi 
exercise_export_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage)826*62c56f98SSadaf Ebrahimi static int exercise_export_key(mbedtls_svc_key_id_t key,
827*62c56f98SSadaf Ebrahimi                                psa_key_usage_t usage)
828*62c56f98SSadaf Ebrahimi {
829*62c56f98SSadaf Ebrahimi     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
830*62c56f98SSadaf Ebrahimi     uint8_t *exported = NULL;
831*62c56f98SSadaf Ebrahimi     size_t exported_size = 0;
832*62c56f98SSadaf Ebrahimi     size_t exported_length = 0;
833*62c56f98SSadaf Ebrahimi     int ok = 0;
834*62c56f98SSadaf Ebrahimi 
835*62c56f98SSadaf Ebrahimi     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
836*62c56f98SSadaf Ebrahimi 
837*62c56f98SSadaf Ebrahimi     exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
838*62c56f98SSadaf Ebrahimi         psa_get_key_type(&attributes),
839*62c56f98SSadaf Ebrahimi         psa_get_key_bits(&attributes));
840*62c56f98SSadaf Ebrahimi     TEST_CALLOC(exported, exported_size);
841*62c56f98SSadaf Ebrahimi 
842*62c56f98SSadaf Ebrahimi     if ((usage & PSA_KEY_USAGE_EXPORT) == 0 &&
843*62c56f98SSadaf Ebrahimi         !PSA_KEY_TYPE_IS_PUBLIC_KEY(psa_get_key_type(&attributes))) {
844*62c56f98SSadaf Ebrahimi         TEST_EQUAL(psa_export_key(key, exported,
845*62c56f98SSadaf Ebrahimi                                   exported_size, &exported_length),
846*62c56f98SSadaf Ebrahimi                    PSA_ERROR_NOT_PERMITTED);
847*62c56f98SSadaf Ebrahimi         ok = 1;
848*62c56f98SSadaf Ebrahimi         goto exit;
849*62c56f98SSadaf Ebrahimi     }
850*62c56f98SSadaf Ebrahimi 
851*62c56f98SSadaf Ebrahimi     PSA_ASSERT(psa_export_key(key,
852*62c56f98SSadaf Ebrahimi                               exported, exported_size,
853*62c56f98SSadaf Ebrahimi                               &exported_length));
854*62c56f98SSadaf Ebrahimi     ok = mbedtls_test_psa_exported_key_sanity_check(
855*62c56f98SSadaf Ebrahimi         psa_get_key_type(&attributes), psa_get_key_bits(&attributes),
856*62c56f98SSadaf Ebrahimi         exported, exported_length);
857*62c56f98SSadaf Ebrahimi 
858*62c56f98SSadaf Ebrahimi exit:
859*62c56f98SSadaf Ebrahimi     /*
860*62c56f98SSadaf Ebrahimi      * Key attributes may have been returned by psa_get_key_attributes()
861*62c56f98SSadaf Ebrahimi      * thus reset them as required.
862*62c56f98SSadaf Ebrahimi      */
863*62c56f98SSadaf Ebrahimi     psa_reset_key_attributes(&attributes);
864*62c56f98SSadaf Ebrahimi 
865*62c56f98SSadaf Ebrahimi     mbedtls_free(exported);
866*62c56f98SSadaf Ebrahimi     return ok;
867*62c56f98SSadaf Ebrahimi }
868*62c56f98SSadaf Ebrahimi 
exercise_export_public_key(mbedtls_svc_key_id_t key)869*62c56f98SSadaf Ebrahimi static int exercise_export_public_key(mbedtls_svc_key_id_t key)
870*62c56f98SSadaf Ebrahimi {
871*62c56f98SSadaf Ebrahimi     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
872*62c56f98SSadaf Ebrahimi     psa_key_type_t public_type;
873*62c56f98SSadaf Ebrahimi     uint8_t *exported = NULL;
874*62c56f98SSadaf Ebrahimi     size_t exported_size = 0;
875*62c56f98SSadaf Ebrahimi     size_t exported_length = 0;
876*62c56f98SSadaf Ebrahimi     int ok = 0;
877*62c56f98SSadaf Ebrahimi 
878*62c56f98SSadaf Ebrahimi     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
879*62c56f98SSadaf Ebrahimi     if (!PSA_KEY_TYPE_IS_ASYMMETRIC(psa_get_key_type(&attributes))) {
880*62c56f98SSadaf Ebrahimi         exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
881*62c56f98SSadaf Ebrahimi             psa_get_key_type(&attributes),
882*62c56f98SSadaf Ebrahimi             psa_get_key_bits(&attributes));
883*62c56f98SSadaf Ebrahimi         TEST_CALLOC(exported, exported_size);
884*62c56f98SSadaf Ebrahimi 
885*62c56f98SSadaf Ebrahimi         TEST_EQUAL(psa_export_public_key(key, exported,
886*62c56f98SSadaf Ebrahimi                                          exported_size, &exported_length),
887*62c56f98SSadaf Ebrahimi                    PSA_ERROR_INVALID_ARGUMENT);
888*62c56f98SSadaf Ebrahimi         ok = 1;
889*62c56f98SSadaf Ebrahimi         goto exit;
890*62c56f98SSadaf Ebrahimi     }
891*62c56f98SSadaf Ebrahimi 
892*62c56f98SSadaf Ebrahimi     public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(
893*62c56f98SSadaf Ebrahimi         psa_get_key_type(&attributes));
894*62c56f98SSadaf Ebrahimi     exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(public_type,
895*62c56f98SSadaf Ebrahimi                                                       psa_get_key_bits(&attributes));
896*62c56f98SSadaf Ebrahimi     TEST_CALLOC(exported, exported_size);
897*62c56f98SSadaf Ebrahimi 
898*62c56f98SSadaf Ebrahimi     PSA_ASSERT(psa_export_public_key(key,
899*62c56f98SSadaf Ebrahimi                                      exported, exported_size,
900*62c56f98SSadaf Ebrahimi                                      &exported_length));
901*62c56f98SSadaf Ebrahimi     ok = mbedtls_test_psa_exported_key_sanity_check(
902*62c56f98SSadaf Ebrahimi         public_type, psa_get_key_bits(&attributes),
903*62c56f98SSadaf Ebrahimi         exported, exported_length);
904*62c56f98SSadaf Ebrahimi 
905*62c56f98SSadaf Ebrahimi exit:
906*62c56f98SSadaf Ebrahimi     /*
907*62c56f98SSadaf Ebrahimi      * Key attributes may have been returned by psa_get_key_attributes()
908*62c56f98SSadaf Ebrahimi      * thus reset them as required.
909*62c56f98SSadaf Ebrahimi      */
910*62c56f98SSadaf Ebrahimi     psa_reset_key_attributes(&attributes);
911*62c56f98SSadaf Ebrahimi 
912*62c56f98SSadaf Ebrahimi     mbedtls_free(exported);
913*62c56f98SSadaf Ebrahimi     return ok;
914*62c56f98SSadaf Ebrahimi }
915*62c56f98SSadaf Ebrahimi 
mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,psa_key_usage_t usage,psa_algorithm_t alg)916*62c56f98SSadaf Ebrahimi int mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key,
917*62c56f98SSadaf Ebrahimi                                   psa_key_usage_t usage,
918*62c56f98SSadaf Ebrahimi                                   psa_algorithm_t alg)
919*62c56f98SSadaf Ebrahimi {
920*62c56f98SSadaf Ebrahimi     int ok = 0;
921*62c56f98SSadaf Ebrahimi 
922*62c56f98SSadaf Ebrahimi     if (!check_key_attributes_sanity(key)) {
923*62c56f98SSadaf Ebrahimi         return 0;
924*62c56f98SSadaf Ebrahimi     }
925*62c56f98SSadaf Ebrahimi 
926*62c56f98SSadaf Ebrahimi     if (alg == 0) {
927*62c56f98SSadaf Ebrahimi         ok = 1; /* If no algorithm, do nothing (used for raw data "keys"). */
928*62c56f98SSadaf Ebrahimi     } else if (PSA_ALG_IS_MAC(alg)) {
929*62c56f98SSadaf Ebrahimi         ok = exercise_mac_key(key, usage, alg);
930*62c56f98SSadaf Ebrahimi     } else if (PSA_ALG_IS_CIPHER(alg)) {
931*62c56f98SSadaf Ebrahimi         ok = exercise_cipher_key(key, usage, alg);
932*62c56f98SSadaf Ebrahimi     } else if (PSA_ALG_IS_AEAD(alg)) {
933*62c56f98SSadaf Ebrahimi         ok = exercise_aead_key(key, usage, alg);
934*62c56f98SSadaf Ebrahimi     } else if (PSA_ALG_IS_SIGN(alg)) {
935*62c56f98SSadaf Ebrahimi         ok = exercise_signature_key(key, usage, alg);
936*62c56f98SSadaf Ebrahimi     } else if (PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
937*62c56f98SSadaf Ebrahimi         ok = exercise_asymmetric_encryption_key(key, usage, alg);
938*62c56f98SSadaf Ebrahimi     } else if (PSA_ALG_IS_KEY_DERIVATION(alg)) {
939*62c56f98SSadaf Ebrahimi         ok = exercise_key_derivation_key(key, usage, alg);
940*62c56f98SSadaf Ebrahimi     } else if (PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
941*62c56f98SSadaf Ebrahimi         ok = exercise_raw_key_agreement_key(key, usage, alg);
942*62c56f98SSadaf Ebrahimi     } else if (PSA_ALG_IS_KEY_AGREEMENT(alg)) {
943*62c56f98SSadaf Ebrahimi         ok = exercise_key_agreement_key(key, usage, alg);
944*62c56f98SSadaf Ebrahimi     } else {
945*62c56f98SSadaf Ebrahimi         TEST_FAIL("No code to exercise this category of algorithm");
946*62c56f98SSadaf Ebrahimi     }
947*62c56f98SSadaf Ebrahimi 
948*62c56f98SSadaf Ebrahimi     ok = ok && exercise_export_key(key, usage);
949*62c56f98SSadaf Ebrahimi     ok = ok && exercise_export_public_key(key);
950*62c56f98SSadaf Ebrahimi 
951*62c56f98SSadaf Ebrahimi exit:
952*62c56f98SSadaf Ebrahimi     return ok;
953*62c56f98SSadaf Ebrahimi }
954*62c56f98SSadaf Ebrahimi 
mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,psa_algorithm_t alg)955*62c56f98SSadaf Ebrahimi psa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type,
956*62c56f98SSadaf Ebrahimi                                                    psa_algorithm_t alg)
957*62c56f98SSadaf Ebrahimi {
958*62c56f98SSadaf Ebrahimi     if (PSA_ALG_IS_MAC(alg) || PSA_ALG_IS_SIGN(alg)) {
959*62c56f98SSadaf Ebrahimi         if (PSA_ALG_IS_SIGN_HASH(alg)) {
960*62c56f98SSadaf Ebrahimi             if (PSA_ALG_SIGN_GET_HASH(alg)) {
961*62c56f98SSadaf Ebrahimi                 return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
962*62c56f98SSadaf Ebrahimi                        PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_VERIFY_MESSAGE :
963*62c56f98SSadaf Ebrahimi                        PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH |
964*62c56f98SSadaf Ebrahimi                        PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
965*62c56f98SSadaf Ebrahimi             }
966*62c56f98SSadaf Ebrahimi         } else if (PSA_ALG_IS_SIGN_MESSAGE(alg)) {
967*62c56f98SSadaf Ebrahimi             return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
968*62c56f98SSadaf Ebrahimi                    PSA_KEY_USAGE_VERIFY_MESSAGE :
969*62c56f98SSadaf Ebrahimi                    PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE;
970*62c56f98SSadaf Ebrahimi         }
971*62c56f98SSadaf Ebrahimi 
972*62c56f98SSadaf Ebrahimi         return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
973*62c56f98SSadaf Ebrahimi                PSA_KEY_USAGE_VERIFY_HASH :
974*62c56f98SSadaf Ebrahimi                PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
975*62c56f98SSadaf Ebrahimi     } else if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg) ||
976*62c56f98SSadaf Ebrahimi                PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)) {
977*62c56f98SSadaf Ebrahimi         return PSA_KEY_TYPE_IS_PUBLIC_KEY(type) ?
978*62c56f98SSadaf Ebrahimi                PSA_KEY_USAGE_ENCRYPT :
979*62c56f98SSadaf Ebrahimi                PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
980*62c56f98SSadaf Ebrahimi     } else if (PSA_ALG_IS_KEY_DERIVATION(alg) ||
981*62c56f98SSadaf Ebrahimi                PSA_ALG_IS_KEY_AGREEMENT(alg)) {
982*62c56f98SSadaf Ebrahimi         return PSA_KEY_USAGE_DERIVE;
983*62c56f98SSadaf Ebrahimi     } else {
984*62c56f98SSadaf Ebrahimi         return 0;
985*62c56f98SSadaf Ebrahimi     }
986*62c56f98SSadaf Ebrahimi 
987*62c56f98SSadaf Ebrahimi }
988*62c56f98SSadaf Ebrahimi 
989*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_CRYPTO_C */
990