xref: /rk3399_ARM-atf/drivers/auth/mbedtls/mbedtls_psa_crypto.c (revision f1318bffd4615701d3043df8b569e56a5dba074e)
138f89369SManish V Badarkhe /*
2*8a7505b0SLauren Wehrmeister  * Copyright (c) 2023-2025, Arm Limited. All rights reserved.
338f89369SManish V Badarkhe  *
438f89369SManish V Badarkhe  * SPDX-License-Identifier: BSD-3-Clause
538f89369SManish V Badarkhe  */
638f89369SManish V Badarkhe 
738f89369SManish V Badarkhe #include <assert.h>
838f89369SManish V Badarkhe #include <stddef.h>
938f89369SManish V Badarkhe #include <string.h>
1038f89369SManish V Badarkhe 
1138f89369SManish V Badarkhe /* mbed TLS headers */
1238f89369SManish V Badarkhe #include <mbedtls/md.h>
1338f89369SManish V Badarkhe #include <mbedtls/memory_buffer_alloc.h>
1438f89369SManish V Badarkhe #include <mbedtls/oid.h>
1538f89369SManish V Badarkhe #include <mbedtls/platform.h>
1655aed7d7SJimmy Brisson #include <mbedtls/psa_util.h>
1738f89369SManish V Badarkhe #include <mbedtls/x509.h>
184eaaaa19SManish V Badarkhe #include <psa/crypto.h>
194eaaaa19SManish V Badarkhe #include <psa/crypto_platform.h>
204eaaaa19SManish V Badarkhe #include <psa/crypto_types.h>
214eaaaa19SManish V Badarkhe #include <psa/crypto_values.h>
2238f89369SManish V Badarkhe 
2338f89369SManish V Badarkhe #include <common/debug.h>
24*8a7505b0SLauren Wehrmeister #include <drivers/auth/auth_util.h>
2538f89369SManish V Badarkhe #include <drivers/auth/crypto_mod.h>
2638f89369SManish V Badarkhe #include <drivers/auth/mbedtls/mbedtls_common.h>
27*8a7505b0SLauren Wehrmeister #include <drivers/auth/mbedtls/mbedtls_psa_crypto.h>
2838f89369SManish V Badarkhe #include <plat/common/platform.h>
2938f89369SManish V Badarkhe 
3038f89369SManish V Badarkhe #define LIB_NAME		"mbed TLS PSA"
3138f89369SManish V Badarkhe 
3212a8e953SRyan Everett /* Minimum required size for a buffer containing a raw EC signature when using
3312a8e953SRyan Everett  * a maximum curve size of 384 bits.
3412a8e953SRyan Everett  * This is calculated as 2 * (384 / 8). */
3512a8e953SRyan Everett #define ECDSA_SIG_BUFFER_SIZE	96U
36255ce97dSManish V Badarkhe 
37255ce97dSManish V Badarkhe /* Size of ASN.1 length and tag in bytes*/
38255ce97dSManish V Badarkhe #define SIZE_OF_ASN1_LEN	1U
39255ce97dSManish V Badarkhe #define SIZE_OF_ASN1_TAG	1U
40255ce97dSManish V Badarkhe 
41*8a7505b0SLauren Wehrmeister /* Global cache for keys */
42*8a7505b0SLauren Wehrmeister key_cache_t key_cache[MAX_CACHED_KEYS] = {0};
43*8a7505b0SLauren Wehrmeister 
4438f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
4538f89369SManish V Badarkhe CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
4638f89369SManish V Badarkhe /*
4738f89369SManish V Badarkhe  * CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available
4838f89369SManish V Badarkhe  * so make sure that mbed TLS MD maximum size must be lesser than this.
4938f89369SManish V Badarkhe  */
5038f89369SManish V Badarkhe CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE,
5138f89369SManish V Badarkhe 	assert_mbedtls_md_size_overflow);
5238f89369SManish V Badarkhe 
5338f89369SManish V Badarkhe #endif /*
5438f89369SManish V Badarkhe 	* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
5538f89369SManish V Badarkhe 	* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
5638f89369SManish V Badarkhe 	*/
5738f89369SManish V Badarkhe 
5838f89369SManish V Badarkhe /*
5938f89369SManish V Badarkhe  * AlgorithmIdentifier  ::=  SEQUENCE  {
6038f89369SManish V Badarkhe  *     algorithm               OBJECT IDENTIFIER,
6138f89369SManish V Badarkhe  *     parameters              ANY DEFINED BY algorithm OPTIONAL
6238f89369SManish V Badarkhe  * }
6338f89369SManish V Badarkhe  *
6438f89369SManish V Badarkhe  * SubjectPublicKeyInfo  ::=  SEQUENCE  {
6538f89369SManish V Badarkhe  *     algorithm            AlgorithmIdentifier,
6638f89369SManish V Badarkhe  *     subjectPublicKey     BIT STRING
6738f89369SManish V Badarkhe  * }
6838f89369SManish V Badarkhe  *
6938f89369SManish V Badarkhe  * DigestInfo ::= SEQUENCE {
7038f89369SManish V Badarkhe  *     digestAlgorithm AlgorithmIdentifier,
7138f89369SManish V Badarkhe  *     digest OCTET STRING
7238f89369SManish V Badarkhe  * }
7338f89369SManish V Badarkhe  */
7438f89369SManish V Badarkhe 
7538f89369SManish V Badarkhe /*
764eaaaa19SManish V Badarkhe  * We pretend using an external RNG (through MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
774eaaaa19SManish V Badarkhe  * mbedTLS config option) so we need to provide an implementation of
784eaaaa19SManish V Badarkhe  * mbedtls_psa_external_get_random(). Provide a fake one, since we do not
794eaaaa19SManish V Badarkhe  * actually have any external RNG and TF-A itself doesn't engage in
804eaaaa19SManish V Badarkhe  * cryptographic operations that demands randomness.
814eaaaa19SManish V Badarkhe  */
mbedtls_psa_external_get_random(mbedtls_psa_external_random_context_t * context,uint8_t * output,size_t output_size,size_t * output_length)824eaaaa19SManish V Badarkhe psa_status_t mbedtls_psa_external_get_random(
834eaaaa19SManish V Badarkhe 			mbedtls_psa_external_random_context_t *context,
844eaaaa19SManish V Badarkhe 			uint8_t *output, size_t output_size,
854eaaaa19SManish V Badarkhe 			size_t *output_length)
864eaaaa19SManish V Badarkhe {
874eaaaa19SManish V Badarkhe 	return PSA_ERROR_INSUFFICIENT_ENTROPY;
884eaaaa19SManish V Badarkhe }
894eaaaa19SManish V Badarkhe 
904eaaaa19SManish V Badarkhe /*
9138f89369SManish V Badarkhe  * Initialize the library and export the descriptor
9238f89369SManish V Badarkhe  */
init(void)9338f89369SManish V Badarkhe static void init(void)
9438f89369SManish V Badarkhe {
9538f89369SManish V Badarkhe 	/* Initialize mbed TLS */
9638f89369SManish V Badarkhe 	mbedtls_init();
974eaaaa19SManish V Badarkhe 
984eaaaa19SManish V Badarkhe 	/* Initialise PSA mbedTLS */
994eaaaa19SManish V Badarkhe 	psa_status_t status = psa_crypto_init();
1004eaaaa19SManish V Badarkhe 
1014eaaaa19SManish V Badarkhe 	if (status != PSA_SUCCESS) {
1024eaaaa19SManish V Badarkhe 		ERROR("Failed to initialize %s crypto (%d).\n", LIB_NAME, status);
1034eaaaa19SManish V Badarkhe 		panic();
1044eaaaa19SManish V Badarkhe 	}
1054eaaaa19SManish V Badarkhe 
1064eaaaa19SManish V Badarkhe 	INFO("PSA crypto initialized successfully!\n");
10738f89369SManish V Badarkhe }
10838f89369SManish V Badarkhe 
10938f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
11038f89369SManish V Badarkhe CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
111*8a7505b0SLauren Wehrmeister /* Destroy all psa key ids created in a loop */
destroy_key_ids(void)112*8a7505b0SLauren Wehrmeister static void destroy_key_ids(void)
113*8a7505b0SLauren Wehrmeister {
114*8a7505b0SLauren Wehrmeister 	for (int i = 0; i < MAX_CACHED_KEYS; i++) {
115*8a7505b0SLauren Wehrmeister 		if (key_cache[i].valid) {
116*8a7505b0SLauren Wehrmeister 			psa_destroy_key(key_cache[i].key_id);
117*8a7505b0SLauren Wehrmeister 		}
118*8a7505b0SLauren Wehrmeister 	}
119*8a7505b0SLauren Wehrmeister }
120*8a7505b0SLauren Wehrmeister 
121*8a7505b0SLauren Wehrmeister /* Retrieve cached key ID, algorithm, and key attributes */
get_cached_psa_key_info(const char * pk_oid,psa_key_id_t * key_id,psa_algorithm_t * psa_alg,psa_key_attributes_t * psa_key_attr)122*8a7505b0SLauren Wehrmeister static bool get_cached_psa_key_info(const char *pk_oid, psa_key_id_t *key_id,
123*8a7505b0SLauren Wehrmeister 		psa_algorithm_t *psa_alg, psa_key_attributes_t *psa_key_attr)
124*8a7505b0SLauren Wehrmeister {
125*8a7505b0SLauren Wehrmeister 	for (int i = 0; i < MAX_CACHED_KEYS; i++) {
126*8a7505b0SLauren Wehrmeister 		if (key_cache[i].valid &&
127*8a7505b0SLauren Wehrmeister 				(strlen(key_cache[i].pk_oid) == strlen(pk_oid)) &&
128*8a7505b0SLauren Wehrmeister 				(strncmp(key_cache[i].pk_oid, pk_oid, strlen(pk_oid)) == 0)) {
129*8a7505b0SLauren Wehrmeister 			*key_id = key_cache[i].key_id;
130*8a7505b0SLauren Wehrmeister 			*psa_alg = key_cache[i].psa_alg;
131*8a7505b0SLauren Wehrmeister 			*psa_key_attr = key_cache[i].psa_key_attr;
132*8a7505b0SLauren Wehrmeister 			return true;
133*8a7505b0SLauren Wehrmeister 		}
134*8a7505b0SLauren Wehrmeister 	}
135*8a7505b0SLauren Wehrmeister 	return false;
136*8a7505b0SLauren Wehrmeister }
137*8a7505b0SLauren Wehrmeister 
138*8a7505b0SLauren Wehrmeister /* Store key ID, algorithm, and key attributes in the cache */
cache_psa_key_info(const char * pk_oid,psa_key_id_t key_id,psa_algorithm_t psa_alg,psa_key_attributes_t psa_key_attr)139*8a7505b0SLauren Wehrmeister static int cache_psa_key_info(const char *pk_oid, psa_key_id_t key_id, psa_algorithm_t psa_alg,
140*8a7505b0SLauren Wehrmeister 		psa_key_attributes_t psa_key_attr)
141*8a7505b0SLauren Wehrmeister {
142*8a7505b0SLauren Wehrmeister 	for (int i = 0; i < MAX_CACHED_KEYS; i++) {
143*8a7505b0SLauren Wehrmeister 		if (!key_cache[i].valid) {
144*8a7505b0SLauren Wehrmeister 			key_cache[i].pk_oid = pk_oid;
145*8a7505b0SLauren Wehrmeister 			key_cache[i].key_id = key_id;
146*8a7505b0SLauren Wehrmeister 			key_cache[i].psa_alg = psa_alg;
147*8a7505b0SLauren Wehrmeister 			key_cache[i].psa_key_attr = psa_key_attr;
148*8a7505b0SLauren Wehrmeister 			key_cache[i].valid = true;
149*8a7505b0SLauren Wehrmeister 			return CRYPTO_SUCCESS;
150*8a7505b0SLauren Wehrmeister 		}
151*8a7505b0SLauren Wehrmeister 	}
152*8a7505b0SLauren Wehrmeister 	return CRYPTO_ERR_SIGNATURE;
153*8a7505b0SLauren Wehrmeister }
154eaa62e82SManish V Badarkhe 
15555aed7d7SJimmy Brisson /*
15655aed7d7SJimmy Brisson  * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has
15755aed7d7SJimmy Brisson  * advised that it's better to copy out the declaration than it would be to
15855aed7d7SJimmy Brisson  * update to 3.5.2, where this function is exposed.
15955aed7d7SJimmy Brisson  */
16055aed7d7SJimmy Brisson int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid,
16155aed7d7SJimmy Brisson 			     const mbedtls_x509_buf *sig_params,
16255aed7d7SJimmy Brisson 			     mbedtls_md_type_t *md_alg,
16355aed7d7SJimmy Brisson 			     mbedtls_pk_type_t *pk_alg,
16455aed7d7SJimmy Brisson 			     void **sig_opts);
1650bc36c83SRyan Everett 
1660bc36c83SRyan Everett /*
1670bc36c83SRyan Everett  * This is a helper function which parses a SignatureAlgorithm OID.
1680bc36c83SRyan Everett  * It extracts the pk algorithm and constructs a psa_algorithm_t object
1690bc36c83SRyan Everett  * to be used by PSA calls.
1700bc36c83SRyan Everett  */
construct_psa_alg(void * sig_alg,unsigned int sig_alg_len,mbedtls_pk_type_t * pk_alg,psa_algorithm_t * psa_alg)1710bc36c83SRyan Everett static int construct_psa_alg(void *sig_alg, unsigned int sig_alg_len,
1720bc36c83SRyan Everett 			     mbedtls_pk_type_t *pk_alg, psa_algorithm_t *psa_alg)
1730bc36c83SRyan Everett {
1740bc36c83SRyan Everett 	int rc;
1750bc36c83SRyan Everett 	mbedtls_md_type_t md_alg;
1760bc36c83SRyan Everett 	void *sig_opts = NULL;
1770bc36c83SRyan Everett 	mbedtls_asn1_buf sig_alg_oid, params;
1780bc36c83SRyan Everett 	unsigned char *p = (unsigned char *) sig_alg;
1790bc36c83SRyan Everett 	unsigned char *end = (unsigned char *) sig_alg + sig_alg_len;
1800bc36c83SRyan Everett 
1810bc36c83SRyan Everett 	rc = mbedtls_asn1_get_alg(&p, end, &sig_alg_oid, &params);
1820bc36c83SRyan Everett 	if (rc != 0) {
1830bc36c83SRyan Everett 		rc = CRYPTO_ERR_SIGNATURE;
1840bc36c83SRyan Everett 		goto end;
1850bc36c83SRyan Everett 	}
1860bc36c83SRyan Everett 
1870bc36c83SRyan Everett 	rc = mbedtls_x509_get_sig_alg(&sig_alg_oid, &params, &md_alg, pk_alg, &sig_opts);
1880bc36c83SRyan Everett 	if (rc != 0) {
1890bc36c83SRyan Everett 		rc = CRYPTO_ERR_SIGNATURE;
1900bc36c83SRyan Everett 		goto end;
1910bc36c83SRyan Everett 	}
1920bc36c83SRyan Everett 
1930bc36c83SRyan Everett 	psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
1940bc36c83SRyan Everett 
1950bc36c83SRyan Everett 	switch (*pk_alg) {
1960bc36c83SRyan Everett 	case MBEDTLS_PK_RSASSA_PSS:
1970bc36c83SRyan Everett 		*psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
1980bc36c83SRyan Everett 		rc = CRYPTO_SUCCESS;
1990bc36c83SRyan Everett 		break;
2000bc36c83SRyan Everett 	case MBEDTLS_PK_ECDSA:
2010bc36c83SRyan Everett 		*psa_alg = PSA_ALG_ECDSA(psa_md_alg);
2020bc36c83SRyan Everett 		rc = CRYPTO_SUCCESS;
2030bc36c83SRyan Everett 		break;
2040bc36c83SRyan Everett 	default:
2050bc36c83SRyan Everett 		*psa_alg = PSA_ALG_NONE;
2060bc36c83SRyan Everett 		rc = CRYPTO_ERR_SIGNATURE;
2070bc36c83SRyan Everett 		break;
2080bc36c83SRyan Everett 	}
2090bc36c83SRyan Everett 
2100bc36c83SRyan Everett end:
2110bc36c83SRyan Everett 	mbedtls_free(sig_opts);
2120bc36c83SRyan Everett 	return rc;
2130bc36c83SRyan Everett }
2140bc36c83SRyan Everett 
2150bc36c83SRyan Everett /*
2160bc36c83SRyan Everett  * Helper functions for mbedtls PK contexts.
2170bc36c83SRyan Everett  */
initialize_pk_context(mbedtls_pk_context * pk,bool * pk_initialized)2180bc36c83SRyan Everett static void initialize_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
2190bc36c83SRyan Everett {
2200bc36c83SRyan Everett 	mbedtls_pk_init(pk);
2210bc36c83SRyan Everett 	*pk_initialized = true;
2220bc36c83SRyan Everett }
2230bc36c83SRyan Everett 
cleanup_pk_context(mbedtls_pk_context * pk,bool * pk_initialized)2240bc36c83SRyan Everett static void cleanup_pk_context(mbedtls_pk_context *pk, bool *pk_initialized)
2250bc36c83SRyan Everett {
2260bc36c83SRyan Everett 	if (*pk_initialized) {
2270bc36c83SRyan Everett 		mbedtls_pk_free(pk);
2280bc36c83SRyan Everett 		*pk_initialized = false;
2290bc36c83SRyan Everett 	}
2300bc36c83SRyan Everett }
2310bc36c83SRyan Everett 
23255aed7d7SJimmy Brisson /*
23338f89369SManish V Badarkhe  * Verify a signature.
23438f89369SManish V Badarkhe  *
23538f89369SManish V Badarkhe  * Parameters are passed using the DER encoding format following the ASN.1
23638f89369SManish V Badarkhe  * structures detailed above.
23738f89369SManish V Badarkhe  */
verify_signature(void * data_ptr,unsigned int data_len,void * sig_ptr,unsigned int sig_len,void * sig_alg,unsigned int sig_alg_len,void * pk_ptr,unsigned int pk_len)23838f89369SManish V Badarkhe static int verify_signature(void *data_ptr, unsigned int data_len,
23938f89369SManish V Badarkhe 			    void *sig_ptr, unsigned int sig_len,
24038f89369SManish V Badarkhe 			    void *sig_alg, unsigned int sig_alg_len,
24138f89369SManish V Badarkhe 			    void *pk_ptr, unsigned int pk_len)
24238f89369SManish V Badarkhe {
24338f89369SManish V Badarkhe 	unsigned char *p, *end;
2440bc36c83SRyan Everett 	mbedtls_pk_context pk;
2450bc36c83SRyan Everett 	bool pk_initialized = false;
2460bc36c83SRyan Everett 	int rc = CRYPTO_ERR_SIGNATURE;
2470bc36c83SRyan Everett 	psa_status_t psa_status = PSA_ERROR_CORRUPTION_DETECTED;
2480bc36c83SRyan Everett 	psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT;
2490bc36c83SRyan Everett 	psa_key_id_t psa_key_id;
2500bc36c83SRyan Everett 	mbedtls_pk_type_t pk_alg;
2510bc36c83SRyan Everett 	psa_algorithm_t psa_alg;
252*8a7505b0SLauren Wehrmeister 	const char *pk_oid = get_current_pk_oid();
25312a8e953SRyan Everett 	__unused unsigned char reformatted_sig[ECDSA_SIG_BUFFER_SIZE] = {0};
254255ce97dSManish V Badarkhe 	unsigned char *local_sig_ptr;
255255ce97dSManish V Badarkhe 	size_t local_sig_len;
256eaa62e82SManish V Badarkhe 
257*8a7505b0SLauren Wehrmeister 	/* Check if key, algorithm, and key attributes are already cached */
258*8a7505b0SLauren Wehrmeister 	if (!get_cached_psa_key_info(pk_oid, &psa_key_id, &psa_alg, &psa_key_attr)) {
2590bc36c83SRyan Everett 		/* Load the key into the PSA key store. */
2600bc36c83SRyan Everett 		initialize_pk_context(&pk, &pk_initialized);
26138f89369SManish V Badarkhe 
2620bc36c83SRyan Everett 		p = (unsigned char *) pk_ptr;
2630bc36c83SRyan Everett 		end = p + pk_len;
2640bc36c83SRyan Everett 		rc = mbedtls_pk_parse_subpubkey(&p, end, &pk);
26538f89369SManish V Badarkhe 		if (rc != 0) {
26638f89369SManish V Badarkhe 			rc = CRYPTO_ERR_SIGNATURE;
267eaa62e82SManish V Badarkhe 			goto end2;
26838f89369SManish V Badarkhe 		}
269255ce97dSManish V Badarkhe 
270*8a7505b0SLauren Wehrmeister 		rc = mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_VERIFY_MESSAGE,
271*8a7505b0SLauren Wehrmeister 				&psa_key_attr);
2720bc36c83SRyan Everett 		if (rc != 0) {
2730bc36c83SRyan Everett 			rc = CRYPTO_ERR_SIGNATURE;
2740bc36c83SRyan Everett 			goto end2;
2750bc36c83SRyan Everett 		}
2760bc36c83SRyan Everett 
2770bc36c83SRyan Everett 		rc = construct_psa_alg(sig_alg, sig_alg_len, &pk_alg, &psa_alg);
2780bc36c83SRyan Everett 		if (rc != CRYPTO_SUCCESS) {
2790bc36c83SRyan Everett 			goto end2;
2800bc36c83SRyan Everett 		}
2810bc36c83SRyan Everett 		psa_set_key_algorithm(&psa_key_attr, psa_alg);
2820bc36c83SRyan Everett 
2830bc36c83SRyan Everett 		rc = mbedtls_pk_import_into_psa(&pk, &psa_key_attr, &psa_key_id);
2840bc36c83SRyan Everett 		if (rc != 0) {
2850bc36c83SRyan Everett 			rc = CRYPTO_ERR_SIGNATURE;
2860bc36c83SRyan Everett 			goto end2;
2870bc36c83SRyan Everett 		}
2880bc36c83SRyan Everett 
289*8a7505b0SLauren Wehrmeister 		/* Cache the key, algorithm, and key attributes for future use */
290*8a7505b0SLauren Wehrmeister 		rc = cache_psa_key_info(pk_oid, psa_key_id, psa_alg, psa_key_attr);
291*8a7505b0SLauren Wehrmeister 		if (rc != CRYPTO_SUCCESS) {
292*8a7505b0SLauren Wehrmeister 			goto end2;
293*8a7505b0SLauren Wehrmeister 		}
294*8a7505b0SLauren Wehrmeister 
2950bc36c83SRyan Everett 		/* Optimize mbedtls heap usage by freeing the pk context now.  */
2960bc36c83SRyan Everett 		cleanup_pk_context(&pk, &pk_initialized);
297*8a7505b0SLauren Wehrmeister 	}
2980bc36c83SRyan Everett 
2990bc36c83SRyan Everett 	/* Extract the signature from sig_ptr. */
3000bc36c83SRyan Everett 	p = (unsigned char *) sig_ptr;
3010bc36c83SRyan Everett 	end = p + sig_len;
3020bc36c83SRyan Everett 	rc = mbedtls_asn1_get_bitstring_null(&p, end, &local_sig_len);
3030bc36c83SRyan Everett 	if (rc != 0) {
3040bc36c83SRyan Everett 		rc = CRYPTO_ERR_SIGNATURE;
3050bc36c83SRyan Everett 		goto end1;
3060bc36c83SRyan Everett 	}
307255ce97dSManish V Badarkhe 	local_sig_ptr = p;
308255ce97dSManish V Badarkhe 
309255ce97dSManish V Badarkhe #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
310255ce97dSManish V Badarkhe TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
311*8a7505b0SLauren Wehrmeister 	if (PSA_ALG_IS_ECDSA(psa_alg)) {
3120bc36c83SRyan Everett 		/* Convert the DER ASN.1 signature to raw format. */
3130bc36c83SRyan Everett 		size_t key_bits = psa_get_key_bits(&psa_key_attr);
314255ce97dSManish V Badarkhe 
3150bc36c83SRyan Everett 		rc = mbedtls_ecdsa_der_to_raw(key_bits, p, local_sig_len,
31612a8e953SRyan Everett 					      reformatted_sig, ECDSA_SIG_BUFFER_SIZE,
3170bc36c83SRyan Everett 					      &local_sig_len);
3180bc36c83SRyan Everett 		if (rc != 0) {
3190bc36c83SRyan Everett 			rc = CRYPTO_ERR_SIGNATURE;
3200bc36c83SRyan Everett 			goto end1;
3210bc36c83SRyan Everett 		}
322255ce97dSManish V Badarkhe 		local_sig_ptr = reformatted_sig;
323255ce97dSManish V Badarkhe 	}
324255ce97dSManish V Badarkhe #endif /*
325255ce97dSManish V Badarkhe 	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
326255ce97dSManish V Badarkhe 	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
327255ce97dSManish V Badarkhe 	**/
32838f89369SManish V Badarkhe 
3290bc36c83SRyan Everett 	/* Verify the signature. */
3300bc36c83SRyan Everett 	psa_status = psa_verify_message(psa_key_id, psa_alg,
331eaa62e82SManish V Badarkhe 				    data_ptr, data_len,
332255ce97dSManish V Badarkhe 				    local_sig_ptr, local_sig_len);
333*8a7505b0SLauren Wehrmeister 
334*8a7505b0SLauren Wehrmeister 	rc = (psa_status == PSA_SUCCESS) ? CRYPTO_SUCCESS : CRYPTO_ERR_SIGNATURE;
33538f89369SManish V Badarkhe 
33638f89369SManish V Badarkhe end1:
337*8a7505b0SLauren Wehrmeister 	return rc;
33838f89369SManish V Badarkhe end2:
3390bc36c83SRyan Everett 	/* Free the pk context, if it is initialized. */
3400bc36c83SRyan Everett 	cleanup_pk_context(&pk, &pk_initialized);
3410bc36c83SRyan Everett 
34238f89369SManish V Badarkhe 	return rc;
34338f89369SManish V Badarkhe }
34438f89369SManish V Badarkhe 
34538f89369SManish V Badarkhe /*
34638f89369SManish V Badarkhe  * Match a hash
34738f89369SManish V Badarkhe  *
34838f89369SManish V Badarkhe  * Digest info is passed in DER format following the ASN.1 structure detailed
34938f89369SManish V Badarkhe  * above.
35038f89369SManish V Badarkhe  */
verify_hash(void * data_ptr,unsigned int data_len,void * digest_info_ptr,unsigned int digest_info_len)35138f89369SManish V Badarkhe static int verify_hash(void *data_ptr, unsigned int data_len,
35238f89369SManish V Badarkhe 		       void *digest_info_ptr, unsigned int digest_info_len)
35338f89369SManish V Badarkhe {
35438f89369SManish V Badarkhe 	mbedtls_asn1_buf hash_oid, params;
35538f89369SManish V Badarkhe 	mbedtls_md_type_t md_alg;
35638f89369SManish V Badarkhe 	unsigned char *p, *end, *hash;
35738f89369SManish V Badarkhe 	size_t len;
35838f89369SManish V Badarkhe 	int rc;
3592ed061c4SManish V Badarkhe 	psa_status_t status;
3602ed061c4SManish V Badarkhe 	psa_algorithm_t psa_md_alg;
36138f89369SManish V Badarkhe 
36238f89369SManish V Badarkhe 	/*
36338f89369SManish V Badarkhe 	 * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after
36438f89369SManish V Badarkhe 	 * it is allowed.  This is necessary to support multiple hash
36538f89369SManish V Badarkhe 	 * algorithms.
36638f89369SManish V Badarkhe 	 */
36738f89369SManish V Badarkhe 	p = (unsigned char *)digest_info_ptr;
36838f89369SManish V Badarkhe 	end = p + digest_info_len;
36938f89369SManish V Badarkhe 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
37038f89369SManish V Badarkhe 				  MBEDTLS_ASN1_SEQUENCE);
37138f89369SManish V Badarkhe 	if (rc != 0) {
37238f89369SManish V Badarkhe 		return CRYPTO_ERR_HASH;
37338f89369SManish V Badarkhe 	}
37438f89369SManish V Badarkhe 
37538f89369SManish V Badarkhe 	end = p + len;
37638f89369SManish V Badarkhe 
37738f89369SManish V Badarkhe 	/* Get the hash algorithm */
37838f89369SManish V Badarkhe 	rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, &params);
37938f89369SManish V Badarkhe 	if (rc != 0) {
38038f89369SManish V Badarkhe 		return CRYPTO_ERR_HASH;
38138f89369SManish V Badarkhe 	}
38238f89369SManish V Badarkhe 
38338f89369SManish V Badarkhe 	/* Hash should be octet string type and consume all bytes */
38438f89369SManish V Badarkhe 	rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
38538f89369SManish V Badarkhe 	if ((rc != 0) || ((size_t)(end - p) != len)) {
38638f89369SManish V Badarkhe 		return CRYPTO_ERR_HASH;
38738f89369SManish V Badarkhe 	}
38838f89369SManish V Badarkhe 	hash = p;
38938f89369SManish V Badarkhe 
3902ed061c4SManish V Badarkhe 	rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
39138f89369SManish V Badarkhe 	if (rc != 0) {
39238f89369SManish V Badarkhe 		return CRYPTO_ERR_HASH;
39338f89369SManish V Badarkhe 	}
39438f89369SManish V Badarkhe 
3952ed061c4SManish V Badarkhe 	/* convert the md_alg to psa_algo */
3962ed061c4SManish V Badarkhe 	psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg);
3972ed061c4SManish V Badarkhe 
3982ed061c4SManish V Badarkhe 	/* Length of hash must match the algorithm's size */
3992ed061c4SManish V Badarkhe 	if (len != PSA_HASH_LENGTH(psa_md_alg)) {
4002ed061c4SManish V Badarkhe 		return CRYPTO_ERR_HASH;
4012ed061c4SManish V Badarkhe 	}
4022ed061c4SManish V Badarkhe 
4032ed061c4SManish V Badarkhe 	/*
4042ed061c4SManish V Badarkhe 	 * Calculate Hash and compare it against the retrieved hash from
4052ed061c4SManish V Badarkhe 	 * the certificate (one shot API).
4062ed061c4SManish V Badarkhe 	 */
4072ed061c4SManish V Badarkhe 	status = psa_hash_compare(psa_md_alg,
4082ed061c4SManish V Badarkhe 				  data_ptr, (size_t)data_len,
4092ed061c4SManish V Badarkhe 				  (const uint8_t *)hash, len);
4102ed061c4SManish V Badarkhe 
4112ed061c4SManish V Badarkhe 	if (status != PSA_SUCCESS) {
41238f89369SManish V Badarkhe 		return CRYPTO_ERR_HASH;
41338f89369SManish V Badarkhe 	}
41438f89369SManish V Badarkhe 
41538f89369SManish V Badarkhe 	return CRYPTO_SUCCESS;
41638f89369SManish V Badarkhe }
41738f89369SManish V Badarkhe #endif /*
41838f89369SManish V Badarkhe 	* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
41938f89369SManish V Badarkhe 	* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
42038f89369SManish V Badarkhe 	*/
42138f89369SManish V Badarkhe 
422*8a7505b0SLauren Wehrmeister /*
423*8a7505b0SLauren Wehrmeister  * Finish crypto usage by destroying the psa_key_ids
424*8a7505b0SLauren Wehrmeister  */
finish(void)425*8a7505b0SLauren Wehrmeister static void finish(void)
426*8a7505b0SLauren Wehrmeister {
427*8a7505b0SLauren Wehrmeister #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
428*8a7505b0SLauren Wehrmeister CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
429*8a7505b0SLauren Wehrmeister 	/* Destroy the psa_key_ids */
430*8a7505b0SLauren Wehrmeister 	destroy_key_ids();
431*8a7505b0SLauren Wehrmeister #endif
432*8a7505b0SLauren Wehrmeister }
433*8a7505b0SLauren Wehrmeister 
43438f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
43538f89369SManish V Badarkhe CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
43638f89369SManish V Badarkhe /*
43738f89369SManish V Badarkhe  * Map a generic crypto message digest algorithm to the corresponding macro used
43838f89369SManish V Badarkhe  * by Mbed TLS.
43938f89369SManish V Badarkhe  */
md_type(enum crypto_md_algo algo)44038f89369SManish V Badarkhe static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo)
44138f89369SManish V Badarkhe {
44238f89369SManish V Badarkhe 	switch (algo) {
44338f89369SManish V Badarkhe 	case CRYPTO_MD_SHA512:
44438f89369SManish V Badarkhe 		return MBEDTLS_MD_SHA512;
44538f89369SManish V Badarkhe 	case CRYPTO_MD_SHA384:
44638f89369SManish V Badarkhe 		return MBEDTLS_MD_SHA384;
44738f89369SManish V Badarkhe 	case CRYPTO_MD_SHA256:
44838f89369SManish V Badarkhe 		return MBEDTLS_MD_SHA256;
44938f89369SManish V Badarkhe 	default:
45038f89369SManish V Badarkhe 		/* Invalid hash algorithm. */
45138f89369SManish V Badarkhe 		return MBEDTLS_MD_NONE;
45238f89369SManish V Badarkhe 	}
45338f89369SManish V Badarkhe }
45438f89369SManish V Badarkhe 
45538f89369SManish V Badarkhe /*
45638f89369SManish V Badarkhe  * Calculate a hash
45738f89369SManish V Badarkhe  *
45838f89369SManish V Badarkhe  * output points to the computed hash
45938f89369SManish V Badarkhe  */
calc_hash(enum crypto_md_algo md_algo,void * data_ptr,unsigned int data_len,unsigned char output[CRYPTO_MD_MAX_SIZE])46038f89369SManish V Badarkhe static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr,
46138f89369SManish V Badarkhe 		     unsigned int data_len,
46238f89369SManish V Badarkhe 		     unsigned char output[CRYPTO_MD_MAX_SIZE])
46338f89369SManish V Badarkhe {
464484b5869SManish V Badarkhe 	size_t hash_length;
465484b5869SManish V Badarkhe 	psa_status_t status;
466484b5869SManish V Badarkhe 	psa_algorithm_t psa_md_alg;
46738f89369SManish V Badarkhe 
468484b5869SManish V Badarkhe 	/* convert the md_alg to psa_algo */
469484b5869SManish V Badarkhe 	psa_md_alg = mbedtls_md_psa_alg_from_type(md_type(md_algo));
47038f89369SManish V Badarkhe 
47138f89369SManish V Badarkhe 	/*
47238f89369SManish V Badarkhe 	 * Calculate the hash of the data, it is safe to pass the
47338f89369SManish V Badarkhe 	 * 'output' hash buffer pointer considering its size is always
47438f89369SManish V Badarkhe 	 * bigger than or equal to MBEDTLS_MD_MAX_SIZE.
47538f89369SManish V Badarkhe 	 */
476484b5869SManish V Badarkhe 	status = psa_hash_compute(psa_md_alg, data_ptr, (size_t)data_len,
477484b5869SManish V Badarkhe 				  (uint8_t *)output, CRYPTO_MD_MAX_SIZE,
478484b5869SManish V Badarkhe 				  &hash_length);
479484b5869SManish V Badarkhe 	if (status != PSA_SUCCESS) {
480484b5869SManish V Badarkhe 		return CRYPTO_ERR_HASH;
481484b5869SManish V Badarkhe 	}
482484b5869SManish V Badarkhe 
483484b5869SManish V Badarkhe 	return CRYPTO_SUCCESS;
48438f89369SManish V Badarkhe }
48538f89369SManish V Badarkhe #endif /*
48638f89369SManish V Badarkhe 	* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
48738f89369SManish V Badarkhe 	* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
48838f89369SManish V Badarkhe 	*/
48938f89369SManish V Badarkhe 
49038f89369SManish V Badarkhe #if TF_MBEDTLS_USE_AES_GCM
49138f89369SManish V Badarkhe /*
49238f89369SManish V Badarkhe  * Stack based buffer allocation for decryption operation. It could
49338f89369SManish V Badarkhe  * be configured to balance stack usage vs execution speed.
49438f89369SManish V Badarkhe  */
49538f89369SManish V Badarkhe #define DEC_OP_BUF_SIZE		128
49638f89369SManish V Badarkhe 
aes_gcm_decrypt(void * data_ptr,size_t len,const void * key,unsigned int key_len,const void * iv,unsigned int iv_len,const void * tag,unsigned int tag_len)49738f89369SManish V Badarkhe static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key,
49838f89369SManish V Badarkhe 			   unsigned int key_len, const void *iv,
49938f89369SManish V Badarkhe 			   unsigned int iv_len, const void *tag,
50038f89369SManish V Badarkhe 			   unsigned int tag_len)
50138f89369SManish V Badarkhe {
5027079ddf9SRyan Everett 	mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
5037079ddf9SRyan Everett 	psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
5047079ddf9SRyan Everett 	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
5057079ddf9SRyan Everett 	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
50638f89369SManish V Badarkhe 	unsigned char buf[DEC_OP_BUF_SIZE];
50738f89369SManish V Badarkhe 	unsigned char *pt = data_ptr;
50838f89369SManish V Badarkhe 	size_t dec_len;
5097079ddf9SRyan Everett 	size_t output_length;
51038f89369SManish V Badarkhe 
5117079ddf9SRyan Everett 	/* Load the key into the PSA key store. */
5127079ddf9SRyan Everett 	psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
5137079ddf9SRyan Everett 	psa_set_key_algorithm(&attributes, PSA_ALG_GCM);
5147079ddf9SRyan Everett 	psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
51538f89369SManish V Badarkhe 
5167079ddf9SRyan Everett 	psa_status = psa_import_key(&attributes, key, key_len, &key_id);
5177079ddf9SRyan Everett 	if (psa_status != PSA_SUCCESS) {
5187079ddf9SRyan Everett 		return CRYPTO_ERR_DECRYPTION;
51938f89369SManish V Badarkhe 	}
52038f89369SManish V Badarkhe 
5217079ddf9SRyan Everett 	/* Perform the decryption. */
5227079ddf9SRyan Everett 	psa_status = psa_aead_decrypt_setup(&operation, key_id, PSA_ALG_GCM);
5237079ddf9SRyan Everett 	if (psa_status != PSA_SUCCESS) {
5247079ddf9SRyan Everett 		goto err;
5257079ddf9SRyan Everett 	}
5267079ddf9SRyan Everett 
5277079ddf9SRyan Everett 	psa_status = psa_aead_set_nonce(&operation, iv, iv_len);
5287079ddf9SRyan Everett 	if (psa_status != PSA_SUCCESS) {
5297079ddf9SRyan Everett 		goto err;
53038f89369SManish V Badarkhe 	}
53138f89369SManish V Badarkhe 
53238f89369SManish V Badarkhe 	while (len > 0) {
53338f89369SManish V Badarkhe 		dec_len = MIN(sizeof(buf), len);
53438f89369SManish V Badarkhe 
5357079ddf9SRyan Everett 		psa_status = psa_aead_update(&operation, pt, dec_len, buf,
5367079ddf9SRyan Everett 					     sizeof(buf), &output_length);
5377079ddf9SRyan Everett 		if (psa_status != PSA_SUCCESS) {
5387079ddf9SRyan Everett 			goto err;
53938f89369SManish V Badarkhe 		}
54038f89369SManish V Badarkhe 
5417079ddf9SRyan Everett 		memcpy(pt, buf, output_length);
5427079ddf9SRyan Everett 		pt += output_length;
54338f89369SManish V Badarkhe 		len -= dec_len;
54438f89369SManish V Badarkhe 	}
54538f89369SManish V Badarkhe 
5467079ddf9SRyan Everett 	/* Verify the tag. */
5477079ddf9SRyan Everett 	psa_status = psa_aead_verify(&operation, NULL, 0, &output_length, tag, tag_len);
5487079ddf9SRyan Everett 	if (psa_status == PSA_SUCCESS) {
5497079ddf9SRyan Everett 		psa_destroy_key(key_id);
5507079ddf9SRyan Everett 		return CRYPTO_SUCCESS;
55138f89369SManish V Badarkhe 	}
55238f89369SManish V Badarkhe 
5537079ddf9SRyan Everett err:
5547079ddf9SRyan Everett 	psa_aead_abort(&operation);
5557079ddf9SRyan Everett 	psa_destroy_key(key_id);
5567079ddf9SRyan Everett 	return CRYPTO_ERR_DECRYPTION;
55738f89369SManish V Badarkhe }
55838f89369SManish V Badarkhe 
55938f89369SManish V Badarkhe /*
56038f89369SManish V Badarkhe  * Authenticated decryption of an image
56138f89369SManish V Badarkhe  */
auth_decrypt(enum crypto_dec_algo dec_algo,void * data_ptr,size_t len,const void * key,unsigned int key_len,unsigned int key_flags,const void * iv,unsigned int iv_len,const void * tag,unsigned int tag_len)56238f89369SManish V Badarkhe static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
56338f89369SManish V Badarkhe 			size_t len, const void *key, unsigned int key_len,
56438f89369SManish V Badarkhe 			unsigned int key_flags, const void *iv,
56538f89369SManish V Badarkhe 			unsigned int iv_len, const void *tag,
56638f89369SManish V Badarkhe 			unsigned int tag_len)
56738f89369SManish V Badarkhe {
56838f89369SManish V Badarkhe 	int rc;
56938f89369SManish V Badarkhe 
57038f89369SManish V Badarkhe 	assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0);
57138f89369SManish V Badarkhe 
57238f89369SManish V Badarkhe 	switch (dec_algo) {
57338f89369SManish V Badarkhe 	case CRYPTO_GCM_DECRYPT:
57438f89369SManish V Badarkhe 		rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len,
57538f89369SManish V Badarkhe 				     tag, tag_len);
57638f89369SManish V Badarkhe 		if (rc != 0)
57738f89369SManish V Badarkhe 			return rc;
57838f89369SManish V Badarkhe 		break;
57938f89369SManish V Badarkhe 	default:
58038f89369SManish V Badarkhe 		return CRYPTO_ERR_DECRYPTION;
58138f89369SManish V Badarkhe 	}
58238f89369SManish V Badarkhe 
58338f89369SManish V Badarkhe 	return CRYPTO_SUCCESS;
58438f89369SManish V Badarkhe }
58538f89369SManish V Badarkhe #endif /* TF_MBEDTLS_USE_AES_GCM */
58638f89369SManish V Badarkhe 
58738f89369SManish V Badarkhe /*
58838f89369SManish V Badarkhe  * Register crypto library descriptor
58938f89369SManish V Badarkhe  */
59038f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
59138f89369SManish V Badarkhe #if TF_MBEDTLS_USE_AES_GCM
59238f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
593*8a7505b0SLauren Wehrmeister 		    auth_decrypt, NULL, finish);
59438f89369SManish V Badarkhe #else
59538f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
596*8a7505b0SLauren Wehrmeister 		    NULL, NULL, finish);
59738f89369SManish V Badarkhe #endif
59838f89369SManish V Badarkhe #elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
59938f89369SManish V Badarkhe #if TF_MBEDTLS_USE_AES_GCM
60038f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
601*8a7505b0SLauren Wehrmeister 		    auth_decrypt, NULL, finish);
60238f89369SManish V Badarkhe #else
60338f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL,
604*8a7505b0SLauren Wehrmeister 		    NULL, NULL, finish);
60538f89369SManish V Badarkhe #endif
60638f89369SManish V Badarkhe #elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
607*8a7505b0SLauren Wehrmeister REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL, finish);
60838f89369SManish V Badarkhe #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
609