1 /* 2 * Copyright (c) 2021-2023, 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 #include <drivers/measured_boot/event_log/event_log.h> 11 #if defined(ARM_COT_cca) 12 #include <tools_share/cca_oid.h> 13 #else 14 #include <tools_share/tbbr_oid.h> 15 #endif /* ARM_COT_cca */ 16 #include <fvp_critical_data.h> 17 18 #include <plat/arm/common/plat_arm.h> 19 #include <plat/common/common_def.h> 20 21 #if defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) 22 CASSERT(ARM_EVENT_LOG_DRAM1_SIZE >= PLAT_ARM_EVENT_LOG_MAX_SIZE, \ 23 assert_res_eventlog_mem_insufficient); 24 #endif /* defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) */ 25 26 /* Event Log data */ 27 static uint64_t event_log_base; 28 29 /* FVP table with platform specific image IDs, names and PCRs */ 30 const event_log_metadata_t fvp_event_log_metadata[] = { 31 { BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 }, 32 { BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 }, 33 { BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 }, 34 { BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 }, 35 { BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 }, 36 { HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 }, 37 { NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 }, 38 { SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 }, 39 { SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 }, 40 { TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 }, 41 { RMM_IMAGE_ID, EVLOG_RMM_STRING, PCR_0}, 42 43 #if defined(SPD_spmd) 44 { SP_PKG1_ID, EVLOG_SP1_STRING, PCR_0 }, 45 { SP_PKG2_ID, EVLOG_SP2_STRING, PCR_0 }, 46 { SP_PKG3_ID, EVLOG_SP3_STRING, PCR_0 }, 47 { SP_PKG4_ID, EVLOG_SP4_STRING, PCR_0 }, 48 { SP_PKG5_ID, EVLOG_SP5_STRING, PCR_0 }, 49 { SP_PKG6_ID, EVLOG_SP6_STRING, PCR_0 }, 50 { SP_PKG7_ID, EVLOG_SP7_STRING, PCR_0 }, 51 { SP_PKG8_ID, EVLOG_SP8_STRING, PCR_0 }, 52 #endif 53 54 { CRITICAL_DATA_ID, EVLOG_CRITICAL_DATA_STRING, PCR_1 }, 55 56 { EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ 57 }; 58 59 void bl2_plat_mboot_init(void) 60 { 61 uint8_t *event_log_start; 62 uint8_t *event_log_finish; 63 size_t bl1_event_log_size; 64 size_t event_log_max_size; 65 int rc; 66 67 rc = arm_get_tb_fw_info(&event_log_base, &bl1_event_log_size, 68 &event_log_max_size); 69 if (rc != 0) { 70 ERROR("%s(): Unable to get Event Log info from TB_FW_CONFIG\n", 71 __func__); 72 /* 73 * It is a fatal error because on FVP platform, BL2 software 74 * assumes that a valid Event Log buffer exist and it will use 75 * same Event Log buffer to append image measurements. 76 */ 77 panic(); 78 } 79 80 /* 81 * BL1 and BL2 share the same Event Log buffer and that BL2 will 82 * append its measurements after BL1's 83 */ 84 event_log_start = (uint8_t *)((uintptr_t)event_log_base + 85 bl1_event_log_size); 86 event_log_finish = (uint8_t *)((uintptr_t)event_log_base + 87 event_log_max_size); 88 89 event_log_init((uint8_t *)event_log_start, event_log_finish); 90 } 91 92 int plat_mboot_measure_critical_data(unsigned int critical_data_id, 93 const void *base, size_t size) 94 { 95 /* 96 * It is very unlikely that the critical data size would be 97 * bigger than 2^32 bytes 98 */ 99 assert(size < UINT32_MAX); 100 assert(base != NULL); 101 102 /* Calculate image hash and record data in Event Log */ 103 int err = event_log_measure_and_record((uintptr_t)base, (uint32_t)size, 104 critical_data_id, 105 fvp_event_log_metadata); 106 if (err != 0) { 107 ERROR("%s%s critical data (%i)\n", 108 "Failed to ", "record", err); 109 return err; 110 } 111 112 return 0; 113 } 114 115 #if TRUSTED_BOARD_BOOT 116 static int fvp_populate_critical_data(struct fvp_critical_data *critical_data) 117 { 118 char *nv_ctr_oids[MAX_NV_CTR_IDS] = { 119 [TRUSTED_NV_CTR_ID] = TRUSTED_FW_NVCOUNTER_OID, 120 [NON_TRUSTED_NV_CTR_ID] = NON_TRUSTED_FW_NVCOUNTER_OID, 121 }; 122 123 for (int i = 0; i < MAX_NV_CTR_IDS; i++) { 124 int rc = plat_get_nv_ctr(nv_ctr_oids[i], 125 &critical_data->nv_ctr[i]); 126 if (rc != 0) { 127 return rc; 128 } 129 } 130 131 return 0; 132 } 133 #endif /* TRUSTED_BOARD_BOOT */ 134 135 static int fvp_populate_and_measure_critical_data(void) 136 { 137 int rc = 0; 138 139 /* 140 * FVP platform only measures 'platform NV-counter' and hence its 141 * measurement makes sense during Trusted-Boot flow only. 142 */ 143 #if TRUSTED_BOARD_BOOT 144 struct fvp_critical_data populate_critical_data; 145 146 rc = fvp_populate_critical_data(&populate_critical_data); 147 if (rc == 0) { 148 rc = plat_mboot_measure_critical_data(CRITICAL_DATA_ID, 149 &populate_critical_data, 150 sizeof(populate_critical_data)); 151 } 152 #endif /* TRUSTED_BOARD_BOOT */ 153 154 return rc; 155 } 156 157 void bl2_plat_mboot_finish(void) 158 { 159 int rc; 160 161 /* Event Log address in Non-Secure memory */ 162 uintptr_t ns_log_addr; 163 164 /* Event Log filled size */ 165 size_t event_log_cur_size; 166 167 rc = fvp_populate_and_measure_critical_data(); 168 if (rc != 0) { 169 panic(); 170 } 171 172 event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base); 173 174 #if defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) 175 /* Copy Event Log to TZC secured DRAM memory */ 176 (void)memcpy((void *)ARM_EVENT_LOG_DRAM1_BASE, 177 (const void *)event_log_base, 178 event_log_cur_size); 179 180 /* Ensure that the Event Log is visible in TZC secured DRAM memory */ 181 flush_dcache_range(ARM_EVENT_LOG_DRAM1_BASE, event_log_cur_size); 182 #endif /* defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) */ 183 184 rc = arm_set_nt_fw_info( 185 #ifdef SPD_opteed 186 (uintptr_t)ARM_EVENT_LOG_DRAM1_BASE, 187 #endif 188 event_log_cur_size, &ns_log_addr); 189 if (rc != 0) { 190 ERROR("%s(): Unable to update %s_FW_CONFIG\n", 191 __func__, "NT"); 192 /* 193 * It is a fatal error because on FVP secure world software 194 * assumes that a valid event log exists and will use it to 195 * record the measurements into the fTPM. 196 * Note: In FVP platform, OP-TEE uses nt_fw_config to get the 197 * secure Event Log buffer address. 198 */ 199 panic(); 200 } 201 202 /* Copy Event Log to Non-secure memory */ 203 (void)memcpy((void *)ns_log_addr, (const void *)event_log_base, 204 event_log_cur_size); 205 206 /* Ensure that the Event Log is visible in Non-secure memory */ 207 flush_dcache_range(ns_log_addr, event_log_cur_size); 208 209 #if defined(SPD_tspd) || defined(SPD_spmd) 210 /* Set Event Log data in TOS_FW_CONFIG */ 211 rc = arm_set_tos_fw_info((uintptr_t)ARM_EVENT_LOG_DRAM1_BASE, 212 event_log_cur_size); 213 if (rc != 0) { 214 ERROR("%s(): Unable to update %s_FW_CONFIG\n", 215 __func__, "TOS"); 216 panic(); 217 } 218 #endif /* defined(SPD_tspd) || defined(SPD_spmd) */ 219 220 dump_event_log((uint8_t *)event_log_base, event_log_cur_size); 221 } 222