blob: 34987e4f0ac9684786804c8c091546fec331f6fe [file] [log] [blame]
Manish V Badarkhe8fbea622023-09-06 10:22:19 +01001/*
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -05002 * Copyright (c) 2023-2025, Arm Limited. All rights reserved.
Manish V Badarkhe8fbea622023-09-06 10:22:19 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <stddef.h>
9#include <string.h>
10
11/* mbed TLS headers */
Manish V Badarkhe8fbea622023-09-06 10:22:19 +010012#include <mbedtls/md.h>
13#include <mbedtls/memory_buffer_alloc.h>
14#include <mbedtls/oid.h>
15#include <mbedtls/platform.h>
Jimmy Brisson640d9912024-04-10 10:20:13 -050016#include <mbedtls/psa_util.h>
Manish V Badarkhe8fbea622023-09-06 10:22:19 +010017#include <mbedtls/x509.h>
Manish V Badarkhef179aa92023-09-06 11:01:37 +010018#include <psa/crypto.h>
19#include <psa/crypto_platform.h>
20#include <psa/crypto_types.h>
21#include <psa/crypto_values.h>
Manish V Badarkhe8fbea622023-09-06 10:22:19 +010022
23#include <common/debug.h>
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -050024#include <drivers/auth/auth_util.h>
Manish V Badarkhe8fbea622023-09-06 10:22:19 +010025#include <drivers/auth/crypto_mod.h>
26#include <drivers/auth/mbedtls/mbedtls_common.h>
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -050027#include <drivers/auth/mbedtls/mbedtls_psa_crypto.h>
Manish V Badarkhe8fbea622023-09-06 10:22:19 +010028#include <plat/common/platform.h>
29
30#define LIB_NAME "mbed TLS PSA"
31
Ryan Everett9c24a2e2024-11-05 10:48:35 +000032/* Minimum required size for a buffer containing a raw EC signature when using
33 * a maximum curve size of 384 bits.
34 * This is calculated as 2 * (384 / 8). */
35#define ECDSA_SIG_BUFFER_SIZE 96U
Manish V Badarkhefad6b232023-09-27 11:37:44 +010036
37/* Size of ASN.1 length and tag in bytes*/
38#define SIZE_OF_ASN1_LEN 1U
39#define SIZE_OF_ASN1_TAG 1U
40
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -050041/* Global cache for keys */
42key_cache_t key_cache[MAX_CACHED_KEYS] = {0};
43
Manish V Badarkhe8fbea622023-09-06 10:22:19 +010044#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
45CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
46/*
47 * CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available
48 * so make sure that mbed TLS MD maximum size must be lesser than this.
49 */
50CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE,
51 assert_mbedtls_md_size_overflow);
52
53#endif /*
54 * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
55 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
56 */
57
58/*
59 * AlgorithmIdentifier ::= SEQUENCE {
60 * algorithm OBJECT IDENTIFIER,
61 * parameters ANY DEFINED BY algorithm OPTIONAL
62 * }
63 *
64 * SubjectPublicKeyInfo ::= SEQUENCE {
65 * algorithm AlgorithmIdentifier,
66 * subjectPublicKey BIT STRING
67 * }
68 *
69 * DigestInfo ::= SEQUENCE {
70 * digestAlgorithm AlgorithmIdentifier,
71 * digest OCTET STRING
72 * }
73 */
Manish V Badarkhef179aa92023-09-06 11:01:37 +010074
75/*
76 * We pretend using an external RNG (through MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
77 * mbedTLS config option) so we need to provide an implementation of
78 * mbedtls_psa_external_get_random(). Provide a fake one, since we do not
79 * actually have any external RNG and TF-A itself doesn't engage in
80 * cryptographic operations that demands randomness.
81 */
82psa_status_t mbedtls_psa_external_get_random(
83 mbedtls_psa_external_random_context_t *context,
84 uint8_t *output, size_t output_size,
85 size_t *output_length)
86{
87 return PSA_ERROR_INSUFFICIENT_ENTROPY;
88}
Manish V Badarkhe8fbea622023-09-06 10:22:19 +010089
90/*
91 * Initialize the library and export the descriptor
92 */
93static void init(void)
94{
95 /* Initialize mbed TLS */
96 mbedtls_init();
Manish V Badarkhef179aa92023-09-06 11:01:37 +010097
98 /* Initialise PSA mbedTLS */
99 psa_status_t status = psa_crypto_init();
100
101 if (status != PSA_SUCCESS) {
102 ERROR("Failed to initialize %s crypto (%d).\n", LIB_NAME, status);
103 panic();
104 }
105
106 INFO("PSA crypto initialized successfully!\n");
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100107}
108
109#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
110CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500111/* Destroy all psa key ids created in a loop */
112static void destroy_key_ids(void)
113{
114 for (int i = 0; i < MAX_CACHED_KEYS; i++) {
115 if (key_cache[i].valid) {
116 psa_destroy_key(key_cache[i].key_id);
117 }
118 }
119}
120
121/* Retrieve cached key ID, algorithm, and key attributes */
122static bool get_cached_psa_key_info(const char *pk_oid, psa_key_id_t *key_id,
123 psa_algorithm_t *psa_alg, psa_key_attributes_t *psa_key_attr)
124{
125 for (int i = 0; i < MAX_CACHED_KEYS; i++) {
126 if (key_cache[i].valid &&
127 (strlen(key_cache[i].pk_oid) == strlen(pk_oid)) &&
128 (strncmp(key_cache[i].pk_oid, pk_oid, strlen(pk_oid)) == 0)) {
129 *key_id = key_cache[i].key_id;
130 *psa_alg = key_cache[i].psa_alg;
131 *psa_key_attr = key_cache[i].psa_key_attr;
132 return true;
133 }
134 }
135 return false;
136}
137
138/* Store key ID, algorithm, and key attributes in the cache */
139static int cache_psa_key_info(const char *pk_oid, psa_key_id_t key_id, psa_algorithm_t psa_alg,
140 psa_key_attributes_t psa_key_attr)
141{
142 for (int i = 0; i < MAX_CACHED_KEYS; i++) {
143 if (!key_cache[i].valid) {
144 key_cache[i].pk_oid = pk_oid;
145 key_cache[i].key_id = key_id;
146 key_cache[i].psa_alg = psa_alg;
147 key_cache[i].psa_key_attr = psa_key_attr;
148 key_cache[i].valid = true;
149 return CRYPTO_SUCCESS;
150 }
151 }
152 return CRYPTO_ERR_SIGNATURE;
153}
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100154
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100155/*
Ryan Everett290915f2024-07-11 16:46:52 +0100156 * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has
157 * advised that it's better to copy out the declaration than it would be to
158 * update to 3.5.2, where this function is exposed.
159 */
160int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid,
161 const mbedtls_x509_buf *sig_params,
162 mbedtls_md_type_t *md_alg,
163 mbedtls_pk_type_t *pk_alg,
164 void **sig_opts);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100165
166/*
Ryan Everett290915f2024-07-11 16:46:52 +0100167 * This is a helper function which parses a SignatureAlgorithm OID.
168 * It extracts the pk algorithm and constructs a psa_algorithm_t object
169 * to be used by PSA calls.
170 */
171static int construct_psa_alg(void *sig_alg, unsigned int sig_alg_len,
172 mbedtls_pk_type_t *pk_alg, psa_algorithm_t *psa_alg)
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100173{
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100174 int rc;
Ryan Everett290915f2024-07-11 16:46:52 +0100175 mbedtls_md_type_t md_alg;
176 void *sig_opts = NULL;
177 mbedtls_asn1_buf sig_alg_oid, params;
178 unsigned char *p = (unsigned char *) sig_alg;
179 unsigned char *end = (unsigned char *) sig_alg + sig_alg_len;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100180
Ryan Everett290915f2024-07-11 16:46:52 +0100181 rc = mbedtls_asn1_get_alg(&p, end, &sig_alg_oid, &params);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100182 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100183 rc = CRYPTO_ERR_SIGNATURE;
184 goto end;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100185 }
186
Ryan Everett290915f2024-07-11 16:46:52 +0100187 rc = mbedtls_x509_get_sig_alg(&sig_alg_oid, &params, &md_alg, pk_alg, &sig_opts);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100188 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100189 rc = CRYPTO_ERR_SIGNATURE;
190 goto end;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100191 }
192
Ryan Everett290915f2024-07-11 16:46:52 +0100193 psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100194
Ryan Everett290915f2024-07-11 16:46:52 +0100195 switch (*pk_alg) {
196 case MBEDTLS_PK_RSASSA_PSS:
197 *psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
198 rc = CRYPTO_SUCCESS;
199 break;
200 case MBEDTLS_PK_ECDSA:
201 *psa_alg = PSA_ALG_ECDSA(psa_md_alg);
202 rc = CRYPTO_SUCCESS;
203 break;
204 default:
205 *psa_alg = PSA_ALG_NONE;
206 rc = CRYPTO_ERR_SIGNATURE;
207 break;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100208 }
209
Ryan Everett290915f2024-07-11 16:46:52 +0100210end:
211 mbedtls_free(sig_opts);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100212 return rc;
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100213}
214
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100215/*
Ryan Everett290915f2024-07-11 16:46:52 +0100216 * Helper functions for mbedtls PK contexts.
217 */
218static void initialize_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100219{
Ryan Everett290915f2024-07-11 16:46:52 +0100220 mbedtls_pk_init(pk);
221 *pk_initialized = true;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100222}
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100223
Ryan Everett290915f2024-07-11 16:46:52 +0100224static void cleanup_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
Jimmy Brisson640d9912024-04-10 10:20:13 -0500225{
Ryan Everett290915f2024-07-11 16:46:52 +0100226 if (*pk_initialized) {
227 mbedtls_pk_free(pk);
228 *pk_initialized = false;
Jimmy Brisson640d9912024-04-10 10:20:13 -0500229 }
Jimmy Brisson640d9912024-04-10 10:20:13 -0500230}
231
232/*
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100233 * Verify a signature.
234 *
235 * Parameters are passed using the DER encoding format following the ASN.1
236 * structures detailed above.
237 */
238static int verify_signature(void *data_ptr, unsigned int data_len,
239 void *sig_ptr, unsigned int sig_len,
240 void *sig_alg, unsigned int sig_alg_len,
241 void *pk_ptr, unsigned int pk_len)
242{
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100243 unsigned char *p, *end;
Ryan Everett290915f2024-07-11 16:46:52 +0100244 mbedtls_pk_context pk;
245 bool pk_initialized = false;
246 int rc = CRYPTO_ERR_SIGNATURE;
247 psa_status_t psa_status = PSA_ERROR_CORRUPTION_DETECTED;
248 psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT;
249 psa_key_id_t psa_key_id;
250 mbedtls_pk_type_t pk_alg;
251 psa_algorithm_t psa_alg;
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500252 const char *pk_oid = get_current_pk_oid();
Ryan Everett9c24a2e2024-11-05 10:48:35 +0000253 __unused unsigned char reformatted_sig[ECDSA_SIG_BUFFER_SIZE] = {0};
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100254 unsigned char *local_sig_ptr;
255 size_t local_sig_len;
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100256
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500257 /* Check if key, algorithm, and key attributes are already cached */
258 if (!get_cached_psa_key_info(pk_oid, &psa_key_id, &psa_alg, &psa_key_attr)) {
259 /* Load the key into the PSA key store. */
260 initialize_pk_context(&pk, &pk_initialized);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100261
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500262 p = (unsigned char *) pk_ptr;
263 end = p + pk_len;
264 rc = mbedtls_pk_parse_subpubkey(&p, end, &pk);
265 if (rc != 0) {
266 rc = CRYPTO_ERR_SIGNATURE;
267 goto end2;
268 }
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100269
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500270 rc = mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_VERIFY_MESSAGE,
271 &psa_key_attr);
272 if (rc != 0) {
273 rc = CRYPTO_ERR_SIGNATURE;
274 goto end2;
275 }
Ryan Everett290915f2024-07-11 16:46:52 +0100276
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500277 rc = construct_psa_alg(sig_alg, sig_alg_len, &pk_alg, &psa_alg);
278 if (rc != CRYPTO_SUCCESS) {
279 goto end2;
280 }
281 psa_set_key_algorithm(&psa_key_attr, psa_alg);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100282
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500283 rc = mbedtls_pk_import_into_psa(&pk, &psa_key_attr, &psa_key_id);
284 if (rc != 0) {
285 rc = CRYPTO_ERR_SIGNATURE;
286 goto end2;
287 }
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100288
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500289 /* Cache the key, algorithm, and key attributes for future use */
290 rc = cache_psa_key_info(pk_oid, psa_key_id, psa_alg, psa_key_attr);
291 if (rc != CRYPTO_SUCCESS) {
292 goto end2;
293 }
294
295 /* Optimize mbedtls heap usage by freeing the pk context now. */
296 cleanup_pk_context(&pk, &pk_initialized);
297 }
Ryan Everett290915f2024-07-11 16:46:52 +0100298
299 /* Extract the signature from sig_ptr. */
300 p = (unsigned char *) sig_ptr;
301 end = p + sig_len;
302 rc = mbedtls_asn1_get_bitstring_null(&p, end, &local_sig_len);
303 if (rc != 0) {
304 rc = CRYPTO_ERR_SIGNATURE;
305 goto end1;
306 }
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100307 local_sig_ptr = p;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100308
309#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
310TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500311 if (PSA_ALG_IS_ECDSA(psa_alg)) {
Ryan Everett290915f2024-07-11 16:46:52 +0100312 /* Convert the DER ASN.1 signature to raw format. */
313 size_t key_bits = psa_get_key_bits(&psa_key_attr);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100314
Ryan Everett290915f2024-07-11 16:46:52 +0100315 rc = mbedtls_ecdsa_der_to_raw(key_bits, p, local_sig_len,
Ryan Everett9c24a2e2024-11-05 10:48:35 +0000316 reformatted_sig, ECDSA_SIG_BUFFER_SIZE,
Ryan Everett290915f2024-07-11 16:46:52 +0100317 &local_sig_len);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100318 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100319 rc = CRYPTO_ERR_SIGNATURE;
320 goto end1;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100321 }
Ryan Everett290915f2024-07-11 16:46:52 +0100322 local_sig_ptr = reformatted_sig;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100323 }
324#endif /*
325 * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
326 * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
327 **/
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100328
Ryan Everett290915f2024-07-11 16:46:52 +0100329 /* Verify the signature. */
330 psa_status = psa_verify_message(psa_key_id, psa_alg,
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100331 data_ptr, data_len,
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100332 local_sig_ptr, local_sig_len);
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500333
334 rc = (psa_status == PSA_SUCCESS) ? CRYPTO_SUCCESS : CRYPTO_ERR_SIGNATURE;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100335
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100336end1:
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500337 return rc;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100338end2:
Ryan Everett290915f2024-07-11 16:46:52 +0100339 /* Free the pk context, if it is initialized. */
340 cleanup_pk_context(&pk, &pk_initialized);
341
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100342 return rc;
343}
344
345/*
346 * Match a hash
347 *
348 * Digest info is passed in DER format following the ASN.1 structure detailed
349 * above.
350 */
351static int verify_hash(void *data_ptr, unsigned int data_len,
352 void *digest_info_ptr, unsigned int digest_info_len)
353{
354 mbedtls_asn1_buf hash_oid, params;
355 mbedtls_md_type_t md_alg;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100356 unsigned char *p, *end, *hash;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100357 size_t len;
358 int rc;
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100359 psa_status_t status;
360 psa_algorithm_t psa_md_alg;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100361
362 /*
363 * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after
364 * it is allowed. This is necessary to support multiple hash
365 * algorithms.
366 */
367 p = (unsigned char *)digest_info_ptr;
368 end = p + digest_info_len;
369 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
370 MBEDTLS_ASN1_SEQUENCE);
371 if (rc != 0) {
372 return CRYPTO_ERR_HASH;
373 }
374
375 end = p + len;
376
377 /* Get the hash algorithm */
378 rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, &params);
379 if (rc != 0) {
380 return CRYPTO_ERR_HASH;
381 }
382
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100383 /* Hash should be octet string type and consume all bytes */
384 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
385 if ((rc != 0) || ((size_t)(end - p) != len)) {
386 return CRYPTO_ERR_HASH;
387 }
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100388 hash = p;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100389
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100390 rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
391 if (rc != 0) {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100392 return CRYPTO_ERR_HASH;
393 }
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100394
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100395 /* convert the md_alg to psa_algo */
396 psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
397
398 /* Length of hash must match the algorithm's size */
399 if (len != PSA_HASH_LENGTH(psa_md_alg)) {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100400 return CRYPTO_ERR_HASH;
401 }
402
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100403 /*
404 * Calculate Hash and compare it against the retrieved hash from
405 * the certificate (one shot API).
406 */
407 status = psa_hash_compare(psa_md_alg,
408 data_ptr, (size_t)data_len,
409 (const uint8_t *)hash, len);
410
411 if (status != PSA_SUCCESS) {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100412 return CRYPTO_ERR_HASH;
413 }
414
415 return CRYPTO_SUCCESS;
416}
417#endif /*
418 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
419 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
420 */
421
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500422/*
423 * Finish crypto usage by destroying the psa_key_ids
424 */
425static void finish(void)
426{
427#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
428CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
429 /* Destroy the psa_key_ids */
430 destroy_key_ids();
431#endif
432}
433
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100434#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
435CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
436/*
437 * Map a generic crypto message digest algorithm to the corresponding macro used
438 * by Mbed TLS.
439 */
440static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo)
441{
442 switch (algo) {
443 case CRYPTO_MD_SHA512:
444 return MBEDTLS_MD_SHA512;
445 case CRYPTO_MD_SHA384:
446 return MBEDTLS_MD_SHA384;
447 case CRYPTO_MD_SHA256:
448 return MBEDTLS_MD_SHA256;
449 default:
450 /* Invalid hash algorithm. */
451 return MBEDTLS_MD_NONE;
452 }
453}
454
455/*
456 * Calculate a hash
457 *
458 * output points to the computed hash
459 */
460static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr,
461 unsigned int data_len,
462 unsigned char output[CRYPTO_MD_MAX_SIZE])
463{
Manish V Badarkhe4139d7b2023-09-06 12:05:05 +0100464 size_t hash_length;
465 psa_status_t status;
466 psa_algorithm_t psa_md_alg;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100467
Manish V Badarkhe4139d7b2023-09-06 12:05:05 +0100468 /* convert the md_alg to psa_algo */
469 psa_md_alg = mbedtls_md_psa_alg_from_type(md_type(md_algo));
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100470
471 /*
472 * Calculate the hash of the data, it is safe to pass the
473 * 'output' hash buffer pointer considering its size is always
474 * bigger than or equal to MBEDTLS_MD_MAX_SIZE.
475 */
Manish V Badarkhe4139d7b2023-09-06 12:05:05 +0100476 status = psa_hash_compute(psa_md_alg, data_ptr, (size_t)data_len,
477 (uint8_t *)output, CRYPTO_MD_MAX_SIZE,
478 &hash_length);
479 if (status != PSA_SUCCESS) {
480 return CRYPTO_ERR_HASH;
481 }
482
483 return CRYPTO_SUCCESS;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100484}
485#endif /*
486 * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
487 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
488 */
489
490#if TF_MBEDTLS_USE_AES_GCM
491/*
492 * Stack based buffer allocation for decryption operation. It could
493 * be configured to balance stack usage vs execution speed.
494 */
495#define DEC_OP_BUF_SIZE 128
496
497static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key,
498 unsigned int key_len, const void *iv,
499 unsigned int iv_len, const void *tag,
500 unsigned int tag_len)
501{
Ryan Everett822cd6a2024-08-12 13:15:53 +0100502 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
503 psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
504 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
505 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100506 unsigned char buf[DEC_OP_BUF_SIZE];
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100507 unsigned char *pt = data_ptr;
508 size_t dec_len;
Ryan Everett822cd6a2024-08-12 13:15:53 +0100509 size_t output_length;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100510
Ryan Everett822cd6a2024-08-12 13:15:53 +0100511 /* Load the key into the PSA key store. */
512 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
513 psa_set_key_algorithm(&attributes, PSA_ALG_GCM);
514 psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100515
Ryan Everett822cd6a2024-08-12 13:15:53 +0100516 psa_status = psa_import_key(&attributes, key, key_len, &key_id);
517 if (psa_status != PSA_SUCCESS) {
518 return CRYPTO_ERR_DECRYPTION;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100519 }
520
Ryan Everett822cd6a2024-08-12 13:15:53 +0100521 /* Perform the decryption. */
522 psa_status = psa_aead_decrypt_setup(&operation, key_id, PSA_ALG_GCM);
523 if (psa_status != PSA_SUCCESS) {
524 goto err;
525 }
526
527 psa_status = psa_aead_set_nonce(&operation, iv, iv_len);
528 if (psa_status != PSA_SUCCESS) {
529 goto err;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100530 }
531
532 while (len > 0) {
533 dec_len = MIN(sizeof(buf), len);
534
Ryan Everett822cd6a2024-08-12 13:15:53 +0100535 psa_status = psa_aead_update(&operation, pt, dec_len, buf,
536 sizeof(buf), &output_length);
537 if (psa_status != PSA_SUCCESS) {
538 goto err;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100539 }
540
Ryan Everett822cd6a2024-08-12 13:15:53 +0100541 memcpy(pt, buf, output_length);
542 pt += output_length;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100543 len -= dec_len;
544 }
545
Ryan Everett822cd6a2024-08-12 13:15:53 +0100546 /* Verify the tag. */
547 psa_status = psa_aead_verify(&operation, NULL, 0, &output_length, tag, tag_len);
548 if (psa_status == PSA_SUCCESS) {
549 psa_destroy_key(key_id);
550 return CRYPTO_SUCCESS;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100551 }
552
Ryan Everett822cd6a2024-08-12 13:15:53 +0100553err:
554 psa_aead_abort(&operation);
555 psa_destroy_key(key_id);
556 return CRYPTO_ERR_DECRYPTION;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100557}
558
559/*
560 * Authenticated decryption of an image
561 */
562static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
563 size_t len, const void *key, unsigned int key_len,
564 unsigned int key_flags, const void *iv,
565 unsigned int iv_len, const void *tag,
566 unsigned int tag_len)
567{
568 int rc;
569
570 assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0);
571
572 switch (dec_algo) {
573 case CRYPTO_GCM_DECRYPT:
574 rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len,
575 tag, tag_len);
576 if (rc != 0)
577 return rc;
578 break;
579 default:
580 return CRYPTO_ERR_DECRYPTION;
581 }
582
583 return CRYPTO_SUCCESS;
584}
585#endif /* TF_MBEDTLS_USE_AES_GCM */
586
587/*
588 * Register crypto library descriptor
589 */
590#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
591#if TF_MBEDTLS_USE_AES_GCM
592REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500593 auth_decrypt, NULL, finish);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100594#else
595REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500596 NULL, NULL, finish);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100597#endif
598#elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
599#if TF_MBEDTLS_USE_AES_GCM
600REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500601 auth_decrypt, NULL, finish);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100602#else
603REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500604 NULL, NULL, finish);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100605#endif
606#elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
Lauren Wehrmeistera3f54032025-04-28 15:46:41 -0500607REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL, finish);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100608#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */