blob: 989652100778005625bb5d430b82e07a7ce17719 [file] [log] [blame]
Alexei Fedorov71d81dc2020-07-13 13:58:06 +01001/*
Harrison Mutai168a02c2025-02-27 15:06:39 +00002 * Copyright (c) 2020-2025, 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>
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010010
Harrison Mutai168a02c2025-02-27 15:06:39 +000011#include "crypto_mod.h"
12#include "event_log.h"
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010013
Manish V Badarkhee112a5a2021-10-06 23:41:50 +010014#if TPM_ALG_ID == TPM_ALG_SHA512
15#define CRYPTO_MD_ID CRYPTO_MD_SHA512
16#elif TPM_ALG_ID == TPM_ALG_SHA384
17#define CRYPTO_MD_ID CRYPTO_MD_SHA384
18#elif TPM_ALG_ID == TPM_ALG_SHA256
19#define CRYPTO_MD_ID CRYPTO_MD_SHA256
20#else
21# error Invalid TPM algorithm.
22#endif /* TPM_ALG_ID */
23
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +010024/* Running Event Log Pointer */
25static uint8_t *log_ptr;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010026
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +010027/* Pointer to the first byte past end of the Event Log buffer */
28static uintptr_t log_end;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010029
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010030/* TCG_EfiSpecIdEvent */
31static const id_event_headers_t id_event_header = {
32 .header = {
33 .pcr_index = PCR_0,
34 .event_type = EV_NO_ACTION,
35 .digest = {0},
36 .event_size = (uint32_t)(sizeof(id_event_struct_t) +
37 (sizeof(id_event_algorithm_size_t) *
38 HASH_ALG_COUNT))
39 },
40
41 .struct_header = {
42 .signature = TCG_ID_EVENT_SIGNATURE_03,
43 .platform_class = PLATFORM_CLASS_CLIENT,
44 .spec_version_minor = TCG_SPEC_VERSION_MINOR_TPM2,
45 .spec_version_major = TCG_SPEC_VERSION_MAJOR_TPM2,
46 .spec_errata = TCG_SPEC_ERRATA_TPM2,
47 .uintn_size = (uint8_t)(sizeof(unsigned int) /
48 sizeof(uint32_t)),
49 .number_of_algorithms = HASH_ALG_COUNT
50 }
51};
52
53static const event2_header_t locality_event_header = {
Sandrine Bailleuxbe761432021-06-23 10:40:08 +020054 /*
55 * All EV_NO_ACTION events SHALL set
56 * TCG_PCR_EVENT2.pcrIndex = 0, unless otherwise specified
57 */
58 .pcr_index = PCR_0,
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010059
Sandrine Bailleuxbe761432021-06-23 10:40:08 +020060 /*
61 * All EV_NO_ACTION events SHALL set
62 * TCG_PCR_EVENT2.eventType = 03h
63 */
64 .event_type = EV_NO_ACTION,
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010065
Sandrine Bailleuxbe761432021-06-23 10:40:08 +020066 /*
67 * All EV_NO_ACTION events SHALL set TCG_PCR_EVENT2.digests to all
68 * 0x00's for each allocated Hash algorithm
69 */
70 .digests = {
71 .count = HASH_ALG_COUNT
72 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010073};
74
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010075/*
Sandrine Bailleux36af1c82021-06-17 15:44:40 +020076 * Record a measurement as a TCG_PCR_EVENT2 event
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010077 *
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +010078 * @param[in] hash Pointer to hash data of TCG_DIGEST_SIZE bytes
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +010079 * @param[in] event_type Type of Event, Various Event Types are
80 * mentioned in tcg.h header
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +010081 * @param[in] metadata_ptr Pointer to event_log_metadata_t structure
Sandrine Bailleux9ebe81e2021-06-23 15:43:02 +020082 *
83 * There must be room for storing this new event into the event log buffer.
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010084 */
Harrison Mutai168a02c2025-02-27 15:06:39 +000085int event_log_record(const uint8_t *hash, uint32_t event_type,
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +010086 const event_log_metadata_t *metadata_ptr)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010087{
88 void *ptr = log_ptr;
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +010089 uint32_t name_len = 0U;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010090
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +010091 /* event_log_buf_init() must have been called prior to this. */
Harrison Mutai168a02c2025-02-27 15:06:39 +000092 if (hash == NULL || metadata_ptr == NULL || log_ptr == NULL) {
93 return -EINVAL;
94 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010095
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +010096 if (metadata_ptr->name != NULL) {
97 name_len = (uint32_t)strlen(metadata_ptr->name) + 1U;
98 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010099
100 /* Check for space in Event Log buffer */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000101 if (((uintptr_t)ptr + (uint32_t)EVENT2_HDR_SIZE + name_len) > log_end) {
102 return -ENOMEM;
103 }
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 */
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100111 ((event2_header_t *)ptr)->pcr_index = metadata_ptr->pcr;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100112
113 /* TCG_PCR_EVENT2.EventType */
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100114 ((event2_header_t *)ptr)->event_type = event_type;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100115
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 */
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100138 if (metadata_ptr->name != NULL) {
139 (void)memcpy((void *)(((event2_data_t *)ptr)->event),
140 (const void *)metadata_ptr->name, name_len);
141 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100142
143 /* End of event data */
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100144 log_ptr = (uint8_t *)((uintptr_t)ptr +
145 offsetof(event2_data_t, event) + name_len);
Harrison Mutai168a02c2025-02-27 15:06:39 +0000146
147 return 0;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100148}
149
Harrison Mutai168a02c2025-02-27 15:06:39 +0000150/*
151 * Initialise the Event Log buffer by setting global pointers
152 * to manage log entries.
153 *
154 * @param[in] event_log_start Base address of the Event Log buffer
155 * @param[in] event_log_finish End address of the Event Log buffer,
156 * pointing to the first byte past the buffer
157 */
158int event_log_buf_init(uint8_t *event_log_start, uint8_t *event_log_finish)
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100159{
Harrison Mutai168a02c2025-02-27 15:06:39 +0000160 if (event_log_start == NULL || event_log_finish == NULL ||
161 event_log_start > event_log_finish) {
162 return -EINVAL;
163 }
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100164
165 log_ptr = event_log_start;
166 log_end = (uintptr_t)event_log_finish;
Harrison Mutai168a02c2025-02-27 15:06:39 +0000167
168 return 0;
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100169}
170
Harrison Mutai168a02c2025-02-27 15:06:39 +0000171/**
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100172 * Initialise Event Log global variables, used during the recording
173 * of various payload measurements into the Event Log buffer
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100174 *
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100175 * @param[in] event_log_start Base address of Event Log buffer
176 * @param[in] event_log_finish End address of Event Log buffer,
177 * it is a first byte past end of the
178 * buffer
179 */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000180int event_log_init(uint8_t *event_log_start, uint8_t *event_log_finish)
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100181{
Harrison Mutai168a02c2025-02-27 15:06:39 +0000182 return event_log_buf_init(event_log_start, event_log_finish);
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100183}
184
Harrison Mutai168a02c2025-02-27 15:06:39 +0000185int event_log_write_specid_event(void)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100186{
Harrison Mutai168a02c2025-02-27 15:06:39 +0000187 void *ptr;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100188
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100189 /* event_log_buf_init() must have been called prior to this. */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000190 if (log_ptr == NULL) {
191 return -EFAULT;
192 }
193
194 if (((uintptr_t)log_ptr + ID_EVENT_SIZE) > log_end) {
195 return -ENOMEM;
196 }
197
198 ptr = log_ptr;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100199
200 /*
201 * Add Specification ID Event first
202 *
203 * Copy TCG_EfiSpecIDEventStruct structure header
204 */
205 (void)memcpy(ptr, (const void *)&id_event_header,
206 sizeof(id_event_header));
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100207 ptr = (uint8_t *)((uintptr_t)ptr + sizeof(id_event_header));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100208
209 /* TCG_EfiSpecIdEventAlgorithmSize structure */
210 ((id_event_algorithm_size_t *)ptr)->algorithm_id = TPM_ALG_ID;
211 ((id_event_algorithm_size_t *)ptr)->digest_size = TCG_DIGEST_SIZE;
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100212 ptr = (uint8_t *)((uintptr_t)ptr + sizeof(id_event_algorithm_size_t));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100213
214 /*
215 * TCG_EfiSpecIDEventStruct.vendorInfoSize
216 * No vendor data
217 */
218 ((id_event_struct_data_t *)ptr)->vendor_info_size = 0;
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100219 log_ptr = (uint8_t *)((uintptr_t)ptr +
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100220 offsetof(id_event_struct_data_t, vendor_info));
Harrison Mutai168a02c2025-02-27 15:06:39 +0000221
222 return 0;
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100223}
224
225/*
226 * Initialises Event Log by writing Specification ID and
227 * Startup Locality events
228 */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000229int event_log_write_header(void)
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100230{
231 const char locality_signature[] = TCG_STARTUP_LOCALITY_SIGNATURE;
232 void *ptr;
Harrison Mutai168a02c2025-02-27 15:06:39 +0000233 int rc;
234
235 rc = event_log_write_specid_event();
236 if (rc < 0) {
237 return rc;
238 }
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100239
Harrison Mutai168a02c2025-02-27 15:06:39 +0000240 if (((uintptr_t)log_ptr + LOC_EVENT_SIZE) > log_end) {
241 return -ENOMEM;
242 }
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100243
244 ptr = log_ptr;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100245
246 /*
247 * The Startup Locality event should be placed in the log before
248 * any event which extends PCR[0].
249 *
250 * Ref. TCG PC Client Platform Firmware Profile 9.4.5.3
251 */
252
253 /* Copy Startup Locality Event Header */
254 (void)memcpy(ptr, (const void *)&locality_event_header,
255 sizeof(locality_event_header));
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100256 ptr = (uint8_t *)((uintptr_t)ptr + sizeof(locality_event_header));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100257
258 /* TCG_PCR_EVENT2.Digests[].AlgorithmId */
259 ((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID;
260
261 /* TCG_PCR_EVENT2.Digests[].Digest[] */
Manish V Badarkhe6e836762022-06-09 22:39:32 +0100262 (void)memset(&((tpmt_ha *)ptr)->digest, 0, TCG_DIGEST_SIZE);
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100263 ptr = (uint8_t *)((uintptr_t)ptr +
264 offsetof(tpmt_ha, digest) + TCG_DIGEST_SIZE);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100265
266 /* TCG_PCR_EVENT2.EventSize */
267 ((event2_data_t *)ptr)->event_size =
268 (uint32_t)sizeof(startup_locality_event_t);
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100269 ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100270
271 /* TCG_EfiStartupLocalityEvent.Signature */
272 (void)memcpy(ptr, (const void *)locality_signature,
273 sizeof(TCG_STARTUP_LOCALITY_SIGNATURE));
274
275 /*
276 * TCG_EfiStartupLocalityEvent.StartupLocality = 0:
277 * the platform's boot firmware
278 */
279 ((startup_locality_event_t *)ptr)->startup_locality = 0U;
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100280 log_ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t));
Harrison Mutai168a02c2025-02-27 15:06:39 +0000281
282 return 0;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100283}
284
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100285int event_log_measure(uintptr_t data_base, uint32_t data_size,
286 unsigned char hash_data[CRYPTO_MD_MAX_SIZE])
287{
288 /* Calculate hash */
289 return crypto_mod_calc_hash(CRYPTO_MD_ID,
290 (void *)data_base, data_size, hash_data);
291}
292
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100293/*
294 * Calculate and write hash of image, configuration data, etc.
295 * to Event Log.
296 *
297 * @param[in] data_base Address of data
298 * @param[in] data_size Size of data
299 * @param[in] data_id Data ID
Manish V Badarkhead44e8b2022-11-18 18:30:08 +0000300 * @param[in] metadata_ptr Event Log metadata
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100301 * @return:
302 * 0 = success
303 * < 0 = error
304 */
Sandrine Bailleux4e9af172021-07-01 14:13:09 +0200305int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size,
Manish V Badarkhead44e8b2022-11-18 18:30:08 +0000306 uint32_t data_id,
307 const event_log_metadata_t *metadata_ptr)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100308{
Manish V Badarkhee112a5a2021-10-06 23:41:50 +0100309 unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100310 int rc;
Manish V Badarkhead44e8b2022-11-18 18:30:08 +0000311
Harrison Mutai168a02c2025-02-27 15:06:39 +0000312 if (metadata_ptr == NULL) {
313 return -EINVAL;
314 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100315
Sandrine Bailleux74b8e172021-06-23 15:44:18 +0200316 /* Get the metadata associated with this image. */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000317 while (metadata_ptr->id != data_id) {
318 if (metadata_ptr->id == EVLOG_INVALID_ID) {
319 return -EINVAL;
320 }
321
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100322 metadata_ptr++;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100323 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100324
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100325 /* Measure the payload with algorithm selected by EventLog driver */
326 rc = event_log_measure(data_base, data_size, hash_data);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100327 if (rc != 0) {
328 return rc;
329 }
330
Harrison Mutai168a02c2025-02-27 15:06:39 +0000331 rc = event_log_record(hash_data, EV_POST_CODE, metadata_ptr);
332 if (rc != 0) {
333 return rc;
334 }
Sandrine Bailleux36af1c82021-06-17 15:44:40 +0200335
Sandrine Bailleux9ebe81e2021-06-23 15:43:02 +0200336 return 0;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100337}
338
339/*
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100340 * Get current Event Log buffer size i.e. used space of Event Log buffer
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100341 *
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100342 * @param[in] event_log_start Base Pointer to Event Log buffer
343 *
344 * @return: current Size of Event Log buffer
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100345 */
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100346size_t event_log_get_cur_size(uint8_t *event_log_start)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100347{
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100348 assert(event_log_start != NULL);
349 assert(log_ptr >= event_log_start);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100350
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100351 return (size_t)((uintptr_t)log_ptr - (uintptr_t)event_log_start);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100352}