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