blob: 761ff298fe5ed487dc1ab102aa271de9e07d0cc9 [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
Harrison Mutai168a02c2025-02-27 15:06:39 +000075int event_log_record(const uint8_t *hash, uint32_t event_type,
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +010076 const event_log_metadata_t *metadata_ptr)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010077{
78 void *ptr = log_ptr;
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +010079 uint32_t name_len = 0U;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010080
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +010081 /* event_log_buf_init() must have been called prior to this. */
Harrison Mutai168a02c2025-02-27 15:06:39 +000082 if (hash == NULL || metadata_ptr == NULL || log_ptr == NULL) {
83 return -EINVAL;
84 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010085
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +010086 if (metadata_ptr->name != NULL) {
87 name_len = (uint32_t)strlen(metadata_ptr->name) + 1U;
88 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010089
90 /* Check for space in Event Log buffer */
Harrison Mutai168a02c2025-02-27 15:06:39 +000091 if (((uintptr_t)ptr + (uint32_t)EVENT2_HDR_SIZE + name_len) > log_end) {
92 return -ENOMEM;
93 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010094
95 /*
96 * As per TCG specifications, firmware components that are measured
97 * into PCR[0] must be logged in the event log using the event type
98 * EV_POST_CODE.
99 */
100 /* TCG_PCR_EVENT2.PCRIndex */
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100101 ((event2_header_t *)ptr)->pcr_index = metadata_ptr->pcr;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100102
103 /* TCG_PCR_EVENT2.EventType */
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100104 ((event2_header_t *)ptr)->event_type = event_type;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100105
106 /* TCG_PCR_EVENT2.Digests.Count */
107 ptr = (uint8_t *)ptr + offsetof(event2_header_t, digests);
108 ((tpml_digest_values *)ptr)->count = HASH_ALG_COUNT;
109
110 /* TCG_PCR_EVENT2.Digests[] */
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100111 ptr = (uint8_t *)((uintptr_t)ptr +
112 offsetof(tpml_digest_values, digests));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100113
114 /* TCG_PCR_EVENT2.Digests[].AlgorithmId */
115 ((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID;
116
117 /* TCG_PCR_EVENT2.Digests[].Digest[] */
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100118 ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100119
Sandrine Bailleux898c0992021-06-17 16:10:40 +0200120 /* Copy digest */
121 (void)memcpy(ptr, (const void *)hash, TCG_DIGEST_SIZE);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100122
123 /* TCG_PCR_EVENT2.EventSize */
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100124 ptr = (uint8_t *)((uintptr_t)ptr + TCG_DIGEST_SIZE);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100125 ((event2_data_t *)ptr)->event_size = name_len;
126
127 /* Copy event data to TCG_PCR_EVENT2.Event */
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100128 if (metadata_ptr->name != NULL) {
129 (void)memcpy((void *)(((event2_data_t *)ptr)->event),
130 (const void *)metadata_ptr->name, name_len);
131 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100132
133 /* End of event data */
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100134 log_ptr = (uint8_t *)((uintptr_t)ptr +
135 offsetof(event2_data_t, event) + name_len);
Harrison Mutai168a02c2025-02-27 15:06:39 +0000136
137 return 0;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100138}
139
Harrison Mutai168a02c2025-02-27 15:06:39 +0000140int event_log_buf_init(uint8_t *event_log_start, uint8_t *event_log_finish)
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100141{
Harrison Mutai168a02c2025-02-27 15:06:39 +0000142 if (event_log_start == NULL || event_log_finish == NULL ||
143 event_log_start > event_log_finish) {
144 return -EINVAL;
145 }
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100146
147 log_ptr = event_log_start;
148 log_end = (uintptr_t)event_log_finish;
Harrison Mutai168a02c2025-02-27 15:06:39 +0000149
150 return 0;
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100151}
152
Harrison Mutai168a02c2025-02-27 15:06:39 +0000153int event_log_init(uint8_t *event_log_start, uint8_t *event_log_finish)
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100154{
Harrison Mutai168a02c2025-02-27 15:06:39 +0000155 return event_log_buf_init(event_log_start, event_log_finish);
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100156}
157
Harrison Mutai168a02c2025-02-27 15:06:39 +0000158int event_log_write_specid_event(void)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100159{
Harrison Mutai168a02c2025-02-27 15:06:39 +0000160 void *ptr;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100161
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100162 /* event_log_buf_init() must have been called prior to this. */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000163 if (log_ptr == NULL) {
164 return -EFAULT;
165 }
166
167 if (((uintptr_t)log_ptr + ID_EVENT_SIZE) > log_end) {
168 return -ENOMEM;
169 }
170
171 ptr = log_ptr;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100172
173 /*
174 * Add Specification ID Event first
175 *
176 * Copy TCG_EfiSpecIDEventStruct structure header
177 */
178 (void)memcpy(ptr, (const void *)&id_event_header,
179 sizeof(id_event_header));
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100180 ptr = (uint8_t *)((uintptr_t)ptr + sizeof(id_event_header));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100181
182 /* TCG_EfiSpecIdEventAlgorithmSize structure */
183 ((id_event_algorithm_size_t *)ptr)->algorithm_id = TPM_ALG_ID;
184 ((id_event_algorithm_size_t *)ptr)->digest_size = TCG_DIGEST_SIZE;
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100185 ptr = (uint8_t *)((uintptr_t)ptr + sizeof(id_event_algorithm_size_t));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100186
187 /*
188 * TCG_EfiSpecIDEventStruct.vendorInfoSize
189 * No vendor data
190 */
191 ((id_event_struct_data_t *)ptr)->vendor_info_size = 0;
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100192 log_ptr = (uint8_t *)((uintptr_t)ptr +
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100193 offsetof(id_event_struct_data_t, vendor_info));
Harrison Mutai168a02c2025-02-27 15:06:39 +0000194
195 return 0;
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100196}
197
Harrison Mutai168a02c2025-02-27 15:06:39 +0000198int event_log_write_header(void)
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100199{
200 const char locality_signature[] = TCG_STARTUP_LOCALITY_SIGNATURE;
201 void *ptr;
Harrison Mutai168a02c2025-02-27 15:06:39 +0000202 int rc;
203
204 rc = event_log_write_specid_event();
205 if (rc < 0) {
206 return rc;
207 }
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100208
Harrison Mutai168a02c2025-02-27 15:06:39 +0000209 if (((uintptr_t)log_ptr + LOC_EVENT_SIZE) > log_end) {
210 return -ENOMEM;
211 }
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100212
213 ptr = log_ptr;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100214
215 /*
216 * The Startup Locality event should be placed in the log before
217 * any event which extends PCR[0].
218 *
219 * Ref. TCG PC Client Platform Firmware Profile 9.4.5.3
220 */
221
222 /* Copy Startup Locality Event Header */
223 (void)memcpy(ptr, (const void *)&locality_event_header,
224 sizeof(locality_event_header));
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100225 ptr = (uint8_t *)((uintptr_t)ptr + sizeof(locality_event_header));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100226
227 /* TCG_PCR_EVENT2.Digests[].AlgorithmId */
228 ((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID;
229
230 /* TCG_PCR_EVENT2.Digests[].Digest[] */
Manish V Badarkhe6e836762022-06-09 22:39:32 +0100231 (void)memset(&((tpmt_ha *)ptr)->digest, 0, TCG_DIGEST_SIZE);
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100232 ptr = (uint8_t *)((uintptr_t)ptr +
233 offsetof(tpmt_ha, digest) + TCG_DIGEST_SIZE);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100234
235 /* TCG_PCR_EVENT2.EventSize */
236 ((event2_data_t *)ptr)->event_size =
237 (uint32_t)sizeof(startup_locality_event_t);
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100238 ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100239
240 /* TCG_EfiStartupLocalityEvent.Signature */
241 (void)memcpy(ptr, (const void *)locality_signature,
242 sizeof(TCG_STARTUP_LOCALITY_SIGNATURE));
243
244 /*
245 * TCG_EfiStartupLocalityEvent.StartupLocality = 0:
246 * the platform's boot firmware
247 */
248 ((startup_locality_event_t *)ptr)->startup_locality = 0U;
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100249 log_ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t));
Harrison Mutai168a02c2025-02-27 15:06:39 +0000250
251 return 0;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100252}
253
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100254int event_log_measure(uintptr_t data_base, uint32_t data_size,
255 unsigned char hash_data[CRYPTO_MD_MAX_SIZE])
256{
257 /* Calculate hash */
258 return crypto_mod_calc_hash(CRYPTO_MD_ID,
259 (void *)data_base, data_size, hash_data);
260}
261
Sandrine Bailleux4e9af172021-07-01 14:13:09 +0200262int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size,
Manish V Badarkhead44e8b2022-11-18 18:30:08 +0000263 uint32_t data_id,
264 const event_log_metadata_t *metadata_ptr)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100265{
Manish V Badarkhee112a5a2021-10-06 23:41:50 +0100266 unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100267 int rc;
Manish V Badarkhead44e8b2022-11-18 18:30:08 +0000268
Harrison Mutai168a02c2025-02-27 15:06:39 +0000269 if (metadata_ptr == NULL) {
270 return -EINVAL;
271 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100272
Sandrine Bailleux74b8e172021-06-23 15:44:18 +0200273 /* Get the metadata associated with this image. */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000274 while (metadata_ptr->id != data_id) {
275 if (metadata_ptr->id == EVLOG_INVALID_ID) {
276 return -EINVAL;
277 }
278
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100279 metadata_ptr++;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100280 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100281
Manish V Badarkhe5a9eaa72022-06-15 15:06:43 +0100282 /* Measure the payload with algorithm selected by EventLog driver */
283 rc = event_log_measure(data_base, data_size, hash_data);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100284 if (rc != 0) {
285 return rc;
286 }
287
Harrison Mutai168a02c2025-02-27 15:06:39 +0000288 rc = event_log_record(hash_data, EV_POST_CODE, metadata_ptr);
289 if (rc != 0) {
290 return rc;
291 }
Sandrine Bailleux36af1c82021-06-17 15:44:40 +0200292
Sandrine Bailleux9ebe81e2021-06-23 15:43:02 +0200293 return 0;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100294}
295
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100296size_t event_log_get_cur_size(uint8_t *event_log_start)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100297{
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100298 assert(event_log_start != NULL);
299 assert(log_ptr >= event_log_start);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100300
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100301 return (size_t)((uintptr_t)log_ptr - (uintptr_t)event_log_start);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100302}