1 /* 2 * Copyright (c) 2021-2025, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <stdint.h> 8 9 #include <common/tbbr/tbbr_img_def.h> 10 #if TRANSFER_LIST 11 #include <tpm_event_log.h> 12 #endif 13 #include <common/measured_boot.h> 14 #include <drivers/auth/crypto_mod.h> 15 #include <drivers/measured_boot/metadata.h> 16 #include <event_measure.h> 17 #include <event_print.h> 18 #if defined(ARM_COT_cca) 19 #include <tools_share/cca_oid.h> 20 #else 21 #include <tools_share/tbbr_oid.h> 22 #endif /* ARM_COT_cca */ 23 #include <fvp_critical_data.h> 24 25 #include <plat/arm/common/plat_arm.h> 26 #include <plat/common/common_def.h> 27 28 #if !TRANSFER_LIST && (defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)) 29 CASSERT(ARM_EVENT_LOG_DRAM1_SIZE >= PLAT_ARM_EVENT_LOG_MAX_SIZE, \ 30 assert_res_eventlog_mem_insufficient); 31 #endif /* defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) */ 32 33 /* Event Log data */ 34 static const uint8_t *event_log_base; 35 36 /* FVP table with platform specific image IDs, names and PCRs */ 37 const event_log_metadata_t fvp_event_log_metadata[] = { 38 { BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 }, 39 { BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 }, 40 { BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 }, 41 { BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 }, 42 { BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 }, 43 { HW_CONFIG_ID, MBOOT_HW_CONFIG_STRING, PCR_0 }, 44 { NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 }, 45 { SCP_BL2_IMAGE_ID, MBOOT_SCP_BL2_IMAGE_STRING, PCR_0 }, 46 { SOC_FW_CONFIG_ID, MBOOT_SOC_FW_CONFIG_STRING, PCR_0 }, 47 { TOS_FW_CONFIG_ID, MBOOT_TOS_FW_CONFIG_STRING, PCR_0 }, 48 { RMM_IMAGE_ID, MBOOT_RMM_IMAGE_STRING, PCR_0}, 49 50 #if defined(SPD_spmd) 51 { SP_PKG1_ID, MBOOT_SP1_STRING, PCR_0 }, 52 { SP_PKG2_ID, MBOOT_SP2_STRING, PCR_0 }, 53 { SP_PKG3_ID, MBOOT_SP3_STRING, PCR_0 }, 54 { SP_PKG4_ID, MBOOT_SP4_STRING, PCR_0 }, 55 { SP_PKG5_ID, MBOOT_SP5_STRING, PCR_0 }, 56 { SP_PKG6_ID, MBOOT_SP6_STRING, PCR_0 }, 57 { SP_PKG7_ID, MBOOT_SP7_STRING, PCR_0 }, 58 { SP_PKG8_ID, MBOOT_SP8_STRING, PCR_0 }, 59 #endif 60 61 { CRITICAL_DATA_ID, EVLOG_CRITICAL_DATA_STRING, PCR_1 }, 62 63 { EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ 64 }; 65 66 void bl2_plat_mboot_init(void) 67 { 68 uint8_t *event_log_start __unused; 69 uint8_t *event_log_finish; 70 size_t bl1_event_log_size __unused = 0; 71 size_t event_log_max_size __unused = 0; 72 struct transfer_list_entry *te __unused; 73 int rc __unused; 74 75 #if TRANSFER_LIST 76 event_log_start = transfer_list_event_log_extend( 77 secure_tl, PLAT_ARM_EVENT_LOG_MAX_SIZE); 78 79 /* 80 * Retrieve the extend event log entry from the transfer list, the API above 81 * returns a cursor position rather than the base address - we need both to 82 * init the library. 83 */ 84 te = transfer_list_find(secure_tl, TL_TAG_TPM_EVLOG); 85 86 event_log_base = 87 transfer_list_entry_data(te) + EVENT_LOG_RESERVED_BYTES; 88 event_log_finish = transfer_list_entry_data(te) + te->data_size; 89 90 bl1_event_log_size = event_log_start - event_log_base; 91 #else 92 rc = arm_get_tb_fw_info((uint64_t *)&event_log_base, 93 &bl1_event_log_size, &event_log_max_size); 94 if (rc != 0) { 95 ERROR("%s(): Unable to get Event Log info from TB_FW_CONFIG\n", 96 __func__); 97 /* 98 * It is a fatal error because on FVP platform, BL2 software 99 * assumes that a valid Event Log buffer exist and it will use 100 * same Event Log buffer to append image measurements. 101 */ 102 panic(); 103 } 104 105 /* 106 * BL1 and BL2 share the same Event Log buffer and that BL2 will 107 * append its measurements after BL1's 108 */ 109 event_log_finish = 110 (uint8_t *)((uintptr_t)event_log_base + event_log_max_size); 111 #endif 112 113 rc = event_log_init_and_reg((uint8_t *)event_log_base, event_log_finish, 114 bl1_event_log_size, crypto_mod_tcg_hash); 115 if (rc < 0) { 116 ERROR("Failed to initialize event log (%d).\n", rc); 117 panic(); 118 } 119 } 120 121 int plat_mboot_measure_critical_data(unsigned int critical_data_id, 122 const void *base, size_t size) 123 { 124 const event_log_metadata_t *metadata_ptr; 125 int err; 126 127 /* 128 * It is very unlikely that the critical data size would be 129 * bigger than 2^32 bytes 130 */ 131 assert(size < UINT32_MAX); 132 assert(base != NULL); 133 134 metadata_ptr = mboot_find_event_log_metadata(fvp_event_log_metadata, 135 critical_data_id); 136 if (metadata_ptr == NULL) { 137 return 0; 138 } 139 140 /* Calculate image hash and record data in Event Log */ 141 err = event_log_measure_and_record(metadata_ptr->pcr, (uintptr_t)base, 142 size, metadata_ptr->name, 143 strlen(metadata_ptr->name) + 1U); 144 if (err != 0) { 145 ERROR("%s%s critical data (%i)\n", 146 "Failed to ", "record", err); 147 return err; 148 } 149 150 return 0; 151 } 152 153 #if TRUSTED_BOARD_BOOT 154 static int fvp_populate_critical_data(struct fvp_critical_data *critical_data) 155 { 156 char *nv_ctr_oids[MAX_NV_CTR_IDS] = { 157 [TRUSTED_NV_CTR_ID] = TRUSTED_FW_NVCOUNTER_OID, 158 [NON_TRUSTED_NV_CTR_ID] = NON_TRUSTED_FW_NVCOUNTER_OID, 159 }; 160 161 for (int i = 0; i < MAX_NV_CTR_IDS; i++) { 162 int rc = plat_get_nv_ctr(nv_ctr_oids[i], 163 &critical_data->nv_ctr[i]); 164 if (rc != 0) { 165 return rc; 166 } 167 } 168 169 return 0; 170 } 171 #endif /* TRUSTED_BOARD_BOOT */ 172 173 static int fvp_populate_and_measure_critical_data(void) 174 { 175 int rc = 0; 176 177 /* 178 * FVP platform only measures 'platform NV-counter' and hence its 179 * measurement makes sense during Trusted-Boot flow only. 180 */ 181 #if TRUSTED_BOARD_BOOT 182 struct fvp_critical_data populate_critical_data; 183 184 rc = fvp_populate_critical_data(&populate_critical_data); 185 if (rc == 0) { 186 rc = plat_mboot_measure_critical_data(CRITICAL_DATA_ID, 187 &populate_critical_data, 188 sizeof(populate_critical_data)); 189 } 190 #endif /* TRUSTED_BOARD_BOOT */ 191 192 return rc; 193 } 194 195 void bl2_plat_mboot_finish(void) 196 { 197 int rc; 198 199 /* Event Log address in Non-Secure memory */ 200 uintptr_t ns_log_addr __unused; 201 202 /* Event Log filled size */ 203 size_t event_log_cur_size; 204 205 struct transfer_list_entry *te __maybe_unused; 206 207 rc = fvp_populate_and_measure_critical_data(); 208 if (rc != 0) { 209 panic(); 210 } 211 212 event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base); 213 214 #if TRANSFER_LIST 215 /* 216 * Re-size the event log for the next stage and update the size to include 217 * the entire event log (i.e., not just what this stage has added.) 218 */ 219 event_log_base = transfer_list_event_log_finish( 220 secure_tl, (uintptr_t)event_log_base + event_log_cur_size); 221 222 /* Ensure changes are visible to the next stage. */ 223 flush_dcache_range((uintptr_t)secure_tl, secure_tl->size); 224 225 event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base); 226 227 /* If there is DT_SPMC_MANIFEST, update event log information. */ 228 te = transfer_list_find(secure_tl, TL_TAG_DT_SPMC_MANIFEST); 229 if (te != NULL) { 230 te = transfer_list_find(secure_tl, TL_TAG_TPM_EVLOG); 231 assert(te != NULL && te->data_size > 0); 232 233 rc = arm_set_tos_fw_info((uintptr_t)transfer_list_entry_data(te), 234 te->data_size); 235 if (rc != 0) { 236 WARN("%s(): Unable to update %s_FW_CONFIG\n", 237 __func__, "TOS"); 238 } 239 240 transfer_list_update_checksum(secure_tl); 241 } 242 #else 243 #if defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) 244 /* Copy Event Log to TZC secured DRAM memory */ 245 (void)memcpy((void *)ARM_EVENT_LOG_DRAM1_BASE, 246 (const void *)event_log_base, 247 event_log_cur_size); 248 249 /* Ensure that the Event Log is visible in TZC secured DRAM memory */ 250 flush_dcache_range(ARM_EVENT_LOG_DRAM1_BASE, event_log_cur_size); 251 #endif /* defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) */ 252 253 rc = arm_set_nt_fw_info( 254 #ifdef SPD_opteed 255 (uintptr_t)ARM_EVENT_LOG_DRAM1_BASE, 256 #endif 257 event_log_cur_size, &ns_log_addr); 258 if (rc != 0) { 259 ERROR("%s(): Unable to update %s_FW_CONFIG\n", 260 __func__, "NT"); 261 /* 262 * It is a fatal error because on FVP secure world software 263 * assumes that a valid event log exists and will use it to 264 * record the measurements into the fTPM. 265 * Note: In FVP platform, OP-TEE uses nt_fw_config to get the 266 * secure Event Log buffer address. 267 */ 268 panic(); 269 } 270 271 /* Copy Event Log to Non-secure memory */ 272 (void)memcpy((void *)ns_log_addr, (const void *)event_log_base, 273 event_log_cur_size); 274 275 /* Ensure that the Event Log is visible in Non-secure memory */ 276 flush_dcache_range(ns_log_addr, event_log_cur_size); 277 278 #if defined(SPD_tspd) || defined(SPD_spmd) 279 /* Set Event Log data in TOS_FW_CONFIG */ 280 rc = arm_set_tos_fw_info((uintptr_t)ARM_EVENT_LOG_DRAM1_BASE, 281 event_log_cur_size); 282 if (rc != 0) { 283 ERROR("%s(): Unable to update %s_FW_CONFIG\n", 284 __func__, "TOS"); 285 panic(); 286 } 287 #endif /* defined(SPD_tspd) || defined(SPD_spmd) */ 288 #endif /* TRANSFER_LIST */ 289 290 event_log_dump((uint8_t *)event_log_base, event_log_cur_size); 291 } 292