xref: /rk3399_ARM-atf/services/std_svc/drtm/drtm_measurements.c (revision 04cf04c72d403e0c057505882fac9002d39d4102)
1 /*
2  * Copyright (c) 2022-2025 Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier:    BSD-3-Clause
5  *
6  * DRTM measurements into TPM PCRs.
7  *
8  * Authors:
9  *      Lucian Paul-Trifu <lucian.paultrifu@gmail.com>
10  *
11  */
12 #include <assert.h>
13 
14 #include <common/debug.h>
15 #include <drivers/auth/crypto_mod.h>
16 #include <drivers/measured_boot/event_log/event_log.h>
17 #include "drtm_main.h"
18 #include "drtm_measurements.h"
19 #include <lib/xlat_tables/xlat_tables_v2.h>
20 
21 /* Event Log buffer */
22 static uint8_t drtm_event_log[PLAT_DRTM_EVENT_LOG_MAX_SIZE];
23 
24 /*
25  * Calculate and write hash of various payloads as per DRTM specification
26  * to Event Log.
27  *
28  * @param[in] data_base         Address of data
29  * @param[in] data_size         Size of data
30  * @param[in] event_type        Type of Event
31  * @param[in] event_name        Name of the Event
32  * @return:
33  *      0 = success
34  *    < 0 = error
35  */
36 static int drtm_event_log_measure_and_record(uintptr_t data_base,
37 					     uint32_t data_size,
38 					     uint32_t event_type,
39 					     const char *event_name,
40 					     unsigned int pcr)
41 {
42 	int rc;
43 	unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
44 	event_log_metadata_t metadata = {0};
45 
46 	metadata.name = event_name;
47 	metadata.pcr = pcr;
48 
49 	/*
50 	 * Measure the payloads requested by D-CRTM and DCE components
51 	 * Hash algorithm decided by the Event Log driver at build-time
52 	 */
53 	rc = event_log_measure(data_base, data_size, hash_data);
54 	if (rc != 0) {
55 		return rc;
56 	}
57 
58 	/* Record the mesasurement in the EventLog buffer */
59 	rc = event_log_record(hash_data, event_type, &metadata);
60 	if (rc != 0) {
61 		return rc;
62 	}
63 
64 	return 0;
65 }
66 
67 /*
68  * Initialise Event Log global variables, used during the recording
69  * of various payload measurements into the Event Log buffer
70  *
71  * @param[in] event_log_start           Base address of Event Log buffer
72  * @param[in] event_log_finish          End address of Event Log buffer,
73  *                                      it is a first byte past end of the
74  *                                      buffer
75  */
76 static void drtm_event_log_init(uint8_t *event_log_start,
77 				uint8_t *event_log_finish)
78 {
79 	event_log_buf_init(event_log_start, event_log_finish);
80 	event_log_write_specid_event();
81 }
82 
83 enum drtm_retc drtm_take_measurements(const struct_drtm_dl_args *a)
84 {
85 	int rc;
86 	uintptr_t dlme_img_mapping;
87 	uint64_t dlme_img_ep;
88 	size_t dlme_img_mapping_bytes;
89 	uint8_t drtm_null_data = 0U;
90 	uint8_t pcr_schema = DL_ARGS_GET_PCR_SCHEMA(a);
91 	const char *drtm_event_arm_sep_data = "ARM_DRTM";
92 
93 	/* Initialise the EventLog driver */
94 	drtm_event_log_init(drtm_event_log, drtm_event_log +
95 			    sizeof(drtm_event_log));
96 
97 	/**
98 	 * Measurements extended into PCR-17.
99 	 *
100 	 * PCR-17: Measure the DCE image.  Extend digest of (char)0 into PCR-17
101 	 * since the D-CRTM and the DCE are not separate.
102 	 */
103 	rc = drtm_event_log_measure_and_record((uintptr_t)&drtm_null_data,
104 					       sizeof(drtm_null_data),
105 					       DRTM_EVENT_ARM_DCE, NULL,
106 					       PCR_17);
107 	CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DCE));
108 
109 	/* PCR-17: Measure the PCR schema DRTM launch argument. */
110 	rc = drtm_event_log_measure_and_record((uintptr_t)&pcr_schema,
111 					       sizeof(pcr_schema),
112 					       DRTM_EVENT_ARM_PCR_SCHEMA,
113 					       NULL, PCR_17);
114 	CHECK_RC(rc,
115 		 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_PCR_SCHEMA));
116 
117 	/* PCR-17: Measure the enable state of external-debug, and trace. */
118 	/*
119 	 * TODO: Measure the enable state of external-debug and trace.  This should
120 	 * be returned through a platform-specific hook.
121 	 */
122 
123 	/* PCR-17: Measure the security lifecycle state. */
124 	/*
125 	 * TODO: Measure the security lifecycle state.  This is an implementation-
126 	 * defined value, retrieved through an implementation-defined mechanisms.
127 	 */
128 
129 	/*
130 	 * PCR-17: Optionally measure the NWd DCE.
131 	 * It is expected that such subsequent DCE stages are signed and verified.
132 	 * Whether they are measured in addition to signing is implementation
133 	 * -defined.
134 	 * Here the choice is to not measure any NWd DCE, in favour of PCR value
135 	 * resilience to any NWd DCE updates.
136 	 */
137 
138 	/* PCR-17: End of DCE measurements. */
139 	rc = drtm_event_log_measure_and_record((uintptr_t)drtm_event_arm_sep_data,
140 					       strlen(drtm_event_arm_sep_data),
141 					       DRTM_EVENT_ARM_SEPARATOR,
142 					       drtm_event_arm_sep_data,
143 					       PCR_17);
144 	CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR));
145 
146 	/**
147 	 * Measurements extended into PCR-18.
148 	 *
149 	 * PCR-18: Measure the PCR schema DRTM launch argument.
150 	 */
151 	rc = drtm_event_log_measure_and_record((uintptr_t)&pcr_schema,
152 					       sizeof(pcr_schema),
153 					       DRTM_EVENT_ARM_PCR_SCHEMA,
154 					       NULL, PCR_18);
155 	CHECK_RC(rc,
156 		 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_PCR_SCHEMA));
157 
158 	/*
159 	 * PCR-18: Measure the public key used to verify DCE image(s) signatures.
160 	 * Extend digest of (char)0, since we do not expect the NWd DCE to be
161 	 * present.
162 	 */
163 	assert(a->dce_nwd_size == 0);
164 	rc = drtm_event_log_measure_and_record((uintptr_t)&drtm_null_data,
165 					       sizeof(drtm_null_data),
166 					       DRTM_EVENT_ARM_DCE_PUBKEY,
167 					       NULL, PCR_18);
168 	CHECK_RC(rc,
169 		 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DCE_PUBKEY));
170 
171 	/* PCR-18: Measure the DLME image. */
172 	dlme_img_mapping_bytes = page_align(a->dlme_img_size, UP);
173 	rc = mmap_add_dynamic_region_alloc_va(a->dlme_paddr + a->dlme_img_off,
174 					      &dlme_img_mapping,
175 					      dlme_img_mapping_bytes, MT_RO_DATA | MT_NS);
176 	if (rc) {
177 		WARN("DRTM: %s: mmap_add_dynamic_region() failed rc=%d\n",
178 		     __func__, rc);
179 		return INTERNAL_ERROR;
180 	}
181 
182 	rc = drtm_event_log_measure_and_record(dlme_img_mapping, a->dlme_img_size,
183 					       DRTM_EVENT_ARM_DLME, NULL,
184 					       PCR_18);
185 	CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DLME));
186 
187 	rc = mmap_remove_dynamic_region(dlme_img_mapping, dlme_img_mapping_bytes);
188 	CHECK_RC(rc, mmap_remove_dynamic_region);
189 
190 	/* PCR-18: Measure the DLME image entry point. */
191 	dlme_img_ep = DL_ARGS_GET_DLME_ENTRY_POINT(a);
192 	drtm_event_log_measure_and_record((uintptr_t)&(a->dlme_img_ep_off),
193 					  sizeof(dlme_img_ep),
194 					  DRTM_EVENT_ARM_DLME_EP, NULL,
195 					  PCR_18);
196 	CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DLME_EP));
197 
198 	/* PCR-18: End of DCE measurements. */
199 	rc = drtm_event_log_measure_and_record((uintptr_t)drtm_event_arm_sep_data,
200 					       strlen(drtm_event_arm_sep_data),
201 					       DRTM_EVENT_ARM_SEPARATOR,
202 					       drtm_event_arm_sep_data,
203 					       PCR_18);
204 	CHECK_RC(rc,
205 		 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR));
206 
207 	/* Measure no Action event but not extend it in PCR */
208 	CHECK_RC(rc,
209 		 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_NO_ACTION));
210 	/*
211 	 * If the DCE is unable to log a measurement because there is no available
212 	 * space in the event log region, the DCE must extend a hash of the value
213 	 * 0xFF (1 byte in size) into PCR[17] and PCR[18] and enter remediation.
214 	 */
215 
216 	return SUCCESS;
217 }
218 
219 void drtm_serialise_event_log(uint8_t *dst, size_t *event_log_size_out)
220 {
221 	*event_log_size_out = event_log_get_cur_size(drtm_event_log);
222 	memcpy(dst, drtm_event_log, *event_log_size_out);
223 }
224