blob: 0e4b57e25cf5ea0482bed306cad040028958c6a2 [file] [log] [blame]
Manish V Badarkhe8fbea622023-09-06 10:22:19 +01001/*
Jimmy Brisson640d9912024-04-10 10:20:13 -05002 * Copyright (c) 2023-2024, 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>
24#include <drivers/auth/crypto_mod.h>
25#include <drivers/auth/mbedtls/mbedtls_common.h>
Manish V Badarkhe8fbea622023-09-06 10:22:19 +010026#include <plat/common/platform.h>
27
28#define LIB_NAME "mbed TLS PSA"
29
Ryan Everett9c24a2e2024-11-05 10:48:35 +000030/* Minimum required size for a buffer containing a raw EC signature when using
31 * a maximum curve size of 384 bits.
32 * This is calculated as 2 * (384 / 8). */
33#define ECDSA_SIG_BUFFER_SIZE 96U
Manish V Badarkhefad6b232023-09-27 11:37:44 +010034
35/* Size of ASN.1 length and tag in bytes*/
36#define SIZE_OF_ASN1_LEN 1U
37#define SIZE_OF_ASN1_TAG 1U
38
Manish V Badarkhe8fbea622023-09-06 10:22:19 +010039#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
40CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
41/*
42 * CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available
43 * so make sure that mbed TLS MD maximum size must be lesser than this.
44 */
45CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE,
46 assert_mbedtls_md_size_overflow);
47
48#endif /*
49 * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
50 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
51 */
52
53/*
54 * AlgorithmIdentifier ::= SEQUENCE {
55 * algorithm OBJECT IDENTIFIER,
56 * parameters ANY DEFINED BY algorithm OPTIONAL
57 * }
58 *
59 * SubjectPublicKeyInfo ::= SEQUENCE {
60 * algorithm AlgorithmIdentifier,
61 * subjectPublicKey BIT STRING
62 * }
63 *
64 * DigestInfo ::= SEQUENCE {
65 * digestAlgorithm AlgorithmIdentifier,
66 * digest OCTET STRING
67 * }
68 */
Manish V Badarkhef179aa92023-09-06 11:01:37 +010069
70/*
71 * We pretend using an external RNG (through MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
72 * mbedTLS config option) so we need to provide an implementation of
73 * mbedtls_psa_external_get_random(). Provide a fake one, since we do not
74 * actually have any external RNG and TF-A itself doesn't engage in
75 * cryptographic operations that demands randomness.
76 */
77psa_status_t mbedtls_psa_external_get_random(
78 mbedtls_psa_external_random_context_t *context,
79 uint8_t *output, size_t output_size,
80 size_t *output_length)
81{
82 return PSA_ERROR_INSUFFICIENT_ENTROPY;
83}
Manish V Badarkhe8fbea622023-09-06 10:22:19 +010084
85/*
86 * Initialize the library and export the descriptor
87 */
88static void init(void)
89{
90 /* Initialize mbed TLS */
91 mbedtls_init();
Manish V Badarkhef179aa92023-09-06 11:01:37 +010092
93 /* Initialise PSA mbedTLS */
94 psa_status_t status = psa_crypto_init();
95
96 if (status != PSA_SUCCESS) {
97 ERROR("Failed to initialize %s crypto (%d).\n", LIB_NAME, status);
98 panic();
99 }
100
101 INFO("PSA crypto initialized successfully!\n");
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100102}
103
104#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
105CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100106
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100107/*
Ryan Everett290915f2024-07-11 16:46:52 +0100108 * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has
109 * advised that it's better to copy out the declaration than it would be to
110 * update to 3.5.2, where this function is exposed.
111 */
112int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid,
113 const mbedtls_x509_buf *sig_params,
114 mbedtls_md_type_t *md_alg,
115 mbedtls_pk_type_t *pk_alg,
116 void **sig_opts);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100117
118/*
Ryan Everett290915f2024-07-11 16:46:52 +0100119 * This is a helper function which parses a SignatureAlgorithm OID.
120 * It extracts the pk algorithm and constructs a psa_algorithm_t object
121 * to be used by PSA calls.
122 */
123static int construct_psa_alg(void *sig_alg, unsigned int sig_alg_len,
124 mbedtls_pk_type_t *pk_alg, psa_algorithm_t *psa_alg)
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100125{
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100126 int rc;
Ryan Everett290915f2024-07-11 16:46:52 +0100127 mbedtls_md_type_t md_alg;
128 void *sig_opts = NULL;
129 mbedtls_asn1_buf sig_alg_oid, params;
130 unsigned char *p = (unsigned char *) sig_alg;
131 unsigned char *end = (unsigned char *) sig_alg + sig_alg_len;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100132
Ryan Everett290915f2024-07-11 16:46:52 +0100133 rc = mbedtls_asn1_get_alg(&p, end, &sig_alg_oid, &params);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100134 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100135 rc = CRYPTO_ERR_SIGNATURE;
136 goto end;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100137 }
138
Ryan Everett290915f2024-07-11 16:46:52 +0100139 rc = mbedtls_x509_get_sig_alg(&sig_alg_oid, &params, &md_alg, pk_alg, &sig_opts);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100140 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100141 rc = CRYPTO_ERR_SIGNATURE;
142 goto end;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100143 }
144
Ryan Everett290915f2024-07-11 16:46:52 +0100145 psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100146
Ryan Everett290915f2024-07-11 16:46:52 +0100147 switch (*pk_alg) {
148 case MBEDTLS_PK_RSASSA_PSS:
149 *psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
150 rc = CRYPTO_SUCCESS;
151 break;
152 case MBEDTLS_PK_ECDSA:
153 *psa_alg = PSA_ALG_ECDSA(psa_md_alg);
154 rc = CRYPTO_SUCCESS;
155 break;
156 default:
157 *psa_alg = PSA_ALG_NONE;
158 rc = CRYPTO_ERR_SIGNATURE;
159 break;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100160 }
161
Ryan Everett290915f2024-07-11 16:46:52 +0100162end:
163 mbedtls_free(sig_opts);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100164 return rc;
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100165}
166
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100167/*
Ryan Everett290915f2024-07-11 16:46:52 +0100168 * Helper functions for mbedtls PK contexts.
169 */
170static void initialize_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100171{
Ryan Everett290915f2024-07-11 16:46:52 +0100172 mbedtls_pk_init(pk);
173 *pk_initialized = true;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100174}
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100175
Ryan Everett290915f2024-07-11 16:46:52 +0100176static void cleanup_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
Jimmy Brisson640d9912024-04-10 10:20:13 -0500177{
Ryan Everett290915f2024-07-11 16:46:52 +0100178 if (*pk_initialized) {
179 mbedtls_pk_free(pk);
180 *pk_initialized = false;
Jimmy Brisson640d9912024-04-10 10:20:13 -0500181 }
Jimmy Brisson640d9912024-04-10 10:20:13 -0500182}
183
184/*
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100185 * Verify a signature.
186 *
187 * Parameters are passed using the DER encoding format following the ASN.1
188 * structures detailed above.
189 */
190static int verify_signature(void *data_ptr, unsigned int data_len,
191 void *sig_ptr, unsigned int sig_len,
192 void *sig_alg, unsigned int sig_alg_len,
193 void *pk_ptr, unsigned int pk_len)
194{
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100195 unsigned char *p, *end;
Ryan Everett290915f2024-07-11 16:46:52 +0100196 mbedtls_pk_context pk;
197 bool pk_initialized = false;
198 int rc = CRYPTO_ERR_SIGNATURE;
199 psa_status_t psa_status = PSA_ERROR_CORRUPTION_DETECTED;
200 psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT;
201 psa_key_id_t psa_key_id;
202 mbedtls_pk_type_t pk_alg;
203 psa_algorithm_t psa_alg;
Ryan Everett9c24a2e2024-11-05 10:48:35 +0000204 __unused unsigned char reformatted_sig[ECDSA_SIG_BUFFER_SIZE] = {0};
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100205 unsigned char *local_sig_ptr;
206 size_t local_sig_len;
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100207
Ryan Everett290915f2024-07-11 16:46:52 +0100208 /* Load the key into the PSA key store. */
209 initialize_pk_context(&pk, &pk_initialized);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100210
Ryan Everett290915f2024-07-11 16:46:52 +0100211 p = (unsigned char *) pk_ptr;
212 end = p + pk_len;
213 rc = mbedtls_pk_parse_subpubkey(&p, end, &pk);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100214 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100215 rc = CRYPTO_ERR_SIGNATURE;
216 goto end2;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100217 }
218
Ryan Everett290915f2024-07-11 16:46:52 +0100219 rc = mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_VERIFY_MESSAGE, &psa_key_attr);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100220 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100221 rc = CRYPTO_ERR_SIGNATURE;
222 goto end2;
223 }
224
225 rc = construct_psa_alg(sig_alg, sig_alg_len, &pk_alg, &psa_alg);
226 if (rc != CRYPTO_SUCCESS) {
227 goto end2;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100228 }
Ryan Everett290915f2024-07-11 16:46:52 +0100229 psa_set_key_algorithm(&psa_key_attr, psa_alg);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100230
Ryan Everett290915f2024-07-11 16:46:52 +0100231 rc = mbedtls_pk_import_into_psa(&pk, &psa_key_attr, &psa_key_id);
232 if (rc != 0) {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100233 rc = CRYPTO_ERR_SIGNATURE;
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100234 goto end2;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100235 }
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100236
Ryan Everett290915f2024-07-11 16:46:52 +0100237 /* Optimize mbedtls heap usage by freeing the pk context now. */
238 cleanup_pk_context(&pk, &pk_initialized);
239
240 /* Extract the signature from sig_ptr. */
241 p = (unsigned char *) sig_ptr;
242 end = p + sig_len;
243 rc = mbedtls_asn1_get_bitstring_null(&p, end, &local_sig_len);
244 if (rc != 0) {
245 rc = CRYPTO_ERR_SIGNATURE;
246 goto end1;
247 }
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100248 local_sig_ptr = p;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100249
250#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
251TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
252 if (pk_alg == MBEDTLS_PK_ECDSA) {
Ryan Everett290915f2024-07-11 16:46:52 +0100253 /* Convert the DER ASN.1 signature to raw format. */
254 size_t key_bits = psa_get_key_bits(&psa_key_attr);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100255
Ryan Everett290915f2024-07-11 16:46:52 +0100256 rc = mbedtls_ecdsa_der_to_raw(key_bits, p, local_sig_len,
Ryan Everett9c24a2e2024-11-05 10:48:35 +0000257 reformatted_sig, ECDSA_SIG_BUFFER_SIZE,
Ryan Everett290915f2024-07-11 16:46:52 +0100258 &local_sig_len);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100259 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100260 rc = CRYPTO_ERR_SIGNATURE;
261 goto end1;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100262 }
Ryan Everett290915f2024-07-11 16:46:52 +0100263 local_sig_ptr = reformatted_sig;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100264 }
265#endif /*
266 * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
267 * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
268 **/
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100269
Ryan Everett290915f2024-07-11 16:46:52 +0100270 /* Verify the signature. */
271 psa_status = psa_verify_message(psa_key_id, psa_alg,
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100272 data_ptr, data_len,
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100273 local_sig_ptr, local_sig_len);
Ryan Everett290915f2024-07-11 16:46:52 +0100274 if (psa_status == PSA_SUCCESS) {
275 /* The signature has been successfully verified. */
276 rc = CRYPTO_SUCCESS;
277 } else {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100278 rc = CRYPTO_ERR_SIGNATURE;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100279 }
280
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100281end1:
Ryan Everett290915f2024-07-11 16:46:52 +0100282 /* Destroy the key from the PSA subsystem. */
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100283 psa_destroy_key(psa_key_id);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100284end2:
Ryan Everett290915f2024-07-11 16:46:52 +0100285 /* Free the pk context, if it is initialized. */
286 cleanup_pk_context(&pk, &pk_initialized);
287
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100288 return rc;
289}
290
291/*
292 * Match a hash
293 *
294 * Digest info is passed in DER format following the ASN.1 structure detailed
295 * above.
296 */
297static int verify_hash(void *data_ptr, unsigned int data_len,
298 void *digest_info_ptr, unsigned int digest_info_len)
299{
300 mbedtls_asn1_buf hash_oid, params;
301 mbedtls_md_type_t md_alg;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100302 unsigned char *p, *end, *hash;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100303 size_t len;
304 int rc;
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100305 psa_status_t status;
306 psa_algorithm_t psa_md_alg;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100307
308 /*
309 * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after
310 * it is allowed. This is necessary to support multiple hash
311 * algorithms.
312 */
313 p = (unsigned char *)digest_info_ptr;
314 end = p + digest_info_len;
315 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
316 MBEDTLS_ASN1_SEQUENCE);
317 if (rc != 0) {
318 return CRYPTO_ERR_HASH;
319 }
320
321 end = p + len;
322
323 /* Get the hash algorithm */
324 rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, &params);
325 if (rc != 0) {
326 return CRYPTO_ERR_HASH;
327 }
328
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100329 /* Hash should be octet string type and consume all bytes */
330 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
331 if ((rc != 0) || ((size_t)(end - p) != len)) {
332 return CRYPTO_ERR_HASH;
333 }
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100334 hash = p;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100335
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100336 rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
337 if (rc != 0) {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100338 return CRYPTO_ERR_HASH;
339 }
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100340
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100341 /* convert the md_alg to psa_algo */
342 psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
343
344 /* Length of hash must match the algorithm's size */
345 if (len != PSA_HASH_LENGTH(psa_md_alg)) {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100346 return CRYPTO_ERR_HASH;
347 }
348
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100349 /*
350 * Calculate Hash and compare it against the retrieved hash from
351 * the certificate (one shot API).
352 */
353 status = psa_hash_compare(psa_md_alg,
354 data_ptr, (size_t)data_len,
355 (const uint8_t *)hash, len);
356
357 if (status != PSA_SUCCESS) {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100358 return CRYPTO_ERR_HASH;
359 }
360
361 return CRYPTO_SUCCESS;
362}
363#endif /*
364 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
365 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
366 */
367
368#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
369CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
370/*
371 * Map a generic crypto message digest algorithm to the corresponding macro used
372 * by Mbed TLS.
373 */
374static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo)
375{
376 switch (algo) {
377 case CRYPTO_MD_SHA512:
378 return MBEDTLS_MD_SHA512;
379 case CRYPTO_MD_SHA384:
380 return MBEDTLS_MD_SHA384;
381 case CRYPTO_MD_SHA256:
382 return MBEDTLS_MD_SHA256;
383 default:
384 /* Invalid hash algorithm. */
385 return MBEDTLS_MD_NONE;
386 }
387}
388
389/*
390 * Calculate a hash
391 *
392 * output points to the computed hash
393 */
394static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr,
395 unsigned int data_len,
396 unsigned char output[CRYPTO_MD_MAX_SIZE])
397{
Manish V Badarkhe4139d7b2023-09-06 12:05:05 +0100398 size_t hash_length;
399 psa_status_t status;
400 psa_algorithm_t psa_md_alg;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100401
Manish V Badarkhe4139d7b2023-09-06 12:05:05 +0100402 /* convert the md_alg to psa_algo */
403 psa_md_alg = mbedtls_md_psa_alg_from_type(md_type(md_algo));
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100404
405 /*
406 * Calculate the hash of the data, it is safe to pass the
407 * 'output' hash buffer pointer considering its size is always
408 * bigger than or equal to MBEDTLS_MD_MAX_SIZE.
409 */
Manish V Badarkhe4139d7b2023-09-06 12:05:05 +0100410 status = psa_hash_compute(psa_md_alg, data_ptr, (size_t)data_len,
411 (uint8_t *)output, CRYPTO_MD_MAX_SIZE,
412 &hash_length);
413 if (status != PSA_SUCCESS) {
414 return CRYPTO_ERR_HASH;
415 }
416
417 return CRYPTO_SUCCESS;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100418}
419#endif /*
420 * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
421 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
422 */
423
424#if TF_MBEDTLS_USE_AES_GCM
425/*
426 * Stack based buffer allocation for decryption operation. It could
427 * be configured to balance stack usage vs execution speed.
428 */
429#define DEC_OP_BUF_SIZE 128
430
431static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key,
432 unsigned int key_len, const void *iv,
433 unsigned int iv_len, const void *tag,
434 unsigned int tag_len)
435{
Ryan Everett822cd6a2024-08-12 13:15:53 +0100436 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
437 psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
438 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
439 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100440 unsigned char buf[DEC_OP_BUF_SIZE];
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100441 unsigned char *pt = data_ptr;
442 size_t dec_len;
Ryan Everett822cd6a2024-08-12 13:15:53 +0100443 size_t output_length;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100444
Ryan Everett822cd6a2024-08-12 13:15:53 +0100445 /* Load the key into the PSA key store. */
446 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
447 psa_set_key_algorithm(&attributes, PSA_ALG_GCM);
448 psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100449
Ryan Everett822cd6a2024-08-12 13:15:53 +0100450 psa_status = psa_import_key(&attributes, key, key_len, &key_id);
451 if (psa_status != PSA_SUCCESS) {
452 return CRYPTO_ERR_DECRYPTION;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100453 }
454
Ryan Everett822cd6a2024-08-12 13:15:53 +0100455 /* Perform the decryption. */
456 psa_status = psa_aead_decrypt_setup(&operation, key_id, PSA_ALG_GCM);
457 if (psa_status != PSA_SUCCESS) {
458 goto err;
459 }
460
461 psa_status = psa_aead_set_nonce(&operation, iv, iv_len);
462 if (psa_status != PSA_SUCCESS) {
463 goto err;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100464 }
465
466 while (len > 0) {
467 dec_len = MIN(sizeof(buf), len);
468
Ryan Everett822cd6a2024-08-12 13:15:53 +0100469 psa_status = psa_aead_update(&operation, pt, dec_len, buf,
470 sizeof(buf), &output_length);
471 if (psa_status != PSA_SUCCESS) {
472 goto err;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100473 }
474
Ryan Everett822cd6a2024-08-12 13:15:53 +0100475 memcpy(pt, buf, output_length);
476 pt += output_length;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100477 len -= dec_len;
478 }
479
Ryan Everett822cd6a2024-08-12 13:15:53 +0100480 /* Verify the tag. */
481 psa_status = psa_aead_verify(&operation, NULL, 0, &output_length, tag, tag_len);
482 if (psa_status == PSA_SUCCESS) {
483 psa_destroy_key(key_id);
484 return CRYPTO_SUCCESS;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100485 }
486
Ryan Everett822cd6a2024-08-12 13:15:53 +0100487err:
488 psa_aead_abort(&operation);
489 psa_destroy_key(key_id);
490 return CRYPTO_ERR_DECRYPTION;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100491}
492
493/*
494 * Authenticated decryption of an image
495 */
496static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
497 size_t len, const void *key, unsigned int key_len,
498 unsigned int key_flags, const void *iv,
499 unsigned int iv_len, const void *tag,
500 unsigned int tag_len)
501{
502 int rc;
503
504 assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0);
505
506 switch (dec_algo) {
507 case CRYPTO_GCM_DECRYPT:
508 rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len,
509 tag, tag_len);
510 if (rc != 0)
511 return rc;
512 break;
513 default:
514 return CRYPTO_ERR_DECRYPTION;
515 }
516
517 return CRYPTO_SUCCESS;
518}
519#endif /* TF_MBEDTLS_USE_AES_GCM */
520
521/*
522 * Register crypto library descriptor
523 */
524#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
525#if TF_MBEDTLS_USE_AES_GCM
526REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
527 auth_decrypt, NULL);
528#else
529REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
530 NULL, NULL);
531#endif
532#elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
533#if TF_MBEDTLS_USE_AES_GCM
534REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
535 auth_decrypt, NULL);
536#else
537REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
538 NULL, NULL);
539#endif
540#elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
541REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL);
542#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */