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