blob: f2ccf15569ffe3c9226d3aa8e8a82a1db4c550f6 [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
Manish V Badarkhefad6b232023-09-27 11:37:44 +010030/* Maximum length of R_S pair in the ECDSA signature in bytes */
31#define MAX_ECDSA_R_S_PAIR_LEN 64U
32
33/* Size of ASN.1 length and tag in bytes*/
34#define SIZE_OF_ASN1_LEN 1U
35#define SIZE_OF_ASN1_TAG 1U
36
Manish V Badarkhe8fbea622023-09-06 10:22:19 +010037#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
38CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
39/*
40 * CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available
41 * so make sure that mbed TLS MD maximum size must be lesser than this.
42 */
43CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE,
44 assert_mbedtls_md_size_overflow);
45
46#endif /*
47 * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
48 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
49 */
50
51/*
52 * AlgorithmIdentifier ::= SEQUENCE {
53 * algorithm OBJECT IDENTIFIER,
54 * parameters ANY DEFINED BY algorithm OPTIONAL
55 * }
56 *
57 * SubjectPublicKeyInfo ::= SEQUENCE {
58 * algorithm AlgorithmIdentifier,
59 * subjectPublicKey BIT STRING
60 * }
61 *
62 * DigestInfo ::= SEQUENCE {
63 * digestAlgorithm AlgorithmIdentifier,
64 * digest OCTET STRING
65 * }
66 */
Manish V Badarkhef179aa92023-09-06 11:01:37 +010067
68/*
69 * We pretend using an external RNG (through MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
70 * mbedTLS config option) so we need to provide an implementation of
71 * mbedtls_psa_external_get_random(). Provide a fake one, since we do not
72 * actually have any external RNG and TF-A itself doesn't engage in
73 * cryptographic operations that demands randomness.
74 */
75psa_status_t mbedtls_psa_external_get_random(
76 mbedtls_psa_external_random_context_t *context,
77 uint8_t *output, size_t output_size,
78 size_t *output_length)
79{
80 return PSA_ERROR_INSUFFICIENT_ENTROPY;
81}
Manish V Badarkhe8fbea622023-09-06 10:22:19 +010082
83/*
84 * Initialize the library and export the descriptor
85 */
86static void init(void)
87{
88 /* Initialize mbed TLS */
89 mbedtls_init();
Manish V Badarkhef179aa92023-09-06 11:01:37 +010090
91 /* Initialise PSA mbedTLS */
92 psa_status_t status = psa_crypto_init();
93
94 if (status != PSA_SUCCESS) {
95 ERROR("Failed to initialize %s crypto (%d).\n", LIB_NAME, status);
96 panic();
97 }
98
99 INFO("PSA crypto initialized successfully!\n");
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100100}
101
102#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
103CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100104
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100105/*
Ryan Everett290915f2024-07-11 16:46:52 +0100106 * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has
107 * advised that it's better to copy out the declaration than it would be to
108 * update to 3.5.2, where this function is exposed.
109 */
110int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid,
111 const mbedtls_x509_buf *sig_params,
112 mbedtls_md_type_t *md_alg,
113 mbedtls_pk_type_t *pk_alg,
114 void **sig_opts);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100115
116/*
Ryan Everett290915f2024-07-11 16:46:52 +0100117 * This is a helper function which parses a SignatureAlgorithm OID.
118 * It extracts the pk algorithm and constructs a psa_algorithm_t object
119 * to be used by PSA calls.
120 */
121static int construct_psa_alg(void *sig_alg, unsigned int sig_alg_len,
122 mbedtls_pk_type_t *pk_alg, psa_algorithm_t *psa_alg)
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100123{
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100124 int rc;
Ryan Everett290915f2024-07-11 16:46:52 +0100125 mbedtls_md_type_t md_alg;
126 void *sig_opts = NULL;
127 mbedtls_asn1_buf sig_alg_oid, params;
128 unsigned char *p = (unsigned char *) sig_alg;
129 unsigned char *end = (unsigned char *) sig_alg + sig_alg_len;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100130
Ryan Everett290915f2024-07-11 16:46:52 +0100131 rc = mbedtls_asn1_get_alg(&p, end, &sig_alg_oid, &params);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100132 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100133 rc = CRYPTO_ERR_SIGNATURE;
134 goto end;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100135 }
136
Ryan Everett290915f2024-07-11 16:46:52 +0100137 rc = mbedtls_x509_get_sig_alg(&sig_alg_oid, &params, &md_alg, pk_alg, &sig_opts);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100138 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100139 rc = CRYPTO_ERR_SIGNATURE;
140 goto end;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100141 }
142
Ryan Everett290915f2024-07-11 16:46:52 +0100143 psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100144
Ryan Everett290915f2024-07-11 16:46:52 +0100145 switch (*pk_alg) {
146 case MBEDTLS_PK_RSASSA_PSS:
147 *psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
148 rc = CRYPTO_SUCCESS;
149 break;
150 case MBEDTLS_PK_ECDSA:
151 *psa_alg = PSA_ALG_ECDSA(psa_md_alg);
152 rc = CRYPTO_SUCCESS;
153 break;
154 default:
155 *psa_alg = PSA_ALG_NONE;
156 rc = CRYPTO_ERR_SIGNATURE;
157 break;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100158 }
159
Ryan Everett290915f2024-07-11 16:46:52 +0100160end:
161 mbedtls_free(sig_opts);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100162 return rc;
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100163}
164
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100165/*
Ryan Everett290915f2024-07-11 16:46:52 +0100166 * Helper functions for mbedtls PK contexts.
167 */
168static void initialize_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100169{
Ryan Everett290915f2024-07-11 16:46:52 +0100170 mbedtls_pk_init(pk);
171 *pk_initialized = true;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100172}
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100173
Ryan Everett290915f2024-07-11 16:46:52 +0100174static void cleanup_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
Jimmy Brisson640d9912024-04-10 10:20:13 -0500175{
Ryan Everett290915f2024-07-11 16:46:52 +0100176 if (*pk_initialized) {
177 mbedtls_pk_free(pk);
178 *pk_initialized = false;
Jimmy Brisson640d9912024-04-10 10:20:13 -0500179 }
Jimmy Brisson640d9912024-04-10 10:20:13 -0500180}
181
182/*
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100183 * Verify a signature.
184 *
185 * Parameters are passed using the DER encoding format following the ASN.1
186 * structures detailed above.
187 */
188static int verify_signature(void *data_ptr, unsigned int data_len,
189 void *sig_ptr, unsigned int sig_len,
190 void *sig_alg, unsigned int sig_alg_len,
191 void *pk_ptr, unsigned int pk_len)
192{
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100193 unsigned char *p, *end;
Ryan Everett290915f2024-07-11 16:46:52 +0100194 mbedtls_pk_context pk;
195 bool pk_initialized = false;
196 int rc = CRYPTO_ERR_SIGNATURE;
197 psa_status_t psa_status = PSA_ERROR_CORRUPTION_DETECTED;
198 psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT;
199 psa_key_id_t psa_key_id;
200 mbedtls_pk_type_t pk_alg;
201 psa_algorithm_t psa_alg;
202 __unused unsigned char reformatted_sig[MAX_ECDSA_R_S_PAIR_LEN] = {0};
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100203 unsigned char *local_sig_ptr;
204 size_t local_sig_len;
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100205
Ryan Everett290915f2024-07-11 16:46:52 +0100206 /* Load the key into the PSA key store. */
207 initialize_pk_context(&pk, &pk_initialized);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100208
Ryan Everett290915f2024-07-11 16:46:52 +0100209 p = (unsigned char *) pk_ptr;
210 end = p + pk_len;
211 rc = mbedtls_pk_parse_subpubkey(&p, end, &pk);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100212 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100213 rc = CRYPTO_ERR_SIGNATURE;
214 goto end2;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100215 }
216
Ryan Everett290915f2024-07-11 16:46:52 +0100217 rc = mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_VERIFY_MESSAGE, &psa_key_attr);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100218 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100219 rc = CRYPTO_ERR_SIGNATURE;
220 goto end2;
221 }
222
223 rc = construct_psa_alg(sig_alg, sig_alg_len, &pk_alg, &psa_alg);
224 if (rc != CRYPTO_SUCCESS) {
225 goto end2;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100226 }
Ryan Everett290915f2024-07-11 16:46:52 +0100227 psa_set_key_algorithm(&psa_key_attr, psa_alg);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100228
Ryan Everett290915f2024-07-11 16:46:52 +0100229 rc = mbedtls_pk_import_into_psa(&pk, &psa_key_attr, &psa_key_id);
230 if (rc != 0) {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100231 rc = CRYPTO_ERR_SIGNATURE;
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100232 goto end2;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100233 }
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100234
Ryan Everett290915f2024-07-11 16:46:52 +0100235 /* Optimize mbedtls heap usage by freeing the pk context now. */
236 cleanup_pk_context(&pk, &pk_initialized);
237
238 /* Extract the signature from sig_ptr. */
239 p = (unsigned char *) sig_ptr;
240 end = p + sig_len;
241 rc = mbedtls_asn1_get_bitstring_null(&p, end, &local_sig_len);
242 if (rc != 0) {
243 rc = CRYPTO_ERR_SIGNATURE;
244 goto end1;
245 }
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100246 local_sig_ptr = p;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100247
248#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
249TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
250 if (pk_alg == MBEDTLS_PK_ECDSA) {
Ryan Everett290915f2024-07-11 16:46:52 +0100251 /* Convert the DER ASN.1 signature to raw format. */
252 size_t key_bits = psa_get_key_bits(&psa_key_attr);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100253
Ryan Everett290915f2024-07-11 16:46:52 +0100254 rc = mbedtls_ecdsa_der_to_raw(key_bits, p, local_sig_len,
255 reformatted_sig, MAX_ECDSA_R_S_PAIR_LEN,
256 &local_sig_len);
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100257 if (rc != 0) {
Ryan Everett290915f2024-07-11 16:46:52 +0100258 rc = CRYPTO_ERR_SIGNATURE;
259 goto end1;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100260 }
Ryan Everett290915f2024-07-11 16:46:52 +0100261 local_sig_ptr = reformatted_sig;
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100262 }
263#endif /*
264 * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
265 * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
266 **/
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100267
Ryan Everett290915f2024-07-11 16:46:52 +0100268 /* Verify the signature. */
269 psa_status = psa_verify_message(psa_key_id, psa_alg,
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100270 data_ptr, data_len,
Manish V Badarkhefad6b232023-09-27 11:37:44 +0100271 local_sig_ptr, local_sig_len);
Ryan Everett290915f2024-07-11 16:46:52 +0100272 if (psa_status == PSA_SUCCESS) {
273 /* The signature has been successfully verified. */
274 rc = CRYPTO_SUCCESS;
275 } else {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100276 rc = CRYPTO_ERR_SIGNATURE;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100277 }
278
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100279end1:
Ryan Everett290915f2024-07-11 16:46:52 +0100280 /* Destroy the key from the PSA subsystem. */
Manish V Badarkhe3e642b42023-09-22 18:06:05 +0100281 psa_destroy_key(psa_key_id);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100282end2:
Ryan Everett290915f2024-07-11 16:46:52 +0100283 /* Free the pk context, if it is initialized. */
284 cleanup_pk_context(&pk, &pk_initialized);
285
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100286 return rc;
287}
288
289/*
290 * Match a hash
291 *
292 * Digest info is passed in DER format following the ASN.1 structure detailed
293 * above.
294 */
295static int verify_hash(void *data_ptr, unsigned int data_len,
296 void *digest_info_ptr, unsigned int digest_info_len)
297{
298 mbedtls_asn1_buf hash_oid, params;
299 mbedtls_md_type_t md_alg;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100300 unsigned char *p, *end, *hash;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100301 size_t len;
302 int rc;
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100303 psa_status_t status;
304 psa_algorithm_t psa_md_alg;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100305
306 /*
307 * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after
308 * it is allowed. This is necessary to support multiple hash
309 * algorithms.
310 */
311 p = (unsigned char *)digest_info_ptr;
312 end = p + digest_info_len;
313 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
314 MBEDTLS_ASN1_SEQUENCE);
315 if (rc != 0) {
316 return CRYPTO_ERR_HASH;
317 }
318
319 end = p + len;
320
321 /* Get the hash algorithm */
322 rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, &params);
323 if (rc != 0) {
324 return CRYPTO_ERR_HASH;
325 }
326
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100327 /* Hash should be octet string type and consume all bytes */
328 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
329 if ((rc != 0) || ((size_t)(end - p) != len)) {
330 return CRYPTO_ERR_HASH;
331 }
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100332 hash = p;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100333
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100334 rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
335 if (rc != 0) {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100336 return CRYPTO_ERR_HASH;
337 }
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100338
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100339 /* convert the md_alg to psa_algo */
340 psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
341
342 /* Length of hash must match the algorithm's size */
343 if (len != PSA_HASH_LENGTH(psa_md_alg)) {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100344 return CRYPTO_ERR_HASH;
345 }
346
Manish V Badarkhec381ea32023-09-06 12:00:20 +0100347 /*
348 * Calculate Hash and compare it against the retrieved hash from
349 * the certificate (one shot API).
350 */
351 status = psa_hash_compare(psa_md_alg,
352 data_ptr, (size_t)data_len,
353 (const uint8_t *)hash, len);
354
355 if (status != PSA_SUCCESS) {
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100356 return CRYPTO_ERR_HASH;
357 }
358
359 return CRYPTO_SUCCESS;
360}
361#endif /*
362 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
363 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
364 */
365
366#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
367CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
368/*
369 * Map a generic crypto message digest algorithm to the corresponding macro used
370 * by Mbed TLS.
371 */
372static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo)
373{
374 switch (algo) {
375 case CRYPTO_MD_SHA512:
376 return MBEDTLS_MD_SHA512;
377 case CRYPTO_MD_SHA384:
378 return MBEDTLS_MD_SHA384;
379 case CRYPTO_MD_SHA256:
380 return MBEDTLS_MD_SHA256;
381 default:
382 /* Invalid hash algorithm. */
383 return MBEDTLS_MD_NONE;
384 }
385}
386
387/*
388 * Calculate a hash
389 *
390 * output points to the computed hash
391 */
392static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr,
393 unsigned int data_len,
394 unsigned char output[CRYPTO_MD_MAX_SIZE])
395{
Manish V Badarkhe4139d7b2023-09-06 12:05:05 +0100396 size_t hash_length;
397 psa_status_t status;
398 psa_algorithm_t psa_md_alg;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100399
Manish V Badarkhe4139d7b2023-09-06 12:05:05 +0100400 /* convert the md_alg to psa_algo */
401 psa_md_alg = mbedtls_md_psa_alg_from_type(md_type(md_algo));
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100402
403 /*
404 * Calculate the hash of the data, it is safe to pass the
405 * 'output' hash buffer pointer considering its size is always
406 * bigger than or equal to MBEDTLS_MD_MAX_SIZE.
407 */
Manish V Badarkhe4139d7b2023-09-06 12:05:05 +0100408 status = psa_hash_compute(psa_md_alg, data_ptr, (size_t)data_len,
409 (uint8_t *)output, CRYPTO_MD_MAX_SIZE,
410 &hash_length);
411 if (status != PSA_SUCCESS) {
412 return CRYPTO_ERR_HASH;
413 }
414
415 return CRYPTO_SUCCESS;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100416}
417#endif /*
418 * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
419 * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
420 */
421
422#if TF_MBEDTLS_USE_AES_GCM
423/*
424 * Stack based buffer allocation for decryption operation. It could
425 * be configured to balance stack usage vs execution speed.
426 */
427#define DEC_OP_BUF_SIZE 128
428
429static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key,
430 unsigned int key_len, const void *iv,
431 unsigned int iv_len, const void *tag,
432 unsigned int tag_len)
433{
Ryan Everett822cd6a2024-08-12 13:15:53 +0100434 mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
435 psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
436 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
437 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100438 unsigned char buf[DEC_OP_BUF_SIZE];
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100439 unsigned char *pt = data_ptr;
440 size_t dec_len;
Ryan Everett822cd6a2024-08-12 13:15:53 +0100441 size_t output_length;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100442
Ryan Everett822cd6a2024-08-12 13:15:53 +0100443 /* Load the key into the PSA key store. */
444 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
445 psa_set_key_algorithm(&attributes, PSA_ALG_GCM);
446 psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100447
Ryan Everett822cd6a2024-08-12 13:15:53 +0100448 psa_status = psa_import_key(&attributes, key, key_len, &key_id);
449 if (psa_status != PSA_SUCCESS) {
450 return CRYPTO_ERR_DECRYPTION;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100451 }
452
Ryan Everett822cd6a2024-08-12 13:15:53 +0100453 /* Perform the decryption. */
454 psa_status = psa_aead_decrypt_setup(&operation, key_id, PSA_ALG_GCM);
455 if (psa_status != PSA_SUCCESS) {
456 goto err;
457 }
458
459 psa_status = psa_aead_set_nonce(&operation, iv, iv_len);
460 if (psa_status != PSA_SUCCESS) {
461 goto err;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100462 }
463
464 while (len > 0) {
465 dec_len = MIN(sizeof(buf), len);
466
Ryan Everett822cd6a2024-08-12 13:15:53 +0100467 psa_status = psa_aead_update(&operation, pt, dec_len, buf,
468 sizeof(buf), &output_length);
469 if (psa_status != PSA_SUCCESS) {
470 goto err;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100471 }
472
Ryan Everett822cd6a2024-08-12 13:15:53 +0100473 memcpy(pt, buf, output_length);
474 pt += output_length;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100475 len -= dec_len;
476 }
477
Ryan Everett822cd6a2024-08-12 13:15:53 +0100478 /* Verify the tag. */
479 psa_status = psa_aead_verify(&operation, NULL, 0, &output_length, tag, tag_len);
480 if (psa_status == PSA_SUCCESS) {
481 psa_destroy_key(key_id);
482 return CRYPTO_SUCCESS;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100483 }
484
Ryan Everett822cd6a2024-08-12 13:15:53 +0100485err:
486 psa_aead_abort(&operation);
487 psa_destroy_key(key_id);
488 return CRYPTO_ERR_DECRYPTION;
Manish V Badarkhe8fbea622023-09-06 10:22:19 +0100489}
490
491/*
492 * Authenticated decryption of an image
493 */
494static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
495 size_t len, const void *key, unsigned int key_len,
496 unsigned int key_flags, const void *iv,
497 unsigned int iv_len, const void *tag,
498 unsigned int tag_len)
499{
500 int rc;
501
502 assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0);
503
504 switch (dec_algo) {
505 case CRYPTO_GCM_DECRYPT:
506 rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len,
507 tag, tag_len);
508 if (rc != 0)
509 return rc;
510 break;
511 default:
512 return CRYPTO_ERR_DECRYPTION;
513 }
514
515 return CRYPTO_SUCCESS;
516}
517#endif /* TF_MBEDTLS_USE_AES_GCM */
518
519/*
520 * Register crypto library descriptor
521 */
522#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
523#if TF_MBEDTLS_USE_AES_GCM
524REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
525 auth_decrypt, NULL);
526#else
527REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
528 NULL, NULL);
529#endif
530#elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
531#if TF_MBEDTLS_USE_AES_GCM
532REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
533 auth_decrypt, NULL);
534#else
535REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
536 NULL, NULL);
537#endif
538#elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
539REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL);
540#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */