blob: 234a694a5f7889ea15d1c1c837725f4e0ad70863 [file] [log] [blame]
Harrison Mutaib6748092025-04-25 16:03:03 +00001/*
2 * Copyright (c) 2020-2025, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <errno.h>
8#include <stdbool.h>
9#include <stdio.h>
10#include <string.h>
11
12#include <common/debug.h>
13#include "event_log.h"
14
15/**
16 * Print a TCG_EfiSpecIDEventStruct entry from the event log.
17 *
18 * This function extracts and prints a TCG_EfiSpecIDEventStruct
19 * entry from the event log for debugging or auditing purposes.
20 *
21 * @param[in,out] log_addr Pointer to the current position in the Event Log.
22 * Updated to the next entry after processing.
23 * @param[in,out] log_size Pointer to the remaining Event Log size.
24 * Updated to reflect the remaining bytes.
25 *
26 * @return 0 on success, or a negative error code on failure.
27 */
28static int event_log_print_id_event(uint8_t **log_addr, size_t *log_size)
29{
30 unsigned int i;
31 uint8_t info_size, *info_size_ptr;
32 void *ptr = *log_addr;
33 id_event_headers_t *event = (id_event_headers_t *)ptr;
34 id_event_algorithm_size_t *alg_ptr;
35 uint32_t event_size, number_of_algorithms;
36 size_t digest_len;
37 const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size);
38
39 if (*log_size < sizeof(id_event_headers_t)) {
40 return -EINVAL;
41 }
42
43 /* The fields of the event log header are defined to be PCRIndex of 0,
44 * EventType of EV_NO_ACTION, Digest of 20 bytes of 0, and
45 * Event content defined as TCG_EfiSpecIDEventStruct.
46 */
47 LOG_EVENT("TCG_EfiSpecIDEvent:\n");
48 LOG_EVENT(" PCRIndex : %u\n", event->header.pcr_index);
49 if (event->header.pcr_index != (uint32_t)PCR_0) {
50 return -EINVAL;
51 }
52
53 LOG_EVENT(" EventType : %u\n", event->header.event_type);
54 if (event->header.event_type != EV_NO_ACTION) {
55 return -EINVAL;
56 }
57
58 LOG_EVENT(" Digest :");
59 for (i = 0U; i < sizeof(event->header.digest); ++i) {
60 uint8_t val = event->header.digest[i];
61
62 (void)printf(" %02x", val);
63 if ((i & U(0xF)) == 0U) {
64 (void)printf("\n");
65 LOG_EVENT("\t\t :");
66 }
67 }
68
69 if ((i & U(0xF)) != 0U) {
70 (void)printf("\n");
71 }
72
73 /* EventSize */
74 event_size = event->header.event_size;
75 LOG_EVENT(" EventSize : %u\n", event_size);
76
77 LOG_EVENT(" Signature : %s\n",
78 event->struct_header.signature);
79 LOG_EVENT(" PlatformClass : %u\n",
80 event->struct_header.platform_class);
81 LOG_EVENT(" SpecVersion : %u.%u.%u\n",
82 event->struct_header.spec_version_major,
83 event->struct_header.spec_version_minor,
84 event->struct_header.spec_errata);
85 LOG_EVENT(" UintnSize : %u\n",
86 event->struct_header.uintn_size);
87
88 /* NumberOfAlgorithms */
89 number_of_algorithms = event->struct_header.number_of_algorithms;
90 LOG_EVENT(" NumberOfAlgorithms : %u\n", number_of_algorithms);
91
92 /* Address of DigestSizes[] */
93 alg_ptr = event->struct_header.digest_size;
94
95 /* Size of DigestSizes[] */
96 digest_len = number_of_algorithms * sizeof(id_event_algorithm_size_t);
97 if (digest_len > (uintptr_t)end_ptr - (uintptr_t)alg_ptr) {
98 return -EFAULT;
99 }
100
101 LOG_EVENT(" DigestSizes :\n");
102 for (i = 0U; i < number_of_algorithms; ++i) {
103 LOG_EVENT(" #%u AlgorithmId : SHA", i);
104 uint16_t algorithm_id = alg_ptr[i].algorithm_id;
105
106 switch (algorithm_id) {
107 case TPM_ALG_SHA256:
108 (void)printf("256\n");
109 break;
110 case TPM_ALG_SHA384:
111 (void)printf("384\n");
112 break;
113 case TPM_ALG_SHA512:
114 (void)printf("512\n");
115 break;
116 default:
117 (void)printf("?\n");
118 ERROR("Algorithm 0x%x not found\n", algorithm_id);
119 return -ENOENT;
120 }
121
122 LOG_EVENT(" DigestSize : %u\n",
123 alg_ptr[i].digest_size);
124 }
125
126 /* Address of VendorInfoSize */
127 info_size_ptr = (uint8_t *)((uintptr_t)alg_ptr + digest_len);
128 if ((uintptr_t)info_size_ptr > (uintptr_t)end_ptr) {
129 return -EFAULT;
130 }
131
132 info_size = *info_size_ptr++;
133 LOG_EVENT(" VendorInfoSize : %u\n", info_size);
134
135 /* Check VendorInfo end address */
136 if (((uintptr_t)info_size_ptr + info_size) > (uintptr_t)end_ptr) {
137 return -EFAULT;
138 }
139
140 /* Check EventSize */
141 if (event_size !=
142 (sizeof(id_event_struct_t) + digest_len + info_size)) {
143 return -EFAULT;
144 }
145
146 if (info_size != 0U) {
147 LOG_EVENT(" VendorInfo :");
148 for (i = 0U; i < info_size; ++i) {
149 (void)printf(" %02x", *info_size_ptr++);
150 }
151 (void)printf("\n");
152 }
153
154 *log_size -= (uintptr_t)info_size_ptr - (uintptr_t)*log_addr;
155 *log_addr = info_size_ptr;
156
157 return 0;
158}
159
160/**
161 * Print a TCG_PCR_EVENT2 entry from the event log.
162 *
163 * This function extracts and prints a TCG_PCR_EVENT2 structure
164 * from the event log for debugging or auditing purposes.
165 *
166 * @param[in,out] log_addr Pointer to the current position in the Event Log.
167 * Updated to the next entry after processing.
168 * @param[in,out] log_size Pointer to the remaining Event Log size.
169 * Updated to reflect the remaining bytes.
170 *
171 * @return 0 on success, or a negative error code on failure.
172 */
173static int event_log_print_pcr_event2(uint8_t **log_addr, size_t *log_size)
174{
175 uint32_t event_size, count;
176 size_t sha_size, digests_size = 0U;
177 void *ptr = *log_addr;
178 const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size);
179
180 if (*log_size < sizeof(event2_header_t)) {
181 return -EINVAL;
182 }
183
184 LOG_EVENT("PCR_Event2:\n");
185 LOG_EVENT(" PCRIndex : %u\n",
186 ((event2_header_t *)ptr)->pcr_index);
187 LOG_EVENT(" EventType : %u\n",
188 ((event2_header_t *)ptr)->event_type);
189
190 count = ((event2_header_t *)ptr)->digests.count;
191 if (count < 1U) {
192 LOG_EVENT("Invalid Digests Count : %u\n", count);
193 return -EINVAL;
194 }
195
196 LOG_EVENT(" Digests Count : %u\n", count);
197
198 /* Address of TCG_PCR_EVENT2.Digests[] */
199 ptr = (uint8_t *)ptr + sizeof(event2_header_t);
200 if ((uintptr_t)ptr > (uintptr_t)end_ptr) {
201 return -EFAULT;
202 }
203
204 for (unsigned int i = 0U; i < count; ++i) {
205 /* Check AlgorithmId address */
206 if (((uintptr_t)ptr + offsetof(tpmt_ha, digest)) >
207 (uintptr_t)end_ptr) {
208 return -EFAULT;
209 }
210
211 LOG_EVENT(" #%u AlgorithmId : SHA", i);
212 switch (((tpmt_ha *)ptr)->algorithm_id) {
213 case TPM_ALG_SHA256:
214 sha_size = SHA256_DIGEST_SIZE;
215 (void)printf("256\n");
216 break;
217 case TPM_ALG_SHA384:
218 sha_size = SHA384_DIGEST_SIZE;
219 (void)printf("384\n");
220 break;
221 case TPM_ALG_SHA512:
222 sha_size = SHA512_DIGEST_SIZE;
223 (void)printf("512\n");
224 break;
225 default:
226 (void)printf("?\n");
227 printf("Algorithm 0x%x not found\n",
228 ((tpmt_ha *)ptr)->algorithm_id);
229 return -ENOENT;
230 }
231
232 /* End of Digest[] */
233 ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest));
234 if (((uintptr_t)ptr + sha_size) > (uintptr_t)end_ptr) {
235 return -EFAULT;
236 }
237
238 /* Total size of all digests */
239 digests_size += sha_size;
240
241 LOG_EVENT(" Digest :");
242 for (unsigned int j = 0U; j < sha_size; ++j) {
243 (void)printf(" %02x", *(uint8_t *)ptr++);
244 if ((j & U(0xF)) == U(0xF)) {
245 (void)printf("\n");
246 if (j < (sha_size - 1U)) {
247 LOG_EVENT("\t\t :");
248 }
249 }
250 }
251 }
252
253 /* TCG_PCR_EVENT2.EventSize */
254 if (((uintptr_t)ptr + offsetof(event2_data_t, event)) >
255 (uintptr_t)end_ptr) {
256 return -EFAULT;
257 }
258
259 event_size = ((event2_data_t *)ptr)->event_size;
260 LOG_EVENT(" EventSize : %u\n", event_size);
261
262 /* Address of TCG_PCR_EVENT2.Event[EventSize] */
263 ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event));
264
265 /* End of TCG_PCR_EVENT2.Event[EventSize] */
266 if (((uintptr_t)ptr + event_size) > (uintptr_t)end_ptr) {
267 return -EFAULT;
268 }
269
270 if ((event_size == sizeof(startup_locality_event_t)) &&
271 (strcmp((const char *)ptr, TCG_STARTUP_LOCALITY_SIGNATURE) == 0)) {
272 LOG_EVENT(" Signature : %s\n",
273 ((startup_locality_event_t *)ptr)->signature);
274 LOG_EVENT(" StartupLocality : %u\n",
275 ((startup_locality_event_t *)ptr)->startup_locality);
276 } else {
277 LOG_EVENT(" Event : %s\n", (uint8_t *)ptr);
278 }
279
280 *log_size -= (uintptr_t)ptr + event_size - (uintptr_t)*log_addr;
281 *log_addr = (uint8_t *)ptr + event_size;
282
283 return 0;
284}
285
286int event_log_dump(uint8_t *log_addr, size_t log_size)
287{
288 int rc;
289
290 if (log_addr == NULL) {
291 return -EINVAL;
292 }
293
294 /* Print TCG_EfiSpecIDEvent */
295 rc = event_log_print_id_event(&log_addr, &log_size);
296
297 if (rc < 0) {
298 return rc;
299 }
300
301 while (log_size != 0U) {
302 rc = event_log_print_pcr_event2(&log_addr, &log_size);
303 if (rc < 0) {
304 return rc;
305 }
306 }
307 return 0;
308}