blob: 8c1f22e3377b69384f7d6fabb9245c8f50169754 [file] [log] [blame]
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Defines APIs that allow an OS to interact with UEFI firmware to query
4 * information about the device.
5 * https://trustedcomputinggroup.org/resource/tcg-efi-protocol-specification/
6 *
7 * Copyright (c) 2020, Linaro Limited
8 */
9
10#define LOG_CATEGORY LOGC_EFI
11#include <common.h>
12#include <dm.h>
13#include <efi_loader.h>
Heinrich Schuchardta45dac12021-09-09 08:50:01 +020014#include <efi_variable.h>
Ilias Apalodimasc1c02102020-11-11 11:18:11 +020015#include <efi_tcg2.h>
16#include <log.h>
Masahisa Kojima163a0d72021-05-26 12:09:58 +090017#include <malloc.h>
Masahisa Kojima3d49ee82021-10-26 17:27:24 +090018#include <smbios.h>
Pali Rohárbdfb6d72021-08-02 15:18:31 +020019#include <version_string.h>
Ilias Apalodimasc1c02102020-11-11 11:18:11 +020020#include <tpm-v2.h>
Ilias Apalodimasd6b55a42021-11-18 10:13:42 +020021#include <tpm_api.h>
Masahisa Kojima163a0d72021-05-26 12:09:58 +090022#include <u-boot/hash-checksum.h>
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +020023#include <u-boot/sha1.h>
24#include <u-boot/sha256.h>
25#include <u-boot/sha512.h>
Masahisa Kojima14cbb332021-11-03 11:04:09 +090026#include <linux/unaligned/be_byteshift.h>
27#include <linux/unaligned/le_byteshift.h>
Ilias Apalodimasc1c02102020-11-11 11:18:11 +020028#include <linux/unaligned/generic.h>
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +020029#include <hexdump.h>
Ilias Apalodimasc1c02102020-11-11 11:18:11 +020030
Ilias Apalodimas5ba03972021-11-18 09:03:39 +020031/**
32 * struct event_log_buffer - internal eventlog management structure
33 *
34 * @buffer: eventlog buffer
35 * @final_buffer: finalevent config table buffer
36 * @pos: current position of 'buffer'
37 * @final_pos: current position of 'final_buffer'
38 * @get_event_called: true if GetEventLog has been invoked at least once
39 * @ebs_called: true if ExitBootServices has been invoked
40 * @truncated: true if the 'buffer' is truncated
41 */
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +020042struct event_log_buffer {
43 void *buffer;
44 void *final_buffer;
45 size_t pos; /* eventlog position */
46 size_t final_pos; /* final events config table position */
47 size_t last_event_size;
48 bool get_event_called;
Ilias Apalodimas5ba03972021-11-18 09:03:39 +020049 bool ebs_called;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +020050 bool truncated;
51};
Ilias Apalodimasc1c02102020-11-11 11:18:11 +020052
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +020053static struct event_log_buffer event_log;
Masahisa Kojima8fc4e0b2021-08-13 16:12:40 +090054static bool tcg2_efi_app_invoked;
Ilias Apalodimasc1c02102020-11-11 11:18:11 +020055/*
56 * When requesting TPM2_CAP_TPM_PROPERTIES the value is on a standard offset.
57 * Since the current tpm2_get_capability() response buffers starts at
58 * 'union tpmu_capabilities data' of 'struct tpms_capability_data', calculate
59 * the response size and offset once for all consumers
60 */
61#define TPM2_RESPONSE_BUFFER_SIZE (sizeof(struct tpms_capability_data) - \
62 offsetof(struct tpms_capability_data, data))
63#define properties_offset (offsetof(struct tpml_tagged_tpm_property, tpm_property) + \
64 offsetof(struct tpms_tagged_property, value))
65
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +020066static const efi_guid_t efi_guid_tcg2_protocol = EFI_TCG2_PROTOCOL_GUID;
67static const efi_guid_t efi_guid_final_events = EFI_TCG2_FINAL_EVENTS_TABLE_GUID;
68
69struct digest_info {
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +020070 u16 hash_alg;
71 u32 hash_mask;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +020072 u16 hash_len;
73};
74
Ilias Apalodimas1f6871d2021-05-25 14:35:31 +030075static const struct digest_info hash_algo_list[] = {
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +020076 {
77 TPM2_ALG_SHA1,
78 EFI_TCG2_BOOT_HASH_ALG_SHA1,
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +020079 TPM2_SHA1_DIGEST_SIZE,
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +020080 },
81 {
82 TPM2_ALG_SHA256,
83 EFI_TCG2_BOOT_HASH_ALG_SHA256,
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +020084 TPM2_SHA256_DIGEST_SIZE,
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +020085 },
86 {
87 TPM2_ALG_SHA384,
88 EFI_TCG2_BOOT_HASH_ALG_SHA384,
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +020089 TPM2_SHA384_DIGEST_SIZE,
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +020090 },
91 {
92 TPM2_ALG_SHA512,
93 EFI_TCG2_BOOT_HASH_ALG_SHA512,
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +020094 TPM2_SHA512_DIGEST_SIZE,
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +020095 },
96};
97
Masahisa Kojima96485d22021-10-26 17:27:26 +090098struct variable_info {
99 const u16 *name;
100 bool accept_empty;
Masahisa Kojima65aa2592021-10-26 17:27:27 +0900101 u32 pcr_index;
Masahisa Kojima96485d22021-10-26 17:27:26 +0900102};
103
104static struct variable_info secure_variables[] = {
Masahisa Kojima65aa2592021-10-26 17:27:27 +0900105 {u"SecureBoot", true, 7},
106 {u"PK", true, 7},
107 {u"KEK", true, 7},
108 {u"db", true, 7},
109 {u"dbx", true, 7},
110 {u"dbt", false, 7},
111 {u"dbr", false, 7},
112 {u"DeployedMode", false, 1},
113 {u"AuditMode", false, 1},
Masahisa Kojimacfbcf052021-08-13 16:12:39 +0900114};
115
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200116#define MAX_HASH_COUNT ARRAY_SIZE(hash_algo_list)
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200117
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200118/**
119 * alg_to_mask - Get a TCG hash mask for algorithms
120 *
121 * @hash_alg: TCG defined algorithm
122 *
123 * @Return: TCG hashing algorithm bitmaps, 0 if the algorithm is not supported
124 */
125static u32 alg_to_mask(u16 hash_alg)
126{
Ilias Apalodimas1f6871d2021-05-25 14:35:31 +0300127 size_t i;
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200128
129 for (i = 0; i < MAX_HASH_COUNT; i++) {
130 if (hash_algo_list[i].hash_alg == hash_alg)
131 return hash_algo_list[i].hash_mask;
132 }
133
134 return 0;
135}
136
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200137/**
138 * alg_to_len - Get a TCG hash len for algorithms
139 *
140 * @hash_alg: TCG defined algorithm
141 *
142 * @Return: len of chosen algorithm, 0 if the algorithm is not supported
143 */
144static u16 alg_to_len(u16 hash_alg)
145{
Ilias Apalodimas1f6871d2021-05-25 14:35:31 +0300146 size_t i;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200147
148 for (i = 0; i < MAX_HASH_COUNT; i++) {
149 if (hash_algo_list[i].hash_alg == hash_alg)
150 return hash_algo_list[i].hash_len;
151 }
152
153 return 0;
154}
155
156static u32 tcg_event_final_size(struct tpml_digest_values *digest_list)
157{
158 u32 len;
Ilias Apalodimas1f6871d2021-05-25 14:35:31 +0300159 size_t i;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200160
161 len = offsetof(struct tcg_pcr_event2, digests);
162 len += offsetof(struct tpml_digest_values, digests);
163 for (i = 0; i < digest_list->count; i++) {
164 u16 hash_alg = digest_list->digests[i].hash_alg;
165
166 len += offsetof(struct tpmt_ha, digest);
167 len += alg_to_len(hash_alg);
168 }
169 len += sizeof(u32); /* tcg_pcr_event2 event_size*/
170
171 return len;
172}
173
174/* tcg2_pcr_extend - Extend PCRs for a TPM2 device for a given tpml_digest_values
175 *
176 * @dev: device
177 * @digest_list: list of digest algorithms to extend
178 *
179 * @Return: status code
180 */
181static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index,
182 struct tpml_digest_values *digest_list)
183{
184 u32 rc;
Ilias Apalodimas1f6871d2021-05-25 14:35:31 +0300185 size_t i;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200186
187 for (i = 0; i < digest_list->count; i++) {
188 u32 alg = digest_list->digests[i].hash_alg;
189
190 rc = tpm2_pcr_extend(dev, pcr_index, alg,
191 (u8 *)&digest_list->digests[i].digest,
192 alg_to_len(alg));
193 if (rc) {
194 EFI_PRINT("Failed to extend PCR\n");
195 return EFI_DEVICE_ERROR;
196 }
197 }
198
199 return EFI_SUCCESS;
200}
201
Ilias Apalodimas5ba03972021-11-18 09:03:39 +0200202/* put_event - Append an agile event to an eventlog
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200203 *
204 * @pcr_index: PCR index
205 * @event_type: type of event added
206 * @digest_list: list of digest algorithms to add
207 * @size: size of event
208 * @event: event to add
Ilias Apalodimas5ba03972021-11-18 09:03:39 +0200209 * @log: log buffer to append the event
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200210 *
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200211 */
Ilias Apalodimas5ba03972021-11-18 09:03:39 +0200212static void put_event(u32 pcr_index, u32 event_type,
213 struct tpml_digest_values *digest_list, u32 size,
214 u8 event[], void *log)
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200215{
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200216 size_t pos;
Ilias Apalodimas1f6871d2021-05-25 14:35:31 +0300217 size_t i;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200218 u32 event_size;
219
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200220 /*
221 * size refers to the length of event[] only, we need to check against
222 * the final tcg_pcr_event2 size
223 */
224 event_size = size + tcg_event_final_size(digest_list);
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200225
226 put_unaligned_le32(pcr_index, log);
227 pos = offsetof(struct tcg_pcr_event2, event_type);
Ilias Apalodimasf8cd72d2021-03-30 00:42:36 +0300228 put_unaligned_le32(event_type, (void *)((uintptr_t)log + pos));
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200229 pos = offsetof(struct tcg_pcr_event2, digests); /* count */
Ilias Apalodimasf8cd72d2021-03-30 00:42:36 +0300230 put_unaligned_le32(digest_list->count, (void *)((uintptr_t)log + pos));
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200231
232 pos += offsetof(struct tpml_digest_values, digests);
233 for (i = 0; i < digest_list->count; i++) {
234 u16 hash_alg = digest_list->digests[i].hash_alg;
235 u8 *digest = (u8 *)&digest_list->digests[i].digest;
236
Ilias Apalodimasf8cd72d2021-03-30 00:42:36 +0300237 put_unaligned_le16(hash_alg, (void *)((uintptr_t)log + pos));
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200238 pos += offsetof(struct tpmt_ha, digest);
Ilias Apalodimasf8cd72d2021-03-30 00:42:36 +0300239 memcpy((void *)((uintptr_t)log + pos), digest, alg_to_len(hash_alg));
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200240 pos += alg_to_len(hash_alg);
241 }
242
Ilias Apalodimasf8cd72d2021-03-30 00:42:36 +0300243 put_unaligned_le32(size, (void *)((uintptr_t)log + pos));
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200244 pos += sizeof(u32); /* tcg_pcr_event2 event_size*/
Ilias Apalodimasf8cd72d2021-03-30 00:42:36 +0300245 memcpy((void *)((uintptr_t)log + pos), event, size);
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200246 pos += size;
247
Ilias Apalodimas5ba03972021-11-18 09:03:39 +0200248 /*
249 * make sure the calculated buffer is what we checked against
250 * This check should never fail. It checks the code above is
251 * calculating the right length for the event we are adding
252 */
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200253 if (pos != event_size)
Ilias Apalodimas5ba03972021-11-18 09:03:39 +0200254 log_err("Appending to the EventLog failed\n");
255}
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200256
Ilias Apalodimas5ba03972021-11-18 09:03:39 +0200257/* tcg2_agile_log_append - Append an agile event to an eventlog
258 *
259 * @pcr_index: PCR index
260 * @event_type: type of event added
261 * @digest_list: list of digest algorithms to add
262 * @size: size of event
263 * @event: event to add
264 * @log: log buffer to append the event
265 *
266 * @Return: status code
267 */
268static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type,
269 struct tpml_digest_values *digest_list,
270 u32 size, u8 event[])
271{
272 void *log = (void *)((uintptr_t)event_log.buffer + event_log.pos);
273 u32 event_size = size + tcg_event_final_size(digest_list);
274 struct efi_tcg2_final_events_table *final_event;
275 efi_status_t ret = EFI_SUCCESS;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200276
Ilias Apalodimas5ba03972021-11-18 09:03:39 +0200277 /* if ExitBootServices hasn't been called update the normal log */
278 if (!event_log.ebs_called) {
279 if (event_log.truncated ||
280 event_log.pos + event_size > TPM2_EVENT_LOG_SIZE) {
281 event_log.truncated = true;
282 return EFI_VOLUME_FULL;
283 }
284 put_event(pcr_index, event_type, digest_list, size, event, log);
285 event_log.pos += event_size;
286 event_log.last_event_size = event_size;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200287 }
288
Ilias Apalodimas5ba03972021-11-18 09:03:39 +0200289 if (!event_log.get_event_called)
290 return ret;
291
292 /* if GetEventLog has been called update FinalEventLog as well */
293 if (event_log.final_pos + event_size > TPM2_EVENT_LOG_SIZE)
294 return EFI_VOLUME_FULL;
295
296 log = (void *)((uintptr_t)event_log.final_buffer + event_log.final_pos);
297 put_event(pcr_index, event_type, digest_list, size, event, log);
298
299 final_event = event_log.final_buffer;
300 final_event->number_of_events++;
301 event_log.final_pos += event_size;
302
303 return ret;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200304}
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200305
306/**
307 * platform_get_tpm_device() - retrieve TPM device
308 *
309 * This function retrieves the udevice implementing a TPM
310 *
311 * This function may be overridden if special initialization is needed.
312 *
313 * @dev: udevice
314 * Return: status code
315 */
316__weak efi_status_t platform_get_tpm2_device(struct udevice **dev)
317{
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200318 for_each_tpm_device(*dev) {
319 /* Only support TPMv2 devices */
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200320 if (tpm_get_version(*dev) == TPM_V2)
321 return EFI_SUCCESS;
322 }
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200323
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200324 return EFI_NOT_FOUND;
325}
326
327/**
328 * tpm2_get_max_command_size() - get the supported max command size
329 *
330 * @dev: TPM device
331 * @max_command_size: output buffer for the size
332 *
333 * Return: 0 on success, -1 on error
334 */
335static int tpm2_get_max_command_size(struct udevice *dev, u16 *max_command_size)
336{
337 u8 response[TPM2_RESPONSE_BUFFER_SIZE];
338 u32 ret;
339
340 memset(response, 0, sizeof(response));
341 ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
342 TPM2_PT_MAX_COMMAND_SIZE, response, 1);
343 if (ret)
344 return -1;
345
346 *max_command_size = (uint16_t)get_unaligned_be32(response +
347 properties_offset);
348
349 return 0;
350}
351
352/**
353 * tpm2_get_max_response_size() - get the supported max response size
354 *
355 * @dev: TPM device
356 * @max_response_size: output buffer for the size
357 *
358 * Return: 0 on success, -1 on error
359 */
360static int tpm2_get_max_response_size(struct udevice *dev,
361 u16 *max_response_size)
362{
363 u8 response[TPM2_RESPONSE_BUFFER_SIZE];
364 u32 ret;
365
366 memset(response, 0, sizeof(response));
367 ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
368 TPM2_PT_MAX_RESPONSE_SIZE, response, 1);
369 if (ret)
370 return -1;
371
372 *max_response_size = (uint16_t)get_unaligned_be32(response +
373 properties_offset);
374
375 return 0;
376}
377
378/**
379 * tpm2_get_manufacturer_id() - get the manufacturer ID
380 *
381 * @dev: TPM device
382 * @manufacturer_id: output buffer for the id
383 *
384 * Return: 0 on success, -1 on error
385 */
386static int tpm2_get_manufacturer_id(struct udevice *dev, u32 *manufacturer_id)
387{
388 u8 response[TPM2_RESPONSE_BUFFER_SIZE];
389 u32 ret;
390
391 memset(response, 0, sizeof(response));
392 ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
393 TPM2_PT_MANUFACTURER, response, 1);
394 if (ret)
395 return -1;
396
397 *manufacturer_id = get_unaligned_be32(response + properties_offset);
398
399 return 0;
400}
401
402/**
403 * tpm2_get_num_pcr() - get the number of PCRs
404 *
405 * @dev: TPM device
406 * @manufacturer_id: output buffer for the number
407 *
408 * Return: 0 on success, -1 on error
409 */
410static int tpm2_get_num_pcr(struct udevice *dev, u32 *num_pcr)
411{
412 u8 response[TPM2_RESPONSE_BUFFER_SIZE];
413 u32 ret;
414
415 memset(response, 0, sizeof(response));
416 ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
417 TPM2_PT_PCR_COUNT, response, 1);
418 if (ret)
419 return -1;
420
421 *num_pcr = get_unaligned_be32(response + properties_offset);
422 if (*num_pcr > TPM2_MAX_PCRS)
423 return -1;
424
425 return 0;
426}
427
428/**
429 * is_active_pcr() - Check if a supported algorithm is active
430 *
431 * @dev: TPM device
432 * @selection: struct of PCR information
433 *
434 * Return: true if PCR is active
435 */
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200436static bool is_active_pcr(struct tpms_pcr_selection *selection)
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200437{
438 int i;
439 /*
440 * check the pcr_select. If at least one of the PCRs supports the
441 * algorithm add it on the active ones
442 */
443 for (i = 0; i < selection->size_of_select; i++) {
444 if (selection->pcr_select[i])
445 return true;
446 }
447
448 return false;
449}
450
451/**
452 * tpm2_get_pcr_info() - get the supported, active PCRs and number of banks
453 *
454 * @dev: TPM device
455 * @supported_pcr: bitmask with the algorithms supported
456 * @active_pcr: bitmask with the active algorithms
457 * @pcr_banks: number of PCR banks
458 *
459 * Return: 0 on success, -1 on error
460 */
461static int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr,
462 u32 *active_pcr, u32 *pcr_banks)
463{
464 u8 response[TPM2_RESPONSE_BUFFER_SIZE];
465 struct tpml_pcr_selection pcrs;
466 u32 ret, num_pcr;
Ilias Apalodimas1f6871d2021-05-25 14:35:31 +0300467 size_t i;
468 int tpm_ret;
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200469
Ilias Apalodimas38de6802021-05-26 21:01:00 +0300470 *supported_pcr = 0;
471 *active_pcr = 0;
472 *pcr_banks = 0;
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200473 memset(response, 0, sizeof(response));
474 ret = tpm2_get_capability(dev, TPM2_CAP_PCRS, 0, response, 1);
475 if (ret)
476 goto out;
477
478 pcrs.count = get_unaligned_be32(response);
479 /*
480 * We only support 5 algorithms for now so check against that
481 * instead of TPM2_NUM_PCR_BANKS
482 */
483 if (pcrs.count > MAX_HASH_COUNT || pcrs.count < 1)
484 goto out;
485
486 tpm_ret = tpm2_get_num_pcr(dev, &num_pcr);
487 if (tpm_ret)
488 goto out;
489
490 for (i = 0; i < pcrs.count; i++) {
491 /*
492 * Definition of TPMS_PCR_SELECTION Structure
493 * hash: u16
494 * size_of_select: u8
495 * pcr_select: u8 array
496 *
497 * The offsets depend on the number of the device PCRs
498 * so we have to calculate them based on that
499 */
500 u32 hash_offset = offsetof(struct tpml_pcr_selection, selection) +
501 i * offsetof(struct tpms_pcr_selection, pcr_select) +
502 i * ((num_pcr + 7) / 8);
503 u32 size_select_offset =
504 hash_offset + offsetof(struct tpms_pcr_selection,
505 size_of_select);
506 u32 pcr_select_offset =
507 hash_offset + offsetof(struct tpms_pcr_selection,
508 pcr_select);
509
510 pcrs.selection[i].hash =
511 get_unaligned_be16(response + hash_offset);
512 pcrs.selection[i].size_of_select =
513 __get_unaligned_be(response + size_select_offset);
514 if (pcrs.selection[i].size_of_select > TPM2_PCR_SELECT_MAX)
515 goto out;
516 /* copy the array of pcr_select */
517 memcpy(pcrs.selection[i].pcr_select, response + pcr_select_offset,
518 pcrs.selection[i].size_of_select);
519 }
520
521 for (i = 0; i < pcrs.count; i++) {
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200522 u32 hash_mask = alg_to_mask(pcrs.selection[i].hash);
523
524 if (hash_mask) {
525 *supported_pcr |= hash_mask;
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200526 if (is_active_pcr(&pcrs.selection[i]))
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200527 *active_pcr |= hash_mask;
528 } else {
529 EFI_PRINT("Unknown algorithm %x\n", pcrs.selection[i].hash);
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200530 }
531 }
532
533 *pcr_banks = pcrs.count;
534
535 return 0;
536out:
537 return -1;
538}
539
540/**
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200541 * __get_active_pcr_banks() - returns the currently active PCR banks
542 *
543 * @active_pcr_banks: pointer for receiving the bitmap of currently
544 * active PCR banks
545 *
546 * Return: status code
547 */
548static efi_status_t __get_active_pcr_banks(u32 *active_pcr_banks)
549{
550 struct udevice *dev;
Ilias Apalodimas38de6802021-05-26 21:01:00 +0300551 u32 active = 0, supported = 0, pcr_banks = 0;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200552 efi_status_t ret;
553 int err;
554
555 ret = platform_get_tpm2_device(&dev);
556 if (ret != EFI_SUCCESS)
557 goto out;
558
559 err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_banks);
560 if (err) {
561 ret = EFI_DEVICE_ERROR;
562 goto out;
563 }
564
565 *active_pcr_banks = active;
566
567out:
568 return ret;
569}
570
571/* tcg2_create_digest - create a list of digests of the supported PCR banks
572 * for a given memory range
573 *
574 * @input: input memory
575 * @length: length of buffer to calculate the digest
576 * @digest_list: list of digests to fill in
577 *
578 * Return: status code
579 */
580static efi_status_t tcg2_create_digest(const u8 *input, u32 length,
581 struct tpml_digest_values *digest_list)
582{
583 sha1_context ctx;
584 sha256_context ctx_256;
585 sha512_context ctx_512;
Masahisa Kojimab1a7a5e2021-04-14 11:55:49 +0900586 u8 final[TPM2_SHA512_DIGEST_SIZE];
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200587 efi_status_t ret;
588 u32 active;
Ilias Apalodimas1f6871d2021-05-25 14:35:31 +0300589 size_t i;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200590
591 ret = __get_active_pcr_banks(&active);
592 if (ret != EFI_SUCCESS)
593 return ret;
594
595 digest_list->count = 0;
596 for (i = 0; i < MAX_HASH_COUNT; i++) {
597 u16 hash_alg = hash_algo_list[i].hash_alg;
598
599 if (!(active & alg_to_mask(hash_alg)))
600 continue;
601 switch (hash_alg) {
602 case TPM2_ALG_SHA1:
603 sha1_starts(&ctx);
604 sha1_update(&ctx, input, length);
605 sha1_finish(&ctx, final);
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200606 break;
607 case TPM2_ALG_SHA256:
608 sha256_starts(&ctx_256);
609 sha256_update(&ctx_256, input, length);
610 sha256_finish(&ctx_256, final);
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200611 break;
612 case TPM2_ALG_SHA384:
613 sha384_starts(&ctx_512);
614 sha384_update(&ctx_512, input, length);
615 sha384_finish(&ctx_512, final);
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200616 break;
617 case TPM2_ALG_SHA512:
618 sha512_starts(&ctx_512);
619 sha512_update(&ctx_512, input, length);
620 sha512_finish(&ctx_512, final);
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200621 break;
622 default:
623 EFI_PRINT("Unsupported algorithm %x\n", hash_alg);
624 return EFI_INVALID_PARAMETER;
625 }
Ruchika Gupta346cee32021-09-14 12:14:31 +0530626 digest_list->digests[digest_list->count].hash_alg = hash_alg;
627 memcpy(&digest_list->digests[digest_list->count].digest, final,
628 (u32)alg_to_len(hash_alg));
Ilias Apalodimas6fe8b4a2021-04-22 14:32:14 +0300629 digest_list->count++;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200630 }
631
632 return EFI_SUCCESS;
633}
634
635/**
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200636 * efi_tcg2_get_capability() - protocol capability information and state information
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200637 *
638 * @this: TCG2 protocol instance
639 * @capability: caller allocated memory with size field to the size of
640 * the structure allocated
641
642 * Return: status code
643 */
644static efi_status_t EFIAPI
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200645efi_tcg2_get_capability(struct efi_tcg2_protocol *this,
646 struct efi_tcg2_boot_service_capability *capability)
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200647{
648 struct udevice *dev;
649 efi_status_t efi_ret;
650 int ret;
651
652 EFI_ENTRY("%p, %p", this, capability);
653
654 if (!this || !capability) {
655 efi_ret = EFI_INVALID_PARAMETER;
656 goto out;
657 }
658
Masahisa Kojimabad49da2021-09-06 12:04:12 +0900659 if (capability->size < BOOT_SERVICE_CAPABILITY_MIN) {
660 capability->size = BOOT_SERVICE_CAPABILITY_MIN;
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200661 efi_ret = EFI_BUFFER_TOO_SMALL;
662 goto out;
663 }
664
665 if (capability->size < sizeof(*capability)) {
666 capability->size = sizeof(*capability);
667 efi_ret = EFI_BUFFER_TOO_SMALL;
668 goto out;
669 }
670
671 capability->structure_version.major = 1;
672 capability->structure_version.minor = 1;
673 capability->protocol_version.major = 1;
674 capability->protocol_version.minor = 1;
675
676 efi_ret = platform_get_tpm2_device(&dev);
677 if (efi_ret != EFI_SUCCESS) {
678 capability->supported_event_logs = 0;
679 capability->hash_algorithm_bitmap = 0;
680 capability->tpm_present_flag = false;
681 capability->max_command_size = 0;
682 capability->max_response_size = 0;
683 capability->manufacturer_id = 0;
684 capability->number_of_pcr_banks = 0;
685 capability->active_pcr_banks = 0;
686
687 efi_ret = EFI_SUCCESS;
688 goto out;
689 }
690
691 /* We only allow a TPMv2 device to register the EFI protocol */
692 capability->supported_event_logs = TCG2_EVENT_LOG_FORMAT_TCG_2;
693
694 capability->tpm_present_flag = true;
695
696 /* Supported and active PCRs */
697 capability->hash_algorithm_bitmap = 0;
698 capability->active_pcr_banks = 0;
699 ret = tpm2_get_pcr_info(dev, &capability->hash_algorithm_bitmap,
700 &capability->active_pcr_banks,
701 &capability->number_of_pcr_banks);
702 if (ret) {
703 efi_ret = EFI_DEVICE_ERROR;
704 goto out;
705 }
706
707 /* Max command size */
708 ret = tpm2_get_max_command_size(dev, &capability->max_command_size);
709 if (ret) {
710 efi_ret = EFI_DEVICE_ERROR;
711 goto out;
712 }
713
714 /* Max response size */
715 ret = tpm2_get_max_response_size(dev, &capability->max_response_size);
716 if (ret) {
717 efi_ret = EFI_DEVICE_ERROR;
718 goto out;
719 }
720
721 /* Manufacturer ID */
722 ret = tpm2_get_manufacturer_id(dev, &capability->manufacturer_id);
723 if (ret) {
724 efi_ret = EFI_DEVICE_ERROR;
725 goto out;
726 }
727
728 return EFI_EXIT(EFI_SUCCESS);
729out:
730 return EFI_EXIT(efi_ret);
731}
732
733/**
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200734 * efi_tcg2_get_eventlog() - retrieve the the address of an event log and its
735 * last entry
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200736 *
737 * @this: TCG2 protocol instance
738 * @log_format: type of event log format
739 * @event_log_location: pointer to the memory address of the event log
740 * @event_log_last_entry: pointer to the address of the start of the last
741 * entry in the event log in memory, if log contains
742 * more than 1 entry
743 * @event_log_truncated: set to true, if the Event Log is missing at i
744 * least one entry
745 *
746 * Return: status code
747 */
748static efi_status_t EFIAPI
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200749efi_tcg2_get_eventlog(struct efi_tcg2_protocol *this,
750 efi_tcg_event_log_format log_format,
751 u64 *event_log_location, u64 *event_log_last_entry,
752 bool *event_log_truncated)
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200753{
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200754 efi_status_t ret = EFI_SUCCESS;
755 struct udevice *dev;
756
757 EFI_ENTRY("%p, %u, %p, %p, %p", this, log_format, event_log_location,
758 event_log_last_entry, event_log_truncated);
759
Masahisa Kojima580d7242021-09-03 10:55:50 +0900760 if (!this || !event_log_location || !event_log_last_entry ||
761 !event_log_truncated) {
762 ret = EFI_INVALID_PARAMETER;
763 goto out;
764 }
765
766 /* Only support TPMV2 */
767 if (log_format != TCG2_EVENT_LOG_FORMAT_TCG_2) {
768 ret = EFI_INVALID_PARAMETER;
769 goto out;
770 }
771
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200772 ret = platform_get_tpm2_device(&dev);
773 if (ret != EFI_SUCCESS) {
774 event_log_location = NULL;
775 event_log_last_entry = NULL;
776 *event_log_truncated = false;
777 ret = EFI_SUCCESS;
778 goto out;
779 }
780 *event_log_location = (uintptr_t)event_log.buffer;
781 *event_log_last_entry = (uintptr_t)(event_log.buffer + event_log.pos -
782 event_log.last_event_size);
783 *event_log_truncated = event_log.truncated;
784 event_log.get_event_called = true;
785
786out:
787 return EFI_EXIT(ret);
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200788}
789
790/**
Masahisa Kojima163a0d72021-05-26 12:09:58 +0900791 * tcg2_hash_pe_image() - calculate PE/COFF image hash
792 *
793 * @efi: pointer to the EFI binary
794 * @efi_size: size of @efi binary
795 * @digest_list: list of digest algorithms to extend
796 *
797 * Return: status code
798 */
799static efi_status_t tcg2_hash_pe_image(void *efi, u64 efi_size,
800 struct tpml_digest_values *digest_list)
801{
802 WIN_CERTIFICATE *wincerts = NULL;
803 size_t wincerts_len;
804 struct efi_image_regions *regs = NULL;
805 void *new_efi = NULL;
806 u8 hash[TPM2_SHA512_DIGEST_SIZE];
807 efi_status_t ret;
808 u32 active;
809 int i;
810
811 new_efi = efi_prepare_aligned_image(efi, &efi_size);
812 if (!new_efi)
813 return EFI_OUT_OF_RESOURCES;
814
815 if (!efi_image_parse(new_efi, efi_size, &regs, &wincerts,
816 &wincerts_len)) {
817 log_err("Parsing PE executable image failed\n");
818 ret = EFI_UNSUPPORTED;
819 goto out;
820 }
821
822 ret = __get_active_pcr_banks(&active);
823 if (ret != EFI_SUCCESS) {
824 goto out;
825 }
826
827 digest_list->count = 0;
828 for (i = 0; i < MAX_HASH_COUNT; i++) {
829 u16 hash_alg = hash_algo_list[i].hash_alg;
830
831 if (!(active & alg_to_mask(hash_alg)))
832 continue;
833 switch (hash_alg) {
834 case TPM2_ALG_SHA1:
835 hash_calculate("sha1", regs->reg, regs->num, hash);
836 break;
837 case TPM2_ALG_SHA256:
838 hash_calculate("sha256", regs->reg, regs->num, hash);
839 break;
840 case TPM2_ALG_SHA384:
841 hash_calculate("sha384", regs->reg, regs->num, hash);
842 break;
843 case TPM2_ALG_SHA512:
844 hash_calculate("sha512", regs->reg, regs->num, hash);
845 break;
846 default:
847 EFI_PRINT("Unsupported algorithm %x\n", hash_alg);
848 return EFI_INVALID_PARAMETER;
849 }
Ruchika Gupta346cee32021-09-14 12:14:31 +0530850 digest_list->digests[digest_list->count].hash_alg = hash_alg;
851 memcpy(&digest_list->digests[digest_list->count].digest, hash,
852 (u32)alg_to_len(hash_alg));
Masahisa Kojima163a0d72021-05-26 12:09:58 +0900853 digest_list->count++;
854 }
855
856out:
857 if (new_efi != efi)
858 free(new_efi);
859 free(regs);
860
861 return ret;
862}
863
864/**
865 * tcg2_measure_pe_image() - measure PE/COFF image
866 *
867 * @efi: pointer to the EFI binary
868 * @efi_size: size of @efi binary
869 * @handle: loaded image handle
870 * @loaded_image: loaded image protocol
871 *
872 * Return: status code
873 */
874efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
875 struct efi_loaded_image_obj *handle,
876 struct efi_loaded_image *loaded_image)
877{
878 struct tpml_digest_values digest_list;
879 efi_status_t ret;
880 struct udevice *dev;
881 u32 pcr_index, event_type, event_size;
882 struct uefi_image_load_event *image_load_event;
883 struct efi_device_path *device_path;
884 u32 device_path_length;
885 IMAGE_DOS_HEADER *dos;
886 IMAGE_NT_HEADERS32 *nt;
887 struct efi_handler *handler;
888
889 ret = platform_get_tpm2_device(&dev);
890 if (ret != EFI_SUCCESS)
891 return ret;
892
893 switch (handle->image_type) {
894 case IMAGE_SUBSYSTEM_EFI_APPLICATION:
895 pcr_index = 4;
896 event_type = EV_EFI_BOOT_SERVICES_APPLICATION;
897 break;
898 case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
899 pcr_index = 2;
900 event_type = EV_EFI_BOOT_SERVICES_DRIVER;
901 break;
902 case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
903 pcr_index = 2;
904 event_type = EV_EFI_RUNTIME_SERVICES_DRIVER;
905 break;
906 default:
907 return EFI_UNSUPPORTED;
908 }
909
910 ret = tcg2_hash_pe_image(efi, efi_size, &digest_list);
911 if (ret != EFI_SUCCESS)
912 return ret;
913
914 ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
915 if (ret != EFI_SUCCESS)
916 return ret;
917
Ilias Apalodimas0bf538c2021-09-09 00:30:49 +0300918 ret = efi_search_protocol(&handle->header,
919 &efi_guid_loaded_image_device_path, &handler);
Masahisa Kojima163a0d72021-05-26 12:09:58 +0900920 if (ret != EFI_SUCCESS)
921 return ret;
922
Ilias Apalodimas0bf538c2021-09-09 00:30:49 +0300923 device_path = handler->protocol_interface;
Masahisa Kojima163a0d72021-05-26 12:09:58 +0900924 device_path_length = efi_dp_size(device_path);
925 if (device_path_length > 0) {
926 /* add end node size */
927 device_path_length += sizeof(struct efi_device_path);
928 }
929 event_size = sizeof(struct uefi_image_load_event) + device_path_length;
Ilias Apalodimas0bf538c2021-09-09 00:30:49 +0300930 image_load_event = calloc(1, event_size);
Masahisa Kojima163a0d72021-05-26 12:09:58 +0900931 if (!image_load_event)
932 return EFI_OUT_OF_RESOURCES;
933
934 image_load_event->image_location_in_memory = (uintptr_t)efi;
935 image_load_event->image_length_in_memory = efi_size;
936 image_load_event->length_of_device_path = device_path_length;
937
938 dos = (IMAGE_DOS_HEADER *)efi;
939 nt = (IMAGE_NT_HEADERS32 *)(efi + dos->e_lfanew);
940 if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
941 IMAGE_NT_HEADERS64 *nt64 = (IMAGE_NT_HEADERS64 *)nt;
942
943 image_load_event->image_link_time_address =
944 nt64->OptionalHeader.ImageBase;
945 } else if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
946 image_load_event->image_link_time_address =
947 nt->OptionalHeader.ImageBase;
948 } else {
949 ret = EFI_INVALID_PARAMETER;
950 goto out;
951 }
952
Ilias Apalodimas0bf538c2021-09-09 00:30:49 +0300953 /* device_path_length might be zero */
954 memcpy(image_load_event->device_path, device_path, device_path_length);
Masahisa Kojima163a0d72021-05-26 12:09:58 +0900955
956 ret = tcg2_agile_log_append(pcr_index, event_type, &digest_list,
957 event_size, (u8 *)image_load_event);
958
959out:
960 free(image_load_event);
961
962 return ret;
963}
964
965/**
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200966 * efi_tcg2_hash_log_extend_event() - extend and optionally log events
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200967 *
968 * @this: TCG2 protocol instance
969 * @flags: bitmap providing additional information on the
970 * operation
971 * @data_to_hash: physical address of the start of the data buffer
972 * to be hashed
973 * @data_to_hash_len: the length in bytes of the buffer referenced by
974 * data_to_hash
975 * @efi_tcg_event: pointer to data buffer containing information
976 * about the event
977 *
978 * Return: status code
979 */
980static efi_status_t EFIAPI
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +0200981efi_tcg2_hash_log_extend_event(struct efi_tcg2_protocol *this, u64 flags,
982 u64 data_to_hash, u64 data_to_hash_len,
983 struct efi_tcg2_event *efi_tcg_event)
Ilias Apalodimasc1c02102020-11-11 11:18:11 +0200984{
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +0200985 struct udevice *dev;
986 efi_status_t ret;
987 u32 event_type, pcr_index, event_size;
988 struct tpml_digest_values digest_list;
989
990 EFI_ENTRY("%p, %llu, %llu, %llu, %p", this, flags, data_to_hash,
991 data_to_hash_len, efi_tcg_event);
992
993 if (!this || !data_to_hash || !efi_tcg_event) {
994 ret = EFI_INVALID_PARAMETER;
995 goto out;
996 }
997
998 ret = platform_get_tpm2_device(&dev);
999 if (ret != EFI_SUCCESS)
1000 goto out;
1001
1002 if (efi_tcg_event->size < efi_tcg_event->header.header_size +
1003 sizeof(u32)) {
1004 ret = EFI_INVALID_PARAMETER;
1005 goto out;
1006 }
1007
Masahisa Kojima538c0f22021-09-03 10:55:52 +09001008 if (efi_tcg_event->header.pcr_index > EFI_TCG2_MAX_PCR_INDEX) {
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001009 ret = EFI_INVALID_PARAMETER;
1010 goto out;
1011 }
1012
1013 /*
1014 * if PE_COFF_IMAGE is set we need to make sure the image is not
1015 * corrupted, verify it and hash the PE/COFF image in accordance with
Masahisa Kojima163a0d72021-05-26 12:09:58 +09001016 * the procedure specified in "Calculating the PE Image Hash"
1017 * section of the "Windows Authenticode Portable Executable Signature
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001018 * Format"
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001019 */
1020 if (flags & PE_COFF_IMAGE) {
Masahisa Kojima163a0d72021-05-26 12:09:58 +09001021 IMAGE_NT_HEADERS32 *nt;
1022
1023 ret = efi_check_pe((void *)(uintptr_t)data_to_hash,
1024 data_to_hash_len, (void **)&nt);
1025 if (ret != EFI_SUCCESS) {
1026 log_err("Not a valid PE-COFF file\n");
Masahisa Kojima580d7242021-09-03 10:55:50 +09001027 ret = EFI_UNSUPPORTED;
Masahisa Kojima163a0d72021-05-26 12:09:58 +09001028 goto out;
1029 }
1030 ret = tcg2_hash_pe_image((void *)(uintptr_t)data_to_hash,
1031 data_to_hash_len, &digest_list);
1032 } else {
1033 ret = tcg2_create_digest((u8 *)(uintptr_t)data_to_hash,
1034 data_to_hash_len, &digest_list);
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001035 }
1036
Masahisa Kojima163a0d72021-05-26 12:09:58 +09001037 if (ret != EFI_SUCCESS)
1038 goto out;
1039
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001040 pcr_index = efi_tcg_event->header.pcr_index;
1041 event_type = efi_tcg_event->header.event_type;
1042
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001043 ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
1044 if (ret != EFI_SUCCESS)
1045 goto out;
1046
1047 if (flags & EFI_TCG2_EXTEND_ONLY) {
1048 if (event_log.truncated)
1049 ret = EFI_VOLUME_FULL;
1050 goto out;
1051 }
1052
1053 /*
1054 * The efi_tcg_event size includes the size component and the
1055 * headersize
1056 */
1057 event_size = efi_tcg_event->size - sizeof(efi_tcg_event->size) -
1058 efi_tcg_event->header.header_size;
1059 ret = tcg2_agile_log_append(pcr_index, event_type, &digest_list,
1060 event_size, efi_tcg_event->event);
1061out:
1062 return EFI_EXIT(ret);
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001063}
1064
1065/**
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +02001066 * efi_tcg2_submit_command() - Send command to the TPM
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001067 *
1068 * @this: TCG2 protocol instance
1069 * @input_param_block_size: size of the TPM input parameter block
1070 * @input_param_block: pointer to the TPM input parameter block
1071 * @output_param_block_size: size of the TPM output parameter block
1072 * @output_param_block: pointer to the TPM output parameter block
1073 *
1074 * Return: status code
1075 */
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001076static efi_status_t EFIAPI
Masahisa Kojima7fc93ca2021-11-04 22:59:16 +09001077efi_tcg2_submit_command(struct efi_tcg2_protocol *this,
1078 u32 input_param_block_size,
1079 u8 *input_param_block,
1080 u32 output_param_block_size,
1081 u8 *output_param_block)
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001082{
Masahisa Kojima7fc93ca2021-11-04 22:59:16 +09001083 struct udevice *dev;
1084 efi_status_t ret;
1085 u32 rc;
1086 size_t resp_buf_size = output_param_block_size;
1087
1088 EFI_ENTRY("%p, %u, %p, %u, %p", this, input_param_block_size,
1089 input_param_block, output_param_block_size, output_param_block);
1090
1091 if (!this || !input_param_block || !input_param_block_size) {
1092 ret = EFI_INVALID_PARAMETER;
1093 goto out;
1094 }
1095
1096 ret = platform_get_tpm2_device(&dev);
1097 if (ret != EFI_SUCCESS)
1098 goto out;
1099
1100 rc = tpm2_submit_command(dev, input_param_block,
1101 output_param_block, &resp_buf_size);
1102 if (rc) {
1103 ret = (rc == -ENOSPC) ? EFI_OUT_OF_RESOURCES : EFI_DEVICE_ERROR;
1104
1105 goto out;
1106 }
1107
1108out:
1109 return EFI_EXIT(ret);
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001110}
1111
1112/**
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +02001113 * efi_tcg2_get_active_pcr_banks() - returns the currently active PCR banks
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001114 *
1115 * @this: TCG2 protocol instance
1116 * @active_pcr_banks: pointer for receiving the bitmap of currently
1117 * active PCR banks
1118 *
1119 * Return: status code
1120 */
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001121static efi_status_t EFIAPI
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +02001122efi_tcg2_get_active_pcr_banks(struct efi_tcg2_protocol *this,
1123 u32 *active_pcr_banks)
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001124{
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001125 efi_status_t ret;
1126
Masahisa Kojima580d7242021-09-03 10:55:50 +09001127 if (!this || !active_pcr_banks) {
1128 ret = EFI_INVALID_PARAMETER;
1129 goto out;
1130 }
1131
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001132 EFI_ENTRY("%p, %p", this, active_pcr_banks);
1133 ret = __get_active_pcr_banks(active_pcr_banks);
1134
Masahisa Kojima580d7242021-09-03 10:55:50 +09001135out:
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001136 return EFI_EXIT(ret);
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001137}
1138
1139/**
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +02001140 * efi_tcg2_set_active_pcr_banks() - sets the currently active PCR banks
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001141 *
1142 * @this: TCG2 protocol instance
1143 * @active_pcr_banks: bitmap of the requested active PCR banks
1144 *
1145 * Return: status code
1146 */
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001147static efi_status_t EFIAPI
Ilias Apalodimas1f6871d2021-05-25 14:35:31 +03001148efi_tcg2_set_active_pcr_banks(__maybe_unused struct efi_tcg2_protocol *this,
1149 u32 __maybe_unused active_pcr_banks)
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001150{
1151 return EFI_UNSUPPORTED;
1152}
1153
1154/**
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +02001155 * efi_tcg2_get_result_of_set_active_pcr_banks() - retrieve result for previous
1156 * set_active_pcr_banks()
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001157 *
1158 * @this: TCG2 protocol instance
1159 * @operation_present: non-zero value to indicate a
1160 * set_active_pcr_banks operation was
1161 * invoked during last boot
1162 * @response: result value could be returned
1163 *
1164 * Return: status code
1165 */
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001166static efi_status_t EFIAPI
Ilias Apalodimas1f6871d2021-05-25 14:35:31 +03001167efi_tcg2_get_result_of_set_active_pcr_banks(__maybe_unused struct efi_tcg2_protocol *this,
1168 u32 __maybe_unused *operation_present,
1169 u32 __maybe_unused *response)
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001170{
1171 return EFI_UNSUPPORTED;
1172}
1173
1174static const struct efi_tcg2_protocol efi_tcg2_protocol = {
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +02001175 .get_capability = efi_tcg2_get_capability,
1176 .get_eventlog = efi_tcg2_get_eventlog,
1177 .hash_log_extend_event = efi_tcg2_hash_log_extend_event,
1178 .submit_command = efi_tcg2_submit_command,
1179 .get_active_pcr_banks = efi_tcg2_get_active_pcr_banks,
1180 .set_active_pcr_banks = efi_tcg2_set_active_pcr_banks,
1181 .get_result_of_set_active_pcr_banks = efi_tcg2_get_result_of_set_active_pcr_banks,
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001182};
1183
1184/**
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001185 * create_specid_event() - Create the first event in the eventlog
1186 *
1187 * @dev: tpm device
1188 * @event_header: Pointer to the final event header
1189 * @event_size: final spec event size
1190 *
1191 * Return: status code
1192 */
1193static efi_status_t create_specid_event(struct udevice *dev, void *buffer,
1194 size_t *event_size)
1195{
1196 struct tcg_efi_spec_id_event *spec_event;
1197 size_t spec_event_size;
1198 efi_status_t ret = EFI_DEVICE_ERROR;
Ruchika Gupta346cee32021-09-14 12:14:31 +05301199 u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0;
Ilias Apalodimas1f6871d2021-05-25 14:35:31 +03001200 int err;
1201 size_t i;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001202
1203 /*
1204 * Create Spec event. This needs to be the first event in the log
1205 * according to the TCG EFI protocol spec
1206 */
1207
1208 /* Setup specID event data */
1209 spec_event = (struct tcg_efi_spec_id_event *)buffer;
1210 memcpy(spec_event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03,
1211 sizeof(spec_event->signature));
1212 put_unaligned_le32(0, &spec_event->platform_class); /* type client */
1213 spec_event->spec_version_minor =
1214 TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2;
1215 spec_event->spec_version_major =
1216 TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2;
1217 spec_event->spec_errata =
1218 TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2;
1219 spec_event->uintn_size = sizeof(efi_uintn_t) / sizeof(u32);
1220
Ruchika Gupta346cee32021-09-14 12:14:31 +05301221 err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_count);
1222
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001223 if (err)
1224 goto out;
Ruchika Gupta346cee32021-09-14 12:14:31 +05301225
1226 for (i = 0; i < pcr_count; i++) {
1227 u16 hash_alg = hash_algo_list[i].hash_alg;
1228 u16 hash_len = hash_algo_list[i].hash_len;
1229
1230 if (active & alg_to_mask(hash_alg)) {
1231 put_unaligned_le16(hash_alg,
1232 &spec_event->digest_sizes[alg_count].algorithm_id);
1233 put_unaligned_le16(hash_len,
1234 &spec_event->digest_sizes[alg_count].digest_size);
1235 alg_count++;
1236 }
1237 }
1238
1239 spec_event->number_of_algorithms = alg_count;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001240 if (spec_event->number_of_algorithms > MAX_HASH_COUNT ||
1241 spec_event->number_of_algorithms < 1)
1242 goto out;
1243
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001244 /*
1245 * the size of the spec event and placement of vendor_info_size
1246 * depends on supported algoriths
1247 */
1248 spec_event_size =
1249 offsetof(struct tcg_efi_spec_id_event, digest_sizes) +
1250 spec_event->number_of_algorithms * sizeof(spec_event->digest_sizes[0]);
1251 /* no vendor info for us */
Ruchika Gupta346cee32021-09-14 12:14:31 +05301252 memset(buffer + spec_event_size, 0, 1);
1253 /* add a byte for vendor_info_size in the spec event */
1254 spec_event_size += 1;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001255 *event_size = spec_event_size;
1256
1257 return EFI_SUCCESS;
1258
1259out:
1260 return ret;
1261}
1262
1263/**
Ilias Apalodimasd8cf1132021-03-25 13:31:45 +02001264 * tcg2_uninit - remove the final event table and free efi memory on failures
1265 */
1266void tcg2_uninit(void)
1267{
1268 efi_status_t ret;
1269
1270 ret = efi_install_configuration_table(&efi_guid_final_events, NULL);
1271 if (ret != EFI_SUCCESS)
1272 log_err("Failed to delete final events config table\n");
1273
1274 efi_free_pool(event_log.buffer);
1275 event_log.buffer = NULL;
1276 efi_free_pool(event_log.final_buffer);
1277 event_log.final_buffer = NULL;
1278}
1279
1280/**
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001281 * create_final_event() - Create the final event and install the config
1282 * defined by the TCG EFI spec
1283 */
1284static efi_status_t create_final_event(void)
1285{
1286 struct efi_tcg2_final_events_table *final_event;
1287 efi_status_t ret;
1288
1289 /*
1290 * All events generated after the invocation of
1291 * EFI_TCG2_GET_EVENT_LOGS need to be stored in an instance of an
1292 * EFI_CONFIGURATION_TABLE
1293 */
1294 ret = efi_allocate_pool(EFI_ACPI_MEMORY_NVS, TPM2_EVENT_LOG_SIZE,
1295 &event_log.final_buffer);
1296 if (ret != EFI_SUCCESS)
1297 goto out;
1298
1299 memset(event_log.final_buffer, 0xff, TPM2_EVENT_LOG_SIZE);
1300 final_event = event_log.final_buffer;
1301 final_event->number_of_events = 0;
1302 final_event->version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
1303 event_log.final_pos = sizeof(*final_event);
1304 ret = efi_install_configuration_table(&efi_guid_final_events,
1305 final_event);
Ilias Apalodimas20527592021-05-12 00:03:41 +03001306 if (ret != EFI_SUCCESS) {
1307 efi_free_pool(event_log.final_buffer);
1308 event_log.final_buffer = NULL;
1309 }
1310
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001311out:
1312 return ret;
1313}
1314
1315/**
1316 * efi_init_event_log() - initialize an eventlog
1317 */
1318static efi_status_t efi_init_event_log(void)
1319{
1320 /*
1321 * vendor_info_size is currently set to 0, we need to change the length
1322 * and allocate the flexible array member if this changes
1323 */
1324 struct tcg_pcr_event *event_header = NULL;
1325 struct udevice *dev;
1326 size_t spec_event_size;
1327 efi_status_t ret;
1328
1329 ret = platform_get_tpm2_device(&dev);
1330 if (ret != EFI_SUCCESS)
1331 goto out;
1332
1333 ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE,
1334 (void **)&event_log.buffer);
1335 if (ret != EFI_SUCCESS)
1336 goto out;
1337
1338 /*
1339 * initialize log area as 0xff so the OS can easily figure out the
1340 * last log entry
1341 */
1342 memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE);
1343 event_log.pos = 0;
1344 event_log.last_event_size = 0;
1345 event_log.get_event_called = false;
Ilias Apalodimas5ba03972021-11-18 09:03:39 +02001346 event_log.ebs_called = false;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001347 event_log.truncated = false;
1348
1349 /*
1350 * The log header is defined to be in SHA1 event log entry format.
1351 * Setup event header
1352 */
1353 event_header = (struct tcg_pcr_event *)event_log.buffer;
1354 put_unaligned_le32(0, &event_header->pcr_index);
1355 put_unaligned_le32(EV_NO_ACTION, &event_header->event_type);
1356 memset(&event_header->digest, 0, sizeof(event_header->digest));
Ilias Apalodimasf8cd72d2021-03-30 00:42:36 +03001357 ret = create_specid_event(dev, (void *)((uintptr_t)event_log.buffer + sizeof(*event_header)),
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001358 &spec_event_size);
1359 if (ret != EFI_SUCCESS)
Ilias Apalodimas20527592021-05-12 00:03:41 +03001360 goto free_pool;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001361 put_unaligned_le32(spec_event_size, &event_header->event_size);
1362 event_log.pos = spec_event_size + sizeof(*event_header);
1363 event_log.last_event_size = event_log.pos;
1364
1365 ret = create_final_event();
Ilias Apalodimas20527592021-05-12 00:03:41 +03001366 if (ret != EFI_SUCCESS)
1367 goto free_pool;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001368
1369out:
1370 return ret;
Ilias Apalodimas20527592021-05-12 00:03:41 +03001371
1372free_pool:
1373 efi_free_pool(event_log.buffer);
1374 event_log.buffer = NULL;
1375 return ret;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001376}
1377
1378/**
Masahisa Kojimacfbcf052021-08-13 16:12:39 +09001379 * tcg2_measure_event() - common function to add event log and extend PCR
1380 *
1381 * @dev: TPM device
1382 * @pcr_index: PCR index
1383 * @event_type: type of event added
1384 * @size: event size
1385 * @event: event data
1386 *
1387 * Return: status code
1388 */
1389static efi_status_t
1390tcg2_measure_event(struct udevice *dev, u32 pcr_index, u32 event_type,
1391 u32 size, u8 event[])
1392{
1393 struct tpml_digest_values digest_list;
1394 efi_status_t ret;
1395
1396 ret = tcg2_create_digest(event, size, &digest_list);
1397 if (ret != EFI_SUCCESS)
1398 goto out;
1399
1400 ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
1401 if (ret != EFI_SUCCESS)
1402 goto out;
1403
1404 ret = tcg2_agile_log_append(pcr_index, event_type, &digest_list,
1405 size, event);
1406
1407out:
1408 return ret;
1409}
1410
1411/**
Ilias Apalodimasf69a2012021-03-24 16:50:46 +02001412 * efi_append_scrtm_version - Append an S-CRTM EV_S_CRTM_VERSION event on the
1413 * eventlog and extend the PCRs
1414 *
1415 * @dev: TPM device
1416 *
1417 * @Return: status code
1418 */
1419static efi_status_t efi_append_scrtm_version(struct udevice *dev)
1420{
Ilias Apalodimasf69a2012021-03-24 16:50:46 +02001421 efi_status_t ret;
1422
Pali Rohárfa9c5da2021-08-02 15:18:30 +02001423 ret = tcg2_measure_event(dev, 0, EV_S_CRTM_VERSION,
1424 strlen(version_string) + 1,
1425 (u8 *)version_string);
Ilias Apalodimasf69a2012021-03-24 16:50:46 +02001426
Ilias Apalodimasf69a2012021-03-24 16:50:46 +02001427 return ret;
1428}
1429
1430/**
Masahisa Kojimacfbcf052021-08-13 16:12:39 +09001431 * tcg2_measure_variable() - add variable event log and extend PCR
1432 *
1433 * @dev: TPM device
1434 * @pcr_index: PCR index
1435 * @event_type: type of event added
1436 * @var_name: variable name
1437 * @guid: guid
1438 * @data_size: variable data size
1439 * @data: variable data
1440 *
1441 * Return: status code
1442 */
1443static efi_status_t tcg2_measure_variable(struct udevice *dev, u32 pcr_index,
Heinrich Schuchardtd47671c2021-09-09 07:12:14 +02001444 u32 event_type, const u16 *var_name,
Masahisa Kojimacfbcf052021-08-13 16:12:39 +09001445 const efi_guid_t *guid,
1446 efi_uintn_t data_size, u8 *data)
1447{
1448 u32 event_size;
1449 efi_status_t ret;
1450 struct efi_tcg2_uefi_variable_data *event;
1451
1452 event_size = sizeof(event->variable_name) +
1453 sizeof(event->unicode_name_length) +
1454 sizeof(event->variable_data_length) +
1455 (u16_strlen(var_name) * sizeof(u16)) + data_size;
1456 event = malloc(event_size);
1457 if (!event)
1458 return EFI_OUT_OF_RESOURCES;
1459
1460 guidcpy(&event->variable_name, guid);
1461 event->unicode_name_length = u16_strlen(var_name);
1462 event->variable_data_length = data_size;
1463 memcpy(event->unicode_name, var_name,
1464 (event->unicode_name_length * sizeof(u16)));
1465 if (data) {
1466 memcpy((u16 *)event->unicode_name + event->unicode_name_length,
1467 data, data_size);
1468 }
1469 ret = tcg2_measure_event(dev, pcr_index, event_type, event_size,
1470 (u8 *)event);
1471 free(event);
1472 return ret;
1473}
1474
1475/**
Masahisa Kojima8fc4e0b2021-08-13 16:12:40 +09001476 * tcg2_measure_boot_variable() - measure boot variables
1477 *
1478 * @dev: TPM device
1479 *
1480 * Return: status code
1481 */
1482static efi_status_t tcg2_measure_boot_variable(struct udevice *dev)
1483{
1484 u16 *boot_order;
1485 u16 *boot_index;
1486 u16 var_name[] = L"BootOrder";
1487 u16 boot_name[] = L"Boot####";
1488 u8 *bootvar;
1489 efi_uintn_t var_data_size;
1490 u32 count, i;
1491 efi_status_t ret;
1492
1493 boot_order = efi_get_var(var_name, &efi_global_variable_guid,
1494 &var_data_size);
1495 if (!boot_order) {
Masahisa Kojimac9c1cdb2021-11-09 18:44:54 +09001496 /* If "BootOrder" is not defined, skip the boot variable measurement */
1497 return EFI_SUCCESS;
Masahisa Kojima8fc4e0b2021-08-13 16:12:40 +09001498 }
1499
1500 ret = tcg2_measure_variable(dev, 1, EV_EFI_VARIABLE_BOOT2, var_name,
1501 &efi_global_variable_guid, var_data_size,
1502 (u8 *)boot_order);
1503 if (ret != EFI_SUCCESS)
1504 goto error;
1505
1506 count = var_data_size / sizeof(*boot_order);
1507 boot_index = boot_order;
1508 for (i = 0; i < count; i++) {
1509 efi_create_indexed_name(boot_name, sizeof(boot_name),
1510 "Boot", *boot_index++);
1511
1512 bootvar = efi_get_var(boot_name, &efi_global_variable_guid,
1513 &var_data_size);
1514
1515 if (!bootvar) {
Masahisa Kojima3961bd92021-11-09 20:35:53 +09001516 log_debug("%ls not found\n", boot_name);
Masahisa Kojima8fc4e0b2021-08-13 16:12:40 +09001517 continue;
1518 }
1519
1520 ret = tcg2_measure_variable(dev, 1, EV_EFI_VARIABLE_BOOT2,
1521 boot_name,
1522 &efi_global_variable_guid,
1523 var_data_size, bootvar);
1524 free(bootvar);
1525 if (ret != EFI_SUCCESS)
1526 goto error;
1527 }
1528
1529error:
1530 free(boot_order);
1531 return ret;
1532}
1533
1534/**
Masahisa Kojima3d49ee82021-10-26 17:27:24 +09001535 * tcg2_measure_smbios() - measure smbios table
1536 *
1537 * @dev: TPM device
1538 * @entry: pointer to the smbios_entry structure
1539 *
1540 * Return: status code
1541 */
1542static efi_status_t
1543tcg2_measure_smbios(struct udevice *dev,
1544 const struct smbios_entry *entry)
1545{
1546 efi_status_t ret;
1547 struct smbios_header *smbios_copy;
1548 struct smbios_handoff_table_pointers2 *event = NULL;
1549 u32 event_size;
1550
1551 /*
1552 * TCG PC Client PFP Spec says
1553 * "SMBIOS structures that contain static configuration information
1554 * (e.g. Platform Manufacturer Enterprise Number assigned by IANA,
1555 * platform model number, Vendor and Device IDs for each SMBIOS table)
1556 * that is relevant to the security of the platform MUST be measured".
1557 * Device dependent parameters such as serial number are cleared to
1558 * zero or spaces for the measurement.
1559 */
1560 event_size = sizeof(struct smbios_handoff_table_pointers2) +
1561 FIELD_SIZEOF(struct efi_configuration_table, guid) +
1562 entry->struct_table_length;
1563 event = calloc(1, event_size);
1564 if (!event) {
1565 ret = EFI_OUT_OF_RESOURCES;
1566 goto out;
1567 }
1568
1569 event->table_description_size = sizeof(SMBIOS_HANDOFF_TABLE_DESC);
1570 memcpy(event->table_description, SMBIOS_HANDOFF_TABLE_DESC,
1571 sizeof(SMBIOS_HANDOFF_TABLE_DESC));
1572 put_unaligned_le64(1, &event->number_of_tables);
1573 guidcpy(&event->table_entry[0].guid, &smbios_guid);
1574 smbios_copy = (struct smbios_header *)((uintptr_t)&event->table_entry[0].table);
1575 memcpy(&event->table_entry[0].table,
1576 (void *)((uintptr_t)entry->struct_table_address),
1577 entry->struct_table_length);
1578
1579 smbios_prepare_measurement(entry, smbios_copy);
1580
1581 ret = tcg2_measure_event(dev, 1, EV_EFI_HANDOFF_TABLES2, event_size,
1582 (u8 *)event);
1583 if (ret != EFI_SUCCESS)
1584 goto out;
1585
1586out:
1587 free(event);
1588
1589 return ret;
1590}
1591
1592/**
1593 * find_smbios_table() - find smbios table
1594 *
1595 * Return: pointer to the smbios table
1596 */
1597static void *find_smbios_table(void)
1598{
1599 u32 i;
1600
1601 for (i = 0; i < systab.nr_tables; i++) {
1602 if (!guidcmp(&smbios_guid, &systab.tables[i].guid))
1603 return systab.tables[i].table;
1604 }
1605
1606 return NULL;
1607}
1608
1609/**
Masahisa Kojimace3dbc52021-10-26 17:27:25 +09001610 * tcg2_measure_gpt_table() - measure gpt table
1611 *
1612 * @dev: TPM device
1613 * @loaded_image: handle to the loaded image
1614 *
1615 * Return: status code
1616 */
1617static efi_status_t
1618tcg2_measure_gpt_data(struct udevice *dev,
1619 struct efi_loaded_image_obj *loaded_image)
1620{
1621 efi_status_t ret;
1622 efi_handle_t handle;
1623 struct efi_handler *dp_handler;
1624 struct efi_device_path *orig_device_path;
1625 struct efi_device_path *device_path;
1626 struct efi_device_path *dp;
1627 struct efi_block_io *block_io;
1628 struct efi_gpt_data *event = NULL;
1629 efi_guid_t null_guid = NULL_GUID;
1630 gpt_header *gpt_h;
1631 gpt_entry *entry = NULL;
1632 gpt_entry *gpt_e;
1633 u32 num_of_valid_entry = 0;
1634 u32 event_size;
1635 u32 i;
1636 u32 total_gpt_entry_size;
1637
1638 ret = efi_search_protocol(&loaded_image->header,
1639 &efi_guid_loaded_image_device_path,
1640 &dp_handler);
1641 if (ret != EFI_SUCCESS)
1642 return ret;
1643
1644 orig_device_path = dp_handler->protocol_interface;
1645 if (!orig_device_path) /* no device path, skip GPT measurement */
1646 return EFI_SUCCESS;
1647
1648 device_path = efi_dp_dup(orig_device_path);
1649 if (!device_path)
1650 return EFI_OUT_OF_RESOURCES;
1651
1652 dp = search_gpt_dp_node(device_path);
1653 if (!dp) {
1654 /* no GPT device path node found, skip GPT measurement */
1655 ret = EFI_SUCCESS;
1656 goto out1;
1657 }
1658
1659 /* read GPT header */
1660 dp->type = DEVICE_PATH_TYPE_END;
1661 dp->sub_type = DEVICE_PATH_SUB_TYPE_END;
1662 dp = device_path;
1663 ret = EFI_CALL(systab.boottime->locate_device_path(&efi_block_io_guid,
1664 &dp, &handle));
1665 if (ret != EFI_SUCCESS)
1666 goto out1;
1667
1668 ret = EFI_CALL(efi_handle_protocol(handle,
1669 &efi_block_io_guid, (void **)&block_io));
1670 if (ret != EFI_SUCCESS)
1671 goto out1;
1672
1673 gpt_h = memalign(block_io->media->io_align, block_io->media->block_size);
1674 if (!gpt_h) {
1675 ret = EFI_OUT_OF_RESOURCES;
1676 goto out2;
1677 }
1678
1679 ret = block_io->read_blocks(block_io, block_io->media->media_id, 1,
1680 block_io->media->block_size, gpt_h);
1681 if (ret != EFI_SUCCESS)
1682 goto out2;
1683
1684 /* read GPT entry */
1685 total_gpt_entry_size = gpt_h->num_partition_entries *
1686 gpt_h->sizeof_partition_entry;
1687 entry = memalign(block_io->media->io_align, total_gpt_entry_size);
1688 if (!entry) {
1689 ret = EFI_OUT_OF_RESOURCES;
1690 goto out2;
1691 }
1692
1693 ret = block_io->read_blocks(block_io, block_io->media->media_id,
1694 gpt_h->partition_entry_lba,
1695 total_gpt_entry_size, entry);
1696 if (ret != EFI_SUCCESS)
1697 goto out2;
1698
1699 /* count valid GPT entry */
1700 gpt_e = entry;
1701 for (i = 0; i < gpt_h->num_partition_entries; i++) {
1702 if (guidcmp(&null_guid, &gpt_e->partition_type_guid))
1703 num_of_valid_entry++;
1704
1705 gpt_e = (gpt_entry *)((u8 *)gpt_e + gpt_h->sizeof_partition_entry);
1706 }
1707
1708 /* prepare event data for measurement */
1709 event_size = sizeof(struct efi_gpt_data) +
1710 (num_of_valid_entry * gpt_h->sizeof_partition_entry);
1711 event = calloc(1, event_size);
1712 if (!event) {
1713 ret = EFI_OUT_OF_RESOURCES;
1714 goto out2;
1715 }
1716 memcpy(event, gpt_h, sizeof(gpt_header));
1717 put_unaligned_le64(num_of_valid_entry, &event->number_of_partitions);
1718
1719 /* copy valid GPT entry */
1720 gpt_e = entry;
1721 num_of_valid_entry = 0;
1722 for (i = 0; i < gpt_h->num_partition_entries; i++) {
1723 if (guidcmp(&null_guid, &gpt_e->partition_type_guid)) {
1724 memcpy((u8 *)event->partitions +
1725 (num_of_valid_entry * gpt_h->sizeof_partition_entry),
1726 gpt_e, gpt_h->sizeof_partition_entry);
1727 num_of_valid_entry++;
1728 }
1729
1730 gpt_e = (gpt_entry *)((u8 *)gpt_e + gpt_h->sizeof_partition_entry);
1731 }
1732
1733 ret = tcg2_measure_event(dev, 5, EV_EFI_GPT_EVENT, event_size, (u8 *)event);
1734 if (ret != EFI_SUCCESS)
1735 goto out2;
1736
1737out2:
1738 EFI_CALL(efi_close_protocol((efi_handle_t)block_io, &efi_block_io_guid,
1739 NULL, NULL));
1740 free(gpt_h);
1741 free(entry);
1742 free(event);
1743out1:
1744 efi_free_pool(device_path);
1745
1746 return ret;
1747}
1748
1749/**
Masahisa Kojima8fc4e0b2021-08-13 16:12:40 +09001750 * efi_tcg2_measure_efi_app_invocation() - measure efi app invocation
1751 *
1752 * Return: status code
1753 */
Masahisa Kojimace3dbc52021-10-26 17:27:25 +09001754efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *handle)
Masahisa Kojima8fc4e0b2021-08-13 16:12:40 +09001755{
1756 efi_status_t ret;
1757 u32 pcr_index;
1758 struct udevice *dev;
1759 u32 event = 0;
Masahisa Kojima3d49ee82021-10-26 17:27:24 +09001760 struct smbios_entry *entry;
Masahisa Kojima8fc4e0b2021-08-13 16:12:40 +09001761
1762 if (tcg2_efi_app_invoked)
1763 return EFI_SUCCESS;
1764
1765 ret = platform_get_tpm2_device(&dev);
1766 if (ret != EFI_SUCCESS)
1767 return ret;
1768
1769 ret = tcg2_measure_boot_variable(dev);
1770 if (ret != EFI_SUCCESS)
1771 goto out;
1772
1773 ret = tcg2_measure_event(dev, 4, EV_EFI_ACTION,
1774 strlen(EFI_CALLING_EFI_APPLICATION),
1775 (u8 *)EFI_CALLING_EFI_APPLICATION);
1776 if (ret != EFI_SUCCESS)
1777 goto out;
1778
Masahisa Kojima3d49ee82021-10-26 17:27:24 +09001779 entry = (struct smbios_entry *)find_smbios_table();
1780 if (entry) {
1781 ret = tcg2_measure_smbios(dev, entry);
1782 if (ret != EFI_SUCCESS)
1783 goto out;
1784 }
1785
Masahisa Kojimace3dbc52021-10-26 17:27:25 +09001786 ret = tcg2_measure_gpt_data(dev, handle);
1787 if (ret != EFI_SUCCESS)
1788 goto out;
1789
Masahisa Kojima8fc4e0b2021-08-13 16:12:40 +09001790 for (pcr_index = 0; pcr_index <= 7; pcr_index++) {
1791 ret = tcg2_measure_event(dev, pcr_index, EV_SEPARATOR,
1792 sizeof(event), (u8 *)&event);
1793 if (ret != EFI_SUCCESS)
1794 goto out;
1795 }
1796
1797 tcg2_efi_app_invoked = true;
1798out:
1799 return ret;
1800}
1801
1802/**
1803 * efi_tcg2_measure_efi_app_exit() - measure efi app exit
1804 *
1805 * Return: status code
1806 */
1807efi_status_t efi_tcg2_measure_efi_app_exit(void)
1808{
1809 efi_status_t ret;
1810 struct udevice *dev;
1811
1812 ret = platform_get_tpm2_device(&dev);
1813 if (ret != EFI_SUCCESS)
1814 return ret;
1815
1816 ret = tcg2_measure_event(dev, 4, EV_EFI_ACTION,
1817 strlen(EFI_RETURNING_FROM_EFI_APPLICATION),
1818 (u8 *)EFI_RETURNING_FROM_EFI_APPLICATION);
1819 return ret;
1820}
1821
1822/**
Masahisa Kojimafdff03e2021-08-13 16:12:41 +09001823 * efi_tcg2_notify_exit_boot_services() - ExitBootService callback
1824 *
1825 * @event: callback event
1826 * @context: callback context
1827 */
1828static void EFIAPI
1829efi_tcg2_notify_exit_boot_services(struct efi_event *event, void *context)
1830{
1831 efi_status_t ret;
1832 struct udevice *dev;
1833
1834 EFI_ENTRY("%p, %p", event, context);
1835
Ilias Apalodimas5ba03972021-11-18 09:03:39 +02001836 event_log.ebs_called = true;
Masahisa Kojimafdff03e2021-08-13 16:12:41 +09001837 ret = platform_get_tpm2_device(&dev);
1838 if (ret != EFI_SUCCESS)
1839 goto out;
1840
1841 ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION,
1842 strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION),
1843 (u8 *)EFI_EXIT_BOOT_SERVICES_INVOCATION);
1844 if (ret != EFI_SUCCESS)
1845 goto out;
1846
1847 ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION,
1848 strlen(EFI_EXIT_BOOT_SERVICES_SUCCEEDED),
1849 (u8 *)EFI_EXIT_BOOT_SERVICES_SUCCEEDED);
1850
1851out:
1852 EFI_EXIT(ret);
1853}
1854
1855/**
1856 * efi_tcg2_notify_exit_boot_services_failed()
1857 * - notify ExitBootServices() is failed
1858 *
1859 * Return: status code
1860 */
1861efi_status_t efi_tcg2_notify_exit_boot_services_failed(void)
1862{
1863 struct udevice *dev;
1864 efi_status_t ret;
1865
1866 ret = platform_get_tpm2_device(&dev);
1867 if (ret != EFI_SUCCESS)
1868 goto out;
1869
1870 ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION,
1871 strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION),
1872 (u8 *)EFI_EXIT_BOOT_SERVICES_INVOCATION);
1873 if (ret != EFI_SUCCESS)
1874 goto out;
1875
1876 ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION,
1877 strlen(EFI_EXIT_BOOT_SERVICES_FAILED),
1878 (u8 *)EFI_EXIT_BOOT_SERVICES_FAILED);
1879
1880out:
1881 return ret;
1882}
1883
1884/**
Masahisa Kojimacfbcf052021-08-13 16:12:39 +09001885 * tcg2_measure_secure_boot_variable() - measure secure boot variables
1886 *
1887 * @dev: TPM device
1888 *
1889 * Return: status code
1890 */
1891static efi_status_t tcg2_measure_secure_boot_variable(struct udevice *dev)
1892{
1893 u8 *data;
1894 efi_uintn_t data_size;
1895 u32 count, i;
1896 efi_status_t ret;
Masahisa Kojima65aa2592021-10-26 17:27:27 +09001897 u8 deployed_mode;
1898 efi_uintn_t size;
1899 u32 deployed_audit_pcr_index = 1;
1900
1901 size = sizeof(deployed_mode);
1902 ret = efi_get_variable_int(u"DeployedMode", &efi_global_variable_guid,
1903 NULL, &size, &deployed_mode, NULL);
1904 if (ret != EFI_SUCCESS || !deployed_mode)
1905 deployed_audit_pcr_index = 7;
Masahisa Kojimacfbcf052021-08-13 16:12:39 +09001906
1907 count = ARRAY_SIZE(secure_variables);
1908 for (i = 0; i < count; i++) {
Heinrich Schuchardta45dac12021-09-09 08:50:01 +02001909 const efi_guid_t *guid;
1910
Masahisa Kojima96485d22021-10-26 17:27:26 +09001911 guid = efi_auth_var_get_guid(secure_variables[i].name);
Heinrich Schuchardta45dac12021-09-09 08:50:01 +02001912
Masahisa Kojima96485d22021-10-26 17:27:26 +09001913 data = efi_get_var(secure_variables[i].name, guid, &data_size);
1914 if (!data && !secure_variables[i].accept_empty)
1915 continue;
Masahisa Kojimacfbcf052021-08-13 16:12:39 +09001916
Masahisa Kojima65aa2592021-10-26 17:27:27 +09001917 if (u16_strcmp(u"DeployedMode", secure_variables[i].name))
1918 secure_variables[i].pcr_index = deployed_audit_pcr_index;
1919 if (u16_strcmp(u"AuditMode", secure_variables[i].name))
1920 secure_variables[i].pcr_index = deployed_audit_pcr_index;
1921
1922 ret = tcg2_measure_variable(dev, secure_variables[i].pcr_index,
Masahisa Kojimacfbcf052021-08-13 16:12:39 +09001923 EV_EFI_VARIABLE_DRIVER_CONFIG,
Masahisa Kojima96485d22021-10-26 17:27:26 +09001924 secure_variables[i].name, guid,
Masahisa Kojimacfbcf052021-08-13 16:12:39 +09001925 data_size, data);
1926 free(data);
1927 if (ret != EFI_SUCCESS)
1928 goto error;
1929 }
1930
Masahisa Kojimacfbcf052021-08-13 16:12:39 +09001931error:
1932 return ret;
1933}
1934
1935/**
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001936 * efi_tcg2_register() - register EFI_TCG2_PROTOCOL
1937 *
1938 * If a TPM2 device is available, the TPM TCG2 Protocol is registered
1939 *
1940 * Return: An error status is only returned if adding the protocol fails.
1941 */
1942efi_status_t efi_tcg2_register(void)
1943{
Ilias Apalodimasd8cf1132021-03-25 13:31:45 +02001944 efi_status_t ret = EFI_SUCCESS;
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001945 struct udevice *dev;
Masahisa Kojimafdff03e2021-08-13 16:12:41 +09001946 struct efi_event *event;
Ilias Apalodimasd6b55a42021-11-18 10:13:42 +02001947 u32 err;
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001948
1949 ret = platform_get_tpm2_device(&dev);
Ilias Apalodimas9aeb3802020-11-16 08:52:41 +02001950 if (ret != EFI_SUCCESS) {
1951 log_warning("Unable to find TPMv2 device\n");
Ilias Apalodimas97f446a2021-05-10 21:19:14 +03001952 return EFI_SUCCESS;
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001953 }
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001954
Ilias Apalodimasd6b55a42021-11-18 10:13:42 +02001955 /* initialize the TPM as early as possible. */
1956 err = tpm_startup(dev, TPM_ST_CLEAR);
1957 if (err) {
1958 log_err("TPM startup failed\n");
1959 goto fail;
1960 }
1961
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001962 ret = efi_init_event_log();
1963 if (ret != EFI_SUCCESS)
Ilias Apalodimasd8cf1132021-03-25 13:31:45 +02001964 goto fail;
Ilias Apalodimasc8d0fd52020-11-30 11:47:40 +02001965
Ilias Apalodimasf69a2012021-03-24 16:50:46 +02001966 ret = efi_append_scrtm_version(dev);
Ilias Apalodimas20527592021-05-12 00:03:41 +03001967 if (ret != EFI_SUCCESS) {
1968 tcg2_uninit();
Ilias Apalodimas97f446a2021-05-10 21:19:14 +03001969 goto fail;
Ilias Apalodimas20527592021-05-12 00:03:41 +03001970 }
Ilias Apalodimasf69a2012021-03-24 16:50:46 +02001971
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02001972 ret = efi_add_protocol(efi_root, &efi_guid_tcg2_protocol,
1973 (void *)&efi_tcg2_protocol);
Ilias Apalodimasd8cf1132021-03-25 13:31:45 +02001974 if (ret != EFI_SUCCESS) {
Ilias Apalodimas20527592021-05-12 00:03:41 +03001975 tcg2_uninit();
Ilias Apalodimasd8cf1132021-03-25 13:31:45 +02001976 goto fail;
1977 }
Masahisa Kojimacfbcf052021-08-13 16:12:39 +09001978
Masahisa Kojimafdff03e2021-08-13 16:12:41 +09001979 ret = efi_create_event(EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
1980 efi_tcg2_notify_exit_boot_services, NULL,
1981 NULL, &event);
1982 if (ret != EFI_SUCCESS) {
1983 tcg2_uninit();
1984 goto fail;
1985 }
1986
Masahisa Kojimacfbcf052021-08-13 16:12:39 +09001987 ret = tcg2_measure_secure_boot_variable(dev);
1988 if (ret != EFI_SUCCESS) {
1989 tcg2_uninit();
1990 goto fail;
1991 }
1992
Ilias Apalodimasd8cf1132021-03-25 13:31:45 +02001993 return ret;
Ilias Apalodimas97f446a2021-05-10 21:19:14 +03001994
Ilias Apalodimasd8cf1132021-03-25 13:31:45 +02001995fail:
Ilias Apalodimas20527592021-05-12 00:03:41 +03001996 log_err("Cannot install EFI_TCG2_PROTOCOL\n");
1997 /*
1998 * Return EFI_SUCCESS and don't stop the EFI subsystem.
1999 * That's done for 2 reasons
2000 * - If the protocol is not installed the PCRs won't be extended. So
2001 * someone later in the boot flow will notice that and take the
2002 * necessary actions.
2003 * - The TPM sandbox is limited and we won't be able to run any efi
2004 * related tests with TCG2 enabled
2005 */
2006 return EFI_SUCCESS;
Ilias Apalodimasc1c02102020-11-11 11:18:11 +02002007}