1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2022, STMicroelectronics - All Rights Reserved 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <endian.h> 8*91f16700Schasinglulu #include <errno.h> 9*91f16700Schasinglulu #include <limits.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <common/debug.h> 12*91f16700Schasinglulu #include <common/tbbr/cot_def.h> 13*91f16700Schasinglulu #include <drivers/clk.h> 14*91f16700Schasinglulu #include <drivers/st/stm32_hash.h> 15*91f16700Schasinglulu #include <lib/fconf/fconf.h> 16*91f16700Schasinglulu #include <lib/fconf/fconf_dyn_cfg_getter.h> 17*91f16700Schasinglulu #include <lib/fconf/fconf_tbbr_getter.h> 18*91f16700Schasinglulu #include <lib/mmio.h> 19*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables_v2.h> 20*91f16700Schasinglulu #include <plat/common/platform.h> 21*91f16700Schasinglulu 22*91f16700Schasinglulu #include <boot_api.h> 23*91f16700Schasinglulu #include <platform_def.h> 24*91f16700Schasinglulu 25*91f16700Schasinglulu #define HEADER_AND_EXT_TOTAL_SIZE 512 26*91f16700Schasinglulu 27*91f16700Schasinglulu static uint8_t der_sha256_header[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 28*91f16700Schasinglulu 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; 29*91f16700Schasinglulu static uint8_t root_pk_hash[HASH_DER_LEN]; 30*91f16700Schasinglulu 31*91f16700Schasinglulu static int copy_hash_from_otp(const char *otp_name, uint8_t *hash, size_t len) 32*91f16700Schasinglulu { 33*91f16700Schasinglulu uint32_t otp_idx; 34*91f16700Schasinglulu uint32_t otp_len; 35*91f16700Schasinglulu size_t i; 36*91f16700Schasinglulu bool valid = false; 37*91f16700Schasinglulu 38*91f16700Schasinglulu assert(len % sizeof(uint32_t) == 0); 39*91f16700Schasinglulu 40*91f16700Schasinglulu if (stm32_get_otp_index(otp_name, &otp_idx, &otp_len) != 0) { 41*91f16700Schasinglulu VERBOSE("%s: get %s index error\n", __func__, otp_name); 42*91f16700Schasinglulu return -EINVAL; 43*91f16700Schasinglulu } 44*91f16700Schasinglulu if (otp_len != (len * CHAR_BIT)) { 45*91f16700Schasinglulu VERBOSE("%s: length Error\n", __func__); 46*91f16700Schasinglulu return -EINVAL; 47*91f16700Schasinglulu } 48*91f16700Schasinglulu 49*91f16700Schasinglulu for (i = 0U; i < len / sizeof(uint32_t); i++) { 50*91f16700Schasinglulu uint32_t tmp; 51*91f16700Schasinglulu uint32_t otp_val; 52*91f16700Schasinglulu uint32_t first; 53*91f16700Schasinglulu 54*91f16700Schasinglulu if (stm32_get_otp_value_from_idx(otp_idx + i, &otp_val) != 0) { 55*91f16700Schasinglulu VERBOSE("%s: unable to read from otp\n", __func__); 56*91f16700Schasinglulu return -EINVAL; 57*91f16700Schasinglulu } 58*91f16700Schasinglulu 59*91f16700Schasinglulu tmp = bswap32(otp_val); 60*91f16700Schasinglulu memcpy(hash + i * sizeof(uint32_t), &tmp, sizeof(tmp)); 61*91f16700Schasinglulu 62*91f16700Schasinglulu if (i == 0U) { 63*91f16700Schasinglulu first = tmp; 64*91f16700Schasinglulu } 65*91f16700Schasinglulu 66*91f16700Schasinglulu /* 67*91f16700Schasinglulu * Check if key hash values in OTP are 0 or 0xFFFFFFFFF 68*91f16700Schasinglulu * programmed : Invalid Key 69*91f16700Schasinglulu */ 70*91f16700Schasinglulu if (!stm32mp_is_closed_device() && !valid) { 71*91f16700Schasinglulu if ((tmp != 0U) && (tmp != 0xFFFFFFFFU) && (tmp != first)) { 72*91f16700Schasinglulu valid = true; 73*91f16700Schasinglulu } 74*91f16700Schasinglulu } 75*91f16700Schasinglulu } 76*91f16700Schasinglulu 77*91f16700Schasinglulu if (!stm32mp_is_closed_device() && !valid) { 78*91f16700Schasinglulu return 0; 79*91f16700Schasinglulu } 80*91f16700Schasinglulu 81*91f16700Schasinglulu return len; 82*91f16700Schasinglulu } 83*91f16700Schasinglulu 84*91f16700Schasinglulu #if STM32_HEADER_VERSION_MAJOR == 1 85*91f16700Schasinglulu static int get_rotpk_hash(void *cookie, uint8_t *hash, size_t len) 86*91f16700Schasinglulu { 87*91f16700Schasinglulu if (cookie != NULL) { 88*91f16700Schasinglulu return -EINVAL; 89*91f16700Schasinglulu } 90*91f16700Schasinglulu 91*91f16700Schasinglulu return copy_hash_from_otp(PKH_OTP, hash, len); 92*91f16700Schasinglulu } 93*91f16700Schasinglulu #else 94*91f16700Schasinglulu static int get_rotpk_hash(void *cookie, uint8_t *hash, size_t len) 95*91f16700Schasinglulu { 96*91f16700Schasinglulu int ret; 97*91f16700Schasinglulu uint32_t pk_idx = 0U; 98*91f16700Schasinglulu uint8_t calc_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES]; 99*91f16700Schasinglulu uint8_t otp_hash[BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES]; 100*91f16700Schasinglulu boot_api_image_header_t *hdr = (boot_api_image_header_t *)(SRAM3_BASE + SRAM3_SIZE - 101*91f16700Schasinglulu HEADER_AND_EXT_TOTAL_SIZE); 102*91f16700Schasinglulu boot_extension_header_t *ext_header = (boot_extension_header_t *)hdr->ext_header; 103*91f16700Schasinglulu boot_ext_header_params_authentication_t *param; 104*91f16700Schasinglulu 105*91f16700Schasinglulu if (cookie != NULL) { 106*91f16700Schasinglulu return -EINVAL; 107*91f16700Schasinglulu } 108*91f16700Schasinglulu 109*91f16700Schasinglulu if (hdr->header_version != BOOT_API_HEADER_VERSION) { 110*91f16700Schasinglulu VERBOSE("%s: unexpected header_version\n", __func__); 111*91f16700Schasinglulu return -EINVAL; 112*91f16700Schasinglulu } 113*91f16700Schasinglulu 114*91f16700Schasinglulu param = (boot_ext_header_params_authentication_t *)ext_header->params; 115*91f16700Schasinglulu 116*91f16700Schasinglulu pk_idx = param->pk_idx; 117*91f16700Schasinglulu 118*91f16700Schasinglulu stm32_hash_init(HASH_SHA256); 119*91f16700Schasinglulu ret = stm32_hash_final_update((uint8_t *)param->pk_hashes, 120*91f16700Schasinglulu param->nb_pk * sizeof(boot_api_sha256_t), calc_hash); 121*91f16700Schasinglulu if (ret != 0) { 122*91f16700Schasinglulu VERBOSE("%s: hash failed\n", __func__); 123*91f16700Schasinglulu return -EINVAL; 124*91f16700Schasinglulu } 125*91f16700Schasinglulu 126*91f16700Schasinglulu ret = copy_hash_from_otp(PKH_OTP, otp_hash, len); 127*91f16700Schasinglulu if (ret < 0) { 128*91f16700Schasinglulu return -EINVAL; 129*91f16700Schasinglulu } 130*91f16700Schasinglulu 131*91f16700Schasinglulu if (ret != 0) { 132*91f16700Schasinglulu ret = memcmp(calc_hash, otp_hash, sizeof(calc_hash)); 133*91f16700Schasinglulu if (ret != 0) { 134*91f16700Schasinglulu VERBOSE("%s: not expected digest\n", __func__); 135*91f16700Schasinglulu return -EINVAL; 136*91f16700Schasinglulu } 137*91f16700Schasinglulu 138*91f16700Schasinglulu ret = sizeof(otp_hash); 139*91f16700Schasinglulu } 140*91f16700Schasinglulu 141*91f16700Schasinglulu memcpy(hash, param->pk_hashes[pk_idx], sizeof(otp_hash)); 142*91f16700Schasinglulu 143*91f16700Schasinglulu return ret; 144*91f16700Schasinglulu } 145*91f16700Schasinglulu #endif 146*91f16700Schasinglulu 147*91f16700Schasinglulu int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, 148*91f16700Schasinglulu unsigned int *flags) 149*91f16700Schasinglulu { 150*91f16700Schasinglulu size_t start_copy_idx = 0U; 151*91f16700Schasinglulu int res; 152*91f16700Schasinglulu 153*91f16700Schasinglulu memcpy(root_pk_hash, der_sha256_header, sizeof(der_sha256_header)); 154*91f16700Schasinglulu start_copy_idx = sizeof(der_sha256_header); 155*91f16700Schasinglulu 156*91f16700Schasinglulu res = get_rotpk_hash(cookie, root_pk_hash + start_copy_idx, 157*91f16700Schasinglulu BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES); 158*91f16700Schasinglulu if (res < 0) { 159*91f16700Schasinglulu return -EINVAL; 160*91f16700Schasinglulu } 161*91f16700Schasinglulu 162*91f16700Schasinglulu *key_len = HASH_DER_LEN; 163*91f16700Schasinglulu *key_ptr = &root_pk_hash; 164*91f16700Schasinglulu *flags = ROTPK_IS_HASH; 165*91f16700Schasinglulu 166*91f16700Schasinglulu if ((res == 0) && !stm32mp_is_closed_device()) { 167*91f16700Schasinglulu *flags |= ROTPK_NOT_DEPLOYED; 168*91f16700Schasinglulu } 169*91f16700Schasinglulu 170*91f16700Schasinglulu return 0; 171*91f16700Schasinglulu } 172*91f16700Schasinglulu 173*91f16700Schasinglulu int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) 174*91f16700Schasinglulu { 175*91f16700Schasinglulu clk_enable(TAMP_BKP_REG_CLK); 176*91f16700Schasinglulu *nv_ctr = mmio_read_32(TAMP_BASE + TAMP_COUNTR); 177*91f16700Schasinglulu clk_disable(TAMP_BKP_REG_CLK); 178*91f16700Schasinglulu 179*91f16700Schasinglulu return 0; 180*91f16700Schasinglulu } 181*91f16700Schasinglulu 182*91f16700Schasinglulu int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) 183*91f16700Schasinglulu { 184*91f16700Schasinglulu clk_enable(TAMP_BKP_REG_CLK); 185*91f16700Schasinglulu while (mmio_read_32(TAMP_BASE + TAMP_COUNTR) != nv_ctr) { 186*91f16700Schasinglulu mmio_write_32(TAMP_BASE + TAMP_COUNTR, 1U); 187*91f16700Schasinglulu } 188*91f16700Schasinglulu clk_disable(TAMP_BKP_REG_CLK); 189*91f16700Schasinglulu 190*91f16700Schasinglulu return 0; 191*91f16700Schasinglulu } 192*91f16700Schasinglulu 193*91f16700Schasinglulu int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) 194*91f16700Schasinglulu { 195*91f16700Schasinglulu assert(heap_addr != NULL); 196*91f16700Schasinglulu assert(heap_size != NULL); 197*91f16700Schasinglulu 198*91f16700Schasinglulu #if STM32MP_USE_EXTERNAL_HEAP 199*91f16700Schasinglulu /* Retrieve the already allocated heap's info from DTB */ 200*91f16700Schasinglulu *heap_addr = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_addr); 201*91f16700Schasinglulu *heap_size = FCONF_GET_PROPERTY(tbbr, dyn_config, mbedtls_heap_size); 202*91f16700Schasinglulu 203*91f16700Schasinglulu /* We expect heap already statically mapped */ 204*91f16700Schasinglulu 205*91f16700Schasinglulu return 0; 206*91f16700Schasinglulu #else 207*91f16700Schasinglulu return get_mbedtls_heap_helper(heap_addr, heap_size); 208*91f16700Schasinglulu #endif 209*91f16700Schasinglulu } 210