xref: /arm-trusted-firmware/drivers/auth/mbedtls/mbedtls_crypto.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <stddef.h>
9*91f16700Schasinglulu #include <string.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu /* mbed TLS headers */
12*91f16700Schasinglulu #include <mbedtls/gcm.h>
13*91f16700Schasinglulu #include <mbedtls/md.h>
14*91f16700Schasinglulu #include <mbedtls/memory_buffer_alloc.h>
15*91f16700Schasinglulu #include <mbedtls/oid.h>
16*91f16700Schasinglulu #include <mbedtls/platform.h>
17*91f16700Schasinglulu #include <mbedtls/version.h>
18*91f16700Schasinglulu #include <mbedtls/x509.h>
19*91f16700Schasinglulu 
20*91f16700Schasinglulu #include <common/debug.h>
21*91f16700Schasinglulu #include <drivers/auth/crypto_mod.h>
22*91f16700Schasinglulu #include <drivers/auth/mbedtls/mbedtls_common.h>
23*91f16700Schasinglulu 
24*91f16700Schasinglulu #include <plat/common/platform.h>
25*91f16700Schasinglulu 
26*91f16700Schasinglulu #define LIB_NAME		"mbed TLS"
27*91f16700Schasinglulu 
28*91f16700Schasinglulu #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
29*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
30*91f16700Schasinglulu /*
31*91f16700Schasinglulu  * CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available
32*91f16700Schasinglulu  * so make sure that mbed TLS MD maximum size must be lesser than this.
33*91f16700Schasinglulu  */
34*91f16700Schasinglulu CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE,
35*91f16700Schasinglulu 	assert_mbedtls_md_size_overflow);
36*91f16700Schasinglulu 
37*91f16700Schasinglulu #endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
38*91f16700Schasinglulu 	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
39*91f16700Schasinglulu 
40*91f16700Schasinglulu /*
41*91f16700Schasinglulu  * AlgorithmIdentifier  ::=  SEQUENCE  {
42*91f16700Schasinglulu  *     algorithm               OBJECT IDENTIFIER,
43*91f16700Schasinglulu  *     parameters              ANY DEFINED BY algorithm OPTIONAL
44*91f16700Schasinglulu  * }
45*91f16700Schasinglulu  *
46*91f16700Schasinglulu  * SubjectPublicKeyInfo  ::=  SEQUENCE  {
47*91f16700Schasinglulu  *     algorithm            AlgorithmIdentifier,
48*91f16700Schasinglulu  *     subjectPublicKey     BIT STRING
49*91f16700Schasinglulu  * }
50*91f16700Schasinglulu  *
51*91f16700Schasinglulu  * DigestInfo ::= SEQUENCE {
52*91f16700Schasinglulu  *     digestAlgorithm AlgorithmIdentifier,
53*91f16700Schasinglulu  *     digest OCTET STRING
54*91f16700Schasinglulu  * }
55*91f16700Schasinglulu  */
56*91f16700Schasinglulu 
57*91f16700Schasinglulu /*
58*91f16700Schasinglulu  * Initialize the library and export the descriptor
59*91f16700Schasinglulu  */
60*91f16700Schasinglulu static void init(void)
61*91f16700Schasinglulu {
62*91f16700Schasinglulu 	/* Initialize mbed TLS */
63*91f16700Schasinglulu 	mbedtls_init();
64*91f16700Schasinglulu }
65*91f16700Schasinglulu 
66*91f16700Schasinglulu #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
67*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
68*91f16700Schasinglulu /*
69*91f16700Schasinglulu  * Verify a signature.
70*91f16700Schasinglulu  *
71*91f16700Schasinglulu  * Parameters are passed using the DER encoding format following the ASN.1
72*91f16700Schasinglulu  * structures detailed above.
73*91f16700Schasinglulu  */
74*91f16700Schasinglulu static int verify_signature(void *data_ptr, unsigned int data_len,
75*91f16700Schasinglulu 			    void *sig_ptr, unsigned int sig_len,
76*91f16700Schasinglulu 			    void *sig_alg, unsigned int sig_alg_len,
77*91f16700Schasinglulu 			    void *pk_ptr, unsigned int pk_len)
78*91f16700Schasinglulu {
79*91f16700Schasinglulu 	mbedtls_asn1_buf sig_oid, sig_params;
80*91f16700Schasinglulu 	mbedtls_asn1_buf signature;
81*91f16700Schasinglulu 	mbedtls_md_type_t md_alg;
82*91f16700Schasinglulu 	mbedtls_pk_type_t pk_alg;
83*91f16700Schasinglulu 	mbedtls_pk_context pk = {0};
84*91f16700Schasinglulu 	int rc;
85*91f16700Schasinglulu 	void *sig_opts = NULL;
86*91f16700Schasinglulu 	const mbedtls_md_info_t *md_info;
87*91f16700Schasinglulu 	unsigned char *p, *end;
88*91f16700Schasinglulu 	unsigned char hash[MBEDTLS_MD_MAX_SIZE];
89*91f16700Schasinglulu 
90*91f16700Schasinglulu 	/* Get pointers to signature OID and parameters */
91*91f16700Schasinglulu 	p = (unsigned char *)sig_alg;
92*91f16700Schasinglulu 	end = (unsigned char *)(p + sig_alg_len);
93*91f16700Schasinglulu 	rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params);
94*91f16700Schasinglulu 	if (rc != 0) {
95*91f16700Schasinglulu 		return CRYPTO_ERR_SIGNATURE;
96*91f16700Schasinglulu 	}
97*91f16700Schasinglulu 
98*91f16700Schasinglulu 	/* Get the actual signature algorithm (MD + PK) */
99*91f16700Schasinglulu 	rc = mbedtls_x509_get_sig_alg(&sig_oid, &sig_params, &md_alg, &pk_alg, &sig_opts);
100*91f16700Schasinglulu 	if (rc != 0) {
101*91f16700Schasinglulu 		return CRYPTO_ERR_SIGNATURE;
102*91f16700Schasinglulu 	}
103*91f16700Schasinglulu 
104*91f16700Schasinglulu 	/* Parse the public key */
105*91f16700Schasinglulu 	mbedtls_pk_init(&pk);
106*91f16700Schasinglulu 	p = (unsigned char *)pk_ptr;
107*91f16700Schasinglulu 	end = (unsigned char *)(p + pk_len);
108*91f16700Schasinglulu 	rc = mbedtls_pk_parse_subpubkey(&p, end, &pk);
109*91f16700Schasinglulu 	if (rc != 0) {
110*91f16700Schasinglulu 		rc = CRYPTO_ERR_SIGNATURE;
111*91f16700Schasinglulu 		goto end2;
112*91f16700Schasinglulu 	}
113*91f16700Schasinglulu 
114*91f16700Schasinglulu 	/* Get the signature (bitstring) */
115*91f16700Schasinglulu 	p = (unsigned char *)sig_ptr;
116*91f16700Schasinglulu 	end = (unsigned char *)(p + sig_len);
117*91f16700Schasinglulu 	signature.tag = *p;
118*91f16700Schasinglulu 	rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len);
119*91f16700Schasinglulu 	if ((rc != 0) || ((size_t)(end - p) != signature.len)) {
120*91f16700Schasinglulu 		rc = CRYPTO_ERR_SIGNATURE;
121*91f16700Schasinglulu 		goto end1;
122*91f16700Schasinglulu 	}
123*91f16700Schasinglulu 	signature.p = p;
124*91f16700Schasinglulu 
125*91f16700Schasinglulu 	/* Calculate the hash of the data */
126*91f16700Schasinglulu 	md_info = mbedtls_md_info_from_type(md_alg);
127*91f16700Schasinglulu 	if (md_info == NULL) {
128*91f16700Schasinglulu 		rc = CRYPTO_ERR_SIGNATURE;
129*91f16700Schasinglulu 		goto end1;
130*91f16700Schasinglulu 	}
131*91f16700Schasinglulu 	p = (unsigned char *)data_ptr;
132*91f16700Schasinglulu 	rc = mbedtls_md(md_info, p, data_len, hash);
133*91f16700Schasinglulu 	if (rc != 0) {
134*91f16700Schasinglulu 		rc = CRYPTO_ERR_SIGNATURE;
135*91f16700Schasinglulu 		goto end1;
136*91f16700Schasinglulu 	}
137*91f16700Schasinglulu 
138*91f16700Schasinglulu 	/* Verify the signature */
139*91f16700Schasinglulu 	rc = mbedtls_pk_verify_ext(pk_alg, sig_opts, &pk, md_alg, hash,
140*91f16700Schasinglulu 			mbedtls_md_get_size(md_info),
141*91f16700Schasinglulu 			signature.p, signature.len);
142*91f16700Schasinglulu 	if (rc != 0) {
143*91f16700Schasinglulu 		rc = CRYPTO_ERR_SIGNATURE;
144*91f16700Schasinglulu 		goto end1;
145*91f16700Schasinglulu 	}
146*91f16700Schasinglulu 
147*91f16700Schasinglulu 	/* Signature verification success */
148*91f16700Schasinglulu 	rc = CRYPTO_SUCCESS;
149*91f16700Schasinglulu 
150*91f16700Schasinglulu end1:
151*91f16700Schasinglulu 	mbedtls_pk_free(&pk);
152*91f16700Schasinglulu end2:
153*91f16700Schasinglulu 	mbedtls_free(sig_opts);
154*91f16700Schasinglulu 	return rc;
155*91f16700Schasinglulu }
156*91f16700Schasinglulu 
157*91f16700Schasinglulu /*
158*91f16700Schasinglulu  * Match a hash
159*91f16700Schasinglulu  *
160*91f16700Schasinglulu  * Digest info is passed in DER format following the ASN.1 structure detailed
161*91f16700Schasinglulu  * above.
162*91f16700Schasinglulu  */
163*91f16700Schasinglulu static int verify_hash(void *data_ptr, unsigned int data_len,
164*91f16700Schasinglulu 		       void *digest_info_ptr, unsigned int digest_info_len)
165*91f16700Schasinglulu {
166*91f16700Schasinglulu 	mbedtls_asn1_buf hash_oid, params;
167*91f16700Schasinglulu 	mbedtls_md_type_t md_alg;
168*91f16700Schasinglulu 	const mbedtls_md_info_t *md_info;
169*91f16700Schasinglulu 	unsigned char *p, *end, *hash;
170*91f16700Schasinglulu 	unsigned char data_hash[MBEDTLS_MD_MAX_SIZE];
171*91f16700Schasinglulu 	size_t len;
172*91f16700Schasinglulu 	int rc;
173*91f16700Schasinglulu 
174*91f16700Schasinglulu 	/*
175*91f16700Schasinglulu 	 * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after
176*91f16700Schasinglulu 	 * it is allowed.  This is necessary to support multiple hash
177*91f16700Schasinglulu 	 * algorithms.
178*91f16700Schasinglulu 	 */
179*91f16700Schasinglulu 	p = (unsigned char *)digest_info_ptr;
180*91f16700Schasinglulu 	end = p + digest_info_len;
181*91f16700Schasinglulu 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
182*91f16700Schasinglulu 				  MBEDTLS_ASN1_SEQUENCE);
183*91f16700Schasinglulu 	if (rc != 0) {
184*91f16700Schasinglulu 		return CRYPTO_ERR_HASH;
185*91f16700Schasinglulu 	}
186*91f16700Schasinglulu 
187*91f16700Schasinglulu 	end = p + len;
188*91f16700Schasinglulu 
189*91f16700Schasinglulu 	/* Get the hash algorithm */
190*91f16700Schasinglulu 	rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, &params);
191*91f16700Schasinglulu 	if (rc != 0) {
192*91f16700Schasinglulu 		return CRYPTO_ERR_HASH;
193*91f16700Schasinglulu 	}
194*91f16700Schasinglulu 
195*91f16700Schasinglulu 	rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
196*91f16700Schasinglulu 	if (rc != 0) {
197*91f16700Schasinglulu 		return CRYPTO_ERR_HASH;
198*91f16700Schasinglulu 	}
199*91f16700Schasinglulu 
200*91f16700Schasinglulu 	md_info = mbedtls_md_info_from_type(md_alg);
201*91f16700Schasinglulu 	if (md_info == NULL) {
202*91f16700Schasinglulu 		return CRYPTO_ERR_HASH;
203*91f16700Schasinglulu 	}
204*91f16700Schasinglulu 
205*91f16700Schasinglulu 	/* Hash should be octet string type and consume all bytes */
206*91f16700Schasinglulu 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
207*91f16700Schasinglulu 	if ((rc != 0) || ((size_t)(end - p) != len)) {
208*91f16700Schasinglulu 		return CRYPTO_ERR_HASH;
209*91f16700Schasinglulu 	}
210*91f16700Schasinglulu 
211*91f16700Schasinglulu 	/* Length of hash must match the algorithm's size */
212*91f16700Schasinglulu 	if (len != mbedtls_md_get_size(md_info)) {
213*91f16700Schasinglulu 		return CRYPTO_ERR_HASH;
214*91f16700Schasinglulu 	}
215*91f16700Schasinglulu 	hash = p;
216*91f16700Schasinglulu 
217*91f16700Schasinglulu 	/* Calculate the hash of the data */
218*91f16700Schasinglulu 	p = (unsigned char *)data_ptr;
219*91f16700Schasinglulu 	rc = mbedtls_md(md_info, p, data_len, data_hash);
220*91f16700Schasinglulu 	if (rc != 0) {
221*91f16700Schasinglulu 		return CRYPTO_ERR_HASH;
222*91f16700Schasinglulu 	}
223*91f16700Schasinglulu 
224*91f16700Schasinglulu 	/* Compare values */
225*91f16700Schasinglulu 	rc = memcmp(data_hash, hash, mbedtls_md_get_size(md_info));
226*91f16700Schasinglulu 	if (rc != 0) {
227*91f16700Schasinglulu 		return CRYPTO_ERR_HASH;
228*91f16700Schasinglulu 	}
229*91f16700Schasinglulu 
230*91f16700Schasinglulu 	return CRYPTO_SUCCESS;
231*91f16700Schasinglulu }
232*91f16700Schasinglulu #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
233*91f16700Schasinglulu 	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
234*91f16700Schasinglulu 
235*91f16700Schasinglulu #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
236*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
237*91f16700Schasinglulu /*
238*91f16700Schasinglulu  * Map a generic crypto message digest algorithm to the corresponding macro used
239*91f16700Schasinglulu  * by Mbed TLS.
240*91f16700Schasinglulu  */
241*91f16700Schasinglulu static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo)
242*91f16700Schasinglulu {
243*91f16700Schasinglulu 	switch (algo) {
244*91f16700Schasinglulu 	case CRYPTO_MD_SHA512:
245*91f16700Schasinglulu 		return MBEDTLS_MD_SHA512;
246*91f16700Schasinglulu 	case CRYPTO_MD_SHA384:
247*91f16700Schasinglulu 		return MBEDTLS_MD_SHA384;
248*91f16700Schasinglulu 	case CRYPTO_MD_SHA256:
249*91f16700Schasinglulu 		return MBEDTLS_MD_SHA256;
250*91f16700Schasinglulu 	default:
251*91f16700Schasinglulu 		/* Invalid hash algorithm. */
252*91f16700Schasinglulu 		return MBEDTLS_MD_NONE;
253*91f16700Schasinglulu 	}
254*91f16700Schasinglulu }
255*91f16700Schasinglulu 
256*91f16700Schasinglulu /*
257*91f16700Schasinglulu  * Calculate a hash
258*91f16700Schasinglulu  *
259*91f16700Schasinglulu  * output points to the computed hash
260*91f16700Schasinglulu  */
261*91f16700Schasinglulu static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr,
262*91f16700Schasinglulu 		     unsigned int data_len,
263*91f16700Schasinglulu 		     unsigned char output[CRYPTO_MD_MAX_SIZE])
264*91f16700Schasinglulu {
265*91f16700Schasinglulu 	const mbedtls_md_info_t *md_info;
266*91f16700Schasinglulu 
267*91f16700Schasinglulu 	md_info = mbedtls_md_info_from_type(md_type(md_algo));
268*91f16700Schasinglulu 	if (md_info == NULL) {
269*91f16700Schasinglulu 		return CRYPTO_ERR_HASH;
270*91f16700Schasinglulu 	}
271*91f16700Schasinglulu 
272*91f16700Schasinglulu 	/*
273*91f16700Schasinglulu 	 * Calculate the hash of the data, it is safe to pass the
274*91f16700Schasinglulu 	 * 'output' hash buffer pointer considering its size is always
275*91f16700Schasinglulu 	 * bigger than or equal to MBEDTLS_MD_MAX_SIZE.
276*91f16700Schasinglulu 	 */
277*91f16700Schasinglulu 	return mbedtls_md(md_info, data_ptr, data_len, output);
278*91f16700Schasinglulu }
279*91f16700Schasinglulu #endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
280*91f16700Schasinglulu 	  CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
281*91f16700Schasinglulu 
282*91f16700Schasinglulu #if TF_MBEDTLS_USE_AES_GCM
283*91f16700Schasinglulu /*
284*91f16700Schasinglulu  * Stack based buffer allocation for decryption operation. It could
285*91f16700Schasinglulu  * be configured to balance stack usage vs execution speed.
286*91f16700Schasinglulu  */
287*91f16700Schasinglulu #define DEC_OP_BUF_SIZE		128
288*91f16700Schasinglulu 
289*91f16700Schasinglulu static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key,
290*91f16700Schasinglulu 			   unsigned int key_len, const void *iv,
291*91f16700Schasinglulu 			   unsigned int iv_len, const void *tag,
292*91f16700Schasinglulu 			   unsigned int tag_len)
293*91f16700Schasinglulu {
294*91f16700Schasinglulu 	mbedtls_gcm_context ctx;
295*91f16700Schasinglulu 	mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
296*91f16700Schasinglulu 	unsigned char buf[DEC_OP_BUF_SIZE];
297*91f16700Schasinglulu 	unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE];
298*91f16700Schasinglulu 	unsigned char *pt = data_ptr;
299*91f16700Schasinglulu 	size_t dec_len;
300*91f16700Schasinglulu 	int diff, i, rc;
301*91f16700Schasinglulu 	size_t output_length __unused;
302*91f16700Schasinglulu 
303*91f16700Schasinglulu 	mbedtls_gcm_init(&ctx);
304*91f16700Schasinglulu 
305*91f16700Schasinglulu 	rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8);
306*91f16700Schasinglulu 	if (rc != 0) {
307*91f16700Schasinglulu 		rc = CRYPTO_ERR_DECRYPTION;
308*91f16700Schasinglulu 		goto exit_gcm;
309*91f16700Schasinglulu 	}
310*91f16700Schasinglulu 
311*91f16700Schasinglulu #if (MBEDTLS_VERSION_MAJOR < 3)
312*91f16700Schasinglulu 	rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0);
313*91f16700Schasinglulu #else
314*91f16700Schasinglulu 	rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len);
315*91f16700Schasinglulu #endif
316*91f16700Schasinglulu 	if (rc != 0) {
317*91f16700Schasinglulu 		rc = CRYPTO_ERR_DECRYPTION;
318*91f16700Schasinglulu 		goto exit_gcm;
319*91f16700Schasinglulu 	}
320*91f16700Schasinglulu 
321*91f16700Schasinglulu 	while (len > 0) {
322*91f16700Schasinglulu 		dec_len = MIN(sizeof(buf), len);
323*91f16700Schasinglulu 
324*91f16700Schasinglulu #if (MBEDTLS_VERSION_MAJOR < 3)
325*91f16700Schasinglulu 		rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf);
326*91f16700Schasinglulu #else
327*91f16700Schasinglulu 		rc = mbedtls_gcm_update(&ctx, pt, dec_len, buf, sizeof(buf), &output_length);
328*91f16700Schasinglulu #endif
329*91f16700Schasinglulu 
330*91f16700Schasinglulu 		if (rc != 0) {
331*91f16700Schasinglulu 			rc = CRYPTO_ERR_DECRYPTION;
332*91f16700Schasinglulu 			goto exit_gcm;
333*91f16700Schasinglulu 		}
334*91f16700Schasinglulu 
335*91f16700Schasinglulu 		memcpy(pt, buf, dec_len);
336*91f16700Schasinglulu 		pt += dec_len;
337*91f16700Schasinglulu 		len -= dec_len;
338*91f16700Schasinglulu 	}
339*91f16700Schasinglulu 
340*91f16700Schasinglulu #if (MBEDTLS_VERSION_MAJOR < 3)
341*91f16700Schasinglulu 	rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf));
342*91f16700Schasinglulu #else
343*91f16700Schasinglulu 	rc = mbedtls_gcm_finish(&ctx, NULL, 0, &output_length, tag_buf, sizeof(tag_buf));
344*91f16700Schasinglulu #endif
345*91f16700Schasinglulu 
346*91f16700Schasinglulu 	if (rc != 0) {
347*91f16700Schasinglulu 		rc = CRYPTO_ERR_DECRYPTION;
348*91f16700Schasinglulu 		goto exit_gcm;
349*91f16700Schasinglulu 	}
350*91f16700Schasinglulu 
351*91f16700Schasinglulu 	/* Check tag in "constant-time" */
352*91f16700Schasinglulu 	for (diff = 0, i = 0; i < tag_len; i++)
353*91f16700Schasinglulu 		diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i];
354*91f16700Schasinglulu 
355*91f16700Schasinglulu 	if (diff != 0) {
356*91f16700Schasinglulu 		rc = CRYPTO_ERR_DECRYPTION;
357*91f16700Schasinglulu 		goto exit_gcm;
358*91f16700Schasinglulu 	}
359*91f16700Schasinglulu 
360*91f16700Schasinglulu 	/* GCM decryption success */
361*91f16700Schasinglulu 	rc = CRYPTO_SUCCESS;
362*91f16700Schasinglulu 
363*91f16700Schasinglulu exit_gcm:
364*91f16700Schasinglulu 	mbedtls_gcm_free(&ctx);
365*91f16700Schasinglulu 	return rc;
366*91f16700Schasinglulu }
367*91f16700Schasinglulu 
368*91f16700Schasinglulu /*
369*91f16700Schasinglulu  * Authenticated decryption of an image
370*91f16700Schasinglulu  */
371*91f16700Schasinglulu static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
372*91f16700Schasinglulu 			size_t len, const void *key, unsigned int key_len,
373*91f16700Schasinglulu 			unsigned int key_flags, const void *iv,
374*91f16700Schasinglulu 			unsigned int iv_len, const void *tag,
375*91f16700Schasinglulu 			unsigned int tag_len)
376*91f16700Schasinglulu {
377*91f16700Schasinglulu 	int rc;
378*91f16700Schasinglulu 
379*91f16700Schasinglulu 	assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0);
380*91f16700Schasinglulu 
381*91f16700Schasinglulu 	switch (dec_algo) {
382*91f16700Schasinglulu 	case CRYPTO_GCM_DECRYPT:
383*91f16700Schasinglulu 		rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len,
384*91f16700Schasinglulu 				     tag, tag_len);
385*91f16700Schasinglulu 		if (rc != 0)
386*91f16700Schasinglulu 			return rc;
387*91f16700Schasinglulu 		break;
388*91f16700Schasinglulu 	default:
389*91f16700Schasinglulu 		return CRYPTO_ERR_DECRYPTION;
390*91f16700Schasinglulu 	}
391*91f16700Schasinglulu 
392*91f16700Schasinglulu 	return CRYPTO_SUCCESS;
393*91f16700Schasinglulu }
394*91f16700Schasinglulu #endif /* TF_MBEDTLS_USE_AES_GCM */
395*91f16700Schasinglulu 
396*91f16700Schasinglulu /*
397*91f16700Schasinglulu  * Register crypto library descriptor
398*91f16700Schasinglulu  */
399*91f16700Schasinglulu #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
400*91f16700Schasinglulu #if TF_MBEDTLS_USE_AES_GCM
401*91f16700Schasinglulu REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
402*91f16700Schasinglulu 		    auth_decrypt, NULL);
403*91f16700Schasinglulu #else
404*91f16700Schasinglulu REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
405*91f16700Schasinglulu 		    NULL, NULL);
406*91f16700Schasinglulu #endif
407*91f16700Schasinglulu #elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
408*91f16700Schasinglulu #if TF_MBEDTLS_USE_AES_GCM
409*91f16700Schasinglulu REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
410*91f16700Schasinglulu 		    auth_decrypt, NULL);
411*91f16700Schasinglulu #else
412*91f16700Schasinglulu REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
413*91f16700Schasinglulu 		    NULL, NULL);
414*91f16700Schasinglulu #endif
415*91f16700Schasinglulu #elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
416*91f16700Schasinglulu REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL);
417*91f16700Schasinglulu #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
418