blob: ff771aa537b43acb73e0a2797cd7964c8ca08bc5 [file] [log] [blame]
Alexei Fedorov71d81dc2020-07-13 13:58:06 +01001/*
Sandrine Bailleux4e9af172021-07-01 14:13:09 +02002 * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
Alexei Fedorov71d81dc2020-07-13 13:58:06 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <errno.h>
9#include <string.h>
10#include <arch_helpers.h>
11
12#include <common/bl_common.h>
13#include <common/debug.h>
14#include <drivers/auth/crypto_mod.h>
Sandrine Bailleux3c2db6f2021-07-07 14:47:08 +020015#include <drivers/measured_boot/event_log/event_log.h>
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010016#include <mbedtls/md.h>
17
18#include <plat/common/platform.h>
19
20/* Event Log data */
21static uint8_t event_log[EVENT_LOG_SIZE];
22
23/* End of Event Log */
24#define EVENT_LOG_END ((uintptr_t)event_log + sizeof(event_log) - 1U)
25
26CASSERT(sizeof(event_log) >= LOG_MIN_SIZE, assert_event_log_size);
27
28/* Pointer in event_log[] */
29static uint8_t *log_ptr = event_log;
30
31/* Pointer to measured_boot_data_t */
32const static measured_boot_data_t *plat_data_ptr;
33
34static uintptr_t tos_fw_config_base;
35static uintptr_t nt_fw_config_base;
36
37/* TCG_EfiSpecIdEvent */
38static const id_event_headers_t id_event_header = {
39 .header = {
40 .pcr_index = PCR_0,
41 .event_type = EV_NO_ACTION,
42 .digest = {0},
43 .event_size = (uint32_t)(sizeof(id_event_struct_t) +
44 (sizeof(id_event_algorithm_size_t) *
45 HASH_ALG_COUNT))
46 },
47
48 .struct_header = {
49 .signature = TCG_ID_EVENT_SIGNATURE_03,
50 .platform_class = PLATFORM_CLASS_CLIENT,
51 .spec_version_minor = TCG_SPEC_VERSION_MINOR_TPM2,
52 .spec_version_major = TCG_SPEC_VERSION_MAJOR_TPM2,
53 .spec_errata = TCG_SPEC_ERRATA_TPM2,
54 .uintn_size = (uint8_t)(sizeof(unsigned int) /
55 sizeof(uint32_t)),
56 .number_of_algorithms = HASH_ALG_COUNT
57 }
58};
59
60static const event2_header_t locality_event_header = {
Sandrine Bailleuxbe761432021-06-23 10:40:08 +020061 /*
62 * All EV_NO_ACTION events SHALL set
63 * TCG_PCR_EVENT2.pcrIndex = 0, unless otherwise specified
64 */
65 .pcr_index = PCR_0,
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010066
Sandrine Bailleuxbe761432021-06-23 10:40:08 +020067 /*
68 * All EV_NO_ACTION events SHALL set
69 * TCG_PCR_EVENT2.eventType = 03h
70 */
71 .event_type = EV_NO_ACTION,
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010072
Sandrine Bailleuxbe761432021-06-23 10:40:08 +020073 /*
74 * All EV_NO_ACTION events SHALL set TCG_PCR_EVENT2.digests to all
75 * 0x00's for each allocated Hash algorithm
76 */
77 .digests = {
78 .count = HASH_ALG_COUNT
79 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010080};
81
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010082/*
Sandrine Bailleux36af1c82021-06-17 15:44:40 +020083 * Record a measurement as a TCG_PCR_EVENT2 event
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010084 *
85 * @param[in] hash Pointer to hash data of TCG_DIGEST_SIZE bytes
86 * @param[in] image_ptr Pointer to image_data_t structure
Sandrine Bailleux9ebe81e2021-06-23 15:43:02 +020087 *
88 * There must be room for storing this new event into the event log buffer.
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010089 */
Sandrine Bailleux898c0992021-06-17 16:10:40 +020090void event_log_record(const uint8_t *hash, const image_data_t *image_ptr)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010091{
92 void *ptr = log_ptr;
93 uint32_t name_len;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010094
95 assert(image_ptr != NULL);
96 assert(image_ptr->name != NULL);
Sandrine Bailleux898c0992021-06-17 16:10:40 +020097 assert(hash != NULL);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010098
99 name_len = (uint32_t)strlen(image_ptr->name) + 1U;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100100
101 /* Check for space in Event Log buffer */
Sandrine Bailleux9ebe81e2021-06-23 15:43:02 +0200102 assert(((uintptr_t)ptr + (uint32_t)EVENT2_HDR_SIZE + name_len) <=
103 EVENT_LOG_END);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100104
105 /*
106 * As per TCG specifications, firmware components that are measured
107 * into PCR[0] must be logged in the event log using the event type
108 * EV_POST_CODE.
109 */
110 /* TCG_PCR_EVENT2.PCRIndex */
111 ((event2_header_t *)ptr)->pcr_index = image_ptr->pcr;
112
113 /* TCG_PCR_EVENT2.EventType */
114 ((event2_header_t *)ptr)->event_type = EV_POST_CODE;
115
116 /* TCG_PCR_EVENT2.Digests.Count */
117 ptr = (uint8_t *)ptr + offsetof(event2_header_t, digests);
118 ((tpml_digest_values *)ptr)->count = HASH_ALG_COUNT;
119
120 /* TCG_PCR_EVENT2.Digests[] */
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100121 ptr = (uint8_t *)((uintptr_t)ptr +
122 offsetof(tpml_digest_values, digests));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100123
124 /* TCG_PCR_EVENT2.Digests[].AlgorithmId */
125 ((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID;
126
127 /* TCG_PCR_EVENT2.Digests[].Digest[] */
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100128 ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100129
Sandrine Bailleux898c0992021-06-17 16:10:40 +0200130 /* Copy digest */
131 (void)memcpy(ptr, (const void *)hash, TCG_DIGEST_SIZE);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100132
133 /* TCG_PCR_EVENT2.EventSize */
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100134 ptr = (uint8_t *)((uintptr_t)ptr + TCG_DIGEST_SIZE);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100135 ((event2_data_t *)ptr)->event_size = name_len;
136
137 /* Copy event data to TCG_PCR_EVENT2.Event */
138 (void)memcpy((void *)(((event2_data_t *)ptr)->event),
139 (const void *)image_ptr->name, name_len);
140
141 /* End of event data */
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100142 log_ptr = (uint8_t *)((uintptr_t)ptr +
143 offsetof(event2_data_t, event) + name_len);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100144}
145
146/*
147 * Init Event Log
148 *
149 * Initialises Event Log by writing Specification ID and
150 * Startup Locality events.
151 */
152void event_log_init(void)
153{
154 const char locality_signature[] = TCG_STARTUP_LOCALITY_SIGNATURE;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100155 void *ptr = event_log;
156
157 /* Get pointer to platform's measured_boot_data_t structure */
158 plat_data_ptr = plat_get_measured_boot_data();
159
160 /*
161 * Add Specification ID Event first
162 *
163 * Copy TCG_EfiSpecIDEventStruct structure header
164 */
165 (void)memcpy(ptr, (const void *)&id_event_header,
166 sizeof(id_event_header));
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100167 ptr = (uint8_t *)((uintptr_t)ptr + sizeof(id_event_header));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100168
169 /* TCG_EfiSpecIdEventAlgorithmSize structure */
170 ((id_event_algorithm_size_t *)ptr)->algorithm_id = TPM_ALG_ID;
171 ((id_event_algorithm_size_t *)ptr)->digest_size = TCG_DIGEST_SIZE;
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100172 ptr = (uint8_t *)((uintptr_t)ptr + sizeof(id_event_algorithm_size_t));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100173
174 /*
175 * TCG_EfiSpecIDEventStruct.vendorInfoSize
176 * No vendor data
177 */
178 ((id_event_struct_data_t *)ptr)->vendor_info_size = 0;
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100179 ptr = (uint8_t *)((uintptr_t)ptr +
180 offsetof(id_event_struct_data_t, vendor_info));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100181
182 /*
183 * The Startup Locality event should be placed in the log before
184 * any event which extends PCR[0].
185 *
186 * Ref. TCG PC Client Platform Firmware Profile 9.4.5.3
187 */
188
189 /* Copy Startup Locality Event Header */
190 (void)memcpy(ptr, (const void *)&locality_event_header,
191 sizeof(locality_event_header));
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100192 ptr = (uint8_t *)((uintptr_t)ptr + sizeof(locality_event_header));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100193
194 /* TCG_PCR_EVENT2.Digests[].AlgorithmId */
195 ((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID;
196
197 /* TCG_PCR_EVENT2.Digests[].Digest[] */
198 (void)memset(&((tpmt_ha *)ptr)->digest, 0, TPM_ALG_ID);
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100199 ptr = (uint8_t *)((uintptr_t)ptr +
200 offsetof(tpmt_ha, digest) + TCG_DIGEST_SIZE);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100201
202 /* TCG_PCR_EVENT2.EventSize */
203 ((event2_data_t *)ptr)->event_size =
204 (uint32_t)sizeof(startup_locality_event_t);
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100205 ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100206
207 /* TCG_EfiStartupLocalityEvent.Signature */
208 (void)memcpy(ptr, (const void *)locality_signature,
209 sizeof(TCG_STARTUP_LOCALITY_SIGNATURE));
210
211 /*
212 * TCG_EfiStartupLocalityEvent.StartupLocality = 0:
213 * the platform's boot firmware
214 */
215 ((startup_locality_event_t *)ptr)->startup_locality = 0U;
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100216 ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100217
218 log_ptr = (uint8_t *)ptr;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100219}
220
221/*
222 * Calculate and write hash of image, configuration data, etc.
223 * to Event Log.
224 *
225 * @param[in] data_base Address of data
226 * @param[in] data_size Size of data
227 * @param[in] data_id Data ID
228 * @return:
229 * 0 = success
230 * < 0 = error
231 */
Sandrine Bailleux4e9af172021-07-01 14:13:09 +0200232int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size,
233 uint32_t data_id)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100234{
235 const image_data_t *data_ptr = plat_data_ptr->images_data;
236 unsigned char hash_data[MBEDTLS_MD_MAX_SIZE];
237 int rc;
238
Sandrine Bailleux74b8e172021-06-23 15:44:18 +0200239 /* Get the metadata associated with this image. */
240 while ((data_ptr->id != INVALID_ID) && (data_ptr->id != data_id)) {
241 data_ptr++;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100242 }
Sandrine Bailleux74b8e172021-06-23 15:44:18 +0200243 assert(data_ptr->id != INVALID_ID);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100244
245 if (data_id == TOS_FW_CONFIG_ID) {
246 tos_fw_config_base = data_base;
247 } else if (data_id == NT_FW_CONFIG_ID) {
248 nt_fw_config_base = data_base;
249 } else {
250 /* No action */
251 }
252
253 /* Calculate hash */
254 rc = crypto_mod_calc_hash((unsigned int)MBEDTLS_MD_ID,
255 (void *)data_base, data_size, hash_data);
256 if (rc != 0) {
257 return rc;
258 }
259
Sandrine Bailleux36af1c82021-06-17 15:44:40 +0200260 event_log_record(hash_data, data_ptr);
261
Sandrine Bailleux9ebe81e2021-06-23 15:43:02 +0200262 return 0;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100263}
264
265/*
266 * Finalise Event Log
267 *
268 * @param[out] log_addr Pointer to return Event Log address
269 * @param[out] log_size Pointer to return Event Log size
270 * @return:
271 * 0 = success
272 * < 0 = error code
273 */
274int event_log_finalise(uint8_t **log_addr, size_t *log_size)
275{
276 /* Event Log size */
277 size_t num_bytes = (uintptr_t)log_ptr - (uintptr_t)event_log;
278 int rc;
279
280 assert(log_addr != NULL);
281 assert(log_size != NULL);
282
283 if (nt_fw_config_base == 0UL) {
284 ERROR("%s(): %s_FW_CONFIG not loaded\n", __func__, "NT");
285 return -ENOENT;
286 }
287
288 /*
289 * Set Event Log data in NT_FW_CONFIG and
290 * get Event Log address in Non-Secure memory
291 */
292 if (plat_data_ptr->set_nt_fw_info != NULL) {
293
294 /* Event Log address in Non-Secure memory */
295 uintptr_t ns_log_addr;
296
297 rc = plat_data_ptr->set_nt_fw_info(
298 nt_fw_config_base,
299#ifdef SPD_opteed
300 (uintptr_t)event_log,
301#endif
302 num_bytes, &ns_log_addr);
303 if (rc != 0) {
304 ERROR("%s(): Unable to update %s_FW_CONFIG\n",
305 __func__, "NT");
306 return rc;
307 }
308
309 /* Copy Event Log to Non-secure memory */
310 (void)memcpy((void *)ns_log_addr, (const void *)event_log,
311 num_bytes);
312
313 /* Ensure that the Event Log is visible in Non-secure memory */
314 flush_dcache_range(ns_log_addr, num_bytes);
315
316 /* Return Event Log address in Non-Secure memory */
317 *log_addr = (uint8_t *)ns_log_addr;
318
319 } else {
320 INFO("%s(): set_%s_fw_info not set\n", __func__, "nt");
321
322 /* Return Event Log address in Secure memory */
323 *log_addr = event_log;
324 }
325
326 if (tos_fw_config_base != 0UL) {
327 if (plat_data_ptr->set_tos_fw_info != NULL) {
328
329 /* Set Event Log data in TOS_FW_CONFIG */
330 rc = plat_data_ptr->set_tos_fw_info(
331 tos_fw_config_base,
332 (uintptr_t)event_log,
333 num_bytes);
334 if (rc != 0) {
335 ERROR("%s(): Unable to update %s_FW_CONFIG\n",
336 __func__, "TOS");
337 return rc;
338 }
339 } else {
340 INFO("%s(): set_%s_fw_info not set\n", __func__, "tos");
341 }
342 } else {
343 INFO("%s(): %s_FW_CONFIG not loaded\n", __func__, "TOS");
344 }
345
346 /* Ensure that the Event Log is visible in Secure memory */
347 flush_dcache_range((uintptr_t)event_log, num_bytes);
348
349 /* Return Event Log size */
350 *log_size = num_bytes;
351
352 return 0;
353}