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