blob: f0b4c969ef4477224701af4c2a5bc49a532d9d7a [file] [log] [blame]
Alexei Fedorov71d81dc2020-07-13 13:58:06 +01001/*
Harrison Mutaif875e8c2025-03-08 15:42:21 +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
Harrison Mutai168a02c2025-02-27 15:06:39 +00007#include <errno.h>
8#include <stdbool.h>
9#include <stdio.h>
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010010#include <string.h>
11
12#include <common/debug.h>
Harrison Mutai168a02c2025-02-27 15:06:39 +000013#include "event_log.h"
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010014
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010015
16/*
17 * Print TCG_EfiSpecIDEventStruct
18 *
19 * @param[in/out] log_addr Pointer to Event Log
20 * @param[in/out] log_size Pointer to Event Log size
21 */
Harrison Mutai168a02c2025-02-27 15:06:39 +000022static int event_log_print_id_event(uint8_t **log_addr, size_t *log_size)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010023{
24 unsigned int i;
25 uint8_t info_size, *info_size_ptr;
26 void *ptr = *log_addr;
27 id_event_headers_t *event = (id_event_headers_t *)ptr;
28 id_event_algorithm_size_t *alg_ptr;
29 uint32_t event_size, number_of_algorithms;
30 size_t digest_len;
Alexei Fedorovf52e6a12020-09-28 14:47:54 +010031 const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010032
Harrison Mutai168a02c2025-02-27 15:06:39 +000033 if (*log_size < sizeof(id_event_headers_t)) {
34 return -EINVAL;
35 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010036
37 /* The fields of the event log header are defined to be PCRIndex of 0,
38 * EventType of EV_NO_ACTION, Digest of 20 bytes of 0, and
39 * Event content defined as TCG_EfiSpecIDEventStruct.
40 */
41 LOG_EVENT("TCG_EfiSpecIDEvent:\n");
42 LOG_EVENT(" PCRIndex : %u\n", event->header.pcr_index);
Harrison Mutai168a02c2025-02-27 15:06:39 +000043 if (event->header.pcr_index != (uint32_t)PCR_0) {
44 return -EINVAL;
45 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010046
47 LOG_EVENT(" EventType : %u\n", event->header.event_type);
Harrison Mutai168a02c2025-02-27 15:06:39 +000048 if (event->header.event_type != EV_NO_ACTION) {
49 return -EINVAL;
50 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010051
52 LOG_EVENT(" Digest :");
53 for (i = 0U; i < sizeof(event->header.digest); ++i) {
54 uint8_t val = event->header.digest[i];
55
56 (void)printf(" %02x", val);
57 if ((i & U(0xF)) == 0U) {
58 (void)printf("\n");
59 LOG_EVENT("\t\t :");
60 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010061 }
Harrison Mutai168a02c2025-02-27 15:06:39 +000062
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010063 if ((i & U(0xF)) != 0U) {
64 (void)printf("\n");
65 }
66
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010067 /* EventSize */
68 event_size = event->header.event_size;
69 LOG_EVENT(" EventSize : %u\n", event_size);
70
71 LOG_EVENT(" Signature : %s\n",
72 event->struct_header.signature);
73 LOG_EVENT(" PlatformClass : %u\n",
74 event->struct_header.platform_class);
75 LOG_EVENT(" SpecVersion : %u.%u.%u\n",
76 event->struct_header.spec_version_major,
77 event->struct_header.spec_version_minor,
78 event->struct_header.spec_errata);
79 LOG_EVENT(" UintnSize : %u\n",
80 event->struct_header.uintn_size);
81
82 /* NumberOfAlgorithms */
83 number_of_algorithms = event->struct_header.number_of_algorithms;
84 LOG_EVENT(" NumberOfAlgorithms : %u\n", number_of_algorithms);
85
86 /* Address of DigestSizes[] */
87 alg_ptr = event->struct_header.digest_size;
88
89 /* Size of DigestSizes[] */
90 digest_len = number_of_algorithms * sizeof(id_event_algorithm_size_t);
Harrison Mutai168a02c2025-02-27 15:06:39 +000091 if (digest_len > (uintptr_t)end_ptr - (uintptr_t)alg_ptr) {
92 return -EFAULT;
93 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +010094
95 LOG_EVENT(" DigestSizes :\n");
96 for (i = 0U; i < number_of_algorithms; ++i) {
97 LOG_EVENT(" #%u AlgorithmId : SHA", i);
98 uint16_t algorithm_id = alg_ptr[i].algorithm_id;
99
100 switch (algorithm_id) {
101 case TPM_ALG_SHA256:
102 (void)printf("256\n");
103 break;
104 case TPM_ALG_SHA384:
105 (void)printf("384\n");
106 break;
107 case TPM_ALG_SHA512:
108 (void)printf("512\n");
109 break;
110 default:
111 (void)printf("?\n");
112 ERROR("Algorithm 0x%x not found\n", algorithm_id);
Harrison Mutai168a02c2025-02-27 15:06:39 +0000113 return -ENOENT;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100114 }
115
116 LOG_EVENT(" DigestSize : %u\n",
117 alg_ptr[i].digest_size);
118 }
119
120 /* Address of VendorInfoSize */
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100121 info_size_ptr = (uint8_t *)((uintptr_t)alg_ptr + digest_len);
Harrison Mutai168a02c2025-02-27 15:06:39 +0000122 if ((uintptr_t)info_size_ptr > (uintptr_t)end_ptr) {
123 return -EFAULT;
124 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100125
126 info_size = *info_size_ptr++;
127 LOG_EVENT(" VendorInfoSize : %u\n", info_size);
128
129 /* Check VendorInfo end address */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000130 if (((uintptr_t)info_size_ptr + info_size) > (uintptr_t)end_ptr) {
131 return -EFAULT;
132 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100133
134 /* Check EventSize */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000135 if (event_size !=
136 (sizeof(id_event_struct_t) + digest_len + info_size)) {
137 return -EFAULT;
138 }
139
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100140 if (info_size != 0U) {
141 LOG_EVENT(" VendorInfo :");
142 for (i = 0U; i < info_size; ++i) {
143 (void)printf(" %02x", *info_size_ptr++);
144 }
145 (void)printf("\n");
146 }
147
148 *log_size -= (uintptr_t)info_size_ptr - (uintptr_t)*log_addr;
149 *log_addr = info_size_ptr;
Harrison Mutai168a02c2025-02-27 15:06:39 +0000150
151 return 0;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100152}
153
154/*
155 * Print TCG_PCR_EVENT2
156 *
157 * @param[in/out] log_addr Pointer to Event Log
158 * @param[in/out] log_size Pointer to Event Log size
159 */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000160static int event_log_print_pcr_event2(uint8_t **log_addr, size_t *log_size)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100161{
162 uint32_t event_size, count;
163 size_t sha_size, digests_size = 0U;
164 void *ptr = *log_addr;
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100165 const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size);
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100166
Harrison Mutai168a02c2025-02-27 15:06:39 +0000167 if (*log_size < sizeof(event2_header_t)) {
168 return -EINVAL;
169 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100170
171 LOG_EVENT("PCR_Event2:\n");
172 LOG_EVENT(" PCRIndex : %u\n",
173 ((event2_header_t *)ptr)->pcr_index);
174 LOG_EVENT(" EventType : %u\n",
175 ((event2_header_t *)ptr)->event_type);
176
177 count = ((event2_header_t *)ptr)->digests.count;
Harrison Mutai168a02c2025-02-27 15:06:39 +0000178 if (count < 1U) {
179 LOG_EVENT("Invalid Digests Count : %u\n", count);
180 return -EINVAL;
181 }
182
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100183 LOG_EVENT(" Digests Count : %u\n", count);
184
185 /* Address of TCG_PCR_EVENT2.Digests[] */
186 ptr = (uint8_t *)ptr + sizeof(event2_header_t);
Harrison Mutai168a02c2025-02-27 15:06:39 +0000187 if ((uintptr_t)ptr > (uintptr_t)end_ptr) {
188 return -EFAULT;
189 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100190
191 for (unsigned int i = 0U; i < count; ++i) {
192 /* Check AlgorithmId address */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000193 if (((uintptr_t)ptr + offsetof(tpmt_ha, digest)) >
194 (uintptr_t)end_ptr) {
195 return -EFAULT;
196 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100197
198 LOG_EVENT(" #%u AlgorithmId : SHA", i);
199 switch (((tpmt_ha *)ptr)->algorithm_id) {
200 case TPM_ALG_SHA256:
201 sha_size = SHA256_DIGEST_SIZE;
202 (void)printf("256\n");
203 break;
204 case TPM_ALG_SHA384:
205 sha_size = SHA384_DIGEST_SIZE;
206 (void)printf("384\n");
207 break;
208 case TPM_ALG_SHA512:
209 sha_size = SHA512_DIGEST_SIZE;
210 (void)printf("512\n");
211 break;
212 default:
213 (void)printf("?\n");
Harrison Mutai168a02c2025-02-27 15:06:39 +0000214 printf("Algorithm 0x%x not found\n",
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100215 ((tpmt_ha *)ptr)->algorithm_id);
Harrison Mutai168a02c2025-02-27 15:06:39 +0000216 return -ENOENT;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100217 }
218
219 /* End of Digest[] */
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100220 ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest));
Harrison Mutai168a02c2025-02-27 15:06:39 +0000221 if (((uintptr_t)ptr + sha_size) > (uintptr_t)end_ptr) {
222 return -EFAULT;
223 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100224
225 /* Total size of all digests */
226 digests_size += sha_size;
227
228 LOG_EVENT(" Digest :");
229 for (unsigned int j = 0U; j < sha_size; ++j) {
230 (void)printf(" %02x", *(uint8_t *)ptr++);
231 if ((j & U(0xF)) == U(0xF)) {
232 (void)printf("\n");
233 if (j < (sha_size - 1U)) {
234 LOG_EVENT("\t\t :");
235 }
236 }
237 }
238 }
239
240 /* TCG_PCR_EVENT2.EventSize */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000241 if (((uintptr_t)ptr + offsetof(event2_data_t, event)) >
242 (uintptr_t)end_ptr) {
243 return -EFAULT;
244 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100245
246 event_size = ((event2_data_t *)ptr)->event_size;
247 LOG_EVENT(" EventSize : %u\n", event_size);
248
249 /* Address of TCG_PCR_EVENT2.Event[EventSize] */
Alexei Fedorovf52e6a12020-09-28 14:47:54 +0100250 ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event));
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100251
252 /* End of TCG_PCR_EVENT2.Event[EventSize] */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000253 if (((uintptr_t)ptr + event_size) > (uintptr_t)end_ptr) {
254 return -EFAULT;
255 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100256
257 if ((event_size == sizeof(startup_locality_event_t)) &&
258 (strcmp((const char *)ptr, TCG_STARTUP_LOCALITY_SIGNATURE) == 0)) {
259 LOG_EVENT(" Signature : %s\n",
260 ((startup_locality_event_t *)ptr)->signature);
261 LOG_EVENT(" StartupLocality : %u\n",
262 ((startup_locality_event_t *)ptr)->startup_locality);
263 } else {
264 LOG_EVENT(" Event : %s\n", (uint8_t *)ptr);
265 }
266
267 *log_size -= (uintptr_t)ptr + event_size - (uintptr_t)*log_addr;
268 *log_addr = (uint8_t *)ptr + event_size;
Harrison Mutai168a02c2025-02-27 15:06:39 +0000269
270 return 0;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100271}
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100272
273/*
274 * Print Event Log
275 *
276 * @param[in] log_addr Pointer to Event Log
277 * @param[in] log_size Event Log size
278 */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000279int event_log_dump(uint8_t *log_addr, size_t log_size)
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100280{
Harrison Mutai168a02c2025-02-27 15:06:39 +0000281 int rc;
282
283 if (log_addr == NULL) {
284 return -EINVAL;
285 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100286
287 /* Print TCG_EfiSpecIDEvent */
Harrison Mutai168a02c2025-02-27 15:06:39 +0000288 rc = event_log_print_id_event(&log_addr, &log_size);
289
290 if (rc < 0) {
291 return rc;
292 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100293
294 while (log_size != 0U) {
Harrison Mutai168a02c2025-02-27 15:06:39 +0000295 rc = event_log_print_pcr_event2(&log_addr, &log_size);
296 if (rc < 0) {
297 return rc;
298 }
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100299 }
Harrison Mutai168a02c2025-02-27 15:06:39 +0000300 return 0;
Alexei Fedorov71d81dc2020-07-13 13:58:06 +0100301}