1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2022-2023, STMicroelectronics - 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 <endian.h> 9*91f16700Schasinglulu #include <errno.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <common/debug.h> 12*91f16700Schasinglulu #include <drivers/auth/crypto_mod.h> 13*91f16700Schasinglulu #include <drivers/io/io_storage.h> 14*91f16700Schasinglulu #include <drivers/st/bsec.h> 15*91f16700Schasinglulu #include <drivers/st/stm32_hash.h> 16*91f16700Schasinglulu #include <drivers/st/stm32_pka.h> 17*91f16700Schasinglulu #include <drivers/st/stm32_rng.h> 18*91f16700Schasinglulu #include <drivers/st/stm32_saes.h> 19*91f16700Schasinglulu #include <lib/utils.h> 20*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables_v2.h> 21*91f16700Schasinglulu #include <mbedtls/asn1.h> 22*91f16700Schasinglulu #include <mbedtls/md.h> 23*91f16700Schasinglulu #include <mbedtls/oid.h> 24*91f16700Schasinglulu #include <mbedtls/platform.h> 25*91f16700Schasinglulu #include <mbedtls/x509.h> 26*91f16700Schasinglulu #include <plat/common/platform.h> 27*91f16700Schasinglulu #include <tools_share/firmware_encrypted.h> 28*91f16700Schasinglulu 29*91f16700Schasinglulu #include <platform_def.h> 30*91f16700Schasinglulu 31*91f16700Schasinglulu #define CRYPTO_HASH_MAX_SIZE 32U 32*91f16700Schasinglulu #define CRYPTO_SIGN_MAX_SIZE 64U 33*91f16700Schasinglulu #define CRYPTO_PUBKEY_MAX_SIZE 64U 34*91f16700Schasinglulu #define CRYPTO_MAX_TAG_SIZE 16U 35*91f16700Schasinglulu 36*91f16700Schasinglulu /* brainpoolP256t1 OID is not defined in mbedTLS */ 37*91f16700Schasinglulu #define OID_EC_GRP_BP256T1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x08" 38*91f16700Schasinglulu 39*91f16700Schasinglulu #if STM32MP_CRYPTO_ROM_LIB 40*91f16700Schasinglulu struct stm32mp_auth_ops { 41*91f16700Schasinglulu uint32_t (*verify_signature)(uint8_t *hash_in, uint8_t *pubkey_in, 42*91f16700Schasinglulu uint8_t *signature, uint32_t ecc_algo); 43*91f16700Schasinglulu }; 44*91f16700Schasinglulu 45*91f16700Schasinglulu static struct stm32mp_auth_ops auth_ops; 46*91f16700Schasinglulu #endif 47*91f16700Schasinglulu 48*91f16700Schasinglulu static void crypto_lib_init(void) 49*91f16700Schasinglulu { 50*91f16700Schasinglulu boot_api_context_t *boot_context __maybe_unused; 51*91f16700Schasinglulu int ret; 52*91f16700Schasinglulu 53*91f16700Schasinglulu NOTICE("TRUSTED_BOARD_BOOT support enabled\n"); 54*91f16700Schasinglulu 55*91f16700Schasinglulu ret = stm32_hash_register(); 56*91f16700Schasinglulu if (ret != 0) { 57*91f16700Schasinglulu ERROR("HASH init (%d)\n", ret); 58*91f16700Schasinglulu panic(); 59*91f16700Schasinglulu } 60*91f16700Schasinglulu 61*91f16700Schasinglulu if (stm32mp_is_closed_device() || stm32mp_is_auth_supported()) { 62*91f16700Schasinglulu #if STM32MP_CRYPTO_ROM_LIB 63*91f16700Schasinglulu boot_context = (boot_api_context_t *)stm32mp_get_boot_ctx_address(); 64*91f16700Schasinglulu auth_ops.verify_signature = boot_context->bootrom_ecdsa_verify_signature; 65*91f16700Schasinglulu #else 66*91f16700Schasinglulu /* Use hardware peripherals */ 67*91f16700Schasinglulu if (stm32_rng_init() != 0) { 68*91f16700Schasinglulu panic(); 69*91f16700Schasinglulu } 70*91f16700Schasinglulu 71*91f16700Schasinglulu if (stm32_saes_driver_init() != 0) { 72*91f16700Schasinglulu panic(); 73*91f16700Schasinglulu } 74*91f16700Schasinglulu 75*91f16700Schasinglulu if (stm32_pka_init() != 0) { 76*91f16700Schasinglulu panic(); 77*91f16700Schasinglulu } 78*91f16700Schasinglulu #endif 79*91f16700Schasinglulu } 80*91f16700Schasinglulu } 81*91f16700Schasinglulu 82*91f16700Schasinglulu static int get_plain_pk_from_asn1(void *pk_ptr, unsigned int pk_len, void **plain_pk, 83*91f16700Schasinglulu size_t *len, int *pk_alg) 84*91f16700Schasinglulu { 85*91f16700Schasinglulu int ret; 86*91f16700Schasinglulu mbedtls_pk_context mbedtls_pk = {0}; 87*91f16700Schasinglulu unsigned char *p, *end; 88*91f16700Schasinglulu mbedtls_asn1_buf alg_params = {0}; 89*91f16700Schasinglulu mbedtls_asn1_buf alg_oid = {0}; 90*91f16700Schasinglulu 91*91f16700Schasinglulu *plain_pk = NULL; 92*91f16700Schasinglulu *len = 0U; 93*91f16700Schasinglulu 94*91f16700Schasinglulu /* Parse the public key */ 95*91f16700Schasinglulu mbedtls_pk_init(&mbedtls_pk); 96*91f16700Schasinglulu p = (unsigned char *)pk_ptr; 97*91f16700Schasinglulu end = (unsigned char *)(p + pk_len); 98*91f16700Schasinglulu 99*91f16700Schasinglulu ret = mbedtls_asn1_get_tag(&p, end, len, 100*91f16700Schasinglulu MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); 101*91f16700Schasinglulu if (ret != 0) { 102*91f16700Schasinglulu return -EINVAL; 103*91f16700Schasinglulu } 104*91f16700Schasinglulu 105*91f16700Schasinglulu end = p + *len; 106*91f16700Schasinglulu ret = mbedtls_asn1_get_alg(&p, end, &alg_oid, &alg_params); 107*91f16700Schasinglulu if (ret != 0) { 108*91f16700Schasinglulu VERBOSE("%s: mbedtls_asn1_get_alg (%d)\n", __func__, ret); 109*91f16700Schasinglulu return -EINVAL; 110*91f16700Schasinglulu } 111*91f16700Schasinglulu 112*91f16700Schasinglulu if (pk_alg != NULL) { 113*91f16700Schasinglulu if ((strlen(MBEDTLS_OID_EC_GRP_SECP256R1) == alg_params.len) && 114*91f16700Schasinglulu (memcmp(MBEDTLS_OID_EC_GRP_SECP256R1, alg_params.p, alg_params.len) == 0)) { 115*91f16700Schasinglulu *pk_alg = BOOT_API_ECDSA_ALGO_TYPE_P256NIST; 116*91f16700Schasinglulu } else if ((strlen(OID_EC_GRP_BP256T1) == alg_params.len) && 117*91f16700Schasinglulu (memcmp(OID_EC_GRP_BP256T1, alg_params.p, alg_params.len) == 0)) { 118*91f16700Schasinglulu *pk_alg = BOOT_API_ECDSA_ALGO_TYPE_BRAINPOOL256; 119*91f16700Schasinglulu } else { 120*91f16700Schasinglulu ERROR("%s: Algorithm is not supported\n", __func__); 121*91f16700Schasinglulu return -EINVAL; 122*91f16700Schasinglulu } 123*91f16700Schasinglulu } 124*91f16700Schasinglulu 125*91f16700Schasinglulu ret = mbedtls_asn1_get_bitstring_null(&p, end, len); 126*91f16700Schasinglulu if (ret != 0) { 127*91f16700Schasinglulu VERBOSE("%s: mbedtls_asn1_get_bitstring_null (%d)\n", __func__, ret); 128*91f16700Schasinglulu return -EINVAL; 129*91f16700Schasinglulu } 130*91f16700Schasinglulu 131*91f16700Schasinglulu /* We remove the ident (0x04) first byte. */ 132*91f16700Schasinglulu if ((*len < 1U) || (p[0] != MBEDTLS_ASN1_OCTET_STRING)) { 133*91f16700Schasinglulu VERBOSE("%s: not expected len or tag\n", __func__); 134*91f16700Schasinglulu return -EINVAL; 135*91f16700Schasinglulu } 136*91f16700Schasinglulu 137*91f16700Schasinglulu *len = *len - 1U; 138*91f16700Schasinglulu *plain_pk = p + 1U; 139*91f16700Schasinglulu 140*91f16700Schasinglulu return 0; 141*91f16700Schasinglulu } 142*91f16700Schasinglulu 143*91f16700Schasinglulu #if STM32MP_CRYPTO_ROM_LIB 144*91f16700Schasinglulu uint32_t verify_signature(uint8_t *hash_in, uint8_t *pubkey_in, 145*91f16700Schasinglulu uint8_t *signature, uint32_t ecc_algo) 146*91f16700Schasinglulu { 147*91f16700Schasinglulu int ret; 148*91f16700Schasinglulu 149*91f16700Schasinglulu ret = mmap_add_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_BASE, 150*91f16700Schasinglulu STM32MP_ROM_SIZE_2MB_ALIGNED, MT_CODE | MT_SECURE); 151*91f16700Schasinglulu if (ret != 0) { 152*91f16700Schasinglulu VERBOSE("%s: mmap_add_dynamic_region (%d)\n", __func__, ret); 153*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 154*91f16700Schasinglulu } 155*91f16700Schasinglulu 156*91f16700Schasinglulu ret = auth_ops.verify_signature(hash_in, pubkey_in, signature, ecc_algo); 157*91f16700Schasinglulu 158*91f16700Schasinglulu if (ret != BOOT_API_RETURN_OK) { 159*91f16700Schasinglulu VERBOSE("%s: auth_ops.verify_sign (%d)\n", __func__, ret); 160*91f16700Schasinglulu ret = CRYPTO_ERR_SIGNATURE; 161*91f16700Schasinglulu } else { 162*91f16700Schasinglulu ret = 0; 163*91f16700Schasinglulu } 164*91f16700Schasinglulu 165*91f16700Schasinglulu mmap_remove_dynamic_region(STM32MP_ROM_BASE, STM32MP_ROM_SIZE_2MB_ALIGNED); 166*91f16700Schasinglulu 167*91f16700Schasinglulu return ret; 168*91f16700Schasinglulu } 169*91f16700Schasinglulu 170*91f16700Schasinglulu static int crypto_convert_pk(void *full_pk_ptr, unsigned int full_pk_len, 171*91f16700Schasinglulu void **hashed_pk_ptr, unsigned int *hashed_pk_len) 172*91f16700Schasinglulu { 173*91f16700Schasinglulu size_t len; 174*91f16700Schasinglulu int ret; 175*91f16700Schasinglulu 176*91f16700Schasinglulu ret = get_plain_pk_from_asn1(full_pk_ptr, full_pk_len, hashed_pk_ptr, &len, NULL); 177*91f16700Schasinglulu if (ret == 0) { 178*91f16700Schasinglulu *hashed_pk_len = (unsigned int)len; 179*91f16700Schasinglulu } 180*91f16700Schasinglulu 181*91f16700Schasinglulu return ret; 182*91f16700Schasinglulu } 183*91f16700Schasinglulu #else /* STM32MP_CRYPTO_ROM_LIB*/ 184*91f16700Schasinglulu static uint32_t verify_signature(uint8_t *hash_in, uint8_t *pubkey_in, 185*91f16700Schasinglulu uint8_t *signature, uint32_t ecc_algo) 186*91f16700Schasinglulu { 187*91f16700Schasinglulu int ret = -1; 188*91f16700Schasinglulu enum stm32_pka_ecdsa_curve_id cid; 189*91f16700Schasinglulu 190*91f16700Schasinglulu switch (ecc_algo) { 191*91f16700Schasinglulu case BOOT_API_ECDSA_ALGO_TYPE_P256NIST: 192*91f16700Schasinglulu #if PKA_USE_NIST_P256 193*91f16700Schasinglulu cid = PKA_NIST_P256; 194*91f16700Schasinglulu ret = 0; 195*91f16700Schasinglulu #else 196*91f16700Schasinglulu WARN("%s nist_p256 requested but not included\n", __func__); 197*91f16700Schasinglulu #endif 198*91f16700Schasinglulu break; 199*91f16700Schasinglulu case BOOT_API_ECDSA_ALGO_TYPE_BRAINPOOL256: 200*91f16700Schasinglulu #if PKA_USE_BRAINPOOL_P256T1 201*91f16700Schasinglulu cid = PKA_BRAINPOOL_P256T1; 202*91f16700Schasinglulu ret = 0; 203*91f16700Schasinglulu #else 204*91f16700Schasinglulu WARN("%s brainpool_p256t1 requested but not included\n", __func__); 205*91f16700Schasinglulu #endif 206*91f16700Schasinglulu break; 207*91f16700Schasinglulu default: 208*91f16700Schasinglulu WARN("%s unexpected ecc_algo(%u)\n", __func__, ecc_algo); 209*91f16700Schasinglulu break; 210*91f16700Schasinglulu } 211*91f16700Schasinglulu 212*91f16700Schasinglulu if (ret < 0) { 213*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 214*91f16700Schasinglulu } 215*91f16700Schasinglulu 216*91f16700Schasinglulu ret = stm32_pka_ecdsa_verif(hash_in, 217*91f16700Schasinglulu BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES, 218*91f16700Schasinglulu signature, BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES / 2U, 219*91f16700Schasinglulu signature + BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES / 2U, 220*91f16700Schasinglulu BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES / 2U, 221*91f16700Schasinglulu pubkey_in, BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES / 2U, 222*91f16700Schasinglulu pubkey_in + BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES / 2U, 223*91f16700Schasinglulu BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES / 2U, cid); 224*91f16700Schasinglulu if (ret < 0) { 225*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 226*91f16700Schasinglulu } 227*91f16700Schasinglulu 228*91f16700Schasinglulu return 0; 229*91f16700Schasinglulu } 230*91f16700Schasinglulu 231*91f16700Schasinglulu static int crypto_convert_pk(void *full_pk_ptr, unsigned int full_pk_len, 232*91f16700Schasinglulu void **hashed_pk_ptr, unsigned int *hashed_pk_len) 233*91f16700Schasinglulu { 234*91f16700Schasinglulu static uint8_t st_pk[CRYPTO_PUBKEY_MAX_SIZE + sizeof(uint32_t)]; 235*91f16700Schasinglulu int ret; 236*91f16700Schasinglulu void *plain_pk; 237*91f16700Schasinglulu size_t len; 238*91f16700Schasinglulu int curve_id; 239*91f16700Schasinglulu uint32_t cid; 240*91f16700Schasinglulu 241*91f16700Schasinglulu ret = get_plain_pk_from_asn1(full_pk_ptr, full_pk_len, &plain_pk, &len, &curve_id); 242*91f16700Schasinglulu if ((ret != 0) || (len > CRYPTO_PUBKEY_MAX_SIZE)) { 243*91f16700Schasinglulu return -EINVAL; 244*91f16700Schasinglulu } 245*91f16700Schasinglulu 246*91f16700Schasinglulu cid = curve_id; /* we want value of curve_id (1 or 2) in a uint32_t */ 247*91f16700Schasinglulu 248*91f16700Schasinglulu memcpy(st_pk, &cid, sizeof(cid)); 249*91f16700Schasinglulu memcpy(st_pk + sizeof(cid), plain_pk, len); 250*91f16700Schasinglulu 251*91f16700Schasinglulu *hashed_pk_ptr = st_pk; 252*91f16700Schasinglulu *hashed_pk_len = (unsigned int)(len + sizeof(cid)); 253*91f16700Schasinglulu 254*91f16700Schasinglulu return 0; 255*91f16700Schasinglulu } 256*91f16700Schasinglulu #endif /* STM32MP_CRYPTO_ROM_LIB */ 257*91f16700Schasinglulu 258*91f16700Schasinglulu static int get_plain_digest_from_asn1(void *digest_ptr, unsigned int digest_len, 259*91f16700Schasinglulu uint8_t **out, size_t *out_len, mbedtls_md_type_t *md_alg) 260*91f16700Schasinglulu { 261*91f16700Schasinglulu int ret; 262*91f16700Schasinglulu mbedtls_asn1_buf hash_oid, params; 263*91f16700Schasinglulu size_t len; 264*91f16700Schasinglulu unsigned char *p, *end; 265*91f16700Schasinglulu 266*91f16700Schasinglulu *out = NULL; 267*91f16700Schasinglulu *out_len = 0U; 268*91f16700Schasinglulu 269*91f16700Schasinglulu /* Digest info should be an MBEDTLS_ASN1_SEQUENCE */ 270*91f16700Schasinglulu p = (unsigned char *)digest_ptr; 271*91f16700Schasinglulu end = p + digest_len; 272*91f16700Schasinglulu ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | 273*91f16700Schasinglulu MBEDTLS_ASN1_SEQUENCE); 274*91f16700Schasinglulu if (ret != 0) { 275*91f16700Schasinglulu return ret; 276*91f16700Schasinglulu } 277*91f16700Schasinglulu 278*91f16700Schasinglulu /* Get the hash algorithm */ 279*91f16700Schasinglulu ret = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms); 280*91f16700Schasinglulu if (ret != 0) { 281*91f16700Schasinglulu return ret; 282*91f16700Schasinglulu } 283*91f16700Schasinglulu 284*91f16700Schasinglulu ret = mbedtls_oid_get_md_alg(&hash_oid, md_alg); 285*91f16700Schasinglulu if (ret != 0) { 286*91f16700Schasinglulu return ret; 287*91f16700Schasinglulu } 288*91f16700Schasinglulu 289*91f16700Schasinglulu ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); 290*91f16700Schasinglulu if (ret != 0) { 291*91f16700Schasinglulu return ret; 292*91f16700Schasinglulu } 293*91f16700Schasinglulu 294*91f16700Schasinglulu /* Length of hash must match the algorithm's size */ 295*91f16700Schasinglulu if (len != BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES) { 296*91f16700Schasinglulu return -1; 297*91f16700Schasinglulu } 298*91f16700Schasinglulu 299*91f16700Schasinglulu *out = p; 300*91f16700Schasinglulu *out_len = len; 301*91f16700Schasinglulu 302*91f16700Schasinglulu return 0; 303*91f16700Schasinglulu } 304*91f16700Schasinglulu 305*91f16700Schasinglulu static int crypto_verify_signature(void *data_ptr, unsigned int data_len, 306*91f16700Schasinglulu void *sig_ptr, unsigned int sig_len, 307*91f16700Schasinglulu void *sig_alg, unsigned int sig_alg_len, 308*91f16700Schasinglulu void *pk_ptr, unsigned int pk_len) 309*91f16700Schasinglulu { 310*91f16700Schasinglulu uint8_t image_hash[CRYPTO_HASH_MAX_SIZE] = {0}; 311*91f16700Schasinglulu uint8_t sig[CRYPTO_SIGN_MAX_SIZE]; 312*91f16700Schasinglulu uint8_t my_pk[CRYPTO_PUBKEY_MAX_SIZE]; 313*91f16700Schasinglulu int ret; 314*91f16700Schasinglulu size_t len; 315*91f16700Schasinglulu mbedtls_asn1_sequence seq; 316*91f16700Schasinglulu mbedtls_asn1_sequence *cur; 317*91f16700Schasinglulu unsigned char *p, *end; 318*91f16700Schasinglulu int curve_id; 319*91f16700Schasinglulu mbedtls_asn1_buf sig_oid, sig_params; 320*91f16700Schasinglulu mbedtls_md_type_t md_alg; 321*91f16700Schasinglulu mbedtls_pk_type_t pk_alg; 322*91f16700Schasinglulu size_t bignum_len = sizeof(sig) / 2U; 323*91f16700Schasinglulu unsigned int seq_num = 0U; 324*91f16700Schasinglulu 325*91f16700Schasinglulu if (!stm32mp_is_closed_device() && !stm32mp_is_auth_supported()) { 326*91f16700Schasinglulu return CRYPTO_SUCCESS; 327*91f16700Schasinglulu } 328*91f16700Schasinglulu 329*91f16700Schasinglulu /* Get pointers to signature OID and parameters */ 330*91f16700Schasinglulu p = (unsigned char *)sig_alg; 331*91f16700Schasinglulu end = (unsigned char *)(p + sig_alg_len); 332*91f16700Schasinglulu ret = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params); 333*91f16700Schasinglulu if (ret != 0) { 334*91f16700Schasinglulu VERBOSE("%s: mbedtls_asn1_get_alg (%d)\n", __func__, ret); 335*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 336*91f16700Schasinglulu } 337*91f16700Schasinglulu 338*91f16700Schasinglulu /* Get the actual signature algorithm (MD + PK) */ 339*91f16700Schasinglulu ret = mbedtls_oid_get_sig_alg(&sig_oid, &md_alg, &pk_alg); 340*91f16700Schasinglulu if (ret != 0) { 341*91f16700Schasinglulu VERBOSE("%s: mbedtls_oid_get_sig_alg (%d)\n", __func__, ret); 342*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 343*91f16700Schasinglulu } 344*91f16700Schasinglulu 345*91f16700Schasinglulu if ((md_alg != MBEDTLS_MD_SHA256) || (pk_alg != MBEDTLS_PK_ECDSA)) { 346*91f16700Schasinglulu VERBOSE("%s: md_alg=%u pk_alg=%u\n", __func__, md_alg, pk_alg); 347*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 348*91f16700Schasinglulu } 349*91f16700Schasinglulu 350*91f16700Schasinglulu ret = get_plain_pk_from_asn1(pk_ptr, pk_len, &pk_ptr, &len, &curve_id); 351*91f16700Schasinglulu if (ret != 0) { 352*91f16700Schasinglulu VERBOSE("%s: get_plain_pk_from_asn1 (%d)\n", __func__, ret); 353*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 354*91f16700Schasinglulu } 355*91f16700Schasinglulu 356*91f16700Schasinglulu /* We expect a known pk_len */ 357*91f16700Schasinglulu if (len != sizeof(my_pk)) { 358*91f16700Schasinglulu VERBOSE("%s: pk_len=%zu sizeof(my_pk)=%zu)\n", __func__, len, sizeof(my_pk)); 359*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 360*91f16700Schasinglulu } 361*91f16700Schasinglulu 362*91f16700Schasinglulu /* Need to copy as auth_ops.verify_signature 363*91f16700Schasinglulu * expects aligned public key. 364*91f16700Schasinglulu */ 365*91f16700Schasinglulu memcpy(my_pk, pk_ptr, sizeof(my_pk)); 366*91f16700Schasinglulu 367*91f16700Schasinglulu /* Get the signature (bitstring) */ 368*91f16700Schasinglulu p = (unsigned char *)sig_ptr; 369*91f16700Schasinglulu end = (unsigned char *)(p + sig_len); 370*91f16700Schasinglulu ret = mbedtls_asn1_get_bitstring_null(&p, end, &len); 371*91f16700Schasinglulu if (ret != 0) { 372*91f16700Schasinglulu VERBOSE("%s: mbedtls_asn1_get_bitstring_null (%d)\n", __func__, ret); 373*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 374*91f16700Schasinglulu } 375*91f16700Schasinglulu 376*91f16700Schasinglulu /* Get r and s from sequence */ 377*91f16700Schasinglulu ret = mbedtls_asn1_get_sequence_of(&p, end, &seq, MBEDTLS_ASN1_INTEGER); 378*91f16700Schasinglulu if (ret != 0) { 379*91f16700Schasinglulu VERBOSE("%s: mbedtls_asn1_get_sequence_of (%d)\n", __func__, ret); 380*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 381*91f16700Schasinglulu } 382*91f16700Schasinglulu 383*91f16700Schasinglulu /* We expect only 2 integers (r and s) from the sequence */ 384*91f16700Schasinglulu if (seq.next->next != NULL) { 385*91f16700Schasinglulu cur = seq.next; 386*91f16700Schasinglulu mbedtls_asn1_sequence *next; 387*91f16700Schasinglulu 388*91f16700Schasinglulu VERBOSE("%s: nb seq != 2\n", __func__); 389*91f16700Schasinglulu /* Free all the sequences */ 390*91f16700Schasinglulu while (cur != NULL) { 391*91f16700Schasinglulu next = cur->next; 392*91f16700Schasinglulu mbedtls_free(cur); 393*91f16700Schasinglulu cur = next; 394*91f16700Schasinglulu } 395*91f16700Schasinglulu 396*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 397*91f16700Schasinglulu } 398*91f16700Schasinglulu 399*91f16700Schasinglulu /* 400*91f16700Schasinglulu * ECDSA signatures are composed of a tuple (R,S) where R and S are between 0 and n. 401*91f16700Schasinglulu * This means that the R and S can have a maximum of 32 each, but can also be smaller. 402*91f16700Schasinglulu * Also seen the integer sequence may (sometime) start with 0x00 as MSB, but we can only 403*91f16700Schasinglulu * manage exactly 2*32 bytes, we remove this higher byte if there are not 00, 404*91f16700Schasinglulu * we will fail either. 405*91f16700Schasinglulu */ 406*91f16700Schasinglulu cur = &seq; 407*91f16700Schasinglulu memset(sig, 0U, sizeof(sig)); 408*91f16700Schasinglulu 409*91f16700Schasinglulu while (cur != NULL) { 410*91f16700Schasinglulu size_t skip = 0U; 411*91f16700Schasinglulu size_t seek = seq_num * bignum_len; 412*91f16700Schasinglulu 413*91f16700Schasinglulu if (cur->buf.len > bignum_len) { 414*91f16700Schasinglulu /* Remove extra 0x00 bytes */ 415*91f16700Schasinglulu skip = cur->buf.len - bignum_len; 416*91f16700Schasinglulu } else if (cur->buf.len < bignum_len) { 417*91f16700Schasinglulu /* Add padding to match HW required size */ 418*91f16700Schasinglulu seek += (bignum_len % cur->buf.len); 419*91f16700Schasinglulu } 420*91f16700Schasinglulu 421*91f16700Schasinglulu if (seek + cur->buf.len > sizeof(sig) + skip) { 422*91f16700Schasinglulu panic(); 423*91f16700Schasinglulu } 424*91f16700Schasinglulu 425*91f16700Schasinglulu memcpy(sig + seek, cur->buf.p + skip, cur->buf.len - skip); 426*91f16700Schasinglulu cur = cur->next; 427*91f16700Schasinglulu seq_num++; 428*91f16700Schasinglulu } 429*91f16700Schasinglulu 430*91f16700Schasinglulu /* Need to free allocated 'next' in mbedtls_asn1_get_sequence_of */ 431*91f16700Schasinglulu mbedtls_free(seq.next); 432*91f16700Schasinglulu 433*91f16700Schasinglulu /* Compute hash for the data covered by the signature */ 434*91f16700Schasinglulu stm32_hash_init(HASH_SHA256); 435*91f16700Schasinglulu 436*91f16700Schasinglulu ret = stm32_hash_final_update((uint8_t *)data_ptr, data_len, image_hash); 437*91f16700Schasinglulu if (ret != 0) { 438*91f16700Schasinglulu VERBOSE("%s: stm32_hash_final_update (%d)\n", __func__, ret); 439*91f16700Schasinglulu return CRYPTO_ERR_SIGNATURE; 440*91f16700Schasinglulu } 441*91f16700Schasinglulu 442*91f16700Schasinglulu return verify_signature(image_hash, my_pk, sig, curve_id); 443*91f16700Schasinglulu } 444*91f16700Schasinglulu 445*91f16700Schasinglulu static int crypto_verify_hash(void *data_ptr, unsigned int data_len, 446*91f16700Schasinglulu void *digest_info_ptr, 447*91f16700Schasinglulu unsigned int digest_info_len) 448*91f16700Schasinglulu { 449*91f16700Schasinglulu int ret; 450*91f16700Schasinglulu uint8_t calc_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES]; 451*91f16700Schasinglulu unsigned char *p; 452*91f16700Schasinglulu mbedtls_md_type_t md_alg; 453*91f16700Schasinglulu size_t len; 454*91f16700Schasinglulu 455*91f16700Schasinglulu /* we receive an asn1 encapsulated digest, we flatten it */ 456*91f16700Schasinglulu ret = get_plain_digest_from_asn1(digest_info_ptr, 457*91f16700Schasinglulu digest_info_len, &p, &len, 458*91f16700Schasinglulu &md_alg); 459*91f16700Schasinglulu if ((ret != 0) || (md_alg != MBEDTLS_MD_SHA256) || (len != sizeof(calc_hash))) { 460*91f16700Schasinglulu return CRYPTO_ERR_HASH; 461*91f16700Schasinglulu } 462*91f16700Schasinglulu 463*91f16700Schasinglulu digest_info_ptr = p; 464*91f16700Schasinglulu digest_info_len = len; 465*91f16700Schasinglulu 466*91f16700Schasinglulu stm32_hash_init(HASH_SHA256); 467*91f16700Schasinglulu 468*91f16700Schasinglulu ret = stm32_hash_final_update(data_ptr, data_len, calc_hash); 469*91f16700Schasinglulu if (ret != 0) { 470*91f16700Schasinglulu VERBOSE("%s: hash failed\n", __func__); 471*91f16700Schasinglulu return CRYPTO_ERR_HASH; 472*91f16700Schasinglulu } 473*91f16700Schasinglulu 474*91f16700Schasinglulu ret = memcmp(calc_hash, digest_info_ptr, digest_info_len); 475*91f16700Schasinglulu if (ret != 0) { 476*91f16700Schasinglulu VERBOSE("%s: not expected digest\n", __func__); 477*91f16700Schasinglulu ret = CRYPTO_ERR_HASH; 478*91f16700Schasinglulu } 479*91f16700Schasinglulu 480*91f16700Schasinglulu return ret; 481*91f16700Schasinglulu } 482*91f16700Schasinglulu 483*91f16700Schasinglulu #if !defined(DECRYPTION_SUPPORT_none) 484*91f16700Schasinglulu static int derive_key(uint8_t *key, size_t *key_len, size_t len, 485*91f16700Schasinglulu unsigned int *flags, const uint8_t *img_id, size_t img_id_len) 486*91f16700Schasinglulu { 487*91f16700Schasinglulu size_t i, j; 488*91f16700Schasinglulu 489*91f16700Schasinglulu assert(*key_len >= 32U); 490*91f16700Schasinglulu 491*91f16700Schasinglulu /* 492*91f16700Schasinglulu * Not a real derivation yet 493*91f16700Schasinglulu * 494*91f16700Schasinglulu * We expect a 32 bytes key, if OTP is only 16 bytes 495*91f16700Schasinglulu * => duplicate. 496*91f16700Schasinglulu */ 497*91f16700Schasinglulu for (i = 0U, j = len; j < 32U; 498*91f16700Schasinglulu i += sizeof(uint32_t), j += sizeof(uint32_t)) { 499*91f16700Schasinglulu memcpy(key + j, key + i, sizeof(uint32_t)); 500*91f16700Schasinglulu } 501*91f16700Schasinglulu 502*91f16700Schasinglulu *key_len = 32U; 503*91f16700Schasinglulu /* Variable 'key' store a real key */ 504*91f16700Schasinglulu *flags = 0U; 505*91f16700Schasinglulu 506*91f16700Schasinglulu return 0; 507*91f16700Schasinglulu } 508*91f16700Schasinglulu 509*91f16700Schasinglulu int plat_get_enc_key_info(enum fw_enc_status_t fw_enc_status, uint8_t *key, 510*91f16700Schasinglulu size_t *key_len, unsigned int *flags, 511*91f16700Schasinglulu const uint8_t *img_id, size_t img_id_len) 512*91f16700Schasinglulu { 513*91f16700Schasinglulu uint32_t otp_idx; 514*91f16700Schasinglulu uint32_t otp_len; 515*91f16700Schasinglulu size_t read_len; 516*91f16700Schasinglulu size_t i; 517*91f16700Schasinglulu 518*91f16700Schasinglulu if (fw_enc_status == FW_ENC_WITH_BSSK) { 519*91f16700Schasinglulu return -EINVAL; 520*91f16700Schasinglulu } 521*91f16700Schasinglulu 522*91f16700Schasinglulu if (stm32_get_otp_index(ENCKEY_OTP, &otp_idx, &otp_len) != 0) { 523*91f16700Schasinglulu VERBOSE("%s: get %s index error\n", __func__, ENCKEY_OTP); 524*91f16700Schasinglulu return -EINVAL; 525*91f16700Schasinglulu } 526*91f16700Schasinglulu 527*91f16700Schasinglulu if (otp_len > (*key_len * CHAR_BIT)) { 528*91f16700Schasinglulu VERBOSE("%s: length Error otp_len=%u key_len=%zu\n", __func__, 529*91f16700Schasinglulu otp_len, *key_len * CHAR_BIT); 530*91f16700Schasinglulu return -EINVAL; 531*91f16700Schasinglulu } 532*91f16700Schasinglulu 533*91f16700Schasinglulu read_len = otp_len / CHAR_BIT; 534*91f16700Schasinglulu assert(read_len % sizeof(uint32_t) == 0); 535*91f16700Schasinglulu 536*91f16700Schasinglulu for (i = 0U; i < read_len / sizeof(uint32_t); i++) { 537*91f16700Schasinglulu uint32_t tmp; 538*91f16700Schasinglulu uint32_t otp_val; 539*91f16700Schasinglulu 540*91f16700Schasinglulu if (stm32_get_otp_value_from_idx(otp_idx + i, &otp_val) != 0) { 541*91f16700Schasinglulu zeromem(key, *key_len); 542*91f16700Schasinglulu VERBOSE("%s: unable to read from otp\n", __func__); 543*91f16700Schasinglulu return -EINVAL; 544*91f16700Schasinglulu } 545*91f16700Schasinglulu 546*91f16700Schasinglulu tmp = bswap32(otp_val); 547*91f16700Schasinglulu memcpy(key + i * sizeof(uint32_t), &tmp, sizeof(tmp)); 548*91f16700Schasinglulu } 549*91f16700Schasinglulu 550*91f16700Schasinglulu /* Now we have the OTP values in key till read_len */ 551*91f16700Schasinglulu 552*91f16700Schasinglulu if (derive_key(key, key_len, read_len, flags, img_id, 553*91f16700Schasinglulu img_id_len) != 0) { 554*91f16700Schasinglulu zeromem(key, *key_len); 555*91f16700Schasinglulu return -EINVAL; 556*91f16700Schasinglulu } 557*91f16700Schasinglulu 558*91f16700Schasinglulu return 0; 559*91f16700Schasinglulu } 560*91f16700Schasinglulu 561*91f16700Schasinglulu static enum stm32_saes_key_selection select_key(unsigned int key_flags) 562*91f16700Schasinglulu { 563*91f16700Schasinglulu if ((key_flags & ENC_KEY_IS_IDENTIFIER) != 0U) { 564*91f16700Schasinglulu panic(); 565*91f16700Schasinglulu } 566*91f16700Schasinglulu 567*91f16700Schasinglulu /* Use the provided key buffer */ 568*91f16700Schasinglulu return STM32_SAES_KEY_SOFT; 569*91f16700Schasinglulu } 570*91f16700Schasinglulu 571*91f16700Schasinglulu static int stm32_decrypt_aes_gcm(void *data, size_t data_len, 572*91f16700Schasinglulu const void *key, unsigned int key_len, 573*91f16700Schasinglulu unsigned int key_flags, 574*91f16700Schasinglulu const void *iv, unsigned int iv_len, 575*91f16700Schasinglulu const void *tag, unsigned int tag_len) 576*91f16700Schasinglulu { 577*91f16700Schasinglulu int ret; 578*91f16700Schasinglulu struct stm32_saes_context ctx; 579*91f16700Schasinglulu unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE]; 580*91f16700Schasinglulu enum stm32_saes_key_selection key_mode; 581*91f16700Schasinglulu unsigned int diff = 0U; 582*91f16700Schasinglulu unsigned int i; 583*91f16700Schasinglulu 584*91f16700Schasinglulu key_mode = select_key(key_flags); 585*91f16700Schasinglulu 586*91f16700Schasinglulu ret = stm32_saes_init(&ctx, true, STM32_SAES_MODE_GCM, key_mode, key, 587*91f16700Schasinglulu key_len, iv, iv_len); 588*91f16700Schasinglulu if (ret != 0) { 589*91f16700Schasinglulu return CRYPTO_ERR_INIT; 590*91f16700Schasinglulu } 591*91f16700Schasinglulu 592*91f16700Schasinglulu ret = stm32_saes_update_assodata(&ctx, true, NULL, 0U); 593*91f16700Schasinglulu if (ret != 0) { 594*91f16700Schasinglulu return CRYPTO_ERR_DECRYPTION; 595*91f16700Schasinglulu } 596*91f16700Schasinglulu 597*91f16700Schasinglulu ret = stm32_saes_update_load(&ctx, true, data, data, data_len); 598*91f16700Schasinglulu if (ret != 0) { 599*91f16700Schasinglulu return CRYPTO_ERR_DECRYPTION; 600*91f16700Schasinglulu } 601*91f16700Schasinglulu 602*91f16700Schasinglulu ret = stm32_saes_final(&ctx, tag_buf, sizeof(tag_buf)); 603*91f16700Schasinglulu if (ret != 0) { 604*91f16700Schasinglulu return CRYPTO_ERR_DECRYPTION; 605*91f16700Schasinglulu } 606*91f16700Schasinglulu 607*91f16700Schasinglulu /* Check tag in "constant-time" */ 608*91f16700Schasinglulu for (i = 0U; i < tag_len; i++) { 609*91f16700Schasinglulu diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i]; 610*91f16700Schasinglulu } 611*91f16700Schasinglulu 612*91f16700Schasinglulu if (diff != 0U) { 613*91f16700Schasinglulu return CRYPTO_ERR_DECRYPTION; 614*91f16700Schasinglulu } 615*91f16700Schasinglulu 616*91f16700Schasinglulu return CRYPTO_SUCCESS; 617*91f16700Schasinglulu } 618*91f16700Schasinglulu 619*91f16700Schasinglulu /* 620*91f16700Schasinglulu * Authenticated decryption of an image 621*91f16700Schasinglulu * 622*91f16700Schasinglulu */ 623*91f16700Schasinglulu static int crypto_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr, size_t len, 624*91f16700Schasinglulu const void *key, unsigned int key_len, unsigned int key_flags, 625*91f16700Schasinglulu const void *iv, unsigned int iv_len, const void *tag, 626*91f16700Schasinglulu unsigned int tag_len) 627*91f16700Schasinglulu { 628*91f16700Schasinglulu int rc = -1; 629*91f16700Schasinglulu uint32_t real_iv[4]; 630*91f16700Schasinglulu 631*91f16700Schasinglulu switch (dec_algo) { 632*91f16700Schasinglulu case CRYPTO_GCM_DECRYPT: 633*91f16700Schasinglulu /* 634*91f16700Schasinglulu * GCM expect a Nonce 635*91f16700Schasinglulu * The AES IV is the nonce (a uint32_t[3]) 636*91f16700Schasinglulu * then a counter (a uint32_t big endian) 637*91f16700Schasinglulu * The counter starts at 2. 638*91f16700Schasinglulu */ 639*91f16700Schasinglulu memcpy(real_iv, iv, iv_len); 640*91f16700Schasinglulu real_iv[3] = htobe32(0x2U); 641*91f16700Schasinglulu 642*91f16700Schasinglulu rc = stm32_decrypt_aes_gcm(data_ptr, len, key, key_len, key_flags, 643*91f16700Schasinglulu real_iv, sizeof(real_iv), tag, tag_len); 644*91f16700Schasinglulu break; 645*91f16700Schasinglulu default: 646*91f16700Schasinglulu rc = CRYPTO_ERR_DECRYPTION; 647*91f16700Schasinglulu break; 648*91f16700Schasinglulu } 649*91f16700Schasinglulu 650*91f16700Schasinglulu if (rc != 0) { 651*91f16700Schasinglulu return rc; 652*91f16700Schasinglulu } 653*91f16700Schasinglulu 654*91f16700Schasinglulu return CRYPTO_SUCCESS; 655*91f16700Schasinglulu } 656*91f16700Schasinglulu 657*91f16700Schasinglulu REGISTER_CRYPTO_LIB("stm32_crypto_lib", 658*91f16700Schasinglulu crypto_lib_init, 659*91f16700Schasinglulu crypto_verify_signature, 660*91f16700Schasinglulu crypto_verify_hash, 661*91f16700Schasinglulu NULL, 662*91f16700Schasinglulu crypto_auth_decrypt, 663*91f16700Schasinglulu crypto_convert_pk); 664*91f16700Schasinglulu 665*91f16700Schasinglulu #else /* No decryption support */ 666*91f16700Schasinglulu REGISTER_CRYPTO_LIB("stm32_crypto_lib", 667*91f16700Schasinglulu crypto_lib_init, 668*91f16700Schasinglulu crypto_verify_signature, 669*91f16700Schasinglulu crypto_verify_hash, 670*91f16700Schasinglulu NULL, 671*91f16700Schasinglulu NULL, 672*91f16700Schasinglulu crypto_convert_pk); 673*91f16700Schasinglulu #endif 674