138f89369SManish V Badarkhe /* 2*55aed7d7SJimmy 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/gcm.h> 1338f89369SManish V Badarkhe #include <mbedtls/md.h> 1438f89369SManish V Badarkhe #include <mbedtls/memory_buffer_alloc.h> 1538f89369SManish V Badarkhe #include <mbedtls/oid.h> 1638f89369SManish V Badarkhe #include <mbedtls/platform.h> 17*55aed7d7SJimmy Brisson #include <mbedtls/psa_util.h> 1838f89369SManish V Badarkhe #include <mbedtls/version.h> 1938f89369SManish V Badarkhe #include <mbedtls/x509.h> 204eaaaa19SManish V Badarkhe #include <psa/crypto.h> 214eaaaa19SManish V Badarkhe #include <psa/crypto_platform.h> 224eaaaa19SManish V Badarkhe #include <psa/crypto_types.h> 234eaaaa19SManish V Badarkhe #include <psa/crypto_values.h> 2438f89369SManish V Badarkhe 2538f89369SManish V Badarkhe #include <common/debug.h> 2638f89369SManish V Badarkhe #include <drivers/auth/crypto_mod.h> 2738f89369SManish V Badarkhe #include <drivers/auth/mbedtls/mbedtls_common.h> 2838f89369SManish V Badarkhe #include <plat/common/platform.h> 2938f89369SManish V Badarkhe 3038f89369SManish V Badarkhe #define LIB_NAME "mbed TLS PSA" 3138f89369SManish V Badarkhe 32255ce97dSManish V Badarkhe /* Maximum length of R_S pair in the ECDSA signature in bytes */ 33255ce97dSManish V Badarkhe #define MAX_ECDSA_R_S_PAIR_LEN 64U 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 107eaa62e82SManish V Badarkhe static void construct_psa_key_alg_and_type(mbedtls_pk_type_t pk_alg, 108eaa62e82SManish V Badarkhe mbedtls_md_type_t md_alg, 109255ce97dSManish V Badarkhe psa_ecc_family_t psa_ecc_family, 110eaa62e82SManish V Badarkhe psa_algorithm_t *psa_alg, 111eaa62e82SManish V Badarkhe psa_key_type_t *psa_key_type) 112eaa62e82SManish V Badarkhe { 113eaa62e82SManish V Badarkhe psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 114eaa62e82SManish V Badarkhe 115eaa62e82SManish V Badarkhe switch (pk_alg) { 116eaa62e82SManish V Badarkhe case MBEDTLS_PK_RSASSA_PSS: 117eaa62e82SManish V Badarkhe *psa_alg = PSA_ALG_RSA_PSS(psa_md_alg); 118eaa62e82SManish V Badarkhe *psa_key_type = PSA_KEY_TYPE_RSA_PUBLIC_KEY; 119eaa62e82SManish V Badarkhe break; 120255ce97dSManish V Badarkhe case MBEDTLS_PK_ECDSA: 121255ce97dSManish V Badarkhe *psa_alg = PSA_ALG_ECDSA(psa_md_alg); 122255ce97dSManish V Badarkhe *psa_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_ecc_family); 123255ce97dSManish V Badarkhe break; 124eaa62e82SManish V Badarkhe default: 125eaa62e82SManish V Badarkhe *psa_alg = PSA_ALG_NONE; 126eaa62e82SManish V Badarkhe *psa_key_type = PSA_KEY_TYPE_NONE; 127eaa62e82SManish V Badarkhe break; 128eaa62e82SManish V Badarkhe } 129eaa62e82SManish V Badarkhe } 130eaa62e82SManish V Badarkhe 131255ce97dSManish V Badarkhe 132255ce97dSManish V Badarkhe #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \ 133255ce97dSManish V Badarkhe TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA 134255ce97dSManish V Badarkhe 135255ce97dSManish V Badarkhe /* 136255ce97dSManish V Badarkhe * This is a helper function to detect padding byte (if the MSB bit of the 137255ce97dSManish V Badarkhe * first data byte is set to 1, for example 0x80) and on detection, ignore the 138255ce97dSManish V Badarkhe * padded byte(0x00) and increase the buffer pointer beyond padded byte and 139255ce97dSManish V Badarkhe * decrease the length of the buffer by 1. 140255ce97dSManish V Badarkhe * 141255ce97dSManish V Badarkhe * On Success returns 0, error otherwise. 142255ce97dSManish V Badarkhe **/ 143255ce97dSManish V Badarkhe static inline int ignore_asn1_int_padding_byte(unsigned char **buf_start, 144255ce97dSManish V Badarkhe size_t *buf_len) 145255ce97dSManish V Badarkhe { 146255ce97dSManish V Badarkhe unsigned char *local_buf = *buf_start; 147255ce97dSManish V Badarkhe 148255ce97dSManish V Badarkhe /* Check for negative number */ 149255ce97dSManish V Badarkhe if ((local_buf[0] & 0x80U) != 0U) { 150255ce97dSManish V Badarkhe return -1; 151255ce97dSManish V Badarkhe } 152255ce97dSManish V Badarkhe 153255ce97dSManish V Badarkhe if ((local_buf[0] == 0U) && (local_buf[1] > 0x7FU) && 154255ce97dSManish V Badarkhe (*buf_len > 1U)) { 155255ce97dSManish V Badarkhe *buf_start = &local_buf[1]; 156255ce97dSManish V Badarkhe (*buf_len)--; 157255ce97dSManish V Badarkhe } 158255ce97dSManish V Badarkhe 159255ce97dSManish V Badarkhe return 0; 160255ce97dSManish V Badarkhe } 161255ce97dSManish V Badarkhe 162255ce97dSManish V Badarkhe /* 163255ce97dSManish V Badarkhe * This is a helper function that gets a pointer to the encoded ECDSA publicKey 164255ce97dSManish V Badarkhe * and its length (as per RFC5280) and returns corresponding decoded publicKey 165255ce97dSManish V Badarkhe * and its length. As well, it retrieves the family of ECC key in the PSA 166255ce97dSManish V Badarkhe * format. 167255ce97dSManish V Badarkhe * 168255ce97dSManish V Badarkhe * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure, 169255ce97dSManish V Badarkhe * otherwise success(0). 170255ce97dSManish V Badarkhe **/ 171255ce97dSManish V Badarkhe static int get_ecdsa_pkinfo_from_asn1(unsigned char **pk_start, 172255ce97dSManish V Badarkhe unsigned int *pk_len, 173255ce97dSManish V Badarkhe psa_ecc_family_t *psa_ecc_family) 174255ce97dSManish V Badarkhe { 175255ce97dSManish V Badarkhe mbedtls_asn1_buf alg_oid, alg_params; 176255ce97dSManish V Badarkhe mbedtls_ecp_group_id grp_id; 177255ce97dSManish V Badarkhe int rc; 178255ce97dSManish V Badarkhe unsigned char *pk_end; 179255ce97dSManish V Badarkhe size_t len; 180255ce97dSManish V Badarkhe size_t curve_bits; 181255ce97dSManish V Badarkhe unsigned char *pk_ptr = *pk_start; 182255ce97dSManish V Badarkhe 183255ce97dSManish V Badarkhe pk_end = pk_ptr + *pk_len; 184255ce97dSManish V Badarkhe rc = mbedtls_asn1_get_tag(&pk_ptr, pk_end, &len, 185255ce97dSManish V Badarkhe MBEDTLS_ASN1_CONSTRUCTED | 186255ce97dSManish V Badarkhe MBEDTLS_ASN1_SEQUENCE); 187255ce97dSManish V Badarkhe if (rc != 0) { 188255ce97dSManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 189255ce97dSManish V Badarkhe } 190255ce97dSManish V Badarkhe 191255ce97dSManish V Badarkhe pk_end = pk_ptr + len; 192255ce97dSManish V Badarkhe rc = mbedtls_asn1_get_alg(&pk_ptr, pk_end, &alg_oid, &alg_params); 193255ce97dSManish V Badarkhe if (rc != 0) { 194255ce97dSManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 195255ce97dSManish V Badarkhe } 196255ce97dSManish V Badarkhe 197255ce97dSManish V Badarkhe if (alg_params.tag == MBEDTLS_ASN1_OID) { 198255ce97dSManish V Badarkhe if (mbedtls_oid_get_ec_grp(&alg_params, &grp_id) != 0) { 199255ce97dSManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 200255ce97dSManish V Badarkhe } 201255ce97dSManish V Badarkhe *psa_ecc_family = mbedtls_ecc_group_to_psa(grp_id, 202255ce97dSManish V Badarkhe &curve_bits); 203255ce97dSManish V Badarkhe } else { 204255ce97dSManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 205255ce97dSManish V Badarkhe } 206255ce97dSManish V Badarkhe 207255ce97dSManish V Badarkhe pk_end = pk_ptr + len - (alg_oid.len + alg_params.len + 208255ce97dSManish V Badarkhe 2 * (SIZE_OF_ASN1_LEN + SIZE_OF_ASN1_TAG)); 209255ce97dSManish V Badarkhe rc = mbedtls_asn1_get_bitstring_null(&pk_ptr, pk_end, &len); 210255ce97dSManish V Badarkhe if (rc != 0) { 211255ce97dSManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 212255ce97dSManish V Badarkhe } 213255ce97dSManish V Badarkhe 214255ce97dSManish V Badarkhe *pk_start = pk_ptr; 215255ce97dSManish V Badarkhe *pk_len = len; 216255ce97dSManish V Badarkhe 217255ce97dSManish V Badarkhe return rc; 218255ce97dSManish V Badarkhe } 219255ce97dSManish V Badarkhe 220255ce97dSManish V Badarkhe /* 221255ce97dSManish V Badarkhe * Ecdsa-Sig-Value ::= SEQUENCE { 222255ce97dSManish V Badarkhe * r INTEGER, 223255ce97dSManish V Badarkhe * s INTEGER 224255ce97dSManish V Badarkhe * } 225255ce97dSManish V Badarkhe * 226255ce97dSManish V Badarkhe * This helper function that gets a pointer to the encoded ECDSA signature and 227255ce97dSManish V Badarkhe * its length (as per RFC5280) and returns corresponding decoded signature 228255ce97dSManish V Badarkhe * (R_S pair) and its size. 229255ce97dSManish V Badarkhe * 230255ce97dSManish V Badarkhe * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure, 231255ce97dSManish V Badarkhe * otherwise success(0). 232255ce97dSManish V Badarkhe **/ 233255ce97dSManish V Badarkhe static int get_ecdsa_signature_from_asn1(unsigned char *sig_ptr, 234255ce97dSManish V Badarkhe size_t *sig_len, 235255ce97dSManish V Badarkhe unsigned char *r_s_pair) 236255ce97dSManish V Badarkhe { 237255ce97dSManish V Badarkhe int rc; 238255ce97dSManish V Badarkhe unsigned char *sig_end; 239255ce97dSManish V Badarkhe size_t len, r_len, s_len; 240255ce97dSManish V Badarkhe 241255ce97dSManish V Badarkhe sig_end = sig_ptr + *sig_len; 242255ce97dSManish V Badarkhe rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &len, 243255ce97dSManish V Badarkhe MBEDTLS_ASN1_CONSTRUCTED | 244255ce97dSManish V Badarkhe MBEDTLS_ASN1_SEQUENCE); 245255ce97dSManish V Badarkhe if (rc != 0) { 246255ce97dSManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 247255ce97dSManish V Badarkhe } 248255ce97dSManish V Badarkhe 249255ce97dSManish V Badarkhe sig_end = sig_ptr + len; 250255ce97dSManish V Badarkhe rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &r_len, 251255ce97dSManish V Badarkhe MBEDTLS_ASN1_INTEGER); 252255ce97dSManish V Badarkhe if (rc != 0) { 253255ce97dSManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 254255ce97dSManish V Badarkhe } 255255ce97dSManish V Badarkhe 256255ce97dSManish V Badarkhe if (ignore_asn1_int_padding_byte(&sig_ptr, &r_len) != 0) { 257255ce97dSManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 258255ce97dSManish V Badarkhe } 259255ce97dSManish V Badarkhe 260255ce97dSManish V Badarkhe (void)memcpy((void *)&r_s_pair[0], (const void *)sig_ptr, r_len); 261255ce97dSManish V Badarkhe 262255ce97dSManish V Badarkhe sig_ptr = sig_ptr + r_len; 263255ce97dSManish V Badarkhe sig_end = sig_ptr + len - (r_len + (SIZE_OF_ASN1_LEN + 264255ce97dSManish V Badarkhe SIZE_OF_ASN1_TAG)); 265255ce97dSManish V Badarkhe rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &s_len, 266255ce97dSManish V Badarkhe MBEDTLS_ASN1_INTEGER); 267255ce97dSManish V Badarkhe if (rc != 0) { 268255ce97dSManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 269255ce97dSManish V Badarkhe } 270255ce97dSManish V Badarkhe 271255ce97dSManish V Badarkhe if (ignore_asn1_int_padding_byte(&sig_ptr, &s_len) != 0) { 272255ce97dSManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 273255ce97dSManish V Badarkhe } 274255ce97dSManish V Badarkhe 275255ce97dSManish V Badarkhe (void)memcpy((void *)&r_s_pair[r_len], (const void *)sig_ptr, s_len); 276255ce97dSManish V Badarkhe 277255ce97dSManish V Badarkhe *sig_len = s_len + r_len; 278255ce97dSManish V Badarkhe 279255ce97dSManish V Badarkhe return 0; 280255ce97dSManish V Badarkhe } 281255ce97dSManish V Badarkhe #endif /* 282255ce97dSManish V Badarkhe * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \ 283255ce97dSManish V Badarkhe * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA 284255ce97dSManish V Badarkhe **/ 285255ce97dSManish V Badarkhe 28638f89369SManish V Badarkhe /* 287*55aed7d7SJimmy Brisson * This is a helper function that adjusts the start of the pk_start to point to 288*55aed7d7SJimmy Brisson * the subjectPublicKey bytes within the SubjectPublicKeyInfo block. 289*55aed7d7SJimmy Brisson * 290*55aed7d7SJimmy Brisson * SubjectPublicKeyInfo ::= SEQUENCE { 291*55aed7d7SJimmy Brisson * algorithm AlgorithmIdentifier, 292*55aed7d7SJimmy Brisson * subjectPublicKey BIT STRING } 293*55aed7d7SJimmy Brisson * 294*55aed7d7SJimmy Brisson * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure, 295*55aed7d7SJimmy Brisson * otherwise success(0). 296*55aed7d7SJimmy Brisson **/ 297*55aed7d7SJimmy Brisson static int pk_bytes_from_subpubkey(unsigned char **pk_start, 298*55aed7d7SJimmy Brisson unsigned int *pk_len) 299*55aed7d7SJimmy Brisson { 300*55aed7d7SJimmy Brisson mbedtls_asn1_buf alg_oid, alg_params; 301*55aed7d7SJimmy Brisson int rc; 302*55aed7d7SJimmy Brisson unsigned char *pk_end; 303*55aed7d7SJimmy Brisson size_t len; 304*55aed7d7SJimmy Brisson unsigned char *pk_ptr = *pk_start; 305*55aed7d7SJimmy Brisson 306*55aed7d7SJimmy Brisson pk_end = pk_ptr + *pk_len; 307*55aed7d7SJimmy Brisson rc = mbedtls_asn1_get_tag(&pk_ptr, pk_end, &len, 308*55aed7d7SJimmy Brisson MBEDTLS_ASN1_CONSTRUCTED | 309*55aed7d7SJimmy Brisson MBEDTLS_ASN1_SEQUENCE); 310*55aed7d7SJimmy Brisson if (rc != 0) { 311*55aed7d7SJimmy Brisson return CRYPTO_ERR_SIGNATURE; 312*55aed7d7SJimmy Brisson } 313*55aed7d7SJimmy Brisson 314*55aed7d7SJimmy Brisson pk_end = pk_ptr + len; 315*55aed7d7SJimmy Brisson rc = mbedtls_asn1_get_alg(&pk_ptr, pk_end, &alg_oid, &alg_params); 316*55aed7d7SJimmy Brisson if (rc != 0) { 317*55aed7d7SJimmy Brisson return CRYPTO_ERR_SIGNATURE; 318*55aed7d7SJimmy Brisson } 319*55aed7d7SJimmy Brisson pk_end = pk_ptr + len - (alg_oid.len + alg_params.len + 320*55aed7d7SJimmy Brisson 2 * (SIZE_OF_ASN1_LEN + SIZE_OF_ASN1_TAG)); 321*55aed7d7SJimmy Brisson rc = mbedtls_asn1_get_bitstring_null(&pk_ptr, pk_end, &len); 322*55aed7d7SJimmy Brisson if (rc != 0) { 323*55aed7d7SJimmy Brisson return CRYPTO_ERR_SIGNATURE; 324*55aed7d7SJimmy Brisson } 325*55aed7d7SJimmy Brisson 326*55aed7d7SJimmy Brisson *pk_start = pk_ptr; 327*55aed7d7SJimmy Brisson *pk_len = len; 328*55aed7d7SJimmy Brisson 329*55aed7d7SJimmy Brisson return rc; 330*55aed7d7SJimmy Brisson } 331*55aed7d7SJimmy Brisson 332*55aed7d7SJimmy Brisson /* 333*55aed7d7SJimmy Brisson * NOTE: This has been made internal in mbedtls 3.6.0 and the mbedtls team has 334*55aed7d7SJimmy Brisson * advised that it's better to copy out the declaration than it would be to 335*55aed7d7SJimmy Brisson * update to 3.5.2, where this function is exposed. 336*55aed7d7SJimmy Brisson */ 337*55aed7d7SJimmy Brisson int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, 338*55aed7d7SJimmy Brisson const mbedtls_x509_buf *sig_params, 339*55aed7d7SJimmy Brisson mbedtls_md_type_t *md_alg, 340*55aed7d7SJimmy Brisson mbedtls_pk_type_t *pk_alg, 341*55aed7d7SJimmy Brisson void **sig_opts); 342*55aed7d7SJimmy Brisson /* 34338f89369SManish V Badarkhe * Verify a signature. 34438f89369SManish V Badarkhe * 34538f89369SManish V Badarkhe * Parameters are passed using the DER encoding format following the ASN.1 34638f89369SManish V Badarkhe * structures detailed above. 34738f89369SManish V Badarkhe */ 34838f89369SManish V Badarkhe static int verify_signature(void *data_ptr, unsigned int data_len, 34938f89369SManish V Badarkhe void *sig_ptr, unsigned int sig_len, 35038f89369SManish V Badarkhe void *sig_alg, unsigned int sig_alg_len, 35138f89369SManish V Badarkhe void *pk_ptr, unsigned int pk_len) 35238f89369SManish V Badarkhe { 35338f89369SManish V Badarkhe mbedtls_asn1_buf sig_oid, sig_params; 35438f89369SManish V Badarkhe mbedtls_asn1_buf signature; 35538f89369SManish V Badarkhe mbedtls_md_type_t md_alg; 35638f89369SManish V Badarkhe mbedtls_pk_type_t pk_alg; 35738f89369SManish V Badarkhe int rc; 35838f89369SManish V Badarkhe void *sig_opts = NULL; 35938f89369SManish V Badarkhe unsigned char *p, *end; 360255ce97dSManish V Badarkhe unsigned char *local_sig_ptr; 361255ce97dSManish V Badarkhe size_t local_sig_len; 362255ce97dSManish V Badarkhe psa_ecc_family_t psa_ecc_family = 0U; 363255ce97dSManish V Badarkhe __unused unsigned char reformatted_sig[MAX_ECDSA_R_S_PAIR_LEN] = {0}; 364eaa62e82SManish V Badarkhe 365eaa62e82SManish V Badarkhe /* construct PSA key algo and type */ 366eaa62e82SManish V Badarkhe psa_status_t status = PSA_SUCCESS; 367eaa62e82SManish V Badarkhe psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT; 368eaa62e82SManish V Badarkhe psa_key_id_t psa_key_id = PSA_KEY_ID_NULL; 369eaa62e82SManish V Badarkhe psa_key_type_t psa_key_type; 370eaa62e82SManish V Badarkhe psa_algorithm_t psa_alg; 37138f89369SManish V Badarkhe 37238f89369SManish V Badarkhe /* Get pointers to signature OID and parameters */ 37338f89369SManish V Badarkhe p = (unsigned char *)sig_alg; 37438f89369SManish V Badarkhe end = (unsigned char *)(p + sig_alg_len); 37538f89369SManish V Badarkhe rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params); 37638f89369SManish V Badarkhe if (rc != 0) { 37738f89369SManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 37838f89369SManish V Badarkhe } 37938f89369SManish V Badarkhe 38038f89369SManish V Badarkhe /* Get the actual signature algorithm (MD + PK) */ 38138f89369SManish V Badarkhe rc = mbedtls_x509_get_sig_alg(&sig_oid, &sig_params, &md_alg, &pk_alg, &sig_opts); 38238f89369SManish V Badarkhe if (rc != 0) { 38338f89369SManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 38438f89369SManish V Badarkhe } 38538f89369SManish V Badarkhe 38638f89369SManish V Badarkhe /* Get the signature (bitstring) */ 38738f89369SManish V Badarkhe p = (unsigned char *)sig_ptr; 38838f89369SManish V Badarkhe end = (unsigned char *)(p + sig_len); 38938f89369SManish V Badarkhe signature.tag = *p; 39038f89369SManish V Badarkhe rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len); 39138f89369SManish V Badarkhe if ((rc != 0) || ((size_t)(end - p) != signature.len)) { 39238f89369SManish V Badarkhe rc = CRYPTO_ERR_SIGNATURE; 393eaa62e82SManish V Badarkhe goto end2; 39438f89369SManish V Badarkhe } 395255ce97dSManish V Badarkhe 396255ce97dSManish V Badarkhe local_sig_ptr = p; 397255ce97dSManish V Badarkhe local_sig_len = signature.len; 398255ce97dSManish V Badarkhe 399255ce97dSManish V Badarkhe #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \ 400255ce97dSManish V Badarkhe TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA 401255ce97dSManish V Badarkhe if (pk_alg == MBEDTLS_PK_ECDSA) { 402255ce97dSManish V Badarkhe rc = get_ecdsa_signature_from_asn1(local_sig_ptr, 403255ce97dSManish V Badarkhe &local_sig_len, 404255ce97dSManish V Badarkhe reformatted_sig); 405255ce97dSManish V Badarkhe if (rc != 0) { 406255ce97dSManish V Badarkhe goto end2; 407255ce97dSManish V Badarkhe } 408255ce97dSManish V Badarkhe 409255ce97dSManish V Badarkhe local_sig_ptr = reformatted_sig; 410255ce97dSManish V Badarkhe 411255ce97dSManish V Badarkhe rc = get_ecdsa_pkinfo_from_asn1((unsigned char **)&pk_ptr, 412255ce97dSManish V Badarkhe &pk_len, 413255ce97dSManish V Badarkhe &psa_ecc_family); 414255ce97dSManish V Badarkhe if (rc != 0) { 415255ce97dSManish V Badarkhe goto end2; 416255ce97dSManish V Badarkhe } 417255ce97dSManish V Badarkhe } 418255ce97dSManish V Badarkhe #endif /* 419255ce97dSManish V Badarkhe * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \ 420255ce97dSManish V Badarkhe * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA 421255ce97dSManish V Badarkhe **/ 42238f89369SManish V Badarkhe 423eaa62e82SManish V Badarkhe /* Convert this pk_alg and md_alg to PSA key type and key algorithm */ 424255ce97dSManish V Badarkhe construct_psa_key_alg_and_type(pk_alg, md_alg, psa_ecc_family, 425eaa62e82SManish V Badarkhe &psa_alg, &psa_key_type); 426eaa62e82SManish V Badarkhe 427eaa62e82SManish V Badarkhe 428eaa62e82SManish V Badarkhe if ((psa_alg == PSA_ALG_NONE) || (psa_key_type == PSA_KEY_TYPE_NONE)) { 42938f89369SManish V Badarkhe rc = CRYPTO_ERR_SIGNATURE; 430eaa62e82SManish V Badarkhe goto end2; 43138f89369SManish V Badarkhe } 43238f89369SManish V Badarkhe 433eaa62e82SManish V Badarkhe /* filled-in key_attributes */ 434eaa62e82SManish V Badarkhe psa_set_key_algorithm(&psa_key_attr, psa_alg); 435eaa62e82SManish V Badarkhe psa_set_key_type(&psa_key_attr, psa_key_type); 436eaa62e82SManish V Badarkhe psa_set_key_usage_flags(&psa_key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE); 437eaa62e82SManish V Badarkhe 438*55aed7d7SJimmy Brisson /* 439*55aed7d7SJimmy Brisson * Note: In the implementation of the psa_import_key function in 440*55aed7d7SJimmy Brisson * version 3.6.0, the function expects the starting pointer of the 441*55aed7d7SJimmy Brisson * subject public key instead of the starting point of 442*55aed7d7SJimmy Brisson * SubjectPublicKeyInfo. 443*55aed7d7SJimmy Brisson * This is only needed while dealing with RSASSA_PSS (RSA Signature 444*55aed7d7SJimmy Brisson * scheme with Appendix based on Probabilistic Signature Scheme) 445*55aed7d7SJimmy Brisson * algorithm. 446*55aed7d7SJimmy Brisson */ 447*55aed7d7SJimmy Brisson if (pk_alg == MBEDTLS_PK_RSASSA_PSS) { 448*55aed7d7SJimmy Brisson rc = pk_bytes_from_subpubkey((unsigned char **) &pk_ptr, &pk_len); 449*55aed7d7SJimmy Brisson goto end2; 450*55aed7d7SJimmy Brisson } 451*55aed7d7SJimmy Brisson 452eaa62e82SManish V Badarkhe /* Get the key_id using import API */ 453eaa62e82SManish V Badarkhe status = psa_import_key(&psa_key_attr, 454eaa62e82SManish V Badarkhe pk_ptr, 455eaa62e82SManish V Badarkhe (size_t)pk_len, 456eaa62e82SManish V Badarkhe &psa_key_id); 457eaa62e82SManish V Badarkhe 458eaa62e82SManish V Badarkhe if (status != PSA_SUCCESS) { 459eaa62e82SManish V Badarkhe rc = CRYPTO_ERR_SIGNATURE; 460eaa62e82SManish V Badarkhe goto end2; 461eaa62e82SManish V Badarkhe } 462eaa62e82SManish V Badarkhe 463eaa62e82SManish V Badarkhe /* 464eaa62e82SManish V Badarkhe * Hash calculation and Signature verification of the given data payload 465eaa62e82SManish V Badarkhe * is wrapped under the psa_verify_message function. 466eaa62e82SManish V Badarkhe */ 467eaa62e82SManish V Badarkhe status = psa_verify_message(psa_key_id, psa_alg, 468eaa62e82SManish V Badarkhe data_ptr, data_len, 469255ce97dSManish V Badarkhe local_sig_ptr, local_sig_len); 470eaa62e82SManish V Badarkhe 471eaa62e82SManish V Badarkhe if (status != PSA_SUCCESS) { 47238f89369SManish V Badarkhe rc = CRYPTO_ERR_SIGNATURE; 47338f89369SManish V Badarkhe goto end1; 47438f89369SManish V Badarkhe } 47538f89369SManish V Badarkhe 47638f89369SManish V Badarkhe /* Signature verification success */ 47738f89369SManish V Badarkhe rc = CRYPTO_SUCCESS; 47838f89369SManish V Badarkhe 47938f89369SManish V Badarkhe end1: 480eaa62e82SManish V Badarkhe /* 481eaa62e82SManish V Badarkhe * Destroy the key if it is created successfully 482eaa62e82SManish V Badarkhe */ 483eaa62e82SManish V Badarkhe psa_destroy_key(psa_key_id); 48438f89369SManish V Badarkhe end2: 48538f89369SManish V Badarkhe mbedtls_free(sig_opts); 48638f89369SManish V Badarkhe return rc; 48738f89369SManish V Badarkhe } 48838f89369SManish V Badarkhe 48938f89369SManish V Badarkhe /* 49038f89369SManish V Badarkhe * Match a hash 49138f89369SManish V Badarkhe * 49238f89369SManish V Badarkhe * Digest info is passed in DER format following the ASN.1 structure detailed 49338f89369SManish V Badarkhe * above. 49438f89369SManish V Badarkhe */ 49538f89369SManish V Badarkhe static int verify_hash(void *data_ptr, unsigned int data_len, 49638f89369SManish V Badarkhe void *digest_info_ptr, unsigned int digest_info_len) 49738f89369SManish V Badarkhe { 49838f89369SManish V Badarkhe mbedtls_asn1_buf hash_oid, params; 49938f89369SManish V Badarkhe mbedtls_md_type_t md_alg; 50038f89369SManish V Badarkhe unsigned char *p, *end, *hash; 50138f89369SManish V Badarkhe size_t len; 50238f89369SManish V Badarkhe int rc; 5032ed061c4SManish V Badarkhe psa_status_t status; 5042ed061c4SManish V Badarkhe psa_algorithm_t psa_md_alg; 50538f89369SManish V Badarkhe 50638f89369SManish V Badarkhe /* 50738f89369SManish V Badarkhe * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after 50838f89369SManish V Badarkhe * it is allowed. This is necessary to support multiple hash 50938f89369SManish V Badarkhe * algorithms. 51038f89369SManish V Badarkhe */ 51138f89369SManish V Badarkhe p = (unsigned char *)digest_info_ptr; 51238f89369SManish V Badarkhe end = p + digest_info_len; 51338f89369SManish V Badarkhe rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | 51438f89369SManish V Badarkhe MBEDTLS_ASN1_SEQUENCE); 51538f89369SManish V Badarkhe if (rc != 0) { 51638f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 51738f89369SManish V Badarkhe } 51838f89369SManish V Badarkhe 51938f89369SManish V Badarkhe end = p + len; 52038f89369SManish V Badarkhe 52138f89369SManish V Badarkhe /* Get the hash algorithm */ 52238f89369SManish V Badarkhe rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms); 52338f89369SManish V Badarkhe if (rc != 0) { 52438f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 52538f89369SManish V Badarkhe } 52638f89369SManish V Badarkhe 52738f89369SManish V Badarkhe /* Hash should be octet string type and consume all bytes */ 52838f89369SManish V Badarkhe rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); 52938f89369SManish V Badarkhe if ((rc != 0) || ((size_t)(end - p) != len)) { 53038f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 53138f89369SManish V Badarkhe } 53238f89369SManish V Badarkhe hash = p; 53338f89369SManish V Badarkhe 5342ed061c4SManish V Badarkhe rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg); 53538f89369SManish V Badarkhe if (rc != 0) { 53638f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 53738f89369SManish V Badarkhe } 53838f89369SManish V Badarkhe 5392ed061c4SManish V Badarkhe /* convert the md_alg to psa_algo */ 5402ed061c4SManish V Badarkhe psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 5412ed061c4SManish V Badarkhe 5422ed061c4SManish V Badarkhe /* Length of hash must match the algorithm's size */ 5432ed061c4SManish V Badarkhe if (len != PSA_HASH_LENGTH(psa_md_alg)) { 5442ed061c4SManish V Badarkhe return CRYPTO_ERR_HASH; 5452ed061c4SManish V Badarkhe } 5462ed061c4SManish V Badarkhe 5472ed061c4SManish V Badarkhe /* 5482ed061c4SManish V Badarkhe * Calculate Hash and compare it against the retrieved hash from 5492ed061c4SManish V Badarkhe * the certificate (one shot API). 5502ed061c4SManish V Badarkhe */ 5512ed061c4SManish V Badarkhe status = psa_hash_compare(psa_md_alg, 5522ed061c4SManish V Badarkhe data_ptr, (size_t)data_len, 5532ed061c4SManish V Badarkhe (const uint8_t *)hash, len); 5542ed061c4SManish V Badarkhe 5552ed061c4SManish V Badarkhe if (status != PSA_SUCCESS) { 55638f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 55738f89369SManish V Badarkhe } 55838f89369SManish V Badarkhe 55938f89369SManish V Badarkhe return CRYPTO_SUCCESS; 56038f89369SManish V Badarkhe } 56138f89369SManish V Badarkhe #endif /* 56238f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 56338f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 56438f89369SManish V Badarkhe */ 56538f89369SManish V Badarkhe 56638f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 56738f89369SManish V Badarkhe CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 56838f89369SManish V Badarkhe /* 56938f89369SManish V Badarkhe * Map a generic crypto message digest algorithm to the corresponding macro used 57038f89369SManish V Badarkhe * by Mbed TLS. 57138f89369SManish V Badarkhe */ 57238f89369SManish V Badarkhe static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo) 57338f89369SManish V Badarkhe { 57438f89369SManish V Badarkhe switch (algo) { 57538f89369SManish V Badarkhe case CRYPTO_MD_SHA512: 57638f89369SManish V Badarkhe return MBEDTLS_MD_SHA512; 57738f89369SManish V Badarkhe case CRYPTO_MD_SHA384: 57838f89369SManish V Badarkhe return MBEDTLS_MD_SHA384; 57938f89369SManish V Badarkhe case CRYPTO_MD_SHA256: 58038f89369SManish V Badarkhe return MBEDTLS_MD_SHA256; 58138f89369SManish V Badarkhe default: 58238f89369SManish V Badarkhe /* Invalid hash algorithm. */ 58338f89369SManish V Badarkhe return MBEDTLS_MD_NONE; 58438f89369SManish V Badarkhe } 58538f89369SManish V Badarkhe } 58638f89369SManish V Badarkhe 58738f89369SManish V Badarkhe /* 58838f89369SManish V Badarkhe * Calculate a hash 58938f89369SManish V Badarkhe * 59038f89369SManish V Badarkhe * output points to the computed hash 59138f89369SManish V Badarkhe */ 59238f89369SManish V Badarkhe static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr, 59338f89369SManish V Badarkhe unsigned int data_len, 59438f89369SManish V Badarkhe unsigned char output[CRYPTO_MD_MAX_SIZE]) 59538f89369SManish V Badarkhe { 596484b5869SManish V Badarkhe size_t hash_length; 597484b5869SManish V Badarkhe psa_status_t status; 598484b5869SManish V Badarkhe psa_algorithm_t psa_md_alg; 59938f89369SManish V Badarkhe 600484b5869SManish V Badarkhe /* convert the md_alg to psa_algo */ 601484b5869SManish V Badarkhe psa_md_alg = mbedtls_md_psa_alg_from_type(md_type(md_algo)); 60238f89369SManish V Badarkhe 60338f89369SManish V Badarkhe /* 60438f89369SManish V Badarkhe * Calculate the hash of the data, it is safe to pass the 60538f89369SManish V Badarkhe * 'output' hash buffer pointer considering its size is always 60638f89369SManish V Badarkhe * bigger than or equal to MBEDTLS_MD_MAX_SIZE. 60738f89369SManish V Badarkhe */ 608484b5869SManish V Badarkhe status = psa_hash_compute(psa_md_alg, data_ptr, (size_t)data_len, 609484b5869SManish V Badarkhe (uint8_t *)output, CRYPTO_MD_MAX_SIZE, 610484b5869SManish V Badarkhe &hash_length); 611484b5869SManish V Badarkhe if (status != PSA_SUCCESS) { 612484b5869SManish V Badarkhe return CRYPTO_ERR_HASH; 613484b5869SManish V Badarkhe } 614484b5869SManish V Badarkhe 615484b5869SManish V Badarkhe return CRYPTO_SUCCESS; 61638f89369SManish V Badarkhe } 61738f89369SManish V Badarkhe #endif /* 61838f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 61938f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 62038f89369SManish V Badarkhe */ 62138f89369SManish V Badarkhe 62238f89369SManish V Badarkhe #if TF_MBEDTLS_USE_AES_GCM 62338f89369SManish V Badarkhe /* 62438f89369SManish V Badarkhe * Stack based buffer allocation for decryption operation. It could 62538f89369SManish V Badarkhe * be configured to balance stack usage vs execution speed. 62638f89369SManish V Badarkhe */ 62738f89369SManish V Badarkhe #define DEC_OP_BUF_SIZE 128 62838f89369SManish V Badarkhe 62938f89369SManish V Badarkhe static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key, 63038f89369SManish V Badarkhe unsigned int key_len, const void *iv, 63138f89369SManish V Badarkhe unsigned int iv_len, const void *tag, 63238f89369SManish V Badarkhe unsigned int tag_len) 63338f89369SManish V Badarkhe { 63438f89369SManish V Badarkhe mbedtls_gcm_context ctx; 63538f89369SManish V Badarkhe mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; 63638f89369SManish V Badarkhe unsigned char buf[DEC_OP_BUF_SIZE]; 63738f89369SManish V Badarkhe unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE]; 63838f89369SManish V Badarkhe unsigned char *pt = data_ptr; 63938f89369SManish V Badarkhe size_t dec_len; 64038f89369SManish V Badarkhe int diff, i, rc; 64138f89369SManish V Badarkhe size_t output_length __unused; 64238f89369SManish V Badarkhe 64338f89369SManish V Badarkhe mbedtls_gcm_init(&ctx); 64438f89369SManish V Badarkhe 64538f89369SManish V Badarkhe rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8); 64638f89369SManish V Badarkhe if (rc != 0) { 64738f89369SManish V Badarkhe rc = CRYPTO_ERR_DECRYPTION; 64838f89369SManish V Badarkhe goto exit_gcm; 64938f89369SManish V Badarkhe } 65038f89369SManish V Badarkhe 65138f89369SManish V Badarkhe #if (MBEDTLS_VERSION_MAJOR < 3) 65238f89369SManish V Badarkhe rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0); 65338f89369SManish V Badarkhe #else 65438f89369SManish V Badarkhe rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len); 65538f89369SManish V Badarkhe #endif 65638f89369SManish V Badarkhe if (rc != 0) { 65738f89369SManish V Badarkhe rc = CRYPTO_ERR_DECRYPTION; 65838f89369SManish V Badarkhe goto exit_gcm; 65938f89369SManish V Badarkhe } 66038f89369SManish V Badarkhe 66138f89369SManish V Badarkhe while (len > 0) { 66238f89369SManish V Badarkhe dec_len = MIN(sizeof(buf), len); 66338f89369SManish V Badarkhe 66438f89369SManish V Badarkhe #if (MBEDTLS_VERSION_MAJOR < 3) 66538f89369SManish V Badarkhe rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf); 66638f89369SManish V Badarkhe #else 66738f89369SManish V Badarkhe rc = mbedtls_gcm_update(&ctx, pt, dec_len, buf, sizeof(buf), &output_length); 66838f89369SManish V Badarkhe #endif 66938f89369SManish V Badarkhe 67038f89369SManish V Badarkhe if (rc != 0) { 67138f89369SManish V Badarkhe rc = CRYPTO_ERR_DECRYPTION; 67238f89369SManish V Badarkhe goto exit_gcm; 67338f89369SManish V Badarkhe } 67438f89369SManish V Badarkhe 67538f89369SManish V Badarkhe memcpy(pt, buf, dec_len); 67638f89369SManish V Badarkhe pt += dec_len; 67738f89369SManish V Badarkhe len -= dec_len; 67838f89369SManish V Badarkhe } 67938f89369SManish V Badarkhe 68038f89369SManish V Badarkhe #if (MBEDTLS_VERSION_MAJOR < 3) 68138f89369SManish V Badarkhe rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf)); 68238f89369SManish V Badarkhe #else 68338f89369SManish V Badarkhe rc = mbedtls_gcm_finish(&ctx, NULL, 0, &output_length, tag_buf, sizeof(tag_buf)); 68438f89369SManish V Badarkhe #endif 68538f89369SManish V Badarkhe 68638f89369SManish V Badarkhe if (rc != 0) { 68738f89369SManish V Badarkhe rc = CRYPTO_ERR_DECRYPTION; 68838f89369SManish V Badarkhe goto exit_gcm; 68938f89369SManish V Badarkhe } 69038f89369SManish V Badarkhe 69138f89369SManish V Badarkhe /* Check tag in "constant-time" */ 69238f89369SManish V Badarkhe for (diff = 0, i = 0; i < tag_len; i++) 69338f89369SManish V Badarkhe diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i]; 69438f89369SManish V Badarkhe 69538f89369SManish V Badarkhe if (diff != 0) { 69638f89369SManish V Badarkhe rc = CRYPTO_ERR_DECRYPTION; 69738f89369SManish V Badarkhe goto exit_gcm; 69838f89369SManish V Badarkhe } 69938f89369SManish V Badarkhe 70038f89369SManish V Badarkhe /* GCM decryption success */ 70138f89369SManish V Badarkhe rc = CRYPTO_SUCCESS; 70238f89369SManish V Badarkhe 70338f89369SManish V Badarkhe exit_gcm: 70438f89369SManish V Badarkhe mbedtls_gcm_free(&ctx); 70538f89369SManish V Badarkhe return rc; 70638f89369SManish V Badarkhe } 70738f89369SManish V Badarkhe 70838f89369SManish V Badarkhe /* 70938f89369SManish V Badarkhe * Authenticated decryption of an image 71038f89369SManish V Badarkhe */ 71138f89369SManish V Badarkhe static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, 71238f89369SManish V Badarkhe size_t len, const void *key, unsigned int key_len, 71338f89369SManish V Badarkhe unsigned int key_flags, const void *iv, 71438f89369SManish V Badarkhe unsigned int iv_len, const void *tag, 71538f89369SManish V Badarkhe unsigned int tag_len) 71638f89369SManish V Badarkhe { 71738f89369SManish V Badarkhe int rc; 71838f89369SManish V Badarkhe 71938f89369SManish V Badarkhe assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0); 72038f89369SManish V Badarkhe 72138f89369SManish V Badarkhe switch (dec_algo) { 72238f89369SManish V Badarkhe case CRYPTO_GCM_DECRYPT: 72338f89369SManish V Badarkhe rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len, 72438f89369SManish V Badarkhe tag, tag_len); 72538f89369SManish V Badarkhe if (rc != 0) 72638f89369SManish V Badarkhe return rc; 72738f89369SManish V Badarkhe break; 72838f89369SManish V Badarkhe default: 72938f89369SManish V Badarkhe return CRYPTO_ERR_DECRYPTION; 73038f89369SManish V Badarkhe } 73138f89369SManish V Badarkhe 73238f89369SManish V Badarkhe return CRYPTO_SUCCESS; 73338f89369SManish V Badarkhe } 73438f89369SManish V Badarkhe #endif /* TF_MBEDTLS_USE_AES_GCM */ 73538f89369SManish V Badarkhe 73638f89369SManish V Badarkhe /* 73738f89369SManish V Badarkhe * Register crypto library descriptor 73838f89369SManish V Badarkhe */ 73938f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 74038f89369SManish V Badarkhe #if TF_MBEDTLS_USE_AES_GCM 74138f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, 74238f89369SManish V Badarkhe auth_decrypt, NULL); 74338f89369SManish V Badarkhe #else 74438f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, 74538f89369SManish V Badarkhe NULL, NULL); 74638f89369SManish V Badarkhe #endif 74738f89369SManish V Badarkhe #elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY 74838f89369SManish V Badarkhe #if TF_MBEDTLS_USE_AES_GCM 74938f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, 75038f89369SManish V Badarkhe auth_decrypt, NULL); 75138f89369SManish V Badarkhe #else 75238f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, 75338f89369SManish V Badarkhe NULL, NULL); 75438f89369SManish V Badarkhe #endif 75538f89369SManish V Badarkhe #elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY 75638f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL); 75738f89369SManish V Badarkhe #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */ 758