148ba0345SManish V Badarkhe /*
25bf0b807SHarrison Mutai * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
348ba0345SManish V Badarkhe *
448ba0345SManish V Badarkhe * SPDX-License-Identifier: BSD-3-Clause
548ba0345SManish V Badarkhe */
648ba0345SManish V Badarkhe
748ba0345SManish V Badarkhe #include <stdint.h>
848ba0345SManish V Badarkhe
9e637a5e1SImre Kis #include <common/tbbr/tbbr_img_def.h>
10b67e9846SHarrison Mutai #if TRANSFER_LIST
11b67e9846SHarrison Mutai #include <tpm_event_log.h>
12b67e9846SHarrison Mutai #endif
13b67e9846SHarrison Mutai #include <drivers/auth/crypto_mod.h>
1409bb42dbSTamas Ban #include <drivers/measured_boot/metadata.h>
15b67e9846SHarrison Mutai #include <event_measure.h>
16b67e9846SHarrison Mutai #include <event_print.h>
17bfbb1cbaSManish V Badarkhe #if defined(ARM_COT_cca)
18bfbb1cbaSManish V Badarkhe #include <tools_share/cca_oid.h>
19bfbb1cbaSManish V Badarkhe #else
20cf21064eSManish V Badarkhe #include <tools_share/tbbr_oid.h>
21bfbb1cbaSManish V Badarkhe #endif /* ARM_COT_cca */
22cf21064eSManish V Badarkhe #include <fvp_critical_data.h>
23cf21064eSManish V Badarkhe
2448ba0345SManish V Badarkhe #include <plat/arm/common/plat_arm.h>
25cf21064eSManish V Badarkhe #include <plat/common/common_def.h>
2648ba0345SManish V Badarkhe
275bf0b807SHarrison Mutai #if !TRANSFER_LIST && (defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd))
28191aa5d3SManish V Badarkhe CASSERT(ARM_EVENT_LOG_DRAM1_SIZE >= PLAT_ARM_EVENT_LOG_MAX_SIZE, \
29191aa5d3SManish V Badarkhe assert_res_eventlog_mem_insufficient);
30191aa5d3SManish V Badarkhe #endif /* defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) */
31191aa5d3SManish V Badarkhe
3248ba0345SManish V Badarkhe /* Event Log data */
330500f447SManish V Badarkhe static uint64_t event_log_base;
3448ba0345SManish V Badarkhe
35b67e9846SHarrison Mutai static const struct event_log_hash_info crypto_hash_info = {
36b67e9846SHarrison Mutai .func = crypto_mod_calc_hash,
37b67e9846SHarrison Mutai .ids = (const uint32_t[]){ CRYPTO_MD_ID },
38b67e9846SHarrison Mutai .count = 1U,
39b67e9846SHarrison Mutai };
40b67e9846SHarrison Mutai
4148ba0345SManish V Badarkhe /* FVP table with platform specific image IDs, names and PCRs */
4248ba0345SManish V Badarkhe const event_log_metadata_t fvp_event_log_metadata[] = {
4309bb42dbSTamas Ban { BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
4409bb42dbSTamas Ban { BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
4509bb42dbSTamas Ban { BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
4609bb42dbSTamas Ban { BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
4709bb42dbSTamas Ban { BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
4809bb42dbSTamas Ban { HW_CONFIG_ID, MBOOT_HW_CONFIG_STRING, PCR_0 },
4909bb42dbSTamas Ban { NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 },
5009bb42dbSTamas Ban { SCP_BL2_IMAGE_ID, MBOOT_SCP_BL2_IMAGE_STRING, PCR_0 },
5109bb42dbSTamas Ban { SOC_FW_CONFIG_ID, MBOOT_SOC_FW_CONFIG_STRING, PCR_0 },
5209bb42dbSTamas Ban { TOS_FW_CONFIG_ID, MBOOT_TOS_FW_CONFIG_STRING, PCR_0 },
5309bb42dbSTamas Ban { RMM_IMAGE_ID, MBOOT_RMM_IMAGE_STRING, PCR_0},
54426a1119SManish V Badarkhe
55e637a5e1SImre Kis #if defined(SPD_spmd)
5609bb42dbSTamas Ban { SP_PKG1_ID, MBOOT_SP1_STRING, PCR_0 },
5709bb42dbSTamas Ban { SP_PKG2_ID, MBOOT_SP2_STRING, PCR_0 },
5809bb42dbSTamas Ban { SP_PKG3_ID, MBOOT_SP3_STRING, PCR_0 },
5909bb42dbSTamas Ban { SP_PKG4_ID, MBOOT_SP4_STRING, PCR_0 },
6009bb42dbSTamas Ban { SP_PKG5_ID, MBOOT_SP5_STRING, PCR_0 },
6109bb42dbSTamas Ban { SP_PKG6_ID, MBOOT_SP6_STRING, PCR_0 },
6209bb42dbSTamas Ban { SP_PKG7_ID, MBOOT_SP7_STRING, PCR_0 },
6309bb42dbSTamas Ban { SP_PKG8_ID, MBOOT_SP8_STRING, PCR_0 },
64e637a5e1SImre Kis #endif
65e637a5e1SImre Kis
66cf21064eSManish V Badarkhe { CRITICAL_DATA_ID, EVLOG_CRITICAL_DATA_STRING, PCR_1 },
67cf21064eSManish V Badarkhe
68426a1119SManish V Badarkhe { EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
6948ba0345SManish V Badarkhe };
7048ba0345SManish V Badarkhe
bl2_plat_mboot_init(void)7148ba0345SManish V Badarkhe void bl2_plat_mboot_init(void)
7248ba0345SManish V Badarkhe {
730500f447SManish V Badarkhe uint8_t *event_log_start;
740500f447SManish V Badarkhe uint8_t *event_log_finish;
75*b199ca1aSBoyan Karatotev size_t bl1_event_log_size __unused = 0;
76*b199ca1aSBoyan Karatotev size_t event_log_max_size __unused = 0;
775bf0b807SHarrison Mutai int rc __unused;
780500f447SManish V Badarkhe
795bf0b807SHarrison Mutai #if TRANSFER_LIST
805bf0b807SHarrison Mutai event_log_start = transfer_list_event_log_extend(
81b67e9846SHarrison Mutai secure_tl, PLAT_ARM_EVENT_LOG_MAX_SIZE);
82b67e9846SHarrison Mutai event_log_finish = event_log_start + PLAT_ARM_EVENT_LOG_MAX_SIZE;
83b67e9846SHarrison Mutai
845bf0b807SHarrison Mutai event_log_base = (uintptr_t)event_log_start;
855bf0b807SHarrison Mutai #else
861cf3e2f0SManish V Badarkhe rc = arm_get_tb_fw_info(&event_log_base, &bl1_event_log_size,
871cf3e2f0SManish V Badarkhe &event_log_max_size);
880500f447SManish V Badarkhe if (rc != 0) {
890500f447SManish V Badarkhe ERROR("%s(): Unable to get Event Log info from TB_FW_CONFIG\n",
900500f447SManish V Badarkhe __func__);
910500f447SManish V Badarkhe /*
920500f447SManish V Badarkhe * It is a fatal error because on FVP platform, BL2 software
930500f447SManish V Badarkhe * assumes that a valid Event Log buffer exist and it will use
940500f447SManish V Badarkhe * same Event Log buffer to append image measurements.
950500f447SManish V Badarkhe */
960500f447SManish V Badarkhe panic();
970500f447SManish V Badarkhe }
980500f447SManish V Badarkhe
990500f447SManish V Badarkhe /*
1000500f447SManish V Badarkhe * BL1 and BL2 share the same Event Log buffer and that BL2 will
1010500f447SManish V Badarkhe * append its measurements after BL1's
1020500f447SManish V Badarkhe */
1035bf0b807SHarrison Mutai event_log_start =
1045bf0b807SHarrison Mutai (uint8_t *)((uintptr_t)event_log_base + bl1_event_log_size);
1055bf0b807SHarrison Mutai event_log_finish =
1065bf0b807SHarrison Mutai (uint8_t *)((uintptr_t)event_log_base + event_log_max_size);
1075bf0b807SHarrison Mutai #endif
1080500f447SManish V Badarkhe
109b67e9846SHarrison Mutai rc = event_log_init_and_reg(event_log_start, event_log_finish,
110b67e9846SHarrison Mutai &crypto_hash_info);
111b67e9846SHarrison Mutai if (rc < 0) {
112b67e9846SHarrison Mutai ERROR("Failed to initialize event log (%d).\n", rc);
113b67e9846SHarrison Mutai panic();
114b67e9846SHarrison Mutai }
11548ba0345SManish V Badarkhe }
11648ba0345SManish V Badarkhe
plat_mboot_measure_critical_data(unsigned int critical_data_id,const void * base,size_t size)117cf21064eSManish V Badarkhe int plat_mboot_measure_critical_data(unsigned int critical_data_id,
118cf21064eSManish V Badarkhe const void *base, size_t size)
119cf21064eSManish V Badarkhe {
120cf21064eSManish V Badarkhe /*
121cf21064eSManish V Badarkhe * It is very unlikely that the critical data size would be
122cf21064eSManish V Badarkhe * bigger than 2^32 bytes
123cf21064eSManish V Badarkhe */
124cf21064eSManish V Badarkhe assert(size < UINT32_MAX);
125cf21064eSManish V Badarkhe assert(base != NULL);
126cf21064eSManish V Badarkhe
127cf21064eSManish V Badarkhe /* Calculate image hash and record data in Event Log */
128cf21064eSManish V Badarkhe int err = event_log_measure_and_record((uintptr_t)base, (uint32_t)size,
1297f3d9eaeSManish V Badarkhe critical_data_id,
1307f3d9eaeSManish V Badarkhe fvp_event_log_metadata);
131cf21064eSManish V Badarkhe if (err != 0) {
132cf21064eSManish V Badarkhe ERROR("%s%s critical data (%i)\n",
133cf21064eSManish V Badarkhe "Failed to ", "record", err);
134cf21064eSManish V Badarkhe return err;
135cf21064eSManish V Badarkhe }
136cf21064eSManish V Badarkhe
137cf21064eSManish V Badarkhe return 0;
138cf21064eSManish V Badarkhe }
139cf21064eSManish V Badarkhe
14088c51c3fSManish V Badarkhe #if TRUSTED_BOARD_BOOT
fvp_populate_critical_data(struct fvp_critical_data * critical_data)141cf21064eSManish V Badarkhe static int fvp_populate_critical_data(struct fvp_critical_data *critical_data)
142cf21064eSManish V Badarkhe {
143cf21064eSManish V Badarkhe char *nv_ctr_oids[MAX_NV_CTR_IDS] = {
144cf21064eSManish V Badarkhe [TRUSTED_NV_CTR_ID] = TRUSTED_FW_NVCOUNTER_OID,
145cf21064eSManish V Badarkhe [NON_TRUSTED_NV_CTR_ID] = NON_TRUSTED_FW_NVCOUNTER_OID,
146cf21064eSManish V Badarkhe };
147cf21064eSManish V Badarkhe
148cf21064eSManish V Badarkhe for (int i = 0; i < MAX_NV_CTR_IDS; i++) {
149cf21064eSManish V Badarkhe int rc = plat_get_nv_ctr(nv_ctr_oids[i],
150cf21064eSManish V Badarkhe &critical_data->nv_ctr[i]);
151cf21064eSManish V Badarkhe if (rc != 0) {
152cf21064eSManish V Badarkhe return rc;
153cf21064eSManish V Badarkhe }
154cf21064eSManish V Badarkhe }
155cf21064eSManish V Badarkhe
156cf21064eSManish V Badarkhe return 0;
157cf21064eSManish V Badarkhe }
15888c51c3fSManish V Badarkhe #endif /* TRUSTED_BOARD_BOOT */
159cf21064eSManish V Badarkhe
fvp_populate_and_measure_critical_data(void)160cf21064eSManish V Badarkhe static int fvp_populate_and_measure_critical_data(void)
161cf21064eSManish V Badarkhe {
16288c51c3fSManish V Badarkhe int rc = 0;
16388c51c3fSManish V Badarkhe
16488c51c3fSManish V Badarkhe /*
16588c51c3fSManish V Badarkhe * FVP platform only measures 'platform NV-counter' and hence its
16688c51c3fSManish V Badarkhe * measurement makes sense during Trusted-Boot flow only.
16788c51c3fSManish V Badarkhe */
16888c51c3fSManish V Badarkhe #if TRUSTED_BOARD_BOOT
169cf21064eSManish V Badarkhe struct fvp_critical_data populate_critical_data;
170cf21064eSManish V Badarkhe
17188c51c3fSManish V Badarkhe rc = fvp_populate_critical_data(&populate_critical_data);
172cf21064eSManish V Badarkhe if (rc == 0) {
173cf21064eSManish V Badarkhe rc = plat_mboot_measure_critical_data(CRITICAL_DATA_ID,
174cf21064eSManish V Badarkhe &populate_critical_data,
175cf21064eSManish V Badarkhe sizeof(populate_critical_data));
176cf21064eSManish V Badarkhe }
17788c51c3fSManish V Badarkhe #endif /* TRUSTED_BOARD_BOOT */
178cf21064eSManish V Badarkhe
179cf21064eSManish V Badarkhe return rc;
180cf21064eSManish V Badarkhe }
181cf21064eSManish V Badarkhe
bl2_plat_mboot_finish(void)18248ba0345SManish V Badarkhe void bl2_plat_mboot_finish(void)
18348ba0345SManish V Badarkhe {
18448ba0345SManish V Badarkhe int rc;
18548ba0345SManish V Badarkhe
18648ba0345SManish V Badarkhe /* Event Log address in Non-Secure memory */
1875bf0b807SHarrison Mutai uintptr_t ns_log_addr __unused;
18848ba0345SManish V Badarkhe
18948ba0345SManish V Badarkhe /* Event Log filled size */
19048ba0345SManish V Badarkhe size_t event_log_cur_size;
19148ba0345SManish V Badarkhe
19210f6ccdcSYeoreum Yun struct transfer_list_entry *te __maybe_unused;
19310f6ccdcSYeoreum Yun
194cf21064eSManish V Badarkhe rc = fvp_populate_and_measure_critical_data();
195cf21064eSManish V Badarkhe if (rc != 0) {
196cf21064eSManish V Badarkhe panic();
197cf21064eSManish V Badarkhe }
198cf21064eSManish V Badarkhe
1990500f447SManish V Badarkhe event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base);
20048ba0345SManish V Badarkhe
2015bf0b807SHarrison Mutai #if TRANSFER_LIST
2025bf0b807SHarrison Mutai /*
2035bf0b807SHarrison Mutai * Re-size the event log for the next stage and update the size to include
2045bf0b807SHarrison Mutai * the entire event log (i.e., not just what this stage has added.)
2055bf0b807SHarrison Mutai */
2065bf0b807SHarrison Mutai event_log_base = (uintptr_t)transfer_list_event_log_finish(
2075bf0b807SHarrison Mutai secure_tl, (uintptr_t)event_log_base + event_log_cur_size);
208b67e9846SHarrison Mutai
209b67e9846SHarrison Mutai /* Ensure changes are visible to the next stage. */
210b67e9846SHarrison Mutai flush_dcache_range((uintptr_t)secure_tl, secure_tl->size);
211b67e9846SHarrison Mutai
2125bf0b807SHarrison Mutai event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base);
21310f6ccdcSYeoreum Yun
21410f6ccdcSYeoreum Yun /* If there is DT_SPMC_MANIFEST, update event log information. */
21510f6ccdcSYeoreum Yun te = transfer_list_find(secure_tl, TL_TAG_DT_SPMC_MANIFEST);
21610f6ccdcSYeoreum Yun if (te != NULL) {
21710f6ccdcSYeoreum Yun te = transfer_list_find(secure_tl, TL_TAG_TPM_EVLOG);
21810f6ccdcSYeoreum Yun assert(te != NULL && te->data_size > 0);
21910f6ccdcSYeoreum Yun
22010f6ccdcSYeoreum Yun rc = arm_set_tos_fw_info((uintptr_t)transfer_list_entry_data(te),
22110f6ccdcSYeoreum Yun te->data_size);
22210f6ccdcSYeoreum Yun if (rc != 0) {
22310f6ccdcSYeoreum Yun WARN("%s(): Unable to update %s_FW_CONFIG\n",
22410f6ccdcSYeoreum Yun __func__, "TOS");
22510f6ccdcSYeoreum Yun }
22610f6ccdcSYeoreum Yun
22710f6ccdcSYeoreum Yun transfer_list_update_checksum(secure_tl);
22810f6ccdcSYeoreum Yun }
2295bf0b807SHarrison Mutai #else
230191aa5d3SManish V Badarkhe #if defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd)
231191aa5d3SManish V Badarkhe /* Copy Event Log to TZC secured DRAM memory */
232191aa5d3SManish V Badarkhe (void)memcpy((void *)ARM_EVENT_LOG_DRAM1_BASE,
233191aa5d3SManish V Badarkhe (const void *)event_log_base,
234191aa5d3SManish V Badarkhe event_log_cur_size);
235191aa5d3SManish V Badarkhe
236191aa5d3SManish V Badarkhe /* Ensure that the Event Log is visible in TZC secured DRAM memory */
237191aa5d3SManish V Badarkhe flush_dcache_range(ARM_EVENT_LOG_DRAM1_BASE, event_log_cur_size);
238191aa5d3SManish V Badarkhe #endif /* defined(SPD_tspd) || defined(SPD_opteed) || defined(SPD_spmd) */
239191aa5d3SManish V Badarkhe
24048ba0345SManish V Badarkhe rc = arm_set_nt_fw_info(
24148ba0345SManish V Badarkhe #ifdef SPD_opteed
242191aa5d3SManish V Badarkhe (uintptr_t)ARM_EVENT_LOG_DRAM1_BASE,
24348ba0345SManish V Badarkhe #endif
24448ba0345SManish V Badarkhe event_log_cur_size, &ns_log_addr);
24548ba0345SManish V Badarkhe if (rc != 0) {
24648ba0345SManish V Badarkhe ERROR("%s(): Unable to update %s_FW_CONFIG\n",
24748ba0345SManish V Badarkhe __func__, "NT");
24848ba0345SManish V Badarkhe /*
24948ba0345SManish V Badarkhe * It is a fatal error because on FVP secure world software
25048ba0345SManish V Badarkhe * assumes that a valid event log exists and will use it to
25148ba0345SManish V Badarkhe * record the measurements into the fTPM.
25248ba0345SManish V Badarkhe * Note: In FVP platform, OP-TEE uses nt_fw_config to get the
25348ba0345SManish V Badarkhe * secure Event Log buffer address.
25448ba0345SManish V Badarkhe */
25548ba0345SManish V Badarkhe panic();
25648ba0345SManish V Badarkhe }
25748ba0345SManish V Badarkhe
25848ba0345SManish V Badarkhe /* Copy Event Log to Non-secure memory */
2590500f447SManish V Badarkhe (void)memcpy((void *)ns_log_addr, (const void *)event_log_base,
26048ba0345SManish V Badarkhe event_log_cur_size);
26148ba0345SManish V Badarkhe
26248ba0345SManish V Badarkhe /* Ensure that the Event Log is visible in Non-secure memory */
26348ba0345SManish V Badarkhe flush_dcache_range(ns_log_addr, event_log_cur_size);
26448ba0345SManish V Badarkhe
26548ba0345SManish V Badarkhe #if defined(SPD_tspd) || defined(SPD_spmd)
26648ba0345SManish V Badarkhe /* Set Event Log data in TOS_FW_CONFIG */
267191aa5d3SManish V Badarkhe rc = arm_set_tos_fw_info((uintptr_t)ARM_EVENT_LOG_DRAM1_BASE,
26848ba0345SManish V Badarkhe event_log_cur_size);
26948ba0345SManish V Badarkhe if (rc != 0) {
27048ba0345SManish V Badarkhe ERROR("%s(): Unable to update %s_FW_CONFIG\n",
27148ba0345SManish V Badarkhe __func__, "TOS");
27248ba0345SManish V Badarkhe panic();
27348ba0345SManish V Badarkhe }
2740500f447SManish V Badarkhe #endif /* defined(SPD_tspd) || defined(SPD_spmd) */
2755bf0b807SHarrison Mutai #endif /* TRANSFER_LIST */
27648ba0345SManish V Badarkhe
277e48d38d0SHarrison Mutai event_log_dump((uint8_t *)event_log_base, event_log_cur_size);
27848ba0345SManish V Badarkhe }
279