138f89369SManish V Badarkhe /* 255aed7d7SJimmy Brisson * Copyright (c) 2023-2024, 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> 2438f89369SManish V Badarkhe #include <drivers/auth/crypto_mod.h> 2538f89369SManish V Badarkhe #include <drivers/auth/mbedtls/mbedtls_common.h> 2638f89369SManish V Badarkhe #include <plat/common/platform.h> 2738f89369SManish V Badarkhe 2838f89369SManish V Badarkhe #define LIB_NAME "mbed TLS PSA" 2938f89369SManish V Badarkhe 30*12a8e953SRyan Everett /* Minimum required size for a buffer containing a raw EC signature when using 31*12a8e953SRyan Everett * a maximum curve size of 384 bits. 32*12a8e953SRyan Everett * This is calculated as 2 * (384 / 8). */ 33*12a8e953SRyan Everett #define ECDSA_SIG_BUFFER_SIZE 96U 34255ce97dSManish V Badarkhe 35255ce97dSManish V Badarkhe /* Size of ASN.1 length and tag in bytes*/ 36255ce97dSManish V Badarkhe #define SIZE_OF_ASN1_LEN 1U 37255ce97dSManish V Badarkhe #define SIZE_OF_ASN1_TAG 1U 38255ce97dSManish V Badarkhe 3938f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 4038f89369SManish V Badarkhe CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 4138f89369SManish V Badarkhe /* 4238f89369SManish V Badarkhe * CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available 4338f89369SManish V Badarkhe * so make sure that mbed TLS MD maximum size must be lesser than this. 4438f89369SManish V Badarkhe */ 4538f89369SManish V Badarkhe CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE, 4638f89369SManish V Badarkhe assert_mbedtls_md_size_overflow); 4738f89369SManish V Badarkhe 4838f89369SManish V Badarkhe #endif /* 4938f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 5038f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 5138f89369SManish V Badarkhe */ 5238f89369SManish V Badarkhe 5338f89369SManish V Badarkhe /* 5438f89369SManish V Badarkhe * AlgorithmIdentifier ::= SEQUENCE { 5538f89369SManish V Badarkhe * algorithm OBJECT IDENTIFIER, 5638f89369SManish V Badarkhe * parameters ANY DEFINED BY algorithm OPTIONAL 5738f89369SManish V Badarkhe * } 5838f89369SManish V Badarkhe * 5938f89369SManish V Badarkhe * SubjectPublicKeyInfo ::= SEQUENCE { 6038f89369SManish V Badarkhe * algorithm AlgorithmIdentifier, 6138f89369SManish V Badarkhe * subjectPublicKey BIT STRING 6238f89369SManish V Badarkhe * } 6338f89369SManish V Badarkhe * 6438f89369SManish V Badarkhe * DigestInfo ::= SEQUENCE { 6538f89369SManish V Badarkhe * digestAlgorithm AlgorithmIdentifier, 6638f89369SManish V Badarkhe * digest OCTET STRING 6738f89369SManish V Badarkhe * } 6838f89369SManish V Badarkhe */ 6938f89369SManish V Badarkhe 7038f89369SManish V Badarkhe /* 714eaaaa19SManish V Badarkhe * We pretend using an external RNG (through MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG 724eaaaa19SManish V Badarkhe * mbedTLS config option) so we need to provide an implementation of 734eaaaa19SManish V Badarkhe * mbedtls_psa_external_get_random(). Provide a fake one, since we do not 744eaaaa19SManish V Badarkhe * actually have any external RNG and TF-A itself doesn't engage in 754eaaaa19SManish V Badarkhe * cryptographic operations that demands randomness. 764eaaaa19SManish V Badarkhe */ 774eaaaa19SManish V Badarkhe psa_status_t mbedtls_psa_external_get_random( 784eaaaa19SManish V Badarkhe mbedtls_psa_external_random_context_t *context, 794eaaaa19SManish V Badarkhe uint8_t *output, size_t output_size, 804eaaaa19SManish V Badarkhe size_t *output_length) 814eaaaa19SManish V Badarkhe { 824eaaaa19SManish V Badarkhe return PSA_ERROR_INSUFFICIENT_ENTROPY; 834eaaaa19SManish V Badarkhe } 844eaaaa19SManish V Badarkhe 854eaaaa19SManish V Badarkhe /* 8638f89369SManish V Badarkhe * Initialize the library and export the descriptor 8738f89369SManish V Badarkhe */ 8838f89369SManish V Badarkhe static void init(void) 8938f89369SManish V Badarkhe { 9038f89369SManish V Badarkhe /* Initialize mbed TLS */ 9138f89369SManish V Badarkhe mbedtls_init(); 924eaaaa19SManish V Badarkhe 934eaaaa19SManish V Badarkhe /* Initialise PSA mbedTLS */ 944eaaaa19SManish V Badarkhe psa_status_t status = psa_crypto_init(); 954eaaaa19SManish V Badarkhe 964eaaaa19SManish V Badarkhe if (status != PSA_SUCCESS) { 974eaaaa19SManish V Badarkhe ERROR("Failed to initialize %s crypto (%d).\n", LIB_NAME, status); 984eaaaa19SManish V Badarkhe panic(); 994eaaaa19SManish V Badarkhe } 1004eaaaa19SManish V Badarkhe 1014eaaaa19SManish V Badarkhe INFO("PSA crypto initialized successfully!\n"); 10238f89369SManish V Badarkhe } 10338f89369SManish V Badarkhe 10438f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 10538f89369SManish V Badarkhe CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 106eaa62e82SManish V Badarkhe 10755aed7d7SJimmy Brisson /* 10855aed7d7SJimmy Brisson * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has 10955aed7d7SJimmy Brisson * advised that it's better to copy out the declaration than it would be to 11055aed7d7SJimmy Brisson * update to 3.5.2, where this function is exposed. 11155aed7d7SJimmy Brisson */ 11255aed7d7SJimmy Brisson int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, 11355aed7d7SJimmy Brisson const mbedtls_x509_buf *sig_params, 11455aed7d7SJimmy Brisson mbedtls_md_type_t *md_alg, 11555aed7d7SJimmy Brisson mbedtls_pk_type_t *pk_alg, 11655aed7d7SJimmy Brisson void **sig_opts); 1170bc36c83SRyan Everett 1180bc36c83SRyan Everett /* 1190bc36c83SRyan Everett * This is a helper function which parses a SignatureAlgorithm OID. 1200bc36c83SRyan Everett * It extracts the pk algorithm and constructs a psa_algorithm_t object 1210bc36c83SRyan Everett * to be used by PSA calls. 1220bc36c83SRyan Everett */ 1230bc36c83SRyan Everett static int construct_psa_alg(void *sig_alg, unsigned int sig_alg_len, 1240bc36c83SRyan Everett mbedtls_pk_type_t *pk_alg, psa_algorithm_t *psa_alg) 1250bc36c83SRyan Everett { 1260bc36c83SRyan Everett int rc; 1270bc36c83SRyan Everett mbedtls_md_type_t md_alg; 1280bc36c83SRyan Everett void *sig_opts = NULL; 1290bc36c83SRyan Everett mbedtls_asn1_buf sig_alg_oid, params; 1300bc36c83SRyan Everett unsigned char *p = (unsigned char *) sig_alg; 1310bc36c83SRyan Everett unsigned char *end = (unsigned char *) sig_alg + sig_alg_len; 1320bc36c83SRyan Everett 1330bc36c83SRyan Everett rc = mbedtls_asn1_get_alg(&p, end, &sig_alg_oid, ¶ms); 1340bc36c83SRyan Everett if (rc != 0) { 1350bc36c83SRyan Everett rc = CRYPTO_ERR_SIGNATURE; 1360bc36c83SRyan Everett goto end; 1370bc36c83SRyan Everett } 1380bc36c83SRyan Everett 1390bc36c83SRyan Everett rc = mbedtls_x509_get_sig_alg(&sig_alg_oid, ¶ms, &md_alg, pk_alg, &sig_opts); 1400bc36c83SRyan Everett if (rc != 0) { 1410bc36c83SRyan Everett rc = CRYPTO_ERR_SIGNATURE; 1420bc36c83SRyan Everett goto end; 1430bc36c83SRyan Everett } 1440bc36c83SRyan Everett 1450bc36c83SRyan Everett psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 1460bc36c83SRyan Everett 1470bc36c83SRyan Everett switch (*pk_alg) { 1480bc36c83SRyan Everett case MBEDTLS_PK_RSASSA_PSS: 1490bc36c83SRyan Everett *psa_alg = PSA_ALG_RSA_PSS(psa_md_alg); 1500bc36c83SRyan Everett rc = CRYPTO_SUCCESS; 1510bc36c83SRyan Everett break; 1520bc36c83SRyan Everett case MBEDTLS_PK_ECDSA: 1530bc36c83SRyan Everett *psa_alg = PSA_ALG_ECDSA(psa_md_alg); 1540bc36c83SRyan Everett rc = CRYPTO_SUCCESS; 1550bc36c83SRyan Everett break; 1560bc36c83SRyan Everett default: 1570bc36c83SRyan Everett *psa_alg = PSA_ALG_NONE; 1580bc36c83SRyan Everett rc = CRYPTO_ERR_SIGNATURE; 1590bc36c83SRyan Everett break; 1600bc36c83SRyan Everett } 1610bc36c83SRyan Everett 1620bc36c83SRyan Everett end: 1630bc36c83SRyan Everett mbedtls_free(sig_opts); 1640bc36c83SRyan Everett return rc; 1650bc36c83SRyan Everett } 1660bc36c83SRyan Everett 1670bc36c83SRyan Everett /* 1680bc36c83SRyan Everett * Helper functions for mbedtls PK contexts. 1690bc36c83SRyan Everett */ 1700bc36c83SRyan Everett static void initialize_pk_context(mbedtls_pk_context *pk, bool *pk_initialized) 1710bc36c83SRyan Everett { 1720bc36c83SRyan Everett mbedtls_pk_init(pk); 1730bc36c83SRyan Everett *pk_initialized = true; 1740bc36c83SRyan Everett } 1750bc36c83SRyan Everett 1760bc36c83SRyan Everett static void cleanup_pk_context(mbedtls_pk_context *pk, bool *pk_initialized) 1770bc36c83SRyan Everett { 1780bc36c83SRyan Everett if (*pk_initialized) { 1790bc36c83SRyan Everett mbedtls_pk_free(pk); 1800bc36c83SRyan Everett *pk_initialized = false; 1810bc36c83SRyan Everett } 1820bc36c83SRyan Everett } 1830bc36c83SRyan Everett 18455aed7d7SJimmy Brisson /* 18538f89369SManish V Badarkhe * Verify a signature. 18638f89369SManish V Badarkhe * 18738f89369SManish V Badarkhe * Parameters are passed using the DER encoding format following the ASN.1 18838f89369SManish V Badarkhe * structures detailed above. 18938f89369SManish V Badarkhe */ 19038f89369SManish V Badarkhe static int verify_signature(void *data_ptr, unsigned int data_len, 19138f89369SManish V Badarkhe void *sig_ptr, unsigned int sig_len, 19238f89369SManish V Badarkhe void *sig_alg, unsigned int sig_alg_len, 19338f89369SManish V Badarkhe void *pk_ptr, unsigned int pk_len) 19438f89369SManish V Badarkhe { 19538f89369SManish V Badarkhe unsigned char *p, *end; 1960bc36c83SRyan Everett mbedtls_pk_context pk; 1970bc36c83SRyan Everett bool pk_initialized = false; 1980bc36c83SRyan Everett int rc = CRYPTO_ERR_SIGNATURE; 1990bc36c83SRyan Everett psa_status_t psa_status = PSA_ERROR_CORRUPTION_DETECTED; 2000bc36c83SRyan Everett psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT; 2010bc36c83SRyan Everett psa_key_id_t psa_key_id; 2020bc36c83SRyan Everett mbedtls_pk_type_t pk_alg; 2030bc36c83SRyan Everett psa_algorithm_t psa_alg; 204*12a8e953SRyan Everett __unused unsigned char reformatted_sig[ECDSA_SIG_BUFFER_SIZE] = {0}; 205255ce97dSManish V Badarkhe unsigned char *local_sig_ptr; 206255ce97dSManish V Badarkhe size_t local_sig_len; 207eaa62e82SManish V Badarkhe 2080bc36c83SRyan Everett /* Load the key into the PSA key store. */ 2090bc36c83SRyan Everett initialize_pk_context(&pk, &pk_initialized); 21038f89369SManish V Badarkhe 2110bc36c83SRyan Everett p = (unsigned char *) pk_ptr; 2120bc36c83SRyan Everett end = p + pk_len; 2130bc36c83SRyan Everett rc = mbedtls_pk_parse_subpubkey(&p, end, &pk); 21438f89369SManish V Badarkhe if (rc != 0) { 21538f89369SManish V Badarkhe rc = CRYPTO_ERR_SIGNATURE; 216eaa62e82SManish V Badarkhe goto end2; 21738f89369SManish V Badarkhe } 218255ce97dSManish V Badarkhe 2190bc36c83SRyan Everett rc = mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_VERIFY_MESSAGE, &psa_key_attr); 2200bc36c83SRyan Everett if (rc != 0) { 2210bc36c83SRyan Everett rc = CRYPTO_ERR_SIGNATURE; 2220bc36c83SRyan Everett goto end2; 2230bc36c83SRyan Everett } 2240bc36c83SRyan Everett 2250bc36c83SRyan Everett rc = construct_psa_alg(sig_alg, sig_alg_len, &pk_alg, &psa_alg); 2260bc36c83SRyan Everett if (rc != CRYPTO_SUCCESS) { 2270bc36c83SRyan Everett goto end2; 2280bc36c83SRyan Everett } 2290bc36c83SRyan Everett psa_set_key_algorithm(&psa_key_attr, psa_alg); 2300bc36c83SRyan Everett 2310bc36c83SRyan Everett rc = mbedtls_pk_import_into_psa(&pk, &psa_key_attr, &psa_key_id); 2320bc36c83SRyan Everett if (rc != 0) { 2330bc36c83SRyan Everett rc = CRYPTO_ERR_SIGNATURE; 2340bc36c83SRyan Everett goto end2; 2350bc36c83SRyan Everett } 2360bc36c83SRyan Everett 2370bc36c83SRyan Everett /* Optimize mbedtls heap usage by freeing the pk context now. */ 2380bc36c83SRyan Everett cleanup_pk_context(&pk, &pk_initialized); 2390bc36c83SRyan Everett 2400bc36c83SRyan Everett /* Extract the signature from sig_ptr. */ 2410bc36c83SRyan Everett p = (unsigned char *) sig_ptr; 2420bc36c83SRyan Everett end = p + sig_len; 2430bc36c83SRyan Everett rc = mbedtls_asn1_get_bitstring_null(&p, end, &local_sig_len); 2440bc36c83SRyan Everett if (rc != 0) { 2450bc36c83SRyan Everett rc = CRYPTO_ERR_SIGNATURE; 2460bc36c83SRyan Everett goto end1; 2470bc36c83SRyan Everett } 248255ce97dSManish V Badarkhe local_sig_ptr = p; 249255ce97dSManish V Badarkhe 250255ce97dSManish V Badarkhe #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \ 251255ce97dSManish V Badarkhe TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA 252255ce97dSManish V Badarkhe if (pk_alg == MBEDTLS_PK_ECDSA) { 2530bc36c83SRyan Everett /* Convert the DER ASN.1 signature to raw format. */ 2540bc36c83SRyan Everett size_t key_bits = psa_get_key_bits(&psa_key_attr); 255255ce97dSManish V Badarkhe 2560bc36c83SRyan Everett rc = mbedtls_ecdsa_der_to_raw(key_bits, p, local_sig_len, 257*12a8e953SRyan Everett reformatted_sig, ECDSA_SIG_BUFFER_SIZE, 2580bc36c83SRyan Everett &local_sig_len); 2590bc36c83SRyan Everett if (rc != 0) { 2600bc36c83SRyan Everett rc = CRYPTO_ERR_SIGNATURE; 2610bc36c83SRyan Everett goto end1; 2620bc36c83SRyan Everett } 263255ce97dSManish V Badarkhe local_sig_ptr = reformatted_sig; 264255ce97dSManish V Badarkhe } 265255ce97dSManish V Badarkhe #endif /* 266255ce97dSManish V Badarkhe * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \ 267255ce97dSManish V Badarkhe * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA 268255ce97dSManish V Badarkhe **/ 26938f89369SManish V Badarkhe 2700bc36c83SRyan Everett /* Verify the signature. */ 2710bc36c83SRyan Everett psa_status = psa_verify_message(psa_key_id, psa_alg, 272eaa62e82SManish V Badarkhe data_ptr, data_len, 273255ce97dSManish V Badarkhe local_sig_ptr, local_sig_len); 2740bc36c83SRyan Everett if (psa_status == PSA_SUCCESS) { 2750bc36c83SRyan Everett /* The signature has been successfully verified. */ 2760bc36c83SRyan Everett rc = CRYPTO_SUCCESS; 2770bc36c83SRyan Everett } else { 27838f89369SManish V Badarkhe rc = CRYPTO_ERR_SIGNATURE; 27938f89369SManish V Badarkhe } 28038f89369SManish V Badarkhe 28138f89369SManish V Badarkhe end1: 2820bc36c83SRyan Everett /* Destroy the key from the PSA subsystem. */ 283eaa62e82SManish V Badarkhe psa_destroy_key(psa_key_id); 28438f89369SManish V Badarkhe end2: 2850bc36c83SRyan Everett /* Free the pk context, if it is initialized. */ 2860bc36c83SRyan Everett cleanup_pk_context(&pk, &pk_initialized); 2870bc36c83SRyan Everett 28838f89369SManish V Badarkhe return rc; 28938f89369SManish V Badarkhe } 29038f89369SManish V Badarkhe 29138f89369SManish V Badarkhe /* 29238f89369SManish V Badarkhe * Match a hash 29338f89369SManish V Badarkhe * 29438f89369SManish V Badarkhe * Digest info is passed in DER format following the ASN.1 structure detailed 29538f89369SManish V Badarkhe * above. 29638f89369SManish V Badarkhe */ 29738f89369SManish V Badarkhe static int verify_hash(void *data_ptr, unsigned int data_len, 29838f89369SManish V Badarkhe void *digest_info_ptr, unsigned int digest_info_len) 29938f89369SManish V Badarkhe { 30038f89369SManish V Badarkhe mbedtls_asn1_buf hash_oid, params; 30138f89369SManish V Badarkhe mbedtls_md_type_t md_alg; 30238f89369SManish V Badarkhe unsigned char *p, *end, *hash; 30338f89369SManish V Badarkhe size_t len; 30438f89369SManish V Badarkhe int rc; 3052ed061c4SManish V Badarkhe psa_status_t status; 3062ed061c4SManish V Badarkhe psa_algorithm_t psa_md_alg; 30738f89369SManish V Badarkhe 30838f89369SManish V Badarkhe /* 30938f89369SManish V Badarkhe * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after 31038f89369SManish V Badarkhe * it is allowed. This is necessary to support multiple hash 31138f89369SManish V Badarkhe * algorithms. 31238f89369SManish V Badarkhe */ 31338f89369SManish V Badarkhe p = (unsigned char *)digest_info_ptr; 31438f89369SManish V Badarkhe end = p + digest_info_len; 31538f89369SManish V Badarkhe rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | 31638f89369SManish V Badarkhe MBEDTLS_ASN1_SEQUENCE); 31738f89369SManish V Badarkhe if (rc != 0) { 31838f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 31938f89369SManish V Badarkhe } 32038f89369SManish V Badarkhe 32138f89369SManish V Badarkhe end = p + len; 32238f89369SManish V Badarkhe 32338f89369SManish V Badarkhe /* Get the hash algorithm */ 32438f89369SManish V Badarkhe rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms); 32538f89369SManish V Badarkhe if (rc != 0) { 32638f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 32738f89369SManish V Badarkhe } 32838f89369SManish V Badarkhe 32938f89369SManish V Badarkhe /* Hash should be octet string type and consume all bytes */ 33038f89369SManish V Badarkhe rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); 33138f89369SManish V Badarkhe if ((rc != 0) || ((size_t)(end - p) != len)) { 33238f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 33338f89369SManish V Badarkhe } 33438f89369SManish V Badarkhe hash = p; 33538f89369SManish V Badarkhe 3362ed061c4SManish V Badarkhe rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg); 33738f89369SManish V Badarkhe if (rc != 0) { 33838f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 33938f89369SManish V Badarkhe } 34038f89369SManish V Badarkhe 3412ed061c4SManish V Badarkhe /* convert the md_alg to psa_algo */ 3422ed061c4SManish V Badarkhe psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 3432ed061c4SManish V Badarkhe 3442ed061c4SManish V Badarkhe /* Length of hash must match the algorithm's size */ 3452ed061c4SManish V Badarkhe if (len != PSA_HASH_LENGTH(psa_md_alg)) { 3462ed061c4SManish V Badarkhe return CRYPTO_ERR_HASH; 3472ed061c4SManish V Badarkhe } 3482ed061c4SManish V Badarkhe 3492ed061c4SManish V Badarkhe /* 3502ed061c4SManish V Badarkhe * Calculate Hash and compare it against the retrieved hash from 3512ed061c4SManish V Badarkhe * the certificate (one shot API). 3522ed061c4SManish V Badarkhe */ 3532ed061c4SManish V Badarkhe status = psa_hash_compare(psa_md_alg, 3542ed061c4SManish V Badarkhe data_ptr, (size_t)data_len, 3552ed061c4SManish V Badarkhe (const uint8_t *)hash, len); 3562ed061c4SManish V Badarkhe 3572ed061c4SManish V Badarkhe if (status != PSA_SUCCESS) { 35838f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 35938f89369SManish V Badarkhe } 36038f89369SManish V Badarkhe 36138f89369SManish V Badarkhe return CRYPTO_SUCCESS; 36238f89369SManish V Badarkhe } 36338f89369SManish V Badarkhe #endif /* 36438f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 36538f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 36638f89369SManish V Badarkhe */ 36738f89369SManish V Badarkhe 36838f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 36938f89369SManish V Badarkhe CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 37038f89369SManish V Badarkhe /* 37138f89369SManish V Badarkhe * Map a generic crypto message digest algorithm to the corresponding macro used 37238f89369SManish V Badarkhe * by Mbed TLS. 37338f89369SManish V Badarkhe */ 37438f89369SManish V Badarkhe static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo) 37538f89369SManish V Badarkhe { 37638f89369SManish V Badarkhe switch (algo) { 37738f89369SManish V Badarkhe case CRYPTO_MD_SHA512: 37838f89369SManish V Badarkhe return MBEDTLS_MD_SHA512; 37938f89369SManish V Badarkhe case CRYPTO_MD_SHA384: 38038f89369SManish V Badarkhe return MBEDTLS_MD_SHA384; 38138f89369SManish V Badarkhe case CRYPTO_MD_SHA256: 38238f89369SManish V Badarkhe return MBEDTLS_MD_SHA256; 38338f89369SManish V Badarkhe default: 38438f89369SManish V Badarkhe /* Invalid hash algorithm. */ 38538f89369SManish V Badarkhe return MBEDTLS_MD_NONE; 38638f89369SManish V Badarkhe } 38738f89369SManish V Badarkhe } 38838f89369SManish V Badarkhe 38938f89369SManish V Badarkhe /* 39038f89369SManish V Badarkhe * Calculate a hash 39138f89369SManish V Badarkhe * 39238f89369SManish V Badarkhe * output points to the computed hash 39338f89369SManish V Badarkhe */ 39438f89369SManish V Badarkhe static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr, 39538f89369SManish V Badarkhe unsigned int data_len, 39638f89369SManish V Badarkhe unsigned char output[CRYPTO_MD_MAX_SIZE]) 39738f89369SManish V Badarkhe { 398484b5869SManish V Badarkhe size_t hash_length; 399484b5869SManish V Badarkhe psa_status_t status; 400484b5869SManish V Badarkhe psa_algorithm_t psa_md_alg; 40138f89369SManish V Badarkhe 402484b5869SManish V Badarkhe /* convert the md_alg to psa_algo */ 403484b5869SManish V Badarkhe psa_md_alg = mbedtls_md_psa_alg_from_type(md_type(md_algo)); 40438f89369SManish V Badarkhe 40538f89369SManish V Badarkhe /* 40638f89369SManish V Badarkhe * Calculate the hash of the data, it is safe to pass the 40738f89369SManish V Badarkhe * 'output' hash buffer pointer considering its size is always 40838f89369SManish V Badarkhe * bigger than or equal to MBEDTLS_MD_MAX_SIZE. 40938f89369SManish V Badarkhe */ 410484b5869SManish V Badarkhe status = psa_hash_compute(psa_md_alg, data_ptr, (size_t)data_len, 411484b5869SManish V Badarkhe (uint8_t *)output, CRYPTO_MD_MAX_SIZE, 412484b5869SManish V Badarkhe &hash_length); 413484b5869SManish V Badarkhe if (status != PSA_SUCCESS) { 414484b5869SManish V Badarkhe return CRYPTO_ERR_HASH; 415484b5869SManish V Badarkhe } 416484b5869SManish V Badarkhe 417484b5869SManish V Badarkhe return CRYPTO_SUCCESS; 41838f89369SManish V Badarkhe } 41938f89369SManish V Badarkhe #endif /* 42038f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 42138f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 42238f89369SManish V Badarkhe */ 42338f89369SManish V Badarkhe 42438f89369SManish V Badarkhe #if TF_MBEDTLS_USE_AES_GCM 42538f89369SManish V Badarkhe /* 42638f89369SManish V Badarkhe * Stack based buffer allocation for decryption operation. It could 42738f89369SManish V Badarkhe * be configured to balance stack usage vs execution speed. 42838f89369SManish V Badarkhe */ 42938f89369SManish V Badarkhe #define DEC_OP_BUF_SIZE 128 43038f89369SManish V Badarkhe 43138f89369SManish V Badarkhe static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key, 43238f89369SManish V Badarkhe unsigned int key_len, const void *iv, 43338f89369SManish V Badarkhe unsigned int iv_len, const void *tag, 43438f89369SManish V Badarkhe unsigned int tag_len) 43538f89369SManish V Badarkhe { 4367079ddf9SRyan Everett mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; 4377079ddf9SRyan Everett psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; 4387079ddf9SRyan Everett psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 4397079ddf9SRyan Everett psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; 44038f89369SManish V Badarkhe unsigned char buf[DEC_OP_BUF_SIZE]; 44138f89369SManish V Badarkhe unsigned char *pt = data_ptr; 44238f89369SManish V Badarkhe size_t dec_len; 4437079ddf9SRyan Everett size_t output_length; 44438f89369SManish V Badarkhe 4457079ddf9SRyan Everett /* Load the key into the PSA key store. */ 4467079ddf9SRyan Everett psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); 4477079ddf9SRyan Everett psa_set_key_algorithm(&attributes, PSA_ALG_GCM); 4487079ddf9SRyan Everett psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); 44938f89369SManish V Badarkhe 4507079ddf9SRyan Everett psa_status = psa_import_key(&attributes, key, key_len, &key_id); 4517079ddf9SRyan Everett if (psa_status != PSA_SUCCESS) { 4527079ddf9SRyan Everett return CRYPTO_ERR_DECRYPTION; 45338f89369SManish V Badarkhe } 45438f89369SManish V Badarkhe 4557079ddf9SRyan Everett /* Perform the decryption. */ 4567079ddf9SRyan Everett psa_status = psa_aead_decrypt_setup(&operation, key_id, PSA_ALG_GCM); 4577079ddf9SRyan Everett if (psa_status != PSA_SUCCESS) { 4587079ddf9SRyan Everett goto err; 4597079ddf9SRyan Everett } 4607079ddf9SRyan Everett 4617079ddf9SRyan Everett psa_status = psa_aead_set_nonce(&operation, iv, iv_len); 4627079ddf9SRyan Everett if (psa_status != PSA_SUCCESS) { 4637079ddf9SRyan Everett goto err; 46438f89369SManish V Badarkhe } 46538f89369SManish V Badarkhe 46638f89369SManish V Badarkhe while (len > 0) { 46738f89369SManish V Badarkhe dec_len = MIN(sizeof(buf), len); 46838f89369SManish V Badarkhe 4697079ddf9SRyan Everett psa_status = psa_aead_update(&operation, pt, dec_len, buf, 4707079ddf9SRyan Everett sizeof(buf), &output_length); 4717079ddf9SRyan Everett if (psa_status != PSA_SUCCESS) { 4727079ddf9SRyan Everett goto err; 47338f89369SManish V Badarkhe } 47438f89369SManish V Badarkhe 4757079ddf9SRyan Everett memcpy(pt, buf, output_length); 4767079ddf9SRyan Everett pt += output_length; 47738f89369SManish V Badarkhe len -= dec_len; 47838f89369SManish V Badarkhe } 47938f89369SManish V Badarkhe 4807079ddf9SRyan Everett /* Verify the tag. */ 4817079ddf9SRyan Everett psa_status = psa_aead_verify(&operation, NULL, 0, &output_length, tag, tag_len); 4827079ddf9SRyan Everett if (psa_status == PSA_SUCCESS) { 4837079ddf9SRyan Everett psa_destroy_key(key_id); 4847079ddf9SRyan Everett return CRYPTO_SUCCESS; 48538f89369SManish V Badarkhe } 48638f89369SManish V Badarkhe 4877079ddf9SRyan Everett err: 4887079ddf9SRyan Everett psa_aead_abort(&operation); 4897079ddf9SRyan Everett psa_destroy_key(key_id); 4907079ddf9SRyan Everett return CRYPTO_ERR_DECRYPTION; 49138f89369SManish V Badarkhe } 49238f89369SManish V Badarkhe 49338f89369SManish V Badarkhe /* 49438f89369SManish V Badarkhe * Authenticated decryption of an image 49538f89369SManish V Badarkhe */ 49638f89369SManish V Badarkhe static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, 49738f89369SManish V Badarkhe size_t len, const void *key, unsigned int key_len, 49838f89369SManish V Badarkhe unsigned int key_flags, const void *iv, 49938f89369SManish V Badarkhe unsigned int iv_len, const void *tag, 50038f89369SManish V Badarkhe unsigned int tag_len) 50138f89369SManish V Badarkhe { 50238f89369SManish V Badarkhe int rc; 50338f89369SManish V Badarkhe 50438f89369SManish V Badarkhe assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0); 50538f89369SManish V Badarkhe 50638f89369SManish V Badarkhe switch (dec_algo) { 50738f89369SManish V Badarkhe case CRYPTO_GCM_DECRYPT: 50838f89369SManish V Badarkhe rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len, 50938f89369SManish V Badarkhe tag, tag_len); 51038f89369SManish V Badarkhe if (rc != 0) 51138f89369SManish V Badarkhe return rc; 51238f89369SManish V Badarkhe break; 51338f89369SManish V Badarkhe default: 51438f89369SManish V Badarkhe return CRYPTO_ERR_DECRYPTION; 51538f89369SManish V Badarkhe } 51638f89369SManish V Badarkhe 51738f89369SManish V Badarkhe return CRYPTO_SUCCESS; 51838f89369SManish V Badarkhe } 51938f89369SManish V Badarkhe #endif /* TF_MBEDTLS_USE_AES_GCM */ 52038f89369SManish V Badarkhe 52138f89369SManish V Badarkhe /* 52238f89369SManish V Badarkhe * Register crypto library descriptor 52338f89369SManish V Badarkhe */ 52438f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 52538f89369SManish V Badarkhe #if TF_MBEDTLS_USE_AES_GCM 52638f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, 52738f89369SManish V Badarkhe auth_decrypt, NULL); 52838f89369SManish V Badarkhe #else 52938f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, 53038f89369SManish V Badarkhe NULL, NULL); 53138f89369SManish V Badarkhe #endif 53238f89369SManish V Badarkhe #elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY 53338f89369SManish V Badarkhe #if TF_MBEDTLS_USE_AES_GCM 53438f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, 53538f89369SManish V Badarkhe auth_decrypt, NULL); 53638f89369SManish V Badarkhe #else 53738f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, 53838f89369SManish V Badarkhe NULL, NULL); 53938f89369SManish V Badarkhe #endif 54038f89369SManish V Badarkhe #elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY 54138f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL); 54238f89369SManish V Badarkhe #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */ 543