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