1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2023, Arm Limited. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu #include <stddef.h> 9*91f16700Schasinglulu #include <string.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu /* mbed TLS headers */ 12*91f16700Schasinglulu #include <mbedtls/gcm.h> 13*91f16700Schasinglulu #include <mbedtls/md.h> 14*91f16700Schasinglulu #include <mbedtls/memory_buffer_alloc.h> 15*91f16700Schasinglulu #include <mbedtls/oid.h> 16*91f16700Schasinglulu #include <mbedtls/platform.h> 17*91f16700Schasinglulu #include <mbedtls/version.h> 18*91f16700Schasinglulu #include <mbedtls/x509.h> 19*91f16700Schasinglulu #include <psa/crypto.h> 20*91f16700Schasinglulu #include <psa/crypto_platform.h> 21*91f16700Schasinglulu #include <psa/crypto_types.h> 22*91f16700Schasinglulu #include <psa/crypto_values.h> 23*91f16700Schasinglulu 24*91f16700Schasinglulu #include <common/debug.h> 25*91f16700Schasinglulu #include <drivers/auth/crypto_mod.h> 26*91f16700Schasinglulu #include <drivers/auth/mbedtls/mbedtls_common.h> 27*91f16700Schasinglulu #include <plat/common/platform.h> 28*91f16700Schasinglulu 29*91f16700Schasinglulu #define LIB_NAME "mbed TLS PSA" 30*91f16700Schasinglulu 31*91f16700Schasinglulu /* Maximum length of R_S pair in the ECDSA signature in bytes */ 32*91f16700Schasinglulu #define MAX_ECDSA_R_S_PAIR_LEN 64U 33*91f16700Schasinglulu 34*91f16700Schasinglulu /* Size of ASN.1 length and tag in bytes*/ 35*91f16700Schasinglulu #define SIZE_OF_ASN1_LEN 1U 36*91f16700Schasinglulu #define SIZE_OF_ASN1_TAG 1U 37*91f16700Schasinglulu 38*91f16700Schasinglulu #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 39*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 40*91f16700Schasinglulu /* 41*91f16700Schasinglulu * CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available 42*91f16700Schasinglulu * so make sure that mbed TLS MD maximum size must be lesser than this. 43*91f16700Schasinglulu */ 44*91f16700Schasinglulu CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE, 45*91f16700Schasinglulu assert_mbedtls_md_size_overflow); 46*91f16700Schasinglulu 47*91f16700Schasinglulu #endif /* 48*91f16700Schasinglulu * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 49*91f16700Schasinglulu * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 50*91f16700Schasinglulu */ 51*91f16700Schasinglulu 52*91f16700Schasinglulu static inline psa_algorithm_t mbedtls_md_psa_alg_from_type( 53*91f16700Schasinglulu mbedtls_md_type_t md_type) 54*91f16700Schasinglulu { 55*91f16700Schasinglulu assert((md_type == MBEDTLS_MD_SHA256) || 56*91f16700Schasinglulu (md_type == MBEDTLS_MD_SHA384) || 57*91f16700Schasinglulu (md_type == MBEDTLS_MD_SHA512)); 58*91f16700Schasinglulu 59*91f16700Schasinglulu return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) (md_type + 0x5); 60*91f16700Schasinglulu } 61*91f16700Schasinglulu 62*91f16700Schasinglulu /* 63*91f16700Schasinglulu * AlgorithmIdentifier ::= SEQUENCE { 64*91f16700Schasinglulu * algorithm OBJECT IDENTIFIER, 65*91f16700Schasinglulu * parameters ANY DEFINED BY algorithm OPTIONAL 66*91f16700Schasinglulu * } 67*91f16700Schasinglulu * 68*91f16700Schasinglulu * SubjectPublicKeyInfo ::= SEQUENCE { 69*91f16700Schasinglulu * algorithm AlgorithmIdentifier, 70*91f16700Schasinglulu * subjectPublicKey BIT STRING 71*91f16700Schasinglulu * } 72*91f16700Schasinglulu * 73*91f16700Schasinglulu * DigestInfo ::= SEQUENCE { 74*91f16700Schasinglulu * digestAlgorithm AlgorithmIdentifier, 75*91f16700Schasinglulu * digest OCTET STRING 76*91f16700Schasinglulu * } 77*91f16700Schasinglulu */ 78*91f16700Schasinglulu 79*91f16700Schasinglulu /* 80*91f16700Schasinglulu * We pretend using an external RNG (through MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG 81*91f16700Schasinglulu * mbedTLS config option) so we need to provide an implementation of 82*91f16700Schasinglulu * mbedtls_psa_external_get_random(). Provide a fake one, since we do not 83*91f16700Schasinglulu * actually have any external RNG and TF-A itself doesn't engage in 84*91f16700Schasinglulu * cryptographic operations that demands randomness. 85*91f16700Schasinglulu */ 86*91f16700Schasinglulu psa_status_t mbedtls_psa_external_get_random( 87*91f16700Schasinglulu mbedtls_psa_external_random_context_t *context, 88*91f16700Schasinglulu uint8_t *output, size_t output_size, 89*91f16700Schasinglulu size_t *output_length) 90*91f16700Schasinglulu { 91*91f16700Schasinglulu return PSA_ERROR_INSUFFICIENT_ENTROPY; 92*91f16700Schasinglulu } 93*91f16700Schasinglulu 94*91f16700Schasinglulu /* 95*91f16700Schasinglulu * Initialize the library and export the descriptor 96*91f16700Schasinglulu */ 97*91f16700Schasinglulu static void init(void) 98*91f16700Schasinglulu { 99*91f16700Schasinglulu /* Initialize mbed TLS */ 100*91f16700Schasinglulu mbedtls_init(); 101*91f16700Schasinglulu 102*91f16700Schasinglulu /* Initialise PSA mbedTLS */ 103*91f16700Schasinglulu psa_status_t status = psa_crypto_init(); 104*91f16700Schasinglulu 105*91f16700Schasinglulu if (status != PSA_SUCCESS) { 106*91f16700Schasinglulu ERROR("Failed to initialize %s crypto (%d).\n", LIB_NAME, status); 107*91f16700Schasinglulu panic(); 108*91f16700Schasinglulu } 109*91f16700Schasinglulu 110*91f16700Schasinglulu INFO("PSA crypto initialized successfully!\n"); 111*91f16700Schasinglulu } 112*91f16700Schasinglulu 113*91f16700Schasinglulu #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 114*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 115*91f16700Schasinglulu 116*91f16700Schasinglulu static void construct_psa_key_alg_and_type(mbedtls_pk_type_t pk_alg, 117*91f16700Schasinglulu mbedtls_md_type_t md_alg, 118*91f16700Schasinglulu psa_ecc_family_t psa_ecc_family, 119*91f16700Schasinglulu psa_algorithm_t *psa_alg, 120*91f16700Schasinglulu psa_key_type_t *psa_key_type) 121*91f16700Schasinglulu { 122*91f16700Schasinglulu psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 123*91f16700Schasinglulu 124*91f16700Schasinglulu switch (pk_alg) { 125*91f16700Schasinglulu case MBEDTLS_PK_RSASSA_PSS: 126*91f16700Schasinglulu *psa_alg = PSA_ALG_RSA_PSS(psa_md_alg); 127*91f16700Schasinglulu *psa_key_type = PSA_KEY_TYPE_RSA_PUBLIC_KEY; 128*91f16700Schasinglulu break; 129*91f16700Schasinglulu case MBEDTLS_PK_ECDSA: 130*91f16700Schasinglulu *psa_alg = PSA_ALG_ECDSA(psa_md_alg); 131*91f16700Schasinglulu *psa_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_ecc_family); 132*91f16700Schasinglulu break; 133*91f16700Schasinglulu default: 134*91f16700Schasinglulu *psa_alg = PSA_ALG_NONE; 135*91f16700Schasinglulu *psa_key_type = PSA_KEY_TYPE_NONE; 136*91f16700Schasinglulu break; 137*91f16700Schasinglulu } 138*91f16700Schasinglulu } 139*91f16700Schasinglulu 140*91f16700Schasinglulu 141*91f16700Schasinglulu #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \ 142*91f16700Schasinglulu TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA 143*91f16700Schasinglulu 144*91f16700Schasinglulu /* 145*91f16700Schasinglulu * This is a helper function to detect padding byte (if the MSB bit of the 146*91f16700Schasinglulu * first data byte is set to 1, for example 0x80) and on detection, ignore the 147*91f16700Schasinglulu * padded byte(0x00) and increase the buffer pointer beyond padded byte and 148*91f16700Schasinglulu * decrease the length of the buffer by 1. 149*91f16700Schasinglulu * 150*91f16700Schasinglulu * On Success returns 0, error otherwise. 151*91f16700Schasinglulu **/ 152*91f16700Schasinglulu static inline int ignore_asn1_int_padding_byte(unsigned char **buf_start, 153*91f16700Schasinglulu size_t *buf_len) 154*91f16700Schasinglulu { 155*91f16700Schasinglulu unsigned char *local_buf = *buf_start; 156*91f16700Schasinglulu 157*91f16700Schasinglulu /* Check for negative number */ 158*91f16700Schasinglulu if ((local_buf[0] & 0x80U) != 0U) { 159*91f16700Schasinglulu return -1; 160*91f16700Schasinglulu } 161*91f16700Schasinglulu 162*91f16700Schasinglulu if ((local_buf[0] == 0U) && (local_buf[1] > 0x7FU) && 163*91f16700Schasinglulu (*buf_len > 1U)) { 164*91f16700Schasinglulu *buf_start = &local_buf[1]; 165*91f16700Schasinglulu (*buf_len)--; 166*91f16700Schasinglulu } 167*91f16700Schasinglulu 168*91f16700Schasinglulu return 0; 169*91f16700Schasinglulu } 170*91f16700Schasinglulu 171*91f16700Schasinglulu /* 172*91f16700Schasinglulu * This is a helper function that gets a pointer to the encoded ECDSA publicKey 173*91f16700Schasinglulu * and its length (as per RFC5280) and returns corresponding decoded publicKey 174*91f16700Schasinglulu * and its length. As well, it retrieves the family of ECC key in the PSA 175*91f16700Schasinglulu * format. 176*91f16700Schasinglulu * 177*91f16700Schasinglulu * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure, 178*91f16700Schasinglulu * otherwise success(0). 179*91f16700Schasinglulu **/ 180*91f16700Schasinglulu static int get_ecdsa_pkinfo_from_asn1(unsigned char **pk_start, 181*91f16700Schasinglulu unsigned int *pk_len, 182*91f16700Schasinglulu psa_ecc_family_t *psa_ecc_family) 183*91f16700Schasinglulu { 184*91f16700Schasinglulu mbedtls_asn1_buf alg_oid, alg_params; 185*91f16700Schasinglulu mbedtls_ecp_group_id grp_id; 186*91f16700Schasinglulu int rc; 187*91f16700Schasinglulu unsigned char *pk_end; 188*91f16700Schasinglulu size_t len; 189*91f16700Schasinglulu size_t curve_bits; 190*91f16700Schasinglulu unsigned char *pk_ptr = *pk_start; 191*91f16700Schasinglulu 192*91f16700Schasinglulu pk_end = pk_ptr + *pk_len; 193*91f16700Schasinglulu rc = mbedtls_asn1_get_tag(&pk_ptr, pk_end, &len, 194*91f16700Schasinglulu MBEDTLS_ASN1_CONSTRUCTED | 195*91f16700Schasinglulu MBEDTLS_ASN1_SEQUENCE); 196*91f16700Schasinglulu if (rc != 0) { 197*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 198*91f16700Schasinglulu } 199*91f16700Schasinglulu 200*91f16700Schasinglulu pk_end = pk_ptr + len; 201*91f16700Schasinglulu rc = mbedtls_asn1_get_alg(&pk_ptr, pk_end, &alg_oid, &alg_params); 202*91f16700Schasinglulu if (rc != 0) { 203*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 204*91f16700Schasinglulu } 205*91f16700Schasinglulu 206*91f16700Schasinglulu if (alg_params.tag == MBEDTLS_ASN1_OID) { 207*91f16700Schasinglulu if (mbedtls_oid_get_ec_grp(&alg_params, &grp_id) != 0) { 208*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 209*91f16700Schasinglulu } 210*91f16700Schasinglulu *psa_ecc_family = mbedtls_ecc_group_to_psa(grp_id, 211*91f16700Schasinglulu &curve_bits); 212*91f16700Schasinglulu } else { 213*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 214*91f16700Schasinglulu } 215*91f16700Schasinglulu 216*91f16700Schasinglulu pk_end = pk_ptr + len - (alg_oid.len + alg_params.len + 217*91f16700Schasinglulu 2 * (SIZE_OF_ASN1_LEN + SIZE_OF_ASN1_TAG)); 218*91f16700Schasinglulu rc = mbedtls_asn1_get_bitstring_null(&pk_ptr, pk_end, &len); 219*91f16700Schasinglulu if (rc != 0) { 220*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 221*91f16700Schasinglulu } 222*91f16700Schasinglulu 223*91f16700Schasinglulu *pk_start = pk_ptr; 224*91f16700Schasinglulu *pk_len = len; 225*91f16700Schasinglulu 226*91f16700Schasinglulu return rc; 227*91f16700Schasinglulu } 228*91f16700Schasinglulu 229*91f16700Schasinglulu /* 230*91f16700Schasinglulu * Ecdsa-Sig-Value ::= SEQUENCE { 231*91f16700Schasinglulu * r INTEGER, 232*91f16700Schasinglulu * s INTEGER 233*91f16700Schasinglulu * } 234*91f16700Schasinglulu * 235*91f16700Schasinglulu * This helper function that gets a pointer to the encoded ECDSA signature and 236*91f16700Schasinglulu * its length (as per RFC5280) and returns corresponding decoded signature 237*91f16700Schasinglulu * (R_S pair) and its size. 238*91f16700Schasinglulu * 239*91f16700Schasinglulu * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure, 240*91f16700Schasinglulu * otherwise success(0). 241*91f16700Schasinglulu **/ 242*91f16700Schasinglulu static int get_ecdsa_signature_from_asn1(unsigned char *sig_ptr, 243*91f16700Schasinglulu size_t *sig_len, 244*91f16700Schasinglulu unsigned char *r_s_pair) 245*91f16700Schasinglulu { 246*91f16700Schasinglulu int rc; 247*91f16700Schasinglulu unsigned char *sig_end; 248*91f16700Schasinglulu size_t len, r_len, s_len; 249*91f16700Schasinglulu 250*91f16700Schasinglulu sig_end = sig_ptr + *sig_len; 251*91f16700Schasinglulu rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &len, 252*91f16700Schasinglulu MBEDTLS_ASN1_CONSTRUCTED | 253*91f16700Schasinglulu MBEDTLS_ASN1_SEQUENCE); 254*91f16700Schasinglulu if (rc != 0) { 255*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 256*91f16700Schasinglulu } 257*91f16700Schasinglulu 258*91f16700Schasinglulu sig_end = sig_ptr + len; 259*91f16700Schasinglulu rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &r_len, 260*91f16700Schasinglulu MBEDTLS_ASN1_INTEGER); 261*91f16700Schasinglulu if (rc != 0) { 262*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 263*91f16700Schasinglulu } 264*91f16700Schasinglulu 265*91f16700Schasinglulu if (ignore_asn1_int_padding_byte(&sig_ptr, &r_len) != 0) { 266*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 267*91f16700Schasinglulu } 268*91f16700Schasinglulu 269*91f16700Schasinglulu (void)memcpy((void *)&r_s_pair[0], (const void *)sig_ptr, r_len); 270*91f16700Schasinglulu 271*91f16700Schasinglulu sig_ptr = sig_ptr + r_len; 272*91f16700Schasinglulu sig_end = sig_ptr + len - (r_len + (SIZE_OF_ASN1_LEN + 273*91f16700Schasinglulu SIZE_OF_ASN1_TAG)); 274*91f16700Schasinglulu rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &s_len, 275*91f16700Schasinglulu MBEDTLS_ASN1_INTEGER); 276*91f16700Schasinglulu if (rc != 0) { 277*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 278*91f16700Schasinglulu } 279*91f16700Schasinglulu 280*91f16700Schasinglulu if (ignore_asn1_int_padding_byte(&sig_ptr, &s_len) != 0) { 281*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 282*91f16700Schasinglulu } 283*91f16700Schasinglulu 284*91f16700Schasinglulu (void)memcpy((void *)&r_s_pair[r_len], (const void *)sig_ptr, s_len); 285*91f16700Schasinglulu 286*91f16700Schasinglulu *sig_len = s_len + r_len; 287*91f16700Schasinglulu 288*91f16700Schasinglulu return 0; 289*91f16700Schasinglulu } 290*91f16700Schasinglulu #endif /* 291*91f16700Schasinglulu * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \ 292*91f16700Schasinglulu * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA 293*91f16700Schasinglulu **/ 294*91f16700Schasinglulu 295*91f16700Schasinglulu /* 296*91f16700Schasinglulu * Verify a signature. 297*91f16700Schasinglulu * 298*91f16700Schasinglulu * Parameters are passed using the DER encoding format following the ASN.1 299*91f16700Schasinglulu * structures detailed above. 300*91f16700Schasinglulu */ 301*91f16700Schasinglulu static int verify_signature(void *data_ptr, unsigned int data_len, 302*91f16700Schasinglulu void *sig_ptr, unsigned int sig_len, 303*91f16700Schasinglulu void *sig_alg, unsigned int sig_alg_len, 304*91f16700Schasinglulu void *pk_ptr, unsigned int pk_len) 305*91f16700Schasinglulu { 306*91f16700Schasinglulu mbedtls_asn1_buf sig_oid, sig_params; 307*91f16700Schasinglulu mbedtls_asn1_buf signature; 308*91f16700Schasinglulu mbedtls_md_type_t md_alg; 309*91f16700Schasinglulu mbedtls_pk_type_t pk_alg; 310*91f16700Schasinglulu int rc; 311*91f16700Schasinglulu void *sig_opts = NULL; 312*91f16700Schasinglulu unsigned char *p, *end; 313*91f16700Schasinglulu unsigned char *local_sig_ptr; 314*91f16700Schasinglulu size_t local_sig_len; 315*91f16700Schasinglulu psa_ecc_family_t psa_ecc_family = 0U; 316*91f16700Schasinglulu __unused unsigned char reformatted_sig[MAX_ECDSA_R_S_PAIR_LEN] = {0}; 317*91f16700Schasinglulu 318*91f16700Schasinglulu /* construct PSA key algo and type */ 319*91f16700Schasinglulu psa_status_t status = PSA_SUCCESS; 320*91f16700Schasinglulu psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT; 321*91f16700Schasinglulu psa_key_id_t psa_key_id = PSA_KEY_ID_NULL; 322*91f16700Schasinglulu psa_key_type_t psa_key_type; 323*91f16700Schasinglulu psa_algorithm_t psa_alg; 324*91f16700Schasinglulu 325*91f16700Schasinglulu /* Get pointers to signature OID and parameters */ 326*91f16700Schasinglulu p = (unsigned char *)sig_alg; 327*91f16700Schasinglulu end = (unsigned char *)(p + sig_alg_len); 328*91f16700Schasinglulu rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params); 329*91f16700Schasinglulu if (rc != 0) { 330*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 331*91f16700Schasinglulu } 332*91f16700Schasinglulu 333*91f16700Schasinglulu /* Get the actual signature algorithm (MD + PK) */ 334*91f16700Schasinglulu rc = mbedtls_x509_get_sig_alg(&sig_oid, &sig_params, &md_alg, &pk_alg, &sig_opts); 335*91f16700Schasinglulu if (rc != 0) { 336*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 337*91f16700Schasinglulu } 338*91f16700Schasinglulu 339*91f16700Schasinglulu /* Get the signature (bitstring) */ 340*91f16700Schasinglulu p = (unsigned char *)sig_ptr; 341*91f16700Schasinglulu end = (unsigned char *)(p + sig_len); 342*91f16700Schasinglulu signature.tag = *p; 343*91f16700Schasinglulu rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len); 344*91f16700Schasinglulu if ((rc != 0) || ((size_t)(end - p) != signature.len)) { 345*91f16700Schasinglulu rc = CRYPTO_ERR_SIGNATURE; 346*91f16700Schasinglulu goto end2; 347*91f16700Schasinglulu } 348*91f16700Schasinglulu 349*91f16700Schasinglulu local_sig_ptr = p; 350*91f16700Schasinglulu local_sig_len = signature.len; 351*91f16700Schasinglulu 352*91f16700Schasinglulu #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \ 353*91f16700Schasinglulu TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA 354*91f16700Schasinglulu if (pk_alg == MBEDTLS_PK_ECDSA) { 355*91f16700Schasinglulu rc = get_ecdsa_signature_from_asn1(local_sig_ptr, 356*91f16700Schasinglulu &local_sig_len, 357*91f16700Schasinglulu reformatted_sig); 358*91f16700Schasinglulu if (rc != 0) { 359*91f16700Schasinglulu goto end2; 360*91f16700Schasinglulu } 361*91f16700Schasinglulu 362*91f16700Schasinglulu local_sig_ptr = reformatted_sig; 363*91f16700Schasinglulu 364*91f16700Schasinglulu rc = get_ecdsa_pkinfo_from_asn1((unsigned char **)&pk_ptr, 365*91f16700Schasinglulu &pk_len, 366*91f16700Schasinglulu &psa_ecc_family); 367*91f16700Schasinglulu if (rc != 0) { 368*91f16700Schasinglulu goto end2; 369*91f16700Schasinglulu } 370*91f16700Schasinglulu } 371*91f16700Schasinglulu #endif /* 372*91f16700Schasinglulu * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \ 373*91f16700Schasinglulu * TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA 374*91f16700Schasinglulu **/ 375*91f16700Schasinglulu 376*91f16700Schasinglulu /* Convert this pk_alg and md_alg to PSA key type and key algorithm */ 377*91f16700Schasinglulu construct_psa_key_alg_and_type(pk_alg, md_alg, psa_ecc_family, 378*91f16700Schasinglulu &psa_alg, &psa_key_type); 379*91f16700Schasinglulu 380*91f16700Schasinglulu 381*91f16700Schasinglulu if ((psa_alg == PSA_ALG_NONE) || (psa_key_type == PSA_KEY_TYPE_NONE)) { 382*91f16700Schasinglulu rc = CRYPTO_ERR_SIGNATURE; 383*91f16700Schasinglulu goto end2; 384*91f16700Schasinglulu } 385*91f16700Schasinglulu 386*91f16700Schasinglulu /* filled-in key_attributes */ 387*91f16700Schasinglulu psa_set_key_algorithm(&psa_key_attr, psa_alg); 388*91f16700Schasinglulu psa_set_key_type(&psa_key_attr, psa_key_type); 389*91f16700Schasinglulu psa_set_key_usage_flags(&psa_key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE); 390*91f16700Schasinglulu 391*91f16700Schasinglulu /* Get the key_id using import API */ 392*91f16700Schasinglulu status = psa_import_key(&psa_key_attr, 393*91f16700Schasinglulu pk_ptr, 394*91f16700Schasinglulu (size_t)pk_len, 395*91f16700Schasinglulu &psa_key_id); 396*91f16700Schasinglulu 397*91f16700Schasinglulu if (status != PSA_SUCCESS) { 398*91f16700Schasinglulu rc = CRYPTO_ERR_SIGNATURE; 399*91f16700Schasinglulu goto end2; 400*91f16700Schasinglulu } 401*91f16700Schasinglulu 402*91f16700Schasinglulu /* 403*91f16700Schasinglulu * Hash calculation and Signature verification of the given data payload 404*91f16700Schasinglulu * is wrapped under the psa_verify_message function. 405*91f16700Schasinglulu */ 406*91f16700Schasinglulu status = psa_verify_message(psa_key_id, psa_alg, 407*91f16700Schasinglulu data_ptr, data_len, 408*91f16700Schasinglulu local_sig_ptr, local_sig_len); 409*91f16700Schasinglulu 410*91f16700Schasinglulu if (status != PSA_SUCCESS) { 411*91f16700Schasinglulu rc = CRYPTO_ERR_SIGNATURE; 412*91f16700Schasinglulu goto end1; 413*91f16700Schasinglulu } 414*91f16700Schasinglulu 415*91f16700Schasinglulu /* Signature verification success */ 416*91f16700Schasinglulu rc = CRYPTO_SUCCESS; 417*91f16700Schasinglulu 418*91f16700Schasinglulu end1: 419*91f16700Schasinglulu /* 420*91f16700Schasinglulu * Destroy the key if it is created successfully 421*91f16700Schasinglulu */ 422*91f16700Schasinglulu psa_destroy_key(psa_key_id); 423*91f16700Schasinglulu end2: 424*91f16700Schasinglulu mbedtls_free(sig_opts); 425*91f16700Schasinglulu return rc; 426*91f16700Schasinglulu } 427*91f16700Schasinglulu 428*91f16700Schasinglulu /* 429*91f16700Schasinglulu * Match a hash 430*91f16700Schasinglulu * 431*91f16700Schasinglulu * Digest info is passed in DER format following the ASN.1 structure detailed 432*91f16700Schasinglulu * above. 433*91f16700Schasinglulu */ 434*91f16700Schasinglulu static int verify_hash(void *data_ptr, unsigned int data_len, 435*91f16700Schasinglulu void *digest_info_ptr, unsigned int digest_info_len) 436*91f16700Schasinglulu { 437*91f16700Schasinglulu mbedtls_asn1_buf hash_oid, params; 438*91f16700Schasinglulu mbedtls_md_type_t md_alg; 439*91f16700Schasinglulu unsigned char *p, *end, *hash; 440*91f16700Schasinglulu size_t len; 441*91f16700Schasinglulu int rc; 442*91f16700Schasinglulu psa_status_t status; 443*91f16700Schasinglulu psa_algorithm_t psa_md_alg; 444*91f16700Schasinglulu 445*91f16700Schasinglulu /* 446*91f16700Schasinglulu * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after 447*91f16700Schasinglulu * it is allowed. This is necessary to support multiple hash 448*91f16700Schasinglulu * algorithms. 449*91f16700Schasinglulu */ 450*91f16700Schasinglulu p = (unsigned char *)digest_info_ptr; 451*91f16700Schasinglulu end = p + digest_info_len; 452*91f16700Schasinglulu rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | 453*91f16700Schasinglulu MBEDTLS_ASN1_SEQUENCE); 454*91f16700Schasinglulu if (rc != 0) { 455*91f16700Schasinglulu return CRYPTO_ERR_HASH; 456*91f16700Schasinglulu } 457*91f16700Schasinglulu 458*91f16700Schasinglulu end = p + len; 459*91f16700Schasinglulu 460*91f16700Schasinglulu /* Get the hash algorithm */ 461*91f16700Schasinglulu rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms); 462*91f16700Schasinglulu if (rc != 0) { 463*91f16700Schasinglulu return CRYPTO_ERR_HASH; 464*91f16700Schasinglulu } 465*91f16700Schasinglulu 466*91f16700Schasinglulu /* Hash should be octet string type and consume all bytes */ 467*91f16700Schasinglulu rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); 468*91f16700Schasinglulu if ((rc != 0) || ((size_t)(end - p) != len)) { 469*91f16700Schasinglulu return CRYPTO_ERR_HASH; 470*91f16700Schasinglulu } 471*91f16700Schasinglulu hash = p; 472*91f16700Schasinglulu 473*91f16700Schasinglulu rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg); 474*91f16700Schasinglulu if (rc != 0) { 475*91f16700Schasinglulu return CRYPTO_ERR_HASH; 476*91f16700Schasinglulu } 477*91f16700Schasinglulu 478*91f16700Schasinglulu /* convert the md_alg to psa_algo */ 479*91f16700Schasinglulu psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 480*91f16700Schasinglulu 481*91f16700Schasinglulu /* Length of hash must match the algorithm's size */ 482*91f16700Schasinglulu if (len != PSA_HASH_LENGTH(psa_md_alg)) { 483*91f16700Schasinglulu return CRYPTO_ERR_HASH; 484*91f16700Schasinglulu } 485*91f16700Schasinglulu 486*91f16700Schasinglulu /* 487*91f16700Schasinglulu * Calculate Hash and compare it against the retrieved hash from 488*91f16700Schasinglulu * the certificate (one shot API). 489*91f16700Schasinglulu */ 490*91f16700Schasinglulu status = psa_hash_compare(psa_md_alg, 491*91f16700Schasinglulu data_ptr, (size_t)data_len, 492*91f16700Schasinglulu (const uint8_t *)hash, len); 493*91f16700Schasinglulu 494*91f16700Schasinglulu if (status != PSA_SUCCESS) { 495*91f16700Schasinglulu return CRYPTO_ERR_HASH; 496*91f16700Schasinglulu } 497*91f16700Schasinglulu 498*91f16700Schasinglulu return CRYPTO_SUCCESS; 499*91f16700Schasinglulu } 500*91f16700Schasinglulu #endif /* 501*91f16700Schasinglulu * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 502*91f16700Schasinglulu * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 503*91f16700Schasinglulu */ 504*91f16700Schasinglulu 505*91f16700Schasinglulu #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 506*91f16700Schasinglulu CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 507*91f16700Schasinglulu /* 508*91f16700Schasinglulu * Map a generic crypto message digest algorithm to the corresponding macro used 509*91f16700Schasinglulu * by Mbed TLS. 510*91f16700Schasinglulu */ 511*91f16700Schasinglulu static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo) 512*91f16700Schasinglulu { 513*91f16700Schasinglulu switch (algo) { 514*91f16700Schasinglulu case CRYPTO_MD_SHA512: 515*91f16700Schasinglulu return MBEDTLS_MD_SHA512; 516*91f16700Schasinglulu case CRYPTO_MD_SHA384: 517*91f16700Schasinglulu return MBEDTLS_MD_SHA384; 518*91f16700Schasinglulu case CRYPTO_MD_SHA256: 519*91f16700Schasinglulu return MBEDTLS_MD_SHA256; 520*91f16700Schasinglulu default: 521*91f16700Schasinglulu /* Invalid hash algorithm. */ 522*91f16700Schasinglulu return MBEDTLS_MD_NONE; 523*91f16700Schasinglulu } 524*91f16700Schasinglulu } 525*91f16700Schasinglulu 526*91f16700Schasinglulu /* 527*91f16700Schasinglulu * Calculate a hash 528*91f16700Schasinglulu * 529*91f16700Schasinglulu * output points to the computed hash 530*91f16700Schasinglulu */ 531*91f16700Schasinglulu static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr, 532*91f16700Schasinglulu unsigned int data_len, 533*91f16700Schasinglulu unsigned char output[CRYPTO_MD_MAX_SIZE]) 534*91f16700Schasinglulu { 535*91f16700Schasinglulu size_t hash_length; 536*91f16700Schasinglulu psa_status_t status; 537*91f16700Schasinglulu psa_algorithm_t psa_md_alg; 538*91f16700Schasinglulu 539*91f16700Schasinglulu /* convert the md_alg to psa_algo */ 540*91f16700Schasinglulu psa_md_alg = mbedtls_md_psa_alg_from_type(md_type(md_algo)); 541*91f16700Schasinglulu 542*91f16700Schasinglulu /* 543*91f16700Schasinglulu * Calculate the hash of the data, it is safe to pass the 544*91f16700Schasinglulu * 'output' hash buffer pointer considering its size is always 545*91f16700Schasinglulu * bigger than or equal to MBEDTLS_MD_MAX_SIZE. 546*91f16700Schasinglulu */ 547*91f16700Schasinglulu status = psa_hash_compute(psa_md_alg, data_ptr, (size_t)data_len, 548*91f16700Schasinglulu (uint8_t *)output, CRYPTO_MD_MAX_SIZE, 549*91f16700Schasinglulu &hash_length); 550*91f16700Schasinglulu if (status != PSA_SUCCESS) { 551*91f16700Schasinglulu return CRYPTO_ERR_HASH; 552*91f16700Schasinglulu } 553*91f16700Schasinglulu 554*91f16700Schasinglulu return CRYPTO_SUCCESS; 555*91f16700Schasinglulu } 556*91f16700Schasinglulu #endif /* 557*91f16700Schasinglulu * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 558*91f16700Schasinglulu * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 559*91f16700Schasinglulu */ 560*91f16700Schasinglulu 561*91f16700Schasinglulu #if TF_MBEDTLS_USE_AES_GCM 562*91f16700Schasinglulu /* 563*91f16700Schasinglulu * Stack based buffer allocation for decryption operation. It could 564*91f16700Schasinglulu * be configured to balance stack usage vs execution speed. 565*91f16700Schasinglulu */ 566*91f16700Schasinglulu #define DEC_OP_BUF_SIZE 128 567*91f16700Schasinglulu 568*91f16700Schasinglulu static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key, 569*91f16700Schasinglulu unsigned int key_len, const void *iv, 570*91f16700Schasinglulu unsigned int iv_len, const void *tag, 571*91f16700Schasinglulu unsigned int tag_len) 572*91f16700Schasinglulu { 573*91f16700Schasinglulu mbedtls_gcm_context ctx; 574*91f16700Schasinglulu mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; 575*91f16700Schasinglulu unsigned char buf[DEC_OP_BUF_SIZE]; 576*91f16700Schasinglulu unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE]; 577*91f16700Schasinglulu unsigned char *pt = data_ptr; 578*91f16700Schasinglulu size_t dec_len; 579*91f16700Schasinglulu int diff, i, rc; 580*91f16700Schasinglulu size_t output_length __unused; 581*91f16700Schasinglulu 582*91f16700Schasinglulu mbedtls_gcm_init(&ctx); 583*91f16700Schasinglulu 584*91f16700Schasinglulu rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8); 585*91f16700Schasinglulu if (rc != 0) { 586*91f16700Schasinglulu rc = CRYPTO_ERR_DECRYPTION; 587*91f16700Schasinglulu goto exit_gcm; 588*91f16700Schasinglulu } 589*91f16700Schasinglulu 590*91f16700Schasinglulu #if (MBEDTLS_VERSION_MAJOR < 3) 591*91f16700Schasinglulu rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0); 592*91f16700Schasinglulu #else 593*91f16700Schasinglulu rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len); 594*91f16700Schasinglulu #endif 595*91f16700Schasinglulu if (rc != 0) { 596*91f16700Schasinglulu rc = CRYPTO_ERR_DECRYPTION; 597*91f16700Schasinglulu goto exit_gcm; 598*91f16700Schasinglulu } 599*91f16700Schasinglulu 600*91f16700Schasinglulu while (len > 0) { 601*91f16700Schasinglulu dec_len = MIN(sizeof(buf), len); 602*91f16700Schasinglulu 603*91f16700Schasinglulu #if (MBEDTLS_VERSION_MAJOR < 3) 604*91f16700Schasinglulu rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf); 605*91f16700Schasinglulu #else 606*91f16700Schasinglulu rc = mbedtls_gcm_update(&ctx, pt, dec_len, buf, sizeof(buf), &output_length); 607*91f16700Schasinglulu #endif 608*91f16700Schasinglulu 609*91f16700Schasinglulu if (rc != 0) { 610*91f16700Schasinglulu rc = CRYPTO_ERR_DECRYPTION; 611*91f16700Schasinglulu goto exit_gcm; 612*91f16700Schasinglulu } 613*91f16700Schasinglulu 614*91f16700Schasinglulu memcpy(pt, buf, dec_len); 615*91f16700Schasinglulu pt += dec_len; 616*91f16700Schasinglulu len -= dec_len; 617*91f16700Schasinglulu } 618*91f16700Schasinglulu 619*91f16700Schasinglulu #if (MBEDTLS_VERSION_MAJOR < 3) 620*91f16700Schasinglulu rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf)); 621*91f16700Schasinglulu #else 622*91f16700Schasinglulu rc = mbedtls_gcm_finish(&ctx, NULL, 0, &output_length, tag_buf, sizeof(tag_buf)); 623*91f16700Schasinglulu #endif 624*91f16700Schasinglulu 625*91f16700Schasinglulu if (rc != 0) { 626*91f16700Schasinglulu rc = CRYPTO_ERR_DECRYPTION; 627*91f16700Schasinglulu goto exit_gcm; 628*91f16700Schasinglulu } 629*91f16700Schasinglulu 630*91f16700Schasinglulu /* Check tag in "constant-time" */ 631*91f16700Schasinglulu for (diff = 0, i = 0; i < tag_len; i++) 632*91f16700Schasinglulu diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i]; 633*91f16700Schasinglulu 634*91f16700Schasinglulu if (diff != 0) { 635*91f16700Schasinglulu rc = CRYPTO_ERR_DECRYPTION; 636*91f16700Schasinglulu goto exit_gcm; 637*91f16700Schasinglulu } 638*91f16700Schasinglulu 639*91f16700Schasinglulu /* GCM decryption success */ 640*91f16700Schasinglulu rc = CRYPTO_SUCCESS; 641*91f16700Schasinglulu 642*91f16700Schasinglulu exit_gcm: 643*91f16700Schasinglulu mbedtls_gcm_free(&ctx); 644*91f16700Schasinglulu return rc; 645*91f16700Schasinglulu } 646*91f16700Schasinglulu 647*91f16700Schasinglulu /* 648*91f16700Schasinglulu * Authenticated decryption of an image 649*91f16700Schasinglulu */ 650*91f16700Schasinglulu static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, 651*91f16700Schasinglulu size_t len, const void *key, unsigned int key_len, 652*91f16700Schasinglulu unsigned int key_flags, const void *iv, 653*91f16700Schasinglulu unsigned int iv_len, const void *tag, 654*91f16700Schasinglulu unsigned int tag_len) 655*91f16700Schasinglulu { 656*91f16700Schasinglulu int rc; 657*91f16700Schasinglulu 658*91f16700Schasinglulu assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0); 659*91f16700Schasinglulu 660*91f16700Schasinglulu switch (dec_algo) { 661*91f16700Schasinglulu case CRYPTO_GCM_DECRYPT: 662*91f16700Schasinglulu rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len, 663*91f16700Schasinglulu tag, tag_len); 664*91f16700Schasinglulu if (rc != 0) 665*91f16700Schasinglulu return rc; 666*91f16700Schasinglulu break; 667*91f16700Schasinglulu default: 668*91f16700Schasinglulu return CRYPTO_ERR_DECRYPTION; 669*91f16700Schasinglulu } 670*91f16700Schasinglulu 671*91f16700Schasinglulu return CRYPTO_SUCCESS; 672*91f16700Schasinglulu } 673*91f16700Schasinglulu #endif /* TF_MBEDTLS_USE_AES_GCM */ 674*91f16700Schasinglulu 675*91f16700Schasinglulu /* 676*91f16700Schasinglulu * Register crypto library descriptor 677*91f16700Schasinglulu */ 678*91f16700Schasinglulu #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 679*91f16700Schasinglulu #if TF_MBEDTLS_USE_AES_GCM 680*91f16700Schasinglulu REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, 681*91f16700Schasinglulu auth_decrypt, NULL); 682*91f16700Schasinglulu #else 683*91f16700Schasinglulu REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, 684*91f16700Schasinglulu NULL, NULL); 685*91f16700Schasinglulu #endif 686*91f16700Schasinglulu #elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY 687*91f16700Schasinglulu #if TF_MBEDTLS_USE_AES_GCM 688*91f16700Schasinglulu REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, 689*91f16700Schasinglulu auth_decrypt, NULL); 690*91f16700Schasinglulu #else 691*91f16700Schasinglulu REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, 692*91f16700Schasinglulu NULL, NULL); 693*91f16700Schasinglulu #endif 694*91f16700Schasinglulu #elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY 695*91f16700Schasinglulu REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL); 696*91f16700Schasinglulu #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */ 697