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