blob: 797d6eb134f6c90597db4f3450c575af57571760 [file] [log] [blame]
Ilias Apalodimas590fef62020-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>
14#include <efi_tcg2.h>
15#include <log.h>
16#include <tpm-v2.h>
Ilias Apalodimas967650d2020-11-30 11:47:40 +020017#include <u-boot/sha1.h>
18#include <u-boot/sha256.h>
19#include <u-boot/sha512.h>
Ilias Apalodimas590fef62020-11-11 11:18:11 +020020#include <linux/unaligned/access_ok.h>
21#include <linux/unaligned/generic.h>
Ilias Apalodimas967650d2020-11-30 11:47:40 +020022#include <hexdump.h>
Ilias Apalodimas590fef62020-11-11 11:18:11 +020023
Ilias Apalodimas967650d2020-11-30 11:47:40 +020024struct event_log_buffer {
25 void *buffer;
26 void *final_buffer;
27 size_t pos; /* eventlog position */
28 size_t final_pos; /* final events config table position */
29 size_t last_event_size;
30 bool get_event_called;
31 bool truncated;
32};
Ilias Apalodimas590fef62020-11-11 11:18:11 +020033
Ilias Apalodimas967650d2020-11-30 11:47:40 +020034static struct event_log_buffer event_log;
Ilias Apalodimas590fef62020-11-11 11:18:11 +020035/*
36 * When requesting TPM2_CAP_TPM_PROPERTIES the value is on a standard offset.
37 * Since the current tpm2_get_capability() response buffers starts at
38 * 'union tpmu_capabilities data' of 'struct tpms_capability_data', calculate
39 * the response size and offset once for all consumers
40 */
41#define TPM2_RESPONSE_BUFFER_SIZE (sizeof(struct tpms_capability_data) - \
42 offsetof(struct tpms_capability_data, data))
43#define properties_offset (offsetof(struct tpml_tagged_tpm_property, tpm_property) + \
44 offsetof(struct tpms_tagged_property, value))
45
Ilias Apalodimas967650d2020-11-30 11:47:40 +020046static const efi_guid_t efi_guid_tcg2_protocol = EFI_TCG2_PROTOCOL_GUID;
47static const efi_guid_t efi_guid_final_events = EFI_TCG2_FINAL_EVENTS_TABLE_GUID;
48
49struct digest_info {
Ilias Apalodimasc67fef62020-11-16 08:52:41 +020050 u16 hash_alg;
51 u32 hash_mask;
Ilias Apalodimas967650d2020-11-30 11:47:40 +020052 u16 hash_len;
53};
54
55const static struct digest_info hash_algo_list[] = {
Ilias Apalodimasc67fef62020-11-16 08:52:41 +020056 {
57 TPM2_ALG_SHA1,
58 EFI_TCG2_BOOT_HASH_ALG_SHA1,
Ilias Apalodimas967650d2020-11-30 11:47:40 +020059 TPM2_SHA1_DIGEST_SIZE,
Ilias Apalodimasc67fef62020-11-16 08:52:41 +020060 },
61 {
62 TPM2_ALG_SHA256,
63 EFI_TCG2_BOOT_HASH_ALG_SHA256,
Ilias Apalodimas967650d2020-11-30 11:47:40 +020064 TPM2_SHA256_DIGEST_SIZE,
Ilias Apalodimasc67fef62020-11-16 08:52:41 +020065 },
66 {
67 TPM2_ALG_SHA384,
68 EFI_TCG2_BOOT_HASH_ALG_SHA384,
Ilias Apalodimas967650d2020-11-30 11:47:40 +020069 TPM2_SHA384_DIGEST_SIZE,
Ilias Apalodimasc67fef62020-11-16 08:52:41 +020070 },
71 {
72 TPM2_ALG_SHA512,
73 EFI_TCG2_BOOT_HASH_ALG_SHA512,
Ilias Apalodimas967650d2020-11-30 11:47:40 +020074 TPM2_SHA512_DIGEST_SIZE,
Ilias Apalodimasc67fef62020-11-16 08:52:41 +020075 },
76};
77
78#define MAX_HASH_COUNT ARRAY_SIZE(hash_algo_list)
Ilias Apalodimas967650d2020-11-30 11:47:40 +020079
Ilias Apalodimasc67fef62020-11-16 08:52:41 +020080/**
81 * alg_to_mask - Get a TCG hash mask for algorithms
82 *
83 * @hash_alg: TCG defined algorithm
84 *
85 * @Return: TCG hashing algorithm bitmaps, 0 if the algorithm is not supported
86 */
87static u32 alg_to_mask(u16 hash_alg)
88{
89 int i;
90
91 for (i = 0; i < MAX_HASH_COUNT; i++) {
92 if (hash_algo_list[i].hash_alg == hash_alg)
93 return hash_algo_list[i].hash_mask;
94 }
95
96 return 0;
97}
98
Ilias Apalodimas967650d2020-11-30 11:47:40 +020099/**
100 * alg_to_len - Get a TCG hash len for algorithms
101 *
102 * @hash_alg: TCG defined algorithm
103 *
104 * @Return: len of chosen algorithm, 0 if the algorithm is not supported
105 */
106static u16 alg_to_len(u16 hash_alg)
107{
108 int i;
109
110 for (i = 0; i < MAX_HASH_COUNT; i++) {
111 if (hash_algo_list[i].hash_alg == hash_alg)
112 return hash_algo_list[i].hash_len;
113 }
114
115 return 0;
116}
117
118static u32 tcg_event_final_size(struct tpml_digest_values *digest_list)
119{
120 u32 len;
121 int i;
122
123 len = offsetof(struct tcg_pcr_event2, digests);
124 len += offsetof(struct tpml_digest_values, digests);
125 for (i = 0; i < digest_list->count; i++) {
126 u16 hash_alg = digest_list->digests[i].hash_alg;
127
128 len += offsetof(struct tpmt_ha, digest);
129 len += alg_to_len(hash_alg);
130 }
131 len += sizeof(u32); /* tcg_pcr_event2 event_size*/
132
133 return len;
134}
135
136/* tcg2_pcr_extend - Extend PCRs for a TPM2 device for a given tpml_digest_values
137 *
138 * @dev: device
139 * @digest_list: list of digest algorithms to extend
140 *
141 * @Return: status code
142 */
143static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index,
144 struct tpml_digest_values *digest_list)
145{
146 u32 rc;
147 int i;
148
149 for (i = 0; i < digest_list->count; i++) {
150 u32 alg = digest_list->digests[i].hash_alg;
151
152 rc = tpm2_pcr_extend(dev, pcr_index, alg,
153 (u8 *)&digest_list->digests[i].digest,
154 alg_to_len(alg));
155 if (rc) {
156 EFI_PRINT("Failed to extend PCR\n");
157 return EFI_DEVICE_ERROR;
158 }
159 }
160
161 return EFI_SUCCESS;
162}
163
164/* tcg2_agile_log_append - Append an agile event to out eventlog
165 *
166 * @pcr_index: PCR index
167 * @event_type: type of event added
168 * @digest_list: list of digest algorithms to add
169 * @size: size of event
170 * @event: event to add
171 *
172 * @Return: status code
173 */
174static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type,
175 struct tpml_digest_values *digest_list,
176 u32 size, u8 event[])
177{
178 void *log = event_log.buffer + event_log.pos;
179 size_t pos;
180 int i;
181 u32 event_size;
182
183 if (event_log.get_event_called)
184 log = event_log.final_buffer + event_log.final_pos;
185
186 /*
187 * size refers to the length of event[] only, we need to check against
188 * the final tcg_pcr_event2 size
189 */
190 event_size = size + tcg_event_final_size(digest_list);
191 if (event_log.pos + event_size > TPM2_EVENT_LOG_SIZE ||
192 event_log.final_pos + event_size > TPM2_EVENT_LOG_SIZE) {
193 event_log.truncated = true;
194 return EFI_VOLUME_FULL;
195 }
196
197 put_unaligned_le32(pcr_index, log);
198 pos = offsetof(struct tcg_pcr_event2, event_type);
199 put_unaligned_le32(event_type, log + pos);
200 pos = offsetof(struct tcg_pcr_event2, digests); /* count */
201 put_unaligned_le32(digest_list->count, log + pos);
202
203 pos += offsetof(struct tpml_digest_values, digests);
204 for (i = 0; i < digest_list->count; i++) {
205 u16 hash_alg = digest_list->digests[i].hash_alg;
206 u8 *digest = (u8 *)&digest_list->digests[i].digest;
207
208 put_unaligned_le16(hash_alg, log + pos);
209 pos += offsetof(struct tpmt_ha, digest);
210 memcpy(log + pos, digest, alg_to_len(hash_alg));
211 pos += alg_to_len(hash_alg);
212 }
213
214 put_unaligned_le32(size, log + pos);
215 pos += sizeof(u32); /* tcg_pcr_event2 event_size*/
216 memcpy(log + pos, event, size);
217 pos += size;
218
219 /* make sure the calculated buffer is what we checked against */
220 if (pos != event_size)
221 return EFI_INVALID_PARAMETER;
222
223 /* if GetEventLog hasn't been called update the normal log */
224 if (!event_log.get_event_called) {
225 event_log.pos += pos;
226 event_log.last_event_size = pos;
227 } else {
228 /* if GetEventLog has been called update config table log */
229 struct efi_tcg2_final_events_table *final_event;
230
231 final_event =
232 (struct efi_tcg2_final_events_table *)(event_log.final_buffer);
233 final_event->number_of_events++;
234 event_log.final_pos += pos;
235 }
236
237 return EFI_SUCCESS;
238}
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200239
240/**
241 * platform_get_tpm_device() - retrieve TPM device
242 *
243 * This function retrieves the udevice implementing a TPM
244 *
245 * This function may be overridden if special initialization is needed.
246 *
247 * @dev: udevice
248 * Return: status code
249 */
250__weak efi_status_t platform_get_tpm2_device(struct udevice **dev)
251{
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200252 for_each_tpm_device(*dev) {
253 /* Only support TPMv2 devices */
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200254 if (tpm_get_version(*dev) == TPM_V2)
255 return EFI_SUCCESS;
256 }
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200257
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200258 return EFI_NOT_FOUND;
259}
260
261/**
262 * tpm2_get_max_command_size() - get the supported max command size
263 *
264 * @dev: TPM device
265 * @max_command_size: output buffer for the size
266 *
267 * Return: 0 on success, -1 on error
268 */
269static int tpm2_get_max_command_size(struct udevice *dev, u16 *max_command_size)
270{
271 u8 response[TPM2_RESPONSE_BUFFER_SIZE];
272 u32 ret;
273
274 memset(response, 0, sizeof(response));
275 ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
276 TPM2_PT_MAX_COMMAND_SIZE, response, 1);
277 if (ret)
278 return -1;
279
280 *max_command_size = (uint16_t)get_unaligned_be32(response +
281 properties_offset);
282
283 return 0;
284}
285
286/**
287 * tpm2_get_max_response_size() - get the supported max response size
288 *
289 * @dev: TPM device
290 * @max_response_size: output buffer for the size
291 *
292 * Return: 0 on success, -1 on error
293 */
294static int tpm2_get_max_response_size(struct udevice *dev,
295 u16 *max_response_size)
296{
297 u8 response[TPM2_RESPONSE_BUFFER_SIZE];
298 u32 ret;
299
300 memset(response, 0, sizeof(response));
301 ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
302 TPM2_PT_MAX_RESPONSE_SIZE, response, 1);
303 if (ret)
304 return -1;
305
306 *max_response_size = (uint16_t)get_unaligned_be32(response +
307 properties_offset);
308
309 return 0;
310}
311
312/**
313 * tpm2_get_manufacturer_id() - get the manufacturer ID
314 *
315 * @dev: TPM device
316 * @manufacturer_id: output buffer for the id
317 *
318 * Return: 0 on success, -1 on error
319 */
320static int tpm2_get_manufacturer_id(struct udevice *dev, u32 *manufacturer_id)
321{
322 u8 response[TPM2_RESPONSE_BUFFER_SIZE];
323 u32 ret;
324
325 memset(response, 0, sizeof(response));
326 ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
327 TPM2_PT_MANUFACTURER, response, 1);
328 if (ret)
329 return -1;
330
331 *manufacturer_id = get_unaligned_be32(response + properties_offset);
332
333 return 0;
334}
335
336/**
337 * tpm2_get_num_pcr() - get the number of PCRs
338 *
339 * @dev: TPM device
340 * @manufacturer_id: output buffer for the number
341 *
342 * Return: 0 on success, -1 on error
343 */
344static int tpm2_get_num_pcr(struct udevice *dev, u32 *num_pcr)
345{
346 u8 response[TPM2_RESPONSE_BUFFER_SIZE];
347 u32 ret;
348
349 memset(response, 0, sizeof(response));
350 ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
351 TPM2_PT_PCR_COUNT, response, 1);
352 if (ret)
353 return -1;
354
355 *num_pcr = get_unaligned_be32(response + properties_offset);
356 if (*num_pcr > TPM2_MAX_PCRS)
357 return -1;
358
359 return 0;
360}
361
362/**
363 * is_active_pcr() - Check if a supported algorithm is active
364 *
365 * @dev: TPM device
366 * @selection: struct of PCR information
367 *
368 * Return: true if PCR is active
369 */
Ilias Apalodimas967650d2020-11-30 11:47:40 +0200370static bool is_active_pcr(struct tpms_pcr_selection *selection)
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200371{
372 int i;
373 /*
374 * check the pcr_select. If at least one of the PCRs supports the
375 * algorithm add it on the active ones
376 */
377 for (i = 0; i < selection->size_of_select; i++) {
378 if (selection->pcr_select[i])
379 return true;
380 }
381
382 return false;
383}
384
385/**
386 * tpm2_get_pcr_info() - get the supported, active PCRs and number of banks
387 *
388 * @dev: TPM device
389 * @supported_pcr: bitmask with the algorithms supported
390 * @active_pcr: bitmask with the active algorithms
391 * @pcr_banks: number of PCR banks
392 *
393 * Return: 0 on success, -1 on error
394 */
395static int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr,
396 u32 *active_pcr, u32 *pcr_banks)
397{
398 u8 response[TPM2_RESPONSE_BUFFER_SIZE];
399 struct tpml_pcr_selection pcrs;
400 u32 ret, num_pcr;
401 int i, tpm_ret;
402
403 memset(response, 0, sizeof(response));
404 ret = tpm2_get_capability(dev, TPM2_CAP_PCRS, 0, response, 1);
405 if (ret)
406 goto out;
407
408 pcrs.count = get_unaligned_be32(response);
409 /*
410 * We only support 5 algorithms for now so check against that
411 * instead of TPM2_NUM_PCR_BANKS
412 */
413 if (pcrs.count > MAX_HASH_COUNT || pcrs.count < 1)
414 goto out;
415
416 tpm_ret = tpm2_get_num_pcr(dev, &num_pcr);
417 if (tpm_ret)
418 goto out;
419
420 for (i = 0; i < pcrs.count; i++) {
421 /*
422 * Definition of TPMS_PCR_SELECTION Structure
423 * hash: u16
424 * size_of_select: u8
425 * pcr_select: u8 array
426 *
427 * The offsets depend on the number of the device PCRs
428 * so we have to calculate them based on that
429 */
430 u32 hash_offset = offsetof(struct tpml_pcr_selection, selection) +
431 i * offsetof(struct tpms_pcr_selection, pcr_select) +
432 i * ((num_pcr + 7) / 8);
433 u32 size_select_offset =
434 hash_offset + offsetof(struct tpms_pcr_selection,
435 size_of_select);
436 u32 pcr_select_offset =
437 hash_offset + offsetof(struct tpms_pcr_selection,
438 pcr_select);
439
440 pcrs.selection[i].hash =
441 get_unaligned_be16(response + hash_offset);
442 pcrs.selection[i].size_of_select =
443 __get_unaligned_be(response + size_select_offset);
444 if (pcrs.selection[i].size_of_select > TPM2_PCR_SELECT_MAX)
445 goto out;
446 /* copy the array of pcr_select */
447 memcpy(pcrs.selection[i].pcr_select, response + pcr_select_offset,
448 pcrs.selection[i].size_of_select);
449 }
450
451 for (i = 0; i < pcrs.count; i++) {
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200452 u32 hash_mask = alg_to_mask(pcrs.selection[i].hash);
453
454 if (hash_mask) {
455 *supported_pcr |= hash_mask;
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200456 if (is_active_pcr(&pcrs.selection[i]))
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200457 *active_pcr |= hash_mask;
458 } else {
459 EFI_PRINT("Unknown algorithm %x\n", pcrs.selection[i].hash);
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200460 }
461 }
462
463 *pcr_banks = pcrs.count;
464
465 return 0;
466out:
467 return -1;
468}
469
470/**
Ilias Apalodimas967650d2020-11-30 11:47:40 +0200471 * __get_active_pcr_banks() - returns the currently active PCR banks
472 *
473 * @active_pcr_banks: pointer for receiving the bitmap of currently
474 * active PCR banks
475 *
476 * Return: status code
477 */
478static efi_status_t __get_active_pcr_banks(u32 *active_pcr_banks)
479{
480 struct udevice *dev;
481 u32 active, supported, pcr_banks;
482 efi_status_t ret;
483 int err;
484
485 ret = platform_get_tpm2_device(&dev);
486 if (ret != EFI_SUCCESS)
487 goto out;
488
489 err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_banks);
490 if (err) {
491 ret = EFI_DEVICE_ERROR;
492 goto out;
493 }
494
495 *active_pcr_banks = active;
496
497out:
498 return ret;
499}
500
501/* tcg2_create_digest - create a list of digests of the supported PCR banks
502 * for a given memory range
503 *
504 * @input: input memory
505 * @length: length of buffer to calculate the digest
506 * @digest_list: list of digests to fill in
507 *
508 * Return: status code
509 */
510static efi_status_t tcg2_create_digest(const u8 *input, u32 length,
511 struct tpml_digest_values *digest_list)
512{
513 sha1_context ctx;
514 sha256_context ctx_256;
515 sha512_context ctx_512;
516 u8 final[TPM2_ALG_SHA512];
517 efi_status_t ret;
518 u32 active;
519 int i;
520
521 ret = __get_active_pcr_banks(&active);
522 if (ret != EFI_SUCCESS)
523 return ret;
524
525 digest_list->count = 0;
526 for (i = 0; i < MAX_HASH_COUNT; i++) {
527 u16 hash_alg = hash_algo_list[i].hash_alg;
528
529 if (!(active & alg_to_mask(hash_alg)))
530 continue;
531 switch (hash_alg) {
532 case TPM2_ALG_SHA1:
533 sha1_starts(&ctx);
534 sha1_update(&ctx, input, length);
535 sha1_finish(&ctx, final);
536 digest_list->count++;
537 break;
538 case TPM2_ALG_SHA256:
539 sha256_starts(&ctx_256);
540 sha256_update(&ctx_256, input, length);
541 sha256_finish(&ctx_256, final);
542 digest_list->count++;
543 break;
544 case TPM2_ALG_SHA384:
545 sha384_starts(&ctx_512);
546 sha384_update(&ctx_512, input, length);
547 sha384_finish(&ctx_512, final);
548 digest_list->count++;
549 break;
550 case TPM2_ALG_SHA512:
551 sha512_starts(&ctx_512);
552 sha512_update(&ctx_512, input, length);
553 sha512_finish(&ctx_512, final);
554 digest_list->count++;
555 break;
556 default:
557 EFI_PRINT("Unsupported algorithm %x\n", hash_alg);
558 return EFI_INVALID_PARAMETER;
559 }
560 digest_list->digests[i].hash_alg = hash_alg;
561 memcpy(&digest_list->digests[i].digest, final, (u32)alg_to_len(hash_alg));
562 }
563
564 return EFI_SUCCESS;
565}
566
567/**
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200568 * efi_tcg2_get_capability() - protocol capability information and state information
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200569 *
570 * @this: TCG2 protocol instance
571 * @capability: caller allocated memory with size field to the size of
572 * the structure allocated
573
574 * Return: status code
575 */
576static efi_status_t EFIAPI
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200577efi_tcg2_get_capability(struct efi_tcg2_protocol *this,
578 struct efi_tcg2_boot_service_capability *capability)
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200579{
580 struct udevice *dev;
581 efi_status_t efi_ret;
582 int ret;
583
584 EFI_ENTRY("%p, %p", this, capability);
585
586 if (!this || !capability) {
587 efi_ret = EFI_INVALID_PARAMETER;
588 goto out;
589 }
590
591 if (capability->size < boot_service_capability_min) {
592 capability->size = boot_service_capability_min;
593 efi_ret = EFI_BUFFER_TOO_SMALL;
594 goto out;
595 }
596
597 if (capability->size < sizeof(*capability)) {
598 capability->size = sizeof(*capability);
599 efi_ret = EFI_BUFFER_TOO_SMALL;
600 goto out;
601 }
602
603 capability->structure_version.major = 1;
604 capability->structure_version.minor = 1;
605 capability->protocol_version.major = 1;
606 capability->protocol_version.minor = 1;
607
608 efi_ret = platform_get_tpm2_device(&dev);
609 if (efi_ret != EFI_SUCCESS) {
610 capability->supported_event_logs = 0;
611 capability->hash_algorithm_bitmap = 0;
612 capability->tpm_present_flag = false;
613 capability->max_command_size = 0;
614 capability->max_response_size = 0;
615 capability->manufacturer_id = 0;
616 capability->number_of_pcr_banks = 0;
617 capability->active_pcr_banks = 0;
618
619 efi_ret = EFI_SUCCESS;
620 goto out;
621 }
622
623 /* We only allow a TPMv2 device to register the EFI protocol */
624 capability->supported_event_logs = TCG2_EVENT_LOG_FORMAT_TCG_2;
625
626 capability->tpm_present_flag = true;
627
628 /* Supported and active PCRs */
629 capability->hash_algorithm_bitmap = 0;
630 capability->active_pcr_banks = 0;
631 ret = tpm2_get_pcr_info(dev, &capability->hash_algorithm_bitmap,
632 &capability->active_pcr_banks,
633 &capability->number_of_pcr_banks);
634 if (ret) {
635 efi_ret = EFI_DEVICE_ERROR;
636 goto out;
637 }
638
639 /* Max command size */
640 ret = tpm2_get_max_command_size(dev, &capability->max_command_size);
641 if (ret) {
642 efi_ret = EFI_DEVICE_ERROR;
643 goto out;
644 }
645
646 /* Max response size */
647 ret = tpm2_get_max_response_size(dev, &capability->max_response_size);
648 if (ret) {
649 efi_ret = EFI_DEVICE_ERROR;
650 goto out;
651 }
652
653 /* Manufacturer ID */
654 ret = tpm2_get_manufacturer_id(dev, &capability->manufacturer_id);
655 if (ret) {
656 efi_ret = EFI_DEVICE_ERROR;
657 goto out;
658 }
659
660 return EFI_EXIT(EFI_SUCCESS);
661out:
662 return EFI_EXIT(efi_ret);
663}
664
665/**
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200666 * efi_tcg2_get_eventlog() - retrieve the the address of an event log and its
667 * last entry
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200668 *
669 * @this: TCG2 protocol instance
670 * @log_format: type of event log format
671 * @event_log_location: pointer to the memory address of the event log
672 * @event_log_last_entry: pointer to the address of the start of the last
673 * entry in the event log in memory, if log contains
674 * more than 1 entry
675 * @event_log_truncated: set to true, if the Event Log is missing at i
676 * least one entry
677 *
678 * Return: status code
679 */
680static efi_status_t EFIAPI
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200681efi_tcg2_get_eventlog(struct efi_tcg2_protocol *this,
682 efi_tcg_event_log_format log_format,
683 u64 *event_log_location, u64 *event_log_last_entry,
684 bool *event_log_truncated)
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200685{
Ilias Apalodimas967650d2020-11-30 11:47:40 +0200686 efi_status_t ret = EFI_SUCCESS;
687 struct udevice *dev;
688
689 EFI_ENTRY("%p, %u, %p, %p, %p", this, log_format, event_log_location,
690 event_log_last_entry, event_log_truncated);
691
692 ret = platform_get_tpm2_device(&dev);
693 if (ret != EFI_SUCCESS) {
694 event_log_location = NULL;
695 event_log_last_entry = NULL;
696 *event_log_truncated = false;
697 ret = EFI_SUCCESS;
698 goto out;
699 }
700 *event_log_location = (uintptr_t)event_log.buffer;
701 *event_log_last_entry = (uintptr_t)(event_log.buffer + event_log.pos -
702 event_log.last_event_size);
703 *event_log_truncated = event_log.truncated;
704 event_log.get_event_called = true;
705
706out:
707 return EFI_EXIT(ret);
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200708}
709
710/**
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200711 * efi_tcg2_hash_log_extend_event() - extend and optionally log events
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200712 *
713 * @this: TCG2 protocol instance
714 * @flags: bitmap providing additional information on the
715 * operation
716 * @data_to_hash: physical address of the start of the data buffer
717 * to be hashed
718 * @data_to_hash_len: the length in bytes of the buffer referenced by
719 * data_to_hash
720 * @efi_tcg_event: pointer to data buffer containing information
721 * about the event
722 *
723 * Return: status code
724 */
725static efi_status_t EFIAPI
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200726efi_tcg2_hash_log_extend_event(struct efi_tcg2_protocol *this, u64 flags,
727 u64 data_to_hash, u64 data_to_hash_len,
728 struct efi_tcg2_event *efi_tcg_event)
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200729{
Ilias Apalodimas967650d2020-11-30 11:47:40 +0200730 struct udevice *dev;
731 efi_status_t ret;
732 u32 event_type, pcr_index, event_size;
733 struct tpml_digest_values digest_list;
734
735 EFI_ENTRY("%p, %llu, %llu, %llu, %p", this, flags, data_to_hash,
736 data_to_hash_len, efi_tcg_event);
737
738 if (!this || !data_to_hash || !efi_tcg_event) {
739 ret = EFI_INVALID_PARAMETER;
740 goto out;
741 }
742
743 ret = platform_get_tpm2_device(&dev);
744 if (ret != EFI_SUCCESS)
745 goto out;
746
747 if (efi_tcg_event->size < efi_tcg_event->header.header_size +
748 sizeof(u32)) {
749 ret = EFI_INVALID_PARAMETER;
750 goto out;
751 }
752
753 if (efi_tcg_event->header.pcr_index < 0 ||
754 efi_tcg_event->header.pcr_index > TPM2_MAX_PCRS) {
755 ret = EFI_INVALID_PARAMETER;
756 goto out;
757 }
758
759 /*
760 * if PE_COFF_IMAGE is set we need to make sure the image is not
761 * corrupted, verify it and hash the PE/COFF image in accordance with
762 * the procedure specified in "Calculating the PE Image Hash"
763 * section of the "Windows Authenticode Portable Executable Signature
764 * Format"
765 * Not supported for now
766 */
767 if (flags & PE_COFF_IMAGE) {
768 ret = EFI_UNSUPPORTED;
769 goto out;
770 }
771
772 pcr_index = efi_tcg_event->header.pcr_index;
773 event_type = efi_tcg_event->header.event_type;
774
775 ret = tcg2_create_digest((u8 *)data_to_hash, data_to_hash_len,
776 &digest_list);
777 if (ret != EFI_SUCCESS)
778 goto out;
779
780 ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
781 if (ret != EFI_SUCCESS)
782 goto out;
783
784 if (flags & EFI_TCG2_EXTEND_ONLY) {
785 if (event_log.truncated)
786 ret = EFI_VOLUME_FULL;
787 goto out;
788 }
789
790 /*
791 * The efi_tcg_event size includes the size component and the
792 * headersize
793 */
794 event_size = efi_tcg_event->size - sizeof(efi_tcg_event->size) -
795 efi_tcg_event->header.header_size;
796 ret = tcg2_agile_log_append(pcr_index, event_type, &digest_list,
797 event_size, efi_tcg_event->event);
798out:
799 return EFI_EXIT(ret);
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200800}
801
802/**
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200803 * efi_tcg2_submit_command() - Send command to the TPM
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200804 *
805 * @this: TCG2 protocol instance
806 * @input_param_block_size: size of the TPM input parameter block
807 * @input_param_block: pointer to the TPM input parameter block
808 * @output_param_block_size: size of the TPM output parameter block
809 * @output_param_block: pointer to the TPM output parameter block
810 *
811 * Return: status code
812 */
Ilias Apalodimas967650d2020-11-30 11:47:40 +0200813static efi_status_t EFIAPI
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200814efi_tcg2_submit_command(struct efi_tcg2_protocol *this,
815 u32 input_param_block_size, u8 *input_param_block,
816 u32 output_param_block_size, u8 *output_param_block)
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200817{
818 return EFI_UNSUPPORTED;
819}
820
821/**
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200822 * efi_tcg2_get_active_pcr_banks() - returns the currently active PCR banks
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200823 *
824 * @this: TCG2 protocol instance
825 * @active_pcr_banks: pointer for receiving the bitmap of currently
826 * active PCR banks
827 *
828 * Return: status code
829 */
Ilias Apalodimas967650d2020-11-30 11:47:40 +0200830static efi_status_t EFIAPI
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200831efi_tcg2_get_active_pcr_banks(struct efi_tcg2_protocol *this,
832 u32 *active_pcr_banks)
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200833{
Ilias Apalodimas967650d2020-11-30 11:47:40 +0200834 efi_status_t ret;
835
836 EFI_ENTRY("%p, %p", this, active_pcr_banks);
837 ret = __get_active_pcr_banks(active_pcr_banks);
838
839 return EFI_EXIT(ret);
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200840}
841
842/**
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200843 * efi_tcg2_set_active_pcr_banks() - sets the currently active PCR banks
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200844 *
845 * @this: TCG2 protocol instance
846 * @active_pcr_banks: bitmap of the requested active PCR banks
847 *
848 * Return: status code
849 */
Ilias Apalodimas967650d2020-11-30 11:47:40 +0200850static efi_status_t EFIAPI
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200851efi_tcg2_set_active_pcr_banks(struct efi_tcg2_protocol *this,
852 u32 active_pcr_banks)
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200853{
854 return EFI_UNSUPPORTED;
855}
856
857/**
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200858 * efi_tcg2_get_result_of_set_active_pcr_banks() - retrieve result for previous
859 * set_active_pcr_banks()
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200860 *
861 * @this: TCG2 protocol instance
862 * @operation_present: non-zero value to indicate a
863 * set_active_pcr_banks operation was
864 * invoked during last boot
865 * @response: result value could be returned
866 *
867 * Return: status code
868 */
Ilias Apalodimas967650d2020-11-30 11:47:40 +0200869static efi_status_t EFIAPI
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200870efi_tcg2_get_result_of_set_active_pcr_banks(struct efi_tcg2_protocol *this,
871 u32 *operation_present, u32 *response)
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200872{
873 return EFI_UNSUPPORTED;
874}
875
876static const struct efi_tcg2_protocol efi_tcg2_protocol = {
Ilias Apalodimasc67fef62020-11-16 08:52:41 +0200877 .get_capability = efi_tcg2_get_capability,
878 .get_eventlog = efi_tcg2_get_eventlog,
879 .hash_log_extend_event = efi_tcg2_hash_log_extend_event,
880 .submit_command = efi_tcg2_submit_command,
881 .get_active_pcr_banks = efi_tcg2_get_active_pcr_banks,
882 .set_active_pcr_banks = efi_tcg2_set_active_pcr_banks,
883 .get_result_of_set_active_pcr_banks = efi_tcg2_get_result_of_set_active_pcr_banks,
Ilias Apalodimas590fef62020-11-11 11:18:11 +0200884};
885
886/**
Ilias Apalodimas967650d2020-11-30 11:47:40 +0200887 * create_specid_event() - Create the first event in the eventlog
888 *
889 * @dev: tpm device
890 * @event_header: Pointer to the final event header
891 * @event_size: final spec event size
892 *
893 * Return: status code
894 */
895static efi_status_t create_specid_event(struct udevice *dev, void *buffer,
896 size_t *event_size)
897{
898 struct tcg_efi_spec_id_event *spec_event;
899 size_t spec_event_size;
900 efi_status_t ret = EFI_DEVICE_ERROR;
901 u32 active, supported;
902 int err, i;
903
904 /*
905 * Create Spec event. This needs to be the first event in the log
906 * according to the TCG EFI protocol spec
907 */
908
909 /* Setup specID event data */
910 spec_event = (struct tcg_efi_spec_id_event *)buffer;
911 memcpy(spec_event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03,
912 sizeof(spec_event->signature));
913 put_unaligned_le32(0, &spec_event->platform_class); /* type client */
914 spec_event->spec_version_minor =
915 TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2;
916 spec_event->spec_version_major =
917 TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2;
918 spec_event->spec_errata =
919 TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2;
920 spec_event->uintn_size = sizeof(efi_uintn_t) / sizeof(u32);
921
922 err = tpm2_get_pcr_info(dev, &supported, &active,
923 &spec_event->number_of_algorithms);
924 if (err)
925 goto out;
926 if (spec_event->number_of_algorithms > MAX_HASH_COUNT ||
927 spec_event->number_of_algorithms < 1)
928 goto out;
929
930 for (i = 0; i < spec_event->number_of_algorithms; i++) {
931 u16 hash_alg = hash_algo_list[i].hash_alg;
932 u16 hash_len = hash_algo_list[i].hash_len;
933
934 if (active && alg_to_mask(hash_alg)) {
935 put_unaligned_le16(hash_alg,
936 &spec_event->digest_sizes[i].algorithm_id);
937 put_unaligned_le16(hash_len,
938 &spec_event->digest_sizes[i].digest_size);
939 }
940 }
941 /*
942 * the size of the spec event and placement of vendor_info_size
943 * depends on supported algoriths
944 */
945 spec_event_size =
946 offsetof(struct tcg_efi_spec_id_event, digest_sizes) +
947 spec_event->number_of_algorithms * sizeof(spec_event->digest_sizes[0]);
948 /* no vendor info for us */
949 memset(buffer + spec_event_size, 0,
950 sizeof(spec_event->vendor_info_size));
951 spec_event_size += sizeof(spec_event->vendor_info_size);
952 *event_size = spec_event_size;
953
954 return EFI_SUCCESS;
955
956out:
957 return ret;
958}
959
960/**
961 * create_final_event() - Create the final event and install the config
962 * defined by the TCG EFI spec
963 */
964static efi_status_t create_final_event(void)
965{
966 struct efi_tcg2_final_events_table *final_event;
967 efi_status_t ret;
968
969 /*
970 * All events generated after the invocation of
971 * EFI_TCG2_GET_EVENT_LOGS need to be stored in an instance of an
972 * EFI_CONFIGURATION_TABLE
973 */
974 ret = efi_allocate_pool(EFI_ACPI_MEMORY_NVS, TPM2_EVENT_LOG_SIZE,
975 &event_log.final_buffer);
976 if (ret != EFI_SUCCESS)
977 goto out;
978
979 memset(event_log.final_buffer, 0xff, TPM2_EVENT_LOG_SIZE);
980 final_event = event_log.final_buffer;
981 final_event->number_of_events = 0;
982 final_event->version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
983 event_log.final_pos = sizeof(*final_event);
984 ret = efi_install_configuration_table(&efi_guid_final_events,
985 final_event);
986 if (ret != EFI_SUCCESS)
987 goto out;
988
989 return EFI_SUCCESS;
990out:
991 return ret;
992}
993
994/**
995 * efi_init_event_log() - initialize an eventlog
996 */
997static efi_status_t efi_init_event_log(void)
998{
999 /*
1000 * vendor_info_size is currently set to 0, we need to change the length
1001 * and allocate the flexible array member if this changes
1002 */
1003 struct tcg_pcr_event *event_header = NULL;
1004 struct udevice *dev;
1005 size_t spec_event_size;
1006 efi_status_t ret;
1007
1008 ret = platform_get_tpm2_device(&dev);
1009 if (ret != EFI_SUCCESS)
1010 goto out;
1011
1012 ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE,
1013 (void **)&event_log.buffer);
1014 if (ret != EFI_SUCCESS)
1015 goto out;
1016
1017 /*
1018 * initialize log area as 0xff so the OS can easily figure out the
1019 * last log entry
1020 */
1021 memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE);
1022 event_log.pos = 0;
1023 event_log.last_event_size = 0;
1024 event_log.get_event_called = false;
1025 event_log.truncated = false;
1026
1027 /*
1028 * The log header is defined to be in SHA1 event log entry format.
1029 * Setup event header
1030 */
1031 event_header = (struct tcg_pcr_event *)event_log.buffer;
1032 put_unaligned_le32(0, &event_header->pcr_index);
1033 put_unaligned_le32(EV_NO_ACTION, &event_header->event_type);
1034 memset(&event_header->digest, 0, sizeof(event_header->digest));
1035 ret = create_specid_event(dev, event_log.buffer + sizeof(*event_header),
1036 &spec_event_size);
1037 if (ret != EFI_SUCCESS)
1038 goto out;
1039 put_unaligned_le32(spec_event_size, &event_header->event_size);
1040 event_log.pos = spec_event_size + sizeof(*event_header);
1041 event_log.last_event_size = event_log.pos;
1042
1043 ret = create_final_event();
1044
1045out:
1046 return ret;
1047}
1048
1049/**
Ilias Apalodimas590fef62020-11-11 11:18:11 +02001050 * efi_tcg2_register() - register EFI_TCG2_PROTOCOL
1051 *
1052 * If a TPM2 device is available, the TPM TCG2 Protocol is registered
1053 *
1054 * Return: An error status is only returned if adding the protocol fails.
1055 */
1056efi_status_t efi_tcg2_register(void)
1057{
1058 efi_status_t ret;
1059 struct udevice *dev;
Ilias Apalodimas590fef62020-11-11 11:18:11 +02001060
1061 ret = platform_get_tpm2_device(&dev);
Ilias Apalodimasc67fef62020-11-16 08:52:41 +02001062 if (ret != EFI_SUCCESS) {
1063 log_warning("Unable to find TPMv2 device\n");
Ilias Apalodimas590fef62020-11-11 11:18:11 +02001064 return EFI_SUCCESS;
1065 }
Ilias Apalodimas967650d2020-11-30 11:47:40 +02001066
1067 ret = efi_init_event_log();
1068 if (ret != EFI_SUCCESS)
1069 return ret;
1070
Ilias Apalodimas590fef62020-11-11 11:18:11 +02001071 ret = efi_add_protocol(efi_root, &efi_guid_tcg2_protocol,
1072 (void *)&efi_tcg2_protocol);
1073 if (ret != EFI_SUCCESS)
1074 log_err("Cannot install EFI_TCG2_PROTOCOL\n");
1075
1076 return ret;
1077}