138f89369SManish V Badarkhe /* 238f89369SManish V Badarkhe * Copyright (c) 2023, 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> 1738f89369SManish V Badarkhe #include <mbedtls/version.h> 1838f89369SManish V Badarkhe #include <mbedtls/x509.h> 194eaaaa19SManish V Badarkhe #include <psa/crypto.h> 204eaaaa19SManish V Badarkhe #include <psa/crypto_platform.h> 214eaaaa19SManish V Badarkhe #include <psa/crypto_types.h> 224eaaaa19SManish V Badarkhe #include <psa/crypto_values.h> 2338f89369SManish V Badarkhe 2438f89369SManish V Badarkhe #include <common/debug.h> 2538f89369SManish V Badarkhe #include <drivers/auth/crypto_mod.h> 2638f89369SManish V Badarkhe #include <drivers/auth/mbedtls/mbedtls_common.h> 2738f89369SManish V Badarkhe #include <plat/common/platform.h> 2838f89369SManish V Badarkhe 2938f89369SManish V Badarkhe #define LIB_NAME "mbed TLS PSA" 3038f89369SManish V Badarkhe 3138f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 3238f89369SManish V Badarkhe CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 3338f89369SManish V Badarkhe /* 3438f89369SManish V Badarkhe * CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available 3538f89369SManish V Badarkhe * so make sure that mbed TLS MD maximum size must be lesser than this. 3638f89369SManish V Badarkhe */ 3738f89369SManish V Badarkhe CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE, 3838f89369SManish V Badarkhe assert_mbedtls_md_size_overflow); 3938f89369SManish V Badarkhe 4038f89369SManish V Badarkhe #endif /* 4138f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 4238f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 4338f89369SManish V Badarkhe */ 4438f89369SManish V Badarkhe 452ed061c4SManish V Badarkhe static inline psa_algorithm_t mbedtls_md_psa_alg_from_type( 462ed061c4SManish V Badarkhe mbedtls_md_type_t md_type) 472ed061c4SManish V Badarkhe { 482ed061c4SManish V Badarkhe assert((md_type == MBEDTLS_MD_SHA256) || 492ed061c4SManish V Badarkhe (md_type == MBEDTLS_MD_SHA384) || 502ed061c4SManish V Badarkhe (md_type == MBEDTLS_MD_SHA512)); 512ed061c4SManish V Badarkhe 522ed061c4SManish V Badarkhe return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) (md_type + 0x5); 532ed061c4SManish V Badarkhe } 542ed061c4SManish V Badarkhe 5538f89369SManish V Badarkhe /* 5638f89369SManish V Badarkhe * AlgorithmIdentifier ::= SEQUENCE { 5738f89369SManish V Badarkhe * algorithm OBJECT IDENTIFIER, 5838f89369SManish V Badarkhe * parameters ANY DEFINED BY algorithm OPTIONAL 5938f89369SManish V Badarkhe * } 6038f89369SManish V Badarkhe * 6138f89369SManish V Badarkhe * SubjectPublicKeyInfo ::= SEQUENCE { 6238f89369SManish V Badarkhe * algorithm AlgorithmIdentifier, 6338f89369SManish V Badarkhe * subjectPublicKey BIT STRING 6438f89369SManish V Badarkhe * } 6538f89369SManish V Badarkhe * 6638f89369SManish V Badarkhe * DigestInfo ::= SEQUENCE { 6738f89369SManish V Badarkhe * digestAlgorithm AlgorithmIdentifier, 6838f89369SManish V Badarkhe * digest OCTET STRING 6938f89369SManish V Badarkhe * } 7038f89369SManish V Badarkhe */ 7138f89369SManish V Badarkhe 7238f89369SManish V Badarkhe /* 734eaaaa19SManish V Badarkhe * We pretend using an external RNG (through MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG 744eaaaa19SManish V Badarkhe * mbedTLS config option) so we need to provide an implementation of 754eaaaa19SManish V Badarkhe * mbedtls_psa_external_get_random(). Provide a fake one, since we do not 764eaaaa19SManish V Badarkhe * actually have any external RNG and TF-A itself doesn't engage in 774eaaaa19SManish V Badarkhe * cryptographic operations that demands randomness. 784eaaaa19SManish V Badarkhe */ 794eaaaa19SManish V Badarkhe psa_status_t mbedtls_psa_external_get_random( 804eaaaa19SManish V Badarkhe mbedtls_psa_external_random_context_t *context, 814eaaaa19SManish V Badarkhe uint8_t *output, size_t output_size, 824eaaaa19SManish V Badarkhe size_t *output_length) 834eaaaa19SManish V Badarkhe { 844eaaaa19SManish V Badarkhe return PSA_ERROR_INSUFFICIENT_ENTROPY; 854eaaaa19SManish V Badarkhe } 864eaaaa19SManish V Badarkhe 874eaaaa19SManish V Badarkhe /* 8838f89369SManish V Badarkhe * Initialize the library and export the descriptor 8938f89369SManish V Badarkhe */ 9038f89369SManish V Badarkhe static void init(void) 9138f89369SManish V Badarkhe { 9238f89369SManish V Badarkhe /* Initialize mbed TLS */ 9338f89369SManish V Badarkhe mbedtls_init(); 944eaaaa19SManish V Badarkhe 954eaaaa19SManish V Badarkhe /* Initialise PSA mbedTLS */ 964eaaaa19SManish V Badarkhe psa_status_t status = psa_crypto_init(); 974eaaaa19SManish V Badarkhe 984eaaaa19SManish V Badarkhe if (status != PSA_SUCCESS) { 994eaaaa19SManish V Badarkhe ERROR("Failed to initialize %s crypto (%d).\n", LIB_NAME, status); 1004eaaaa19SManish V Badarkhe panic(); 1014eaaaa19SManish V Badarkhe } 1024eaaaa19SManish V Badarkhe 1034eaaaa19SManish V Badarkhe INFO("PSA crypto initialized successfully!\n"); 10438f89369SManish V Badarkhe } 10538f89369SManish V Badarkhe 10638f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 10738f89369SManish V Badarkhe CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 108*eaa62e82SManish V Badarkhe 109*eaa62e82SManish V Badarkhe static void construct_psa_key_alg_and_type(mbedtls_pk_type_t pk_alg, 110*eaa62e82SManish V Badarkhe mbedtls_md_type_t md_alg, 111*eaa62e82SManish V Badarkhe psa_algorithm_t *psa_alg, 112*eaa62e82SManish V Badarkhe psa_key_type_t *psa_key_type) 113*eaa62e82SManish V Badarkhe { 114*eaa62e82SManish V Badarkhe psa_algorithm_t psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 115*eaa62e82SManish V Badarkhe 116*eaa62e82SManish V Badarkhe switch (pk_alg) { 117*eaa62e82SManish V Badarkhe case MBEDTLS_PK_RSASSA_PSS: 118*eaa62e82SManish V Badarkhe *psa_alg = PSA_ALG_RSA_PSS(psa_md_alg); 119*eaa62e82SManish V Badarkhe *psa_key_type = PSA_KEY_TYPE_RSA_PUBLIC_KEY; 120*eaa62e82SManish V Badarkhe break; 121*eaa62e82SManish V Badarkhe default: 122*eaa62e82SManish V Badarkhe *psa_alg = PSA_ALG_NONE; 123*eaa62e82SManish V Badarkhe *psa_key_type = PSA_KEY_TYPE_NONE; 124*eaa62e82SManish V Badarkhe break; 125*eaa62e82SManish V Badarkhe } 126*eaa62e82SManish V Badarkhe } 127*eaa62e82SManish V Badarkhe 12838f89369SManish V Badarkhe /* 12938f89369SManish V Badarkhe * Verify a signature. 13038f89369SManish V Badarkhe * 13138f89369SManish V Badarkhe * Parameters are passed using the DER encoding format following the ASN.1 13238f89369SManish V Badarkhe * structures detailed above. 13338f89369SManish V Badarkhe */ 13438f89369SManish V Badarkhe static int verify_signature(void *data_ptr, unsigned int data_len, 13538f89369SManish V Badarkhe void *sig_ptr, unsigned int sig_len, 13638f89369SManish V Badarkhe void *sig_alg, unsigned int sig_alg_len, 13738f89369SManish V Badarkhe void *pk_ptr, unsigned int pk_len) 13838f89369SManish V Badarkhe { 13938f89369SManish V Badarkhe mbedtls_asn1_buf sig_oid, sig_params; 14038f89369SManish V Badarkhe mbedtls_asn1_buf signature; 14138f89369SManish V Badarkhe mbedtls_md_type_t md_alg; 14238f89369SManish V Badarkhe mbedtls_pk_type_t pk_alg; 14338f89369SManish V Badarkhe int rc; 14438f89369SManish V Badarkhe void *sig_opts = NULL; 14538f89369SManish V Badarkhe unsigned char *p, *end; 146*eaa62e82SManish V Badarkhe 147*eaa62e82SManish V Badarkhe /* construct PSA key algo and type */ 148*eaa62e82SManish V Badarkhe psa_status_t status = PSA_SUCCESS; 149*eaa62e82SManish V Badarkhe psa_key_attributes_t psa_key_attr = PSA_KEY_ATTRIBUTES_INIT; 150*eaa62e82SManish V Badarkhe psa_key_id_t psa_key_id = PSA_KEY_ID_NULL; 151*eaa62e82SManish V Badarkhe psa_key_type_t psa_key_type; 152*eaa62e82SManish V Badarkhe psa_algorithm_t psa_alg; 15338f89369SManish V Badarkhe 15438f89369SManish V Badarkhe /* Get pointers to signature OID and parameters */ 15538f89369SManish V Badarkhe p = (unsigned char *)sig_alg; 15638f89369SManish V Badarkhe end = (unsigned char *)(p + sig_alg_len); 15738f89369SManish V Badarkhe rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params); 15838f89369SManish V Badarkhe if (rc != 0) { 15938f89369SManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 16038f89369SManish V Badarkhe } 16138f89369SManish V Badarkhe 16238f89369SManish V Badarkhe /* Get the actual signature algorithm (MD + PK) */ 16338f89369SManish V Badarkhe rc = mbedtls_x509_get_sig_alg(&sig_oid, &sig_params, &md_alg, &pk_alg, &sig_opts); 16438f89369SManish V Badarkhe if (rc != 0) { 16538f89369SManish V Badarkhe return CRYPTO_ERR_SIGNATURE; 16638f89369SManish V Badarkhe } 16738f89369SManish V Badarkhe 16838f89369SManish V Badarkhe /* Get the signature (bitstring) */ 16938f89369SManish V Badarkhe p = (unsigned char *)sig_ptr; 17038f89369SManish V Badarkhe end = (unsigned char *)(p + sig_len); 17138f89369SManish V Badarkhe signature.tag = *p; 17238f89369SManish V Badarkhe rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len); 17338f89369SManish V Badarkhe if ((rc != 0) || ((size_t)(end - p) != signature.len)) { 17438f89369SManish V Badarkhe rc = CRYPTO_ERR_SIGNATURE; 175*eaa62e82SManish V Badarkhe goto end2; 17638f89369SManish V Badarkhe } 17738f89369SManish V Badarkhe signature.p = p; 17838f89369SManish V Badarkhe 179*eaa62e82SManish V Badarkhe /* Convert this pk_alg and md_alg to PSA key type and key algorithm */ 180*eaa62e82SManish V Badarkhe construct_psa_key_alg_and_type(pk_alg, md_alg, 181*eaa62e82SManish V Badarkhe &psa_alg, &psa_key_type); 182*eaa62e82SManish V Badarkhe 183*eaa62e82SManish V Badarkhe 184*eaa62e82SManish V Badarkhe if ((psa_alg == PSA_ALG_NONE) || (psa_key_type == PSA_KEY_TYPE_NONE)) { 18538f89369SManish V Badarkhe rc = CRYPTO_ERR_SIGNATURE; 186*eaa62e82SManish V Badarkhe goto end2; 18738f89369SManish V Badarkhe } 18838f89369SManish V Badarkhe 189*eaa62e82SManish V Badarkhe /* filled-in key_attributes */ 190*eaa62e82SManish V Badarkhe psa_set_key_algorithm(&psa_key_attr, psa_alg); 191*eaa62e82SManish V Badarkhe psa_set_key_type(&psa_key_attr, psa_key_type); 192*eaa62e82SManish V Badarkhe psa_set_key_usage_flags(&psa_key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE); 193*eaa62e82SManish V Badarkhe 194*eaa62e82SManish V Badarkhe /* Get the key_id using import API */ 195*eaa62e82SManish V Badarkhe status = psa_import_key(&psa_key_attr, 196*eaa62e82SManish V Badarkhe pk_ptr, 197*eaa62e82SManish V Badarkhe (size_t)pk_len, 198*eaa62e82SManish V Badarkhe &psa_key_id); 199*eaa62e82SManish V Badarkhe 200*eaa62e82SManish V Badarkhe if (status != PSA_SUCCESS) { 201*eaa62e82SManish V Badarkhe rc = CRYPTO_ERR_SIGNATURE; 202*eaa62e82SManish V Badarkhe goto end2; 203*eaa62e82SManish V Badarkhe } 204*eaa62e82SManish V Badarkhe 205*eaa62e82SManish V Badarkhe /* 206*eaa62e82SManish V Badarkhe * Hash calculation and Signature verification of the given data payload 207*eaa62e82SManish V Badarkhe * is wrapped under the psa_verify_message function. 208*eaa62e82SManish V Badarkhe */ 209*eaa62e82SManish V Badarkhe status = psa_verify_message(psa_key_id, psa_alg, 210*eaa62e82SManish V Badarkhe data_ptr, data_len, 21138f89369SManish V Badarkhe signature.p, signature.len); 212*eaa62e82SManish V Badarkhe 213*eaa62e82SManish V Badarkhe if (status != PSA_SUCCESS) { 21438f89369SManish V Badarkhe rc = CRYPTO_ERR_SIGNATURE; 21538f89369SManish V Badarkhe goto end1; 21638f89369SManish V Badarkhe } 21738f89369SManish V Badarkhe 21838f89369SManish V Badarkhe /* Signature verification success */ 21938f89369SManish V Badarkhe rc = CRYPTO_SUCCESS; 22038f89369SManish V Badarkhe 22138f89369SManish V Badarkhe end1: 222*eaa62e82SManish V Badarkhe /* 223*eaa62e82SManish V Badarkhe * Destroy the key if it is created successfully 224*eaa62e82SManish V Badarkhe */ 225*eaa62e82SManish V Badarkhe psa_destroy_key(psa_key_id); 22638f89369SManish V Badarkhe end2: 22738f89369SManish V Badarkhe mbedtls_free(sig_opts); 22838f89369SManish V Badarkhe return rc; 22938f89369SManish V Badarkhe } 23038f89369SManish V Badarkhe 23138f89369SManish V Badarkhe /* 23238f89369SManish V Badarkhe * Match a hash 23338f89369SManish V Badarkhe * 23438f89369SManish V Badarkhe * Digest info is passed in DER format following the ASN.1 structure detailed 23538f89369SManish V Badarkhe * above. 23638f89369SManish V Badarkhe */ 23738f89369SManish V Badarkhe static int verify_hash(void *data_ptr, unsigned int data_len, 23838f89369SManish V Badarkhe void *digest_info_ptr, unsigned int digest_info_len) 23938f89369SManish V Badarkhe { 24038f89369SManish V Badarkhe mbedtls_asn1_buf hash_oid, params; 24138f89369SManish V Badarkhe mbedtls_md_type_t md_alg; 24238f89369SManish V Badarkhe unsigned char *p, *end, *hash; 24338f89369SManish V Badarkhe size_t len; 24438f89369SManish V Badarkhe int rc; 2452ed061c4SManish V Badarkhe psa_status_t status; 2462ed061c4SManish V Badarkhe psa_algorithm_t psa_md_alg; 24738f89369SManish V Badarkhe 24838f89369SManish V Badarkhe /* 24938f89369SManish V Badarkhe * Digest info should be an MBEDTLS_ASN1_SEQUENCE, but padding after 25038f89369SManish V Badarkhe * it is allowed. This is necessary to support multiple hash 25138f89369SManish V Badarkhe * algorithms. 25238f89369SManish V Badarkhe */ 25338f89369SManish V Badarkhe p = (unsigned char *)digest_info_ptr; 25438f89369SManish V Badarkhe end = p + digest_info_len; 25538f89369SManish V Badarkhe rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | 25638f89369SManish V Badarkhe MBEDTLS_ASN1_SEQUENCE); 25738f89369SManish V Badarkhe if (rc != 0) { 25838f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 25938f89369SManish V Badarkhe } 26038f89369SManish V Badarkhe 26138f89369SManish V Badarkhe end = p + len; 26238f89369SManish V Badarkhe 26338f89369SManish V Badarkhe /* Get the hash algorithm */ 26438f89369SManish V Badarkhe rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms); 26538f89369SManish V Badarkhe if (rc != 0) { 26638f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 26738f89369SManish V Badarkhe } 26838f89369SManish V Badarkhe 26938f89369SManish V Badarkhe /* Hash should be octet string type and consume all bytes */ 27038f89369SManish V Badarkhe rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); 27138f89369SManish V Badarkhe if ((rc != 0) || ((size_t)(end - p) != len)) { 27238f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 27338f89369SManish V Badarkhe } 27438f89369SManish V Badarkhe hash = p; 27538f89369SManish V Badarkhe 2762ed061c4SManish V Badarkhe rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg); 27738f89369SManish V Badarkhe if (rc != 0) { 27838f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 27938f89369SManish V Badarkhe } 28038f89369SManish V Badarkhe 2812ed061c4SManish V Badarkhe /* convert the md_alg to psa_algo */ 2822ed061c4SManish V Badarkhe psa_md_alg = mbedtls_md_psa_alg_from_type(md_alg); 2832ed061c4SManish V Badarkhe 2842ed061c4SManish V Badarkhe /* Length of hash must match the algorithm's size */ 2852ed061c4SManish V Badarkhe if (len != PSA_HASH_LENGTH(psa_md_alg)) { 2862ed061c4SManish V Badarkhe return CRYPTO_ERR_HASH; 2872ed061c4SManish V Badarkhe } 2882ed061c4SManish V Badarkhe 2892ed061c4SManish V Badarkhe /* 2902ed061c4SManish V Badarkhe * Calculate Hash and compare it against the retrieved hash from 2912ed061c4SManish V Badarkhe * the certificate (one shot API). 2922ed061c4SManish V Badarkhe */ 2932ed061c4SManish V Badarkhe status = psa_hash_compare(psa_md_alg, 2942ed061c4SManish V Badarkhe data_ptr, (size_t)data_len, 2952ed061c4SManish V Badarkhe (const uint8_t *)hash, len); 2962ed061c4SManish V Badarkhe 2972ed061c4SManish V Badarkhe if (status != PSA_SUCCESS) { 29838f89369SManish V Badarkhe return CRYPTO_ERR_HASH; 29938f89369SManish V Badarkhe } 30038f89369SManish V Badarkhe 30138f89369SManish V Badarkhe return CRYPTO_SUCCESS; 30238f89369SManish V Badarkhe } 30338f89369SManish V Badarkhe #endif /* 30438f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \ 30538f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 30638f89369SManish V Badarkhe */ 30738f89369SManish V Badarkhe 30838f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 30938f89369SManish V Badarkhe CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 31038f89369SManish V Badarkhe /* 31138f89369SManish V Badarkhe * Map a generic crypto message digest algorithm to the corresponding macro used 31238f89369SManish V Badarkhe * by Mbed TLS. 31338f89369SManish V Badarkhe */ 31438f89369SManish V Badarkhe static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo) 31538f89369SManish V Badarkhe { 31638f89369SManish V Badarkhe switch (algo) { 31738f89369SManish V Badarkhe case CRYPTO_MD_SHA512: 31838f89369SManish V Badarkhe return MBEDTLS_MD_SHA512; 31938f89369SManish V Badarkhe case CRYPTO_MD_SHA384: 32038f89369SManish V Badarkhe return MBEDTLS_MD_SHA384; 32138f89369SManish V Badarkhe case CRYPTO_MD_SHA256: 32238f89369SManish V Badarkhe return MBEDTLS_MD_SHA256; 32338f89369SManish V Badarkhe default: 32438f89369SManish V Badarkhe /* Invalid hash algorithm. */ 32538f89369SManish V Badarkhe return MBEDTLS_MD_NONE; 32638f89369SManish V Badarkhe } 32738f89369SManish V Badarkhe } 32838f89369SManish V Badarkhe 32938f89369SManish V Badarkhe /* 33038f89369SManish V Badarkhe * Calculate a hash 33138f89369SManish V Badarkhe * 33238f89369SManish V Badarkhe * output points to the computed hash 33338f89369SManish V Badarkhe */ 33438f89369SManish V Badarkhe static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr, 33538f89369SManish V Badarkhe unsigned int data_len, 33638f89369SManish V Badarkhe unsigned char output[CRYPTO_MD_MAX_SIZE]) 33738f89369SManish V Badarkhe { 338484b5869SManish V Badarkhe size_t hash_length; 339484b5869SManish V Badarkhe psa_status_t status; 340484b5869SManish V Badarkhe psa_algorithm_t psa_md_alg; 34138f89369SManish V Badarkhe 342484b5869SManish V Badarkhe /* convert the md_alg to psa_algo */ 343484b5869SManish V Badarkhe psa_md_alg = mbedtls_md_psa_alg_from_type(md_type(md_algo)); 34438f89369SManish V Badarkhe 34538f89369SManish V Badarkhe /* 34638f89369SManish V Badarkhe * Calculate the hash of the data, it is safe to pass the 34738f89369SManish V Badarkhe * 'output' hash buffer pointer considering its size is always 34838f89369SManish V Badarkhe * bigger than or equal to MBEDTLS_MD_MAX_SIZE. 34938f89369SManish V Badarkhe */ 350484b5869SManish V Badarkhe status = psa_hash_compute(psa_md_alg, data_ptr, (size_t)data_len, 351484b5869SManish V Badarkhe (uint8_t *)output, CRYPTO_MD_MAX_SIZE, 352484b5869SManish V Badarkhe &hash_length); 353484b5869SManish V Badarkhe if (status != PSA_SUCCESS) { 354484b5869SManish V Badarkhe return CRYPTO_ERR_HASH; 355484b5869SManish V Badarkhe } 356484b5869SManish V Badarkhe 357484b5869SManish V Badarkhe return CRYPTO_SUCCESS; 35838f89369SManish V Badarkhe } 35938f89369SManish V Badarkhe #endif /* 36038f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \ 36138f89369SManish V Badarkhe * CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 36238f89369SManish V Badarkhe */ 36338f89369SManish V Badarkhe 36438f89369SManish V Badarkhe #if TF_MBEDTLS_USE_AES_GCM 36538f89369SManish V Badarkhe /* 36638f89369SManish V Badarkhe * Stack based buffer allocation for decryption operation. It could 36738f89369SManish V Badarkhe * be configured to balance stack usage vs execution speed. 36838f89369SManish V Badarkhe */ 36938f89369SManish V Badarkhe #define DEC_OP_BUF_SIZE 128 37038f89369SManish V Badarkhe 37138f89369SManish V Badarkhe static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key, 37238f89369SManish V Badarkhe unsigned int key_len, const void *iv, 37338f89369SManish V Badarkhe unsigned int iv_len, const void *tag, 37438f89369SManish V Badarkhe unsigned int tag_len) 37538f89369SManish V Badarkhe { 37638f89369SManish V Badarkhe mbedtls_gcm_context ctx; 37738f89369SManish V Badarkhe mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; 37838f89369SManish V Badarkhe unsigned char buf[DEC_OP_BUF_SIZE]; 37938f89369SManish V Badarkhe unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE]; 38038f89369SManish V Badarkhe unsigned char *pt = data_ptr; 38138f89369SManish V Badarkhe size_t dec_len; 38238f89369SManish V Badarkhe int diff, i, rc; 38338f89369SManish V Badarkhe size_t output_length __unused; 38438f89369SManish V Badarkhe 38538f89369SManish V Badarkhe mbedtls_gcm_init(&ctx); 38638f89369SManish V Badarkhe 38738f89369SManish V Badarkhe rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8); 38838f89369SManish V Badarkhe if (rc != 0) { 38938f89369SManish V Badarkhe rc = CRYPTO_ERR_DECRYPTION; 39038f89369SManish V Badarkhe goto exit_gcm; 39138f89369SManish V Badarkhe } 39238f89369SManish V Badarkhe 39338f89369SManish V Badarkhe #if (MBEDTLS_VERSION_MAJOR < 3) 39438f89369SManish V Badarkhe rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0); 39538f89369SManish V Badarkhe #else 39638f89369SManish V Badarkhe rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len); 39738f89369SManish V Badarkhe #endif 39838f89369SManish V Badarkhe if (rc != 0) { 39938f89369SManish V Badarkhe rc = CRYPTO_ERR_DECRYPTION; 40038f89369SManish V Badarkhe goto exit_gcm; 40138f89369SManish V Badarkhe } 40238f89369SManish V Badarkhe 40338f89369SManish V Badarkhe while (len > 0) { 40438f89369SManish V Badarkhe dec_len = MIN(sizeof(buf), len); 40538f89369SManish V Badarkhe 40638f89369SManish V Badarkhe #if (MBEDTLS_VERSION_MAJOR < 3) 40738f89369SManish V Badarkhe rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf); 40838f89369SManish V Badarkhe #else 40938f89369SManish V Badarkhe rc = mbedtls_gcm_update(&ctx, pt, dec_len, buf, sizeof(buf), &output_length); 41038f89369SManish V Badarkhe #endif 41138f89369SManish V Badarkhe 41238f89369SManish V Badarkhe if (rc != 0) { 41338f89369SManish V Badarkhe rc = CRYPTO_ERR_DECRYPTION; 41438f89369SManish V Badarkhe goto exit_gcm; 41538f89369SManish V Badarkhe } 41638f89369SManish V Badarkhe 41738f89369SManish V Badarkhe memcpy(pt, buf, dec_len); 41838f89369SManish V Badarkhe pt += dec_len; 41938f89369SManish V Badarkhe len -= dec_len; 42038f89369SManish V Badarkhe } 42138f89369SManish V Badarkhe 42238f89369SManish V Badarkhe #if (MBEDTLS_VERSION_MAJOR < 3) 42338f89369SManish V Badarkhe rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf)); 42438f89369SManish V Badarkhe #else 42538f89369SManish V Badarkhe rc = mbedtls_gcm_finish(&ctx, NULL, 0, &output_length, tag_buf, sizeof(tag_buf)); 42638f89369SManish V Badarkhe #endif 42738f89369SManish V Badarkhe 42838f89369SManish V Badarkhe if (rc != 0) { 42938f89369SManish V Badarkhe rc = CRYPTO_ERR_DECRYPTION; 43038f89369SManish V Badarkhe goto exit_gcm; 43138f89369SManish V Badarkhe } 43238f89369SManish V Badarkhe 43338f89369SManish V Badarkhe /* Check tag in "constant-time" */ 43438f89369SManish V Badarkhe for (diff = 0, i = 0; i < tag_len; i++) 43538f89369SManish V Badarkhe diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i]; 43638f89369SManish V Badarkhe 43738f89369SManish V Badarkhe if (diff != 0) { 43838f89369SManish V Badarkhe rc = CRYPTO_ERR_DECRYPTION; 43938f89369SManish V Badarkhe goto exit_gcm; 44038f89369SManish V Badarkhe } 44138f89369SManish V Badarkhe 44238f89369SManish V Badarkhe /* GCM decryption success */ 44338f89369SManish V Badarkhe rc = CRYPTO_SUCCESS; 44438f89369SManish V Badarkhe 44538f89369SManish V Badarkhe exit_gcm: 44638f89369SManish V Badarkhe mbedtls_gcm_free(&ctx); 44738f89369SManish V Badarkhe return rc; 44838f89369SManish V Badarkhe } 44938f89369SManish V Badarkhe 45038f89369SManish V Badarkhe /* 45138f89369SManish V Badarkhe * Authenticated decryption of an image 45238f89369SManish V Badarkhe */ 45338f89369SManish V Badarkhe static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, 45438f89369SManish V Badarkhe size_t len, const void *key, unsigned int key_len, 45538f89369SManish V Badarkhe unsigned int key_flags, const void *iv, 45638f89369SManish V Badarkhe unsigned int iv_len, const void *tag, 45738f89369SManish V Badarkhe unsigned int tag_len) 45838f89369SManish V Badarkhe { 45938f89369SManish V Badarkhe int rc; 46038f89369SManish V Badarkhe 46138f89369SManish V Badarkhe assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0); 46238f89369SManish V Badarkhe 46338f89369SManish V Badarkhe switch (dec_algo) { 46438f89369SManish V Badarkhe case CRYPTO_GCM_DECRYPT: 46538f89369SManish V Badarkhe rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len, 46638f89369SManish V Badarkhe tag, tag_len); 46738f89369SManish V Badarkhe if (rc != 0) 46838f89369SManish V Badarkhe return rc; 46938f89369SManish V Badarkhe break; 47038f89369SManish V Badarkhe default: 47138f89369SManish V Badarkhe return CRYPTO_ERR_DECRYPTION; 47238f89369SManish V Badarkhe } 47338f89369SManish V Badarkhe 47438f89369SManish V Badarkhe return CRYPTO_SUCCESS; 47538f89369SManish V Badarkhe } 47638f89369SManish V Badarkhe #endif /* TF_MBEDTLS_USE_AES_GCM */ 47738f89369SManish V Badarkhe 47838f89369SManish V Badarkhe /* 47938f89369SManish V Badarkhe * Register crypto library descriptor 48038f89369SManish V Badarkhe */ 48138f89369SManish V Badarkhe #if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC 48238f89369SManish V Badarkhe #if TF_MBEDTLS_USE_AES_GCM 48338f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, 48438f89369SManish V Badarkhe auth_decrypt, NULL); 48538f89369SManish V Badarkhe #else 48638f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash, 48738f89369SManish V Badarkhe NULL, NULL); 48838f89369SManish V Badarkhe #endif 48938f89369SManish V Badarkhe #elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY 49038f89369SManish V Badarkhe #if TF_MBEDTLS_USE_AES_GCM 49138f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, 49238f89369SManish V Badarkhe auth_decrypt, NULL); 49338f89369SManish V Badarkhe #else 49438f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL, 49538f89369SManish V Badarkhe NULL, NULL); 49638f89369SManish V Badarkhe #endif 49738f89369SManish V Badarkhe #elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY 49838f89369SManish V Badarkhe REGISTER_CRYPTO_LIB(LIB_NAME, init, NULL, NULL, calc_hash, NULL, NULL); 49938f89369SManish V Badarkhe #endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */ 500