xref: /rk3399_ARM-atf/plat/qemu/qemu/qemu_measured_boot.c (revision b73aa414e4ab919c3a57373235072f3401364d80)
1 /*
2  * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
3  * Copyright (c) 2022-2023, Linaro.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <stdint.h>
9 
10 #include <plat/common/common_def.h>
11 #include <plat/common/platform.h>
12 
13 #include <common/debug.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 #include <tools_share/tbbr_oid.h>
19 
20 #include "../common/qemu_private.h"
21 
22 /* Event Log data */
23 static uint8_t event_log[PLAT_EVENT_LOG_MAX_SIZE];
24 static uint64_t event_log_base;
25 
26 static const struct event_log_hash_info crypto_hash_info = {
27 	.func = crypto_mod_calc_hash,
28 	.ids = (const uint32_t[]){ CRYPTO_MD_ID },
29 	.count = 1U,
30 };
31 
32 /* QEMU table with platform specific image IDs, names and PCRs */
33 static const event_log_metadata_t qemu_event_log_metadata[] = {
34 	{ BL31_IMAGE_ID, MBOOT_BL31_IMAGE_STRING, PCR_0 },
35 	{ BL32_IMAGE_ID, MBOOT_BL32_IMAGE_STRING, PCR_0 },
36 	{ BL32_EXTRA1_IMAGE_ID, MBOOT_BL32_EXTRA1_IMAGE_STRING, PCR_0 },
37 	{ BL32_EXTRA2_IMAGE_ID, MBOOT_BL32_EXTRA2_IMAGE_STRING, PCR_0 },
38 	{ BL33_IMAGE_ID, MBOOT_BL33_IMAGE_STRING, PCR_0 },
39 	{ HW_CONFIG_ID, MBOOT_HW_CONFIG_STRING, PCR_0 },
40 	{ NT_FW_CONFIG_ID, MBOOT_NT_FW_CONFIG_STRING, PCR_0 },
41 	{ SCP_BL2_IMAGE_ID, MBOOT_SCP_BL2_IMAGE_STRING, PCR_0 },
42 	{ SOC_FW_CONFIG_ID, MBOOT_SOC_FW_CONFIG_STRING, PCR_0 },
43 	{ TOS_FW_CONFIG_ID, MBOOT_TOS_FW_CONFIG_STRING, PCR_0 },
44 
45 	{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) }	/* Terminator */
46 };
47 
bl2_plat_mboot_init(void)48 void bl2_plat_mboot_init(void)
49 {
50 	/*
51 	 * Here we assume that BL1/ROM code doesn't have the driver
52 	 * to measure the BL2 code which is a common case for
53 	 * already existing platforms
54 	 */
55 	int rc = event_log_init_and_reg(
56 		event_log, event_log + sizeof(event_log), &crypto_hash_info);
57 	if (rc < 0) {
58 		ERROR("Failed to initialize event log (%d).\n", rc);
59 		panic();
60 	}
61 
62 	rc = event_log_write_header();
63 	if (rc < 0) {
64 		ERROR("Failed to write event log header (%d).\n", rc);
65 		panic();
66 	}
67 
68 	/*
69 	 * TBD - Add code to do self measurement of BL2 code and add an
70 	 * event for BL2 measurement
71 	 */
72 
73 	event_log_base = (uintptr_t)event_log;
74 }
75 
bl2_plat_mboot_finish(void)76 void bl2_plat_mboot_finish(void)
77 {
78 	int rc;
79 
80 	/* Event Log address in Non-Secure memory */
81 	uintptr_t ns_log_addr;
82 
83 	/* Event Log filled size */
84 	size_t event_log_cur_size;
85 
86 	event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base);
87 
88 	event_log_dump((uint8_t *)event_log_base, event_log_cur_size);
89 
90 #if TRANSFER_LIST
91 	if (!plat_handoff_mboot((void *)event_log_base, event_log_cur_size,
92 				(void *)(uintptr_t)FW_HANDOFF_BASE))
93 		return;
94 #endif
95 
96 	rc = qemu_set_nt_fw_info(
97 #ifdef SPD_opteed
98 			    (uintptr_t)event_log_base,
99 #endif
100 			    event_log_cur_size, &ns_log_addr);
101 	if (rc != 0) {
102 		ERROR("%s(): Unable to update %s_FW_CONFIG\n",
103 		      __func__, "NT");
104 		/*
105 		 * It is a non-fatal error because on QEMU secure world software
106 		 * assumes that a valid event log exists and will use it to
107 		 * record the measurements into the fTPM or sw-tpm, but the boot
108 		 * can also happen without TPM on the platform. It's up to
109 		 * higher layer in boot sequence to decide if this is fatal or
110 		 * not, e.g. by not providing access to TPM encrypted storage.
111 		 * Note: In QEMU platform, OP-TEE uses nt_fw_config to get the
112 		 * secure Event Log buffer address.
113 		 */
114 		WARN("Ignoring TPM errors, continuing without\n");
115 		return;
116 	}
117 
118 	/* Copy Event Log to Non-secure memory */
119 	(void)memcpy((void *)ns_log_addr, (const void *)event_log_base,
120 		     event_log_cur_size);
121 
122 	/* Ensure that the Event Log is visible in Non-secure memory */
123 	flush_dcache_range(ns_log_addr, event_log_cur_size);
124 
125 #if defined(SPD_tspd) || defined(SPD_spmd)
126 	/* Set Event Log data in TOS_FW_CONFIG */
127 	rc = qemu_set_tos_fw_info((uintptr_t)event_log_base,
128 				 event_log_cur_size);
129 	if (rc != 0) {
130 		ERROR("%s(): Unable to update %s_FW_CONFIG\n",
131 		      __func__, "TOS");
132 		panic();
133 	}
134 #endif /* defined(SPD_tspd) || defined(SPD_spmd) */
135 
136 }
137 
plat_mboot_measure_image(unsigned int image_id,image_info_t * image_data)138 int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
139 {
140 	/* Calculate image hash and record data in Event Log */
141 	int err = event_log_measure_and_record(image_data->image_base,
142 					       image_data->image_size,
143 					       image_id,
144 					       qemu_event_log_metadata);
145 	if (err != 0) {
146 		ERROR("%s%s image id %u (%i)\n",
147 		      "Failed to ", "record", image_id, err);
148 		return err;
149 	}
150 
151 	return 0;
152 }
153 
plat_mboot_measure_key(const void * pk_oid,const void * pk_ptr,size_t pk_len)154 int plat_mboot_measure_key(const void *pk_oid, const void *pk_ptr,
155 			   size_t pk_len)
156 {
157 	return 0;
158 }
159