2018-07-12 14:56:34 +00:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
2018-04-06 19:38:57 +00:00
|
|
|
From: Matthew Garrett <mjg59@coreos.com>
|
|
|
|
Date: Tue, 14 Jul 2015 17:06:35 -0700
|
2019-07-16 09:23:51 +00:00
|
|
|
Subject: [PATCH] TPM support
|
2018-04-06 19:38:57 +00:00
|
|
|
|
|
|
|
Add support for performing basic TPM measurements. Right now this only
|
2019-07-16 09:23:51 +00:00
|
|
|
supports extending PCRs statically and only on UEFI, but will measure
|
|
|
|
all modules as they're loaded, kernel and initrd images, command line,
|
|
|
|
grub commands and multiboot images.
|
|
|
|
|
|
|
|
Signed-off-by: Matthew Garrett <mjg59@coreos.com>
|
|
|
|
[hdegoede: fix hash_log_extend_event prototype and compile warnings]
|
|
|
|
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
|
[michael.marineau: fix warnings when compiling for other platforms]
|
|
|
|
Michael Marineau <michael.marineau@coreos.com>
|
|
|
|
[javierm: squash in a single patch and drop legacy BIOS support]
|
|
|
|
Javier Martinez Canillas <javierm@redhat.com>
|
2018-04-06 19:38:57 +00:00
|
|
|
---
|
2019-07-16 09:23:51 +00:00
|
|
|
grub-core/Makefile.core.def | 2 +
|
|
|
|
grub-core/kern/dl.c | 4 +
|
|
|
|
grub-core/kern/efi/tpm.c | 274 ++++++++++++++++++++++++++++++++++
|
|
|
|
grub-core/kern/tpm.c | 19 +++
|
|
|
|
grub-core/lib/cmdline.c | 7 +-
|
|
|
|
grub-core/loader/i386/efi/linux.c | 6 +
|
|
|
|
grub-core/loader/i386/linux.c | 6 +
|
|
|
|
grub-core/loader/i386/multiboot_mbi.c | 4 +
|
|
|
|
grub-core/loader/linux.c | 4 +
|
|
|
|
grub-core/loader/multiboot.c | 3 +
|
|
|
|
grub-core/loader/multiboot_mbi2.c | 5 +-
|
|
|
|
grub-core/script/execute.c | 26 +++-
|
|
|
|
include/grub/efi/tpm.h | 153 +++++++++++++++++++
|
|
|
|
include/grub/tpm.h | 94 ++++++++++++
|
|
|
|
grub-core/Makefile.am | 1 +
|
|
|
|
15 files changed, 604 insertions(+), 4 deletions(-)
|
2018-04-06 19:38:57 +00:00
|
|
|
create mode 100644 grub-core/kern/efi/tpm.c
|
|
|
|
create mode 100644 grub-core/kern/tpm.c
|
|
|
|
create mode 100644 include/grub/efi/tpm.h
|
|
|
|
create mode 100644 include/grub/tpm.h
|
|
|
|
|
|
|
|
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
2019-07-16 09:23:51 +00:00
|
|
|
index 63b33490b11..3be42a95195 100644
|
2018-04-06 19:38:57 +00:00
|
|
|
--- a/grub-core/Makefile.core.def
|
|
|
|
+++ b/grub-core/Makefile.core.def
|
2019-07-16 09:23:51 +00:00
|
|
|
@@ -130,6 +130,7 @@ kernel = {
|
|
|
|
common = kern/rescue_reader.c;
|
2018-04-06 19:38:57 +00:00
|
|
|
common = kern/term.c;
|
|
|
|
common = kern/backtrace.c;
|
|
|
|
+ common = kern/tpm.c;
|
|
|
|
|
|
|
|
x86 = kern/i386/backtrace.c;
|
|
|
|
i386_xen = kern/i386/backtrace.c;
|
2019-07-16 09:23:51 +00:00
|
|
|
@@ -198,6 +199,7 @@ kernel = {
|
2018-04-06 19:38:57 +00:00
|
|
|
efi = kern/acpi.c;
|
|
|
|
efi = kern/efi/acpi.c;
|
|
|
|
efi = lib/envblk.c;
|
|
|
|
+ efi = kern/efi/tpm.c;
|
|
|
|
i386_coreboot = kern/i386/pc/acpi.c;
|
|
|
|
i386_multiboot = kern/i386/pc/acpi.c;
|
|
|
|
i386_coreboot = kern/acpi.c;
|
|
|
|
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
2019-07-16 09:23:51 +00:00
|
|
|
index eb8b969cded..91105bc4677 100644
|
2018-04-06 19:38:57 +00:00
|
|
|
--- a/grub-core/kern/dl.c
|
|
|
|
+++ b/grub-core/kern/dl.c
|
|
|
|
@@ -33,6 +33,7 @@
|
|
|
|
#include <grub/cache.h>
|
|
|
|
#include <grub/i18n.h>
|
|
|
|
#include <grub/efi/sb.h>
|
|
|
|
+#include <grub/tpm.h>
|
|
|
|
|
|
|
|
/* Platforms where modules are in a readonly area of memory. */
|
|
|
|
#if defined(GRUB_MACHINE_QEMU)
|
2019-07-16 09:23:51 +00:00
|
|
|
@@ -829,6 +830,9 @@ grub_dl_load_file (const char *filename)
|
2018-04-06 19:38:57 +00:00
|
|
|
opens of the same device. */
|
|
|
|
grub_file_close (file);
|
|
|
|
|
2019-07-16 09:23:51 +00:00
|
|
|
+ grub_tpm_measure(core, size, GRUB_BINARY_PCR, "grub_module", filename);
|
|
|
|
+ grub_print_error();
|
2018-04-06 19:38:57 +00:00
|
|
|
+
|
|
|
|
mod = grub_dl_load_core (core, size);
|
|
|
|
grub_free (core);
|
|
|
|
if (! mod)
|
|
|
|
diff --git a/grub-core/kern/efi/tpm.c b/grub-core/kern/efi/tpm.c
|
|
|
|
new file mode 100644
|
2019-07-16 09:23:51 +00:00
|
|
|
index 00000000000..0d3ebe22e57
|
2018-04-06 19:38:57 +00:00
|
|
|
--- /dev/null
|
|
|
|
+++ b/grub-core/kern/efi/tpm.c
|
2019-07-16 09:23:51 +00:00
|
|
|
@@ -0,0 +1,274 @@
|
2018-04-06 19:38:57 +00:00
|
|
|
+#include <grub/err.h>
|
|
|
|
+#include <grub/i18n.h>
|
|
|
|
+#include <grub/efi/api.h>
|
|
|
|
+#include <grub/efi/efi.h>
|
|
|
|
+#include <grub/efi/tpm.h>
|
|
|
|
+#include <grub/mm.h>
|
|
|
|
+#include <grub/tpm.h>
|
|
|
|
+#include <grub/term.h>
|
|
|
|
+
|
|
|
|
+static grub_efi_guid_t tpm_guid = EFI_TPM_GUID;
|
|
|
|
+static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID;
|
|
|
|
+
|
|
|
|
+static grub_efi_boolean_t grub_tpm_present(grub_efi_tpm_protocol_t *tpm)
|
|
|
|
+{
|
|
|
|
+ grub_efi_status_t status;
|
|
|
|
+ TCG_EFI_BOOT_SERVICE_CAPABILITY caps;
|
|
|
|
+ grub_uint32_t flags;
|
|
|
|
+ grub_efi_physical_address_t eventlog, lastevent;
|
|
|
|
+
|
|
|
|
+ caps.Size = (grub_uint8_t)sizeof(caps);
|
|
|
|
+
|
|
|
|
+ status = efi_call_5(tpm->status_check, tpm, &caps, &flags, &eventlog,
|
|
|
|
+ &lastevent);
|
|
|
|
+
|
|
|
|
+ if (status != GRUB_EFI_SUCCESS || caps.TPMDeactivatedFlag
|
|
|
|
+ || !caps.TPMPresentFlag)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static grub_efi_boolean_t grub_tpm2_present(grub_efi_tpm2_protocol_t *tpm)
|
|
|
|
+{
|
|
|
|
+ grub_efi_status_t status;
|
|
|
|
+ EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
|
|
|
|
+
|
|
|
|
+ caps.Size = (grub_uint8_t)sizeof(caps);
|
|
|
|
+
|
|
|
|
+ status = efi_call_2(tpm->get_capability, tpm, &caps);
|
|
|
|
+
|
|
|
|
+ if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static grub_efi_boolean_t grub_tpm_handle_find(grub_efi_handle_t *tpm_handle,
|
|
|
|
+ grub_efi_uint8_t *protocol_version)
|
|
|
|
+{
|
|
|
|
+ grub_efi_handle_t *handles;
|
|
|
|
+ grub_efi_uintn_t num_handles;
|
|
|
|
+
|
|
|
|
+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm_guid, NULL,
|
|
|
|
+ &num_handles);
|
|
|
|
+ if (handles && num_handles > 0) {
|
|
|
|
+ *tpm_handle = handles[0];
|
|
|
|
+ *protocol_version = 1;
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL,
|
|
|
|
+ &num_handles);
|
|
|
|
+ if (handles && num_handles > 0) {
|
|
|
|
+ *tpm_handle = handles[0];
|
|
|
|
+ *protocol_version = 2;
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static grub_err_t
|
|
|
|
+grub_tpm1_execute(grub_efi_handle_t tpm_handle,
|
|
|
|
+ PassThroughToTPM_InputParamBlock *inbuf,
|
|
|
|
+ PassThroughToTPM_OutputParamBlock *outbuf)
|
|
|
|
+{
|
|
|
|
+ grub_efi_status_t status;
|
|
|
|
+ grub_efi_tpm_protocol_t *tpm;
|
|
|
|
+ grub_uint32_t inhdrsize = sizeof(*inbuf) - sizeof(inbuf->TPMOperandIn);
|
|
|
|
+ grub_uint32_t outhdrsize = sizeof(*outbuf) - sizeof(outbuf->TPMOperandOut);
|
|
|
|
+
|
|
|
|
+ tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid,
|
|
|
|
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
|
|
+
|
|
|
|
+ if (!grub_tpm_present(tpm))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ /* UEFI TPM protocol takes the raw operand block, no param block header */
|
|
|
|
+ status = efi_call_5 (tpm->pass_through_to_tpm, tpm,
|
|
|
|
+ inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn,
|
|
|
|
+ outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut);
|
|
|
|
+
|
|
|
|
+ switch (status) {
|
|
|
|
+ case GRUB_EFI_SUCCESS:
|
|
|
|
+ return 0;
|
|
|
|
+ case GRUB_EFI_DEVICE_ERROR:
|
|
|
|
+ return grub_error (GRUB_ERR_IO, N_("Command failed"));
|
|
|
|
+ case GRUB_EFI_INVALID_PARAMETER:
|
|
|
|
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
|
|
|
|
+ case GRUB_EFI_BUFFER_TOO_SMALL:
|
|
|
|
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small"));
|
|
|
|
+ case GRUB_EFI_NOT_FOUND:
|
|
|
|
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
|
|
|
|
+ default:
|
|
|
|
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static grub_err_t
|
|
|
|
+grub_tpm2_execute(grub_efi_handle_t tpm_handle,
|
|
|
|
+ PassThroughToTPM_InputParamBlock *inbuf,
|
|
|
|
+ PassThroughToTPM_OutputParamBlock *outbuf)
|
|
|
|
+{
|
|
|
|
+ grub_efi_status_t status;
|
|
|
|
+ grub_efi_tpm2_protocol_t *tpm;
|
|
|
|
+ grub_uint32_t inhdrsize = sizeof(*inbuf) - sizeof(inbuf->TPMOperandIn);
|
|
|
|
+ grub_uint32_t outhdrsize = sizeof(*outbuf) - sizeof(outbuf->TPMOperandOut);
|
|
|
|
+
|
|
|
|
+ tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
|
|
|
|
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
|
|
+
|
|
|
|
+ if (!grub_tpm2_present(tpm))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ /* UEFI TPM protocol takes the raw operand block, no param block header */
|
|
|
|
+ status = efi_call_5 (tpm->submit_command, tpm,
|
|
|
|
+ inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn,
|
|
|
|
+ outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut);
|
|
|
|
+
|
|
|
|
+ switch (status) {
|
|
|
|
+ case GRUB_EFI_SUCCESS:
|
|
|
|
+ return 0;
|
|
|
|
+ case GRUB_EFI_DEVICE_ERROR:
|
|
|
|
+ return grub_error (GRUB_ERR_IO, N_("Command failed"));
|
|
|
|
+ case GRUB_EFI_INVALID_PARAMETER:
|
|
|
|
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
|
|
|
|
+ case GRUB_EFI_BUFFER_TOO_SMALL:
|
|
|
|
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small"));
|
|
|
|
+ case GRUB_EFI_NOT_FOUND:
|
|
|
|
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
|
|
|
|
+ default:
|
|
|
|
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+grub_err_t
|
|
|
|
+grub_tpm_execute(PassThroughToTPM_InputParamBlock *inbuf,
|
|
|
|
+ PassThroughToTPM_OutputParamBlock *outbuf)
|
|
|
|
+{
|
|
|
|
+ grub_efi_handle_t tpm_handle;
|
|
|
|
+ grub_uint8_t protocol_version;
|
|
|
|
+
|
|
|
|
+ /* It's not a hard failure for there to be no TPM */
|
|
|
|
+ if (!grub_tpm_handle_find(&tpm_handle, &protocol_version))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if (protocol_version == 1) {
|
|
|
|
+ return grub_tpm1_execute(tpm_handle, inbuf, outbuf);
|
|
|
|
+ } else {
|
|
|
|
+ return grub_tpm2_execute(tpm_handle, inbuf, outbuf);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static grub_err_t
|
|
|
|
+grub_tpm1_log_event(grub_efi_handle_t tpm_handle, unsigned char *buf,
|
|
|
|
+ grub_size_t size, grub_uint8_t pcr,
|
|
|
|
+ const char *description)
|
|
|
|
+{
|
2019-07-16 09:23:51 +00:00
|
|
|
+ TCG_PCR_EVENT *event;
|
2018-04-06 19:38:57 +00:00
|
|
|
+ grub_efi_status_t status;
|
|
|
|
+ grub_efi_tpm_protocol_t *tpm;
|
|
|
|
+ grub_efi_physical_address_t lastevent;
|
|
|
|
+ grub_uint32_t algorithm;
|
|
|
|
+ grub_uint32_t eventnum = 0;
|
|
|
|
+
|
|
|
|
+ tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid,
|
|
|
|
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
|
|
+
|
|
|
|
+ if (!grub_tpm_present(tpm))
|
|
|
|
+ return 0;
|
|
|
|
+
|
2019-07-16 09:23:51 +00:00
|
|
|
+ event = grub_zalloc(sizeof (TCG_PCR_EVENT) + grub_strlen(description) + 1);
|
2018-04-06 19:38:57 +00:00
|
|
|
+ if (!event)
|
|
|
|
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
|
|
|
+ N_("cannot allocate TPM event buffer"));
|
|
|
|
+
|
2019-07-16 09:23:51 +00:00
|
|
|
+ event->PCRIndex = pcr;
|
|
|
|
+ event->EventType = EV_IPL;
|
|
|
|
+ event->EventSize = grub_strlen(description) + 1;
|
|
|
|
+ grub_memcpy(event->Event, description, event->EventSize);
|
2018-04-06 19:38:57 +00:00
|
|
|
+
|
|
|
|
+ algorithm = TCG_ALG_SHA;
|
2019-07-16 09:23:51 +00:00
|
|
|
+ status = efi_call_7 (tpm->log_extend_event, tpm,
|
|
|
|
+ (unsigned long) buf, (grub_uint64_t) size,
|
2018-04-06 19:38:57 +00:00
|
|
|
+ algorithm, event, &eventnum, &lastevent);
|
|
|
|
+
|
|
|
|
+ switch (status) {
|
|
|
|
+ case GRUB_EFI_SUCCESS:
|
|
|
|
+ return 0;
|
|
|
|
+ case GRUB_EFI_DEVICE_ERROR:
|
|
|
|
+ return grub_error (GRUB_ERR_IO, N_("Command failed"));
|
|
|
|
+ case GRUB_EFI_INVALID_PARAMETER:
|
|
|
|
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
|
|
|
|
+ case GRUB_EFI_BUFFER_TOO_SMALL:
|
|
|
|
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small"));
|
|
|
|
+ case GRUB_EFI_NOT_FOUND:
|
|
|
|
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
|
|
|
|
+ default:
|
|
|
|
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static grub_err_t
|
|
|
|
+grub_tpm2_log_event(grub_efi_handle_t tpm_handle, unsigned char *buf,
|
|
|
|
+ grub_size_t size, grub_uint8_t pcr,
|
|
|
|
+ const char *description)
|
|
|
|
+{
|
|
|
|
+ EFI_TCG2_EVENT *event;
|
|
|
|
+ grub_efi_status_t status;
|
|
|
|
+ grub_efi_tpm2_protocol_t *tpm;
|
|
|
|
+
|
|
|
|
+ tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
|
|
|
|
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
|
|
+
|
|
|
|
+ if (!grub_tpm2_present(tpm))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ event = grub_zalloc(sizeof (EFI_TCG2_EVENT) + grub_strlen(description) + 1);
|
|
|
|
+ if (!event)
|
|
|
|
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
|
|
|
+ N_("cannot allocate TPM event buffer"));
|
|
|
|
+
|
|
|
|
+ event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
|
|
|
|
+ event->Header.HeaderVersion = 1;
|
|
|
|
+ event->Header.PCRIndex = pcr;
|
|
|
|
+ event->Header.EventType = EV_IPL;
|
|
|
|
+ event->Size = sizeof(*event) - sizeof(event->Event) + grub_strlen(description) + 1;
|
|
|
|
+ grub_memcpy(event->Event, description, grub_strlen(description) + 1);
|
|
|
|
+
|
2019-07-16 09:23:51 +00:00
|
|
|
+ status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, (unsigned long) buf,
|
2018-04-06 19:38:57 +00:00
|
|
|
+ (grub_uint64_t) size, event);
|
|
|
|
+
|
|
|
|
+ switch (status) {
|
|
|
|
+ case GRUB_EFI_SUCCESS:
|
|
|
|
+ return 0;
|
|
|
|
+ case GRUB_EFI_DEVICE_ERROR:
|
|
|
|
+ return grub_error (GRUB_ERR_IO, N_("Command failed"));
|
|
|
|
+ case GRUB_EFI_INVALID_PARAMETER:
|
|
|
|
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
|
|
|
|
+ case GRUB_EFI_BUFFER_TOO_SMALL:
|
|
|
|
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small"));
|
|
|
|
+ case GRUB_EFI_NOT_FOUND:
|
|
|
|
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
|
|
|
|
+ default:
|
|
|
|
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+grub_err_t
|
|
|
|
+grub_tpm_log_event(unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
|
|
|
+ const char *description)
|
|
|
|
+{
|
|
|
|
+ grub_efi_handle_t tpm_handle;
|
|
|
|
+ grub_efi_uint8_t protocol_version;
|
|
|
|
+
|
|
|
|
+ if (!grub_tpm_handle_find(&tpm_handle, &protocol_version))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if (protocol_version == 1) {
|
|
|
|
+ return grub_tpm1_log_event(tpm_handle, buf, size, pcr, description);
|
|
|
|
+ } else {
|
|
|
|
+ return grub_tpm2_log_event(tpm_handle, buf, size, pcr, description);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
diff --git a/grub-core/kern/tpm.c b/grub-core/kern/tpm.c
|
|
|
|
new file mode 100644
|
2019-07-16 09:23:51 +00:00
|
|
|
index 00000000000..e5e8fced624
|
2018-04-06 19:38:57 +00:00
|
|
|
--- /dev/null
|
|
|
|
+++ b/grub-core/kern/tpm.c
|
2019-07-16 09:23:51 +00:00
|
|
|
@@ -0,0 +1,19 @@
|
2018-04-06 19:38:57 +00:00
|
|
|
+#include <grub/err.h>
|
|
|
|
+#include <grub/i18n.h>
|
|
|
|
+#include <grub/misc.h>
|
|
|
|
+#include <grub/mm.h>
|
|
|
|
+#include <grub/tpm.h>
|
|
|
|
+#include <grub/term.h>
|
|
|
|
+
|
|
|
|
+grub_err_t
|
|
|
|
+grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
2019-07-16 09:23:51 +00:00
|
|
|
+ const char *kind, const char *description)
|
2018-04-06 19:38:57 +00:00
|
|
|
+{
|
2019-07-16 09:23:51 +00:00
|
|
|
+ grub_err_t ret;
|
|
|
|
+ char *desc = grub_xasprintf("%s %s", kind, description);
|
|
|
|
+ if (!desc)
|
|
|
|
+ return GRUB_ERR_OUT_OF_MEMORY;
|
|
|
|
+ ret = grub_tpm_log_event(buf, size, pcr, desc);
|
|
|
|
+ grub_free(desc);
|
|
|
|
+ return ret;
|
2018-04-06 19:38:57 +00:00
|
|
|
+}
|
2019-07-16 09:23:51 +00:00
|
|
|
diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c
|
|
|
|
index 970ea868c14..d5c12957cad 100644
|
|
|
|
--- a/grub-core/lib/cmdline.c
|
|
|
|
+++ b/grub-core/lib/cmdline.c
|
|
|
|
@@ -19,6 +19,7 @@
|
|
|
|
|
|
|
|
#include <grub/lib/cmdline.h>
|
|
|
|
#include <grub/misc.h>
|
|
|
|
+#include <grub/tpm.h>
|
|
|
|
|
|
|
|
static int
|
|
|
|
is_hex(char c)
|
|
|
|
@@ -79,7 +80,7 @@ int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
|
|
|
|
{
|
|
|
|
int i, space;
|
|
|
|
unsigned int arg_size;
|
|
|
|
- char *c;
|
|
|
|
+ char *c, *orig = buf;
|
|
|
|
|
|
|
|
for (i = 0; i < argc; i++)
|
|
|
|
{
|
|
|
|
@@ -125,5 +126,9 @@ int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
|
|
|
|
|
|
|
|
*buf = 0;
|
|
|
|
|
|
|
|
+ grub_tpm_measure ((void *)orig, grub_strlen (orig), GRUB_ASCII_PCR,
|
|
|
|
+ "grub_kernel_cmdline", orig);
|
|
|
|
+ grub_print_error();
|
|
|
|
+
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
|
|
|
index 800c3e54022..ea9f5134e67 100644
|
|
|
|
--- a/grub-core/loader/i386/efi/linux.c
|
|
|
|
+++ b/grub-core/loader/i386/efi/linux.c
|
|
|
|
@@ -27,6 +27,7 @@
|
|
|
|
#include <grub/lib/cmdline.h>
|
|
|
|
#include <grub/efi/efi.h>
|
|
|
|
#include <grub/efi/linux.h>
|
|
|
|
+#include <grub/tpm.h>
|
|
|
|
|
|
|
|
GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
|
|
|
|
|
@@ -131,6 +132,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|
|
|
argv[i]);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
+ grub_tpm_measure (ptr, cursize, GRUB_BINARY_PCR, "grub_linuxefi", "Initrd");
|
|
|
|
+ grub_print_error();
|
|
|
|
ptr += cursize;
|
|
|
|
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
|
|
|
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
|
|
|
@@ -195,6 +198,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ grub_tpm_measure (kernel, filelen, GRUB_BINARY_PCR, "grub_linuxefi", "Kernel");
|
|
|
|
+ grub_print_error();
|
|
|
|
+
|
|
|
|
rc = grub_linuxefi_secure_validate (kernel, filelen);
|
|
|
|
if (rc < 0)
|
|
|
|
{
|
|
|
|
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
|
|
|
|
index c84747ea857..76304f05700 100644
|
|
|
|
--- a/grub-core/loader/i386/linux.c
|
|
|
|
+++ b/grub-core/loader/i386/linux.c
|
|
|
|
@@ -36,6 +36,7 @@
|
|
|
|
#include <grub/lib/cmdline.h>
|
|
|
|
#include <grub/linux.h>
|
|
|
|
#include <grub/efi/sb.h>
|
|
|
|
+#include <grub/tpm.h>
|
|
|
|
|
|
|
|
GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
|
|
|
|
|
@@ -724,7 +725,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ grub_tpm_measure (kernel, len, GRUB_BINARY_PCR, "grub_linux", "Kernel");
|
|
|
|
+ grub_print_error();
|
|
|
|
+
|
|
|
|
grub_memcpy (&lh, kernel, sizeof (lh));
|
|
|
|
+
|
|
|
|
kernel_offset = sizeof (lh);
|
|
|
|
|
|
|
|
if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55))
|
|
|
|
@@ -1038,6 +1043,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
|
|
|
|
|
|
len = prot_file_size;
|
|
|
|
grub_memcpy (prot_mode_mem, kernel + kernel_offset, len);
|
|
|
|
+ kernel_offset += len;
|
|
|
|
|
|
|
|
if (grub_errno == GRUB_ERR_NONE)
|
|
|
|
{
|
|
|
|
diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c
|
|
|
|
index dc98dbcae25..ca85358f771 100644
|
|
|
|
--- a/grub-core/loader/i386/multiboot_mbi.c
|
|
|
|
+++ b/grub-core/loader/i386/multiboot_mbi.c
|
|
|
|
@@ -36,6 +36,7 @@
|
|
|
|
#include <grub/net.h>
|
|
|
|
#include <grub/i18n.h>
|
|
|
|
#include <grub/lib/cmdline.h>
|
|
|
|
+#include <grub/tpm.h>
|
|
|
|
|
|
|
|
#ifdef GRUB_MACHINE_EFI
|
|
|
|
#include <grub/efi/efi.h>
|
|
|
|
@@ -173,6 +174,9 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
|
|
|
return grub_errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ grub_tpm_measure((unsigned char*)buffer, len, GRUB_BINARY_PCR, "grub_multiboot", filename);
|
|
|
|
+ grub_print_error();
|
|
|
|
+
|
|
|
|
header = find_header (buffer, len);
|
|
|
|
|
|
|
|
if (header == 0)
|
|
|
|
diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
|
|
|
|
index be6fa0f4d45..c2c7cfcd0fd 100644
|
|
|
|
--- a/grub-core/loader/linux.c
|
|
|
|
+++ b/grub-core/loader/linux.c
|
|
|
|
@@ -4,6 +4,7 @@
|
|
|
|
#include <grub/misc.h>
|
|
|
|
#include <grub/file.h>
|
|
|
|
#include <grub/mm.h>
|
|
|
|
+#include <grub/tpm.h>
|
|
|
|
|
|
|
|
struct newc_head
|
|
|
|
{
|
|
|
|
@@ -288,6 +289,9 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
|
|
|
|
grub_initrd_close (initrd_ctx);
|
|
|
|
return grub_errno;
|
|
|
|
}
|
|
|
|
+ grub_tpm_measure (ptr, cursize, GRUB_BINARY_PCR, "grub_initrd", "Initrd");
|
|
|
|
+ grub_print_error();
|
|
|
|
+
|
|
|
|
ptr += cursize;
|
|
|
|
}
|
|
|
|
if (newc)
|
|
|
|
diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
|
|
|
|
index 26df46a4161..9a8dae5565b 100644
|
|
|
|
--- a/grub-core/loader/multiboot.c
|
|
|
|
+++ b/grub-core/loader/multiboot.c
|
|
|
|
@@ -51,6 +51,7 @@
|
|
|
|
#include <grub/memory.h>
|
|
|
|
#include <grub/i18n.h>
|
|
|
|
#include <grub/efi/sb.h>
|
|
|
|
+#include <grub/tpm.h>
|
|
|
|
|
|
|
|
GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
|
|
|
|
|
@@ -440,6 +441,8 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
|
|
|
|
}
|
|
|
|
|
|
|
|
grub_file_close (file);
|
|
|
|
+ grub_tpm_measure (module, size, GRUB_BINARY_PCR, "grub_multiboot", argv[0]);
|
|
|
|
+ grub_print_error();
|
|
|
|
return GRUB_ERR_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
|
|
|
|
index 4df6595954d..54078455e2f 100644
|
|
|
|
--- a/grub-core/loader/multiboot_mbi2.c
|
|
|
|
+++ b/grub-core/loader/multiboot_mbi2.c
|
|
|
|
@@ -36,6 +36,7 @@
|
|
|
|
#include <grub/i18n.h>
|
|
|
|
#include <grub/net.h>
|
|
|
|
#include <grub/lib/cmdline.h>
|
|
|
|
+#include <grub/tpm.h>
|
|
|
|
|
|
|
|
#if defined (GRUB_MACHINE_EFI)
|
|
|
|
#include <grub/efi/efi.h>
|
|
|
|
@@ -131,8 +132,10 @@ grub_multiboot2_load (grub_file_t file, const char *filename)
|
|
|
|
|
|
|
|
COMPILE_TIME_ASSERT (MULTIBOOT_HEADER_ALIGN % 4 == 0);
|
|
|
|
|
|
|
|
+ grub_tpm_measure ((unsigned char *)mld.buffer, len, GRUB_BINARY_PCR, "grub_multiboot", filename);
|
|
|
|
+ grub_print_error();
|
|
|
|
+
|
|
|
|
header = find_header (mld.buffer, len);
|
|
|
|
-
|
|
|
|
if (header == 0)
|
|
|
|
{
|
|
|
|
grub_free (mld.buffer);
|
|
|
|
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
|
|
|
|
index cf6cd6601d6..93965777138 100644
|
|
|
|
--- a/grub-core/script/execute.c
|
|
|
|
+++ b/grub-core/script/execute.c
|
|
|
|
@@ -30,6 +30,7 @@
|
|
|
|
#ifdef GRUB_MACHINE_IEEE1275
|
|
|
|
#include <grub/ieee1275/ieee1275.h>
|
|
|
|
#endif
|
|
|
|
+#include <grub/tpm.h>
|
|
|
|
|
|
|
|
/* Max digits for a char is 3 (0xFF is 255), similarly for an int it
|
|
|
|
is sizeof (int) * 3, and one extra for a possible -ve sign. */
|
|
|
|
@@ -967,8 +968,9 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
|
|
|
|
grub_err_t ret = 0;
|
|
|
|
grub_script_function_t func = 0;
|
|
|
|
char errnobuf[18];
|
|
|
|
- char *cmdname;
|
|
|
|
- int argc;
|
|
|
|
+ char *cmdname, *cmdstring;
|
|
|
|
+ int argc, offset = 0, cmdlen = 0;
|
|
|
|
+ unsigned int i;
|
|
|
|
char **args;
|
|
|
|
int invert;
|
|
|
|
struct grub_script_argv argv = { 0, 0, 0 };
|
|
|
|
@@ -977,6 +979,26 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
|
|
|
|
if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args[0])
|
|
|
|
return grub_errno;
|
|
|
|
|
|
|
|
+ for (i = 0; i < argv.argc; i++) {
|
|
|
|
+ cmdlen += grub_strlen (argv.args[i]) + 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cmdstring = grub_malloc (cmdlen);
|
|
|
|
+ if (!cmdstring)
|
|
|
|
+ {
|
|
|
|
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
|
|
|
+ N_("cannot allocate command buffer"));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < argv.argc; i++) {
|
|
|
|
+ offset += grub_snprintf (cmdstring + offset, cmdlen - offset, "%s ",
|
|
|
|
+ argv.args[i]);
|
|
|
|
+ }
|
|
|
|
+ cmdstring[cmdlen-1]= '\0';
|
|
|
|
+ grub_tpm_measure ((unsigned char *)cmdstring, cmdlen, GRUB_ASCII_PCR,
|
|
|
|
+ "grub_cmd", cmdstring);
|
|
|
|
+ grub_print_error();
|
|
|
|
+ grub_free(cmdstring);
|
|
|
|
invert = 0;
|
|
|
|
argc = argv.argc - 1;
|
|
|
|
args = argv.args + 1;
|
2018-04-06 19:38:57 +00:00
|
|
|
diff --git a/include/grub/efi/tpm.h b/include/grub/efi/tpm.h
|
|
|
|
new file mode 100644
|
2019-07-16 09:23:51 +00:00
|
|
|
index 00000000000..63d8a0fe714
|
2018-04-06 19:38:57 +00:00
|
|
|
--- /dev/null
|
|
|
|
+++ b/include/grub/efi/tpm.h
|
|
|
|
@@ -0,0 +1,153 @@
|
|
|
|
+/*
|
|
|
|
+ * GRUB -- GRand Unified Bootloader
|
|
|
|
+ * Copyright (C) 2015 Free Software Foundation, Inc.
|
|
|
|
+ *
|
|
|
|
+ * GRUB is free software: you can redistribute it and/or modify
|
|
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
|
|
+ * the Free Software Foundation, either version 3 of the License, or
|
|
|
|
+ * (at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * GRUB is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
+ * GNU General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU General Public License
|
|
|
|
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#ifndef GRUB_EFI_TPM_HEADER
|
|
|
|
+#define GRUB_EFI_TPM_HEADER 1
|
|
|
|
+
|
|
|
|
+#define EFI_TPM_GUID {0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd }};
|
|
|
|
+#define EFI_TPM2_GUID {0x607f766c, 0x7455, 0x42be, {0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f }};
|
|
|
|
+
|
|
|
|
+typedef struct {
|
|
|
|
+ grub_efi_uint8_t Major;
|
|
|
|
+ grub_efi_uint8_t Minor;
|
|
|
|
+ grub_efi_uint8_t RevMajor;
|
|
|
|
+ grub_efi_uint8_t RevMinor;
|
|
|
|
+} TCG_VERSION;
|
|
|
|
+
|
|
|
|
+typedef struct _TCG_EFI_BOOT_SERVICE_CAPABILITY {
|
|
|
|
+ grub_efi_uint8_t Size; /// Size of this structure.
|
|
|
|
+ TCG_VERSION StructureVersion;
|
|
|
|
+ TCG_VERSION ProtocolSpecVersion;
|
|
|
|
+ grub_efi_uint8_t HashAlgorithmBitmap; /// Hash algorithms .
|
|
|
|
+ char TPMPresentFlag; /// 00h = TPM not present.
|
|
|
|
+ char TPMDeactivatedFlag; /// 01h = TPM currently deactivated.
|
|
|
|
+} TCG_EFI_BOOT_SERVICE_CAPABILITY;
|
|
|
|
+
|
|
|
|
+typedef struct {
|
|
|
|
+ grub_efi_uint32_t PCRIndex;
|
|
|
|
+ grub_efi_uint32_t EventType;
|
|
|
|
+ grub_efi_uint8_t digest[20];
|
|
|
|
+ grub_efi_uint32_t EventSize;
|
|
|
|
+ grub_efi_uint8_t Event[1];
|
|
|
|
+} TCG_PCR_EVENT;
|
|
|
|
+
|
|
|
|
+struct grub_efi_tpm_protocol
|
|
|
|
+{
|
|
|
|
+ grub_efi_status_t (*status_check) (struct grub_efi_tpm_protocol *this,
|
|
|
|
+ TCG_EFI_BOOT_SERVICE_CAPABILITY *ProtocolCapability,
|
|
|
|
+ grub_efi_uint32_t *TCGFeatureFlags,
|
|
|
|
+ grub_efi_physical_address_t *EventLogLocation,
|
|
|
|
+ grub_efi_physical_address_t *EventLogLastEntry);
|
|
|
|
+ grub_efi_status_t (*hash_all) (struct grub_efi_tpm_protocol *this,
|
|
|
|
+ grub_efi_uint8_t *HashData,
|
|
|
|
+ grub_efi_uint64_t HashLen,
|
|
|
|
+ grub_efi_uint32_t AlgorithmId,
|
|
|
|
+ grub_efi_uint64_t *HashedDataLen,
|
|
|
|
+ grub_efi_uint8_t **HashedDataResult);
|
|
|
|
+ grub_efi_status_t (*log_event) (struct grub_efi_tpm_protocol *this,
|
|
|
|
+ TCG_PCR_EVENT *TCGLogData,
|
|
|
|
+ grub_efi_uint32_t *EventNumber,
|
|
|
|
+ grub_efi_uint32_t Flags);
|
|
|
|
+ grub_efi_status_t (*pass_through_to_tpm) (struct grub_efi_tpm_protocol *this,
|
|
|
|
+ grub_efi_uint32_t TpmInputParameterBlockSize,
|
|
|
|
+ grub_efi_uint8_t *TpmInputParameterBlock,
|
|
|
|
+ grub_efi_uint32_t TpmOutputParameterBlockSize,
|
|
|
|
+ grub_efi_uint8_t *TpmOutputParameterBlock);
|
|
|
|
+ grub_efi_status_t (*log_extend_event) (struct grub_efi_tpm_protocol *this,
|
|
|
|
+ grub_efi_physical_address_t HashData,
|
|
|
|
+ grub_efi_uint64_t HashDataLen,
|
|
|
|
+ grub_efi_uint32_t AlgorithmId,
|
|
|
|
+ TCG_PCR_EVENT *TCGLogData,
|
|
|
|
+ grub_efi_uint32_t *EventNumber,
|
|
|
|
+ grub_efi_physical_address_t *EventLogLastEntry);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+typedef struct grub_efi_tpm_protocol grub_efi_tpm_protocol_t;
|
|
|
|
+
|
|
|
|
+typedef grub_efi_uint32_t EFI_TCG2_EVENT_LOG_BITMAP;
|
|
|
|
+typedef grub_efi_uint32_t EFI_TCG2_EVENT_LOG_FORMAT;
|
|
|
|
+typedef grub_efi_uint32_t EFI_TCG2_EVENT_ALGORITHM_BITMAP;
|
|
|
|
+
|
|
|
|
+typedef struct tdEFI_TCG2_VERSION {
|
|
|
|
+ grub_efi_uint8_t Major;
|
|
|
|
+ grub_efi_uint8_t Minor;
|
|
|
|
+} GRUB_PACKED EFI_TCG2_VERSION;
|
|
|
|
+
|
|
|
|
+typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
|
|
|
|
+ grub_efi_uint8_t Size;
|
|
|
|
+ EFI_TCG2_VERSION StructureVersion;
|
|
|
|
+ EFI_TCG2_VERSION ProtocolVersion;
|
|
|
|
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
|
|
|
|
+ EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
|
|
|
|
+ grub_efi_boolean_t TPMPresentFlag;
|
|
|
|
+ grub_efi_uint16_t MaxCommandSize;
|
|
|
|
+ grub_efi_uint16_t MaxResponseSize;
|
|
|
|
+ grub_efi_uint32_t ManufacturerID;
|
|
|
|
+ grub_efi_uint32_t NumberOfPcrBanks;
|
|
|
|
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
|
|
|
|
+} EFI_TCG2_BOOT_SERVICE_CAPABILITY;
|
|
|
|
+
|
|
|
|
+typedef grub_efi_uint32_t TCG_PCRINDEX;
|
|
|
|
+typedef grub_efi_uint32_t TCG_EVENTTYPE;
|
|
|
|
+
|
|
|
|
+typedef struct tdEFI_TCG2_EVENT_HEADER {
|
|
|
|
+ grub_efi_uint32_t HeaderSize;
|
|
|
|
+ grub_efi_uint16_t HeaderVersion;
|
|
|
|
+ TCG_PCRINDEX PCRIndex;
|
|
|
|
+ TCG_EVENTTYPE EventType;
|
|
|
|
+} GRUB_PACKED EFI_TCG2_EVENT_HEADER;
|
|
|
|
+
|
|
|
|
+typedef struct tdEFI_TCG2_EVENT {
|
|
|
|
+ grub_efi_uint32_t Size;
|
|
|
|
+ EFI_TCG2_EVENT_HEADER Header;
|
|
|
|
+ grub_efi_uint8_t Event[1];
|
|
|
|
+} GRUB_PACKED EFI_TCG2_EVENT;
|
|
|
|
+
|
|
|
|
+struct grub_efi_tpm2_protocol
|
|
|
|
+{
|
|
|
|
+ grub_efi_status_t (*get_capability) (struct grub_efi_tpm2_protocol *this,
|
|
|
|
+ EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability);
|
|
|
|
+ grub_efi_status_t (*get_event_log) (struct grub_efi_tpm2_protocol *this,
|
|
|
|
+ EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
|
|
|
|
+ grub_efi_physical_address_t *EventLogLocation,
|
|
|
|
+ grub_efi_physical_address_t *EventLogLastEntry,
|
|
|
|
+ grub_efi_boolean_t *EventLogTruncated);
|
|
|
|
+ grub_efi_status_t (*hash_log_extend_event) (struct grub_efi_tpm2_protocol *this,
|
|
|
|
+ grub_efi_uint64_t Flags,
|
2019-07-16 09:23:51 +00:00
|
|
|
+ grub_efi_physical_address_t DataToHash,
|
2018-04-06 19:38:57 +00:00
|
|
|
+ grub_efi_uint64_t DataToHashLen,
|
|
|
|
+ EFI_TCG2_EVENT *EfiTcgEvent);
|
|
|
|
+ grub_efi_status_t (*submit_command) (struct grub_efi_tpm2_protocol *this,
|
|
|
|
+ grub_efi_uint32_t InputParameterBlockSize,
|
|
|
|
+ grub_efi_uint8_t *InputParameterBlock,
|
|
|
|
+ grub_efi_uint32_t OutputParameterBlockSize,
|
|
|
|
+ grub_efi_uint8_t *OutputParameterBlock);
|
|
|
|
+ grub_efi_status_t (*get_active_pcr_blanks) (struct grub_efi_tpm2_protocol *this,
|
|
|
|
+ grub_efi_uint32_t *ActivePcrBanks);
|
|
|
|
+ grub_efi_status_t (*set_active_pcr_banks) (struct grub_efi_tpm2_protocol *this,
|
|
|
|
+ grub_efi_uint32_t ActivePcrBanks);
|
|
|
|
+ grub_efi_status_t (*get_result_of_set_active_pcr_banks) (struct grub_efi_tpm2_protocol *this,
|
|
|
|
+ grub_efi_uint32_t *OperationPresent,
|
|
|
|
+ grub_efi_uint32_t *Response);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+typedef struct grub_efi_tpm2_protocol grub_efi_tpm2_protocol_t;
|
|
|
|
+
|
|
|
|
+#define TCG_ALG_SHA 0x00000004
|
|
|
|
+
|
|
|
|
+#endif
|
|
|
|
diff --git a/include/grub/tpm.h b/include/grub/tpm.h
|
|
|
|
new file mode 100644
|
2019-07-16 09:23:51 +00:00
|
|
|
index 00000000000..ce52be4ff7f
|
2018-04-06 19:38:57 +00:00
|
|
|
--- /dev/null
|
|
|
|
+++ b/include/grub/tpm.h
|
2019-07-16 09:23:51 +00:00
|
|
|
@@ -0,0 +1,94 @@
|
2018-04-06 19:38:57 +00:00
|
|
|
+/*
|
|
|
|
+ * GRUB -- GRand Unified Bootloader
|
|
|
|
+ * Copyright (C) 2015 Free Software Foundation, Inc.
|
|
|
|
+ *
|
|
|
|
+ * GRUB is free software: you can redistribute it and/or modify
|
|
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
|
|
+ * the Free Software Foundation, either version 3 of the License, or
|
|
|
|
+ * (at your option) any later version.
|
|
|
|
+ *
|
|
|
|
+ * GRUB is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
+ * GNU General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU General Public License
|
|
|
|
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#ifndef GRUB_TPM_HEADER
|
|
|
|
+#define GRUB_TPM_HEADER 1
|
|
|
|
+
|
|
|
|
+#define SHA1_DIGEST_SIZE 20
|
|
|
|
+
|
|
|
|
+#define TPM_BASE 0x0
|
|
|
|
+#define TPM_SUCCESS TPM_BASE
|
|
|
|
+#define TPM_AUTHFAIL (TPM_BASE + 0x1)
|
|
|
|
+#define TPM_BADINDEX (TPM_BASE + 0x2)
|
|
|
|
+
|
2019-07-16 09:23:51 +00:00
|
|
|
+#define GRUB_ASCII_PCR 8
|
|
|
|
+#define GRUB_BINARY_PCR 9
|
2018-04-06 19:38:57 +00:00
|
|
|
+
|
|
|
|
+#define TPM_TAG_RQU_COMMAND 0x00C1
|
|
|
|
+#define TPM_ORD_Extend 0x14
|
|
|
|
+
|
|
|
|
+#define EV_IPL 0x0d
|
|
|
|
+
|
|
|
|
+/* TCG_PassThroughToTPM Input Parameter Block */
|
|
|
|
+typedef struct {
|
|
|
|
+ grub_uint16_t IPBLength;
|
|
|
|
+ grub_uint16_t Reserved1;
|
|
|
|
+ grub_uint16_t OPBLength;
|
|
|
|
+ grub_uint16_t Reserved2;
|
|
|
|
+ grub_uint8_t TPMOperandIn[1];
|
|
|
|
+} GRUB_PACKED PassThroughToTPM_InputParamBlock;
|
|
|
|
+
|
|
|
|
+/* TCG_PassThroughToTPM Output Parameter Block */
|
|
|
|
+typedef struct {
|
|
|
|
+ grub_uint16_t OPBLength;
|
|
|
|
+ grub_uint16_t Reserved;
|
|
|
|
+ grub_uint8_t TPMOperandOut[1];
|
|
|
|
+} GRUB_PACKED PassThroughToTPM_OutputParamBlock;
|
|
|
|
+
|
|
|
|
+typedef struct {
|
|
|
|
+ grub_uint16_t tag;
|
|
|
|
+ grub_uint32_t paramSize;
|
|
|
|
+ grub_uint32_t ordinal;
|
|
|
|
+ grub_uint32_t pcrNum;
|
|
|
|
+ grub_uint8_t inDigest[SHA1_DIGEST_SIZE]; /* The 160 bit value representing the event to be recorded. */
|
|
|
|
+} GRUB_PACKED ExtendIncoming;
|
|
|
|
+
|
|
|
|
+/* TPM_Extend Outgoing Operand */
|
|
|
|
+typedef struct {
|
|
|
|
+ grub_uint16_t tag;
|
|
|
|
+ grub_uint32_t paramSize;
|
|
|
|
+ grub_uint32_t returnCode;
|
|
|
|
+ grub_uint8_t outDigest[SHA1_DIGEST_SIZE]; /* The PCR value after execution of the command. */
|
|
|
|
+} GRUB_PACKED ExtendOutgoing;
|
|
|
|
+
|
|
|
|
+grub_err_t EXPORT_FUNC(grub_tpm_measure) (unsigned char *buf, grub_size_t size,
|
2019-07-16 09:23:51 +00:00
|
|
|
+ grub_uint8_t pcr, const char *kind,
|
2018-04-06 19:38:57 +00:00
|
|
|
+ const char *description);
|
2019-07-16 09:23:51 +00:00
|
|
|
+#if defined (GRUB_MACHINE_EFI)
|
2018-04-06 19:38:57 +00:00
|
|
|
+grub_err_t grub_tpm_execute(PassThroughToTPM_InputParamBlock *inbuf,
|
|
|
|
+ PassThroughToTPM_OutputParamBlock *outbuf);
|
|
|
|
+grub_err_t grub_tpm_log_event(unsigned char *buf, grub_size_t size,
|
|
|
|
+ grub_uint8_t pcr, const char *description);
|
|
|
|
+#else
|
2019-07-16 09:23:51 +00:00
|
|
|
+static inline grub_err_t grub_tpm_execute(
|
|
|
|
+ PassThroughToTPM_InputParamBlock *inbuf __attribute__ ((unused)),
|
|
|
|
+ PassThroughToTPM_OutputParamBlock *outbuf __attribute__ ((unused)))
|
|
|
|
+{
|
|
|
|
+ return 0;
|
|
|
|
+};
|
|
|
|
+static inline grub_err_t grub_tpm_log_event(
|
|
|
|
+ unsigned char *buf __attribute__ ((unused)),
|
|
|
|
+ grub_size_t size __attribute__ ((unused)),
|
|
|
|
+ grub_uint8_t pcr __attribute__ ((unused)),
|
|
|
|
+ const char *description __attribute__ ((unused)))
|
2018-04-06 19:38:57 +00:00
|
|
|
+{
|
|
|
|
+ return 0;
|
|
|
|
+};
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#endif
|
|
|
|
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
2018-07-27 16:57:04 +00:00
|
|
|
index f36200bd688..3781bb9cbb9 100644
|
2018-04-06 19:38:57 +00:00
|
|
|
--- a/grub-core/Makefile.am
|
|
|
|
+++ b/grub-core/Makefile.am
|
|
|
|
@@ -94,6 +94,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
|
|
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
|
|
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
|
|
|
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
|
|
|
|
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/tpm.h
|
|
|
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
|
|
|
|
|
|
|
|
if COND_i386_pc
|