diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 8b413c380..db2264ff5 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2489,6 +2489,13 @@ module = {
common = commands/testspeed.c;
};
+module = {
+ name = tpm;
+ common = commands/tpm.c;
+ efi = commands/efi/tpm.c;
+ enable = x86_64_efi;
+};
+
module = {
name = tr;
common = commands/tr.c;
diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c
new file mode 100644
index 000000000..563ceba7a
--- /dev/null
+++ b/grub-core/commands/efi/tpm.c
@@ -0,0 +1,333 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2018 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 .
+ *
+ * EFI TPM support code.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+typedef TCG_PCR_EVENT grub_tpm_event_t;
+
+static grub_efi_guid_t tpm_guid = EFI_TPM_GUID;
+static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID;
+
+static grub_efi_handle_t *grub_tpm_handle;
+static grub_uint8_t grub_tpm_version;
+
+static grub_int8_t tpm1_present = -1;
+static grub_int8_t tpm2_present = -1;
+
+static grub_efi_boolean_t
+grub_tpm1_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;
+
+ if (tpm1_present != -1)
+ return (grub_efi_boolean_t) tpm1_present;
+
+ 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 tpm1_present = 0;
+
+ return tpm1_present = 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);
+
+ if (tpm2_present != -1)
+ return (grub_efi_boolean_t) tpm2_present;
+
+ status = efi_call_2 (tpm->get_capability, tpm, &caps);
+
+ if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag)
+ return tpm2_present = 0;
+
+ return tpm2_present = 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;
+
+ if (grub_tpm_handle != NULL)
+ {
+ *tpm_handle = &grub_tpm_handle;
+ *protocol_version = grub_tpm_version;
+ return 1;
+ }
+
+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm_guid, NULL,
+ &num_handles);
+ if (handles && num_handles > 0)
+ {
+ grub_tpm_handle = handles[0];
+ *tpm_handle = handles[0];
+ grub_tpm_version = 1;
+ *protocol_version = 1;
+ return 1;
+ }
+
+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL,
+ &num_handles);
+ if (handles && num_handles > 0)
+ {
+ grub_tpm_handle = handles[0];
+ *tpm_handle = handles[0];
+ grub_tpm_version = 2;
+ *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_tpm1_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;
+
+ /* Absence of a TPM isn't a failure. */
+ 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)
+{
+ grub_tpm_event_t *event;
+ 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_tpm1_present (tpm))
+ return 0;
+
+ event = grub_zalloc (sizeof (*event) + grub_strlen (description) + 1);
+ if (!event)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ N_("cannot allocate TPM event buffer"));
+
+ event->PCRIndex = pcr;
+ event->EventType = EV_IPL;
+ event->EventSize = grub_strlen (description) + 1;
+ grub_memcpy (event->Event, description, event->EventSize);
+
+ algorithm = TCG_ALG_SHA;
+ status = efi_call_7 (tpm->log_extend_event, tpm, buf, (grub_uint64_t) size,
+ 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);
+
+ status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, buf,
+ (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/commands/tpm.c b/grub-core/commands/tpm.c
new file mode 100644
index 000000000..1441c494d
--- /dev/null
+++ b/grub-core/commands/tpm.c
@@ -0,0 +1,102 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2018 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 .
+ *
+ * Core TPM support code.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+grub_err_t
+grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
+ const char *description)
+{
+ return grub_tpm_log_event (buf, size, pcr, description);
+}
+
+static grub_err_t
+grub_tpm_verify_init (grub_file_t io,
+ enum grub_file_type type __attribute__ ((unused)),
+ void **context, enum grub_verify_flags *flags)
+{
+ *context = io->name;
+ *flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_tpm_verify_write (void *context, void *buf, grub_size_t size)
+{
+ return grub_tpm_measure (buf, size, GRUB_BINARY_PCR, context);
+}
+
+static grub_err_t
+grub_tpm_verify_string (char *str, enum grub_verify_string_type type)
+{
+ const char *prefix = NULL;
+ char *description;
+ grub_err_t status;
+
+ switch (type)
+ {
+ case GRUB_VERIFY_KERNEL_CMDLINE:
+ prefix = "kernel_cmdline: ";
+ break;
+ case GRUB_VERIFY_MODULE_CMDLINE:
+ prefix = "module_cmdline: ";
+ break;
+ case GRUB_VERIFY_COMMAND:
+ prefix = "grub_cmd: ";
+ break;
+ }
+ description = grub_malloc (grub_strlen (str) + grub_strlen (prefix) + 1);
+ if (!description)
+ return grub_errno;
+ grub_memcpy (description, prefix, grub_strlen (prefix));
+ grub_memcpy (description + grub_strlen (prefix), str,
+ grub_strlen (str) + 1);
+ status =
+ grub_tpm_measure ((unsigned char *) str, grub_strlen (str),
+ GRUB_STRING_PCR, description);
+ grub_free (description);
+ return status;
+}
+
+struct grub_file_verifier grub_tpm_verifier = {
+ .name = "tpm",
+ .init = grub_tpm_verify_init,
+ .write = grub_tpm_verify_write,
+ .verify_string = grub_tpm_verify_string,
+};
+
+GRUB_MOD_INIT (tpm)
+{
+ grub_verifier_register (&grub_tpm_verifier);
+}
+
+GRUB_MOD_FINI (tpm)
+{
+ grub_verifier_unregister (&grub_tpm_verifier);
+}
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
index a02af418a..3bcf56aad 100644
--- a/grub-core/kern/dl.c
+++ b/grub-core/kern/dl.c
@@ -730,7 +730,7 @@ grub_dl_load_file (const char *filename)
opens of the same device. */
grub_file_close (file);
- grub_tpm_measure(core, size, GRUB_BINARY_PCR, "grub_module", filename);
+ grub_tpm_measure(core, size, GRUB_BINARY_PCR, filename);
grub_print_error();
mod = grub_dl_load_core (core, size);
diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c
index a28316cc6..da499aba0 100644
--- a/grub-core/kern/i386/efi/init.c
+++ b/grub-core/kern/i386/efi/init.c
@@ -27,6 +27,7 @@
#include
#include
#include
+#include
void
grub_machine_init (void)
diff --git a/grub-core/kern/tpm.c b/grub-core/kern/tpm.c
index e5e8fced6..9841d8d38 100644
--- a/grub-core/kern/tpm.c
+++ b/grub-core/kern/tpm.c
@@ -7,13 +7,8 @@
grub_err_t
grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
- const char *kind, const char *description)
+ const char *description)
{
- 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;
+ return grub_tpm_log_event (buf, size, pcr, description);
}
+
diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c
index b37155053..ecfbe3409 100644
--- a/grub-core/lib/cmdline.c
+++ b/grub-core/lib/cmdline.c
@@ -106,9 +106,5 @@ grub_create_loader_cmdline (int argc, char *argv[], char *buf,
*buf = 0;
- grub_tpm_measure ((void *)orig_buf, grub_strlen (orig_buf), GRUB_ASCII_PCR,
- "grub_kernel_cmdline", orig_buf);
- grub_print_error();
-
return grub_verify_string (orig_buf, type);
}
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
index 22a3618d8..fc3d949c9 100644
--- a/grub-core/loader/i386/efi/linux.c
+++ b/grub-core/loader/i386/efi/linux.c
@@ -169,8 +169,9 @@ 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();
+ // TODO figure out the GRUB_VERIFY_ equivalent for this one
+ //grub_tpm_measure (ptr, cursize, GRUB_BINARY_PCR, "Initrd");
+ //grub_print_error();
ptr += cursize;
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
@@ -226,8 +227,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();
+ // TODO figure out the GRUB_VERIFY_ equivalent for this one
+ //grub_tpm_measure (kernel, filelen, GRUB_BINARY_PCR, "Kernel");
+ //grub_print_error();
if (! grub_linuxefi_secure_validate (kernel, filelen))
{
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index be746ce74..7841d6ce8 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -681,8 +681,9 @@ 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();
+ // TODO figure out the GRUB_VERIFY_ equivalent for this one
+ //grub_tpm_measure (kernel, len, GRUB_BINARY_PCR, "Kernel");
+ //grub_print_error();
grub_memcpy (&lh, kernel, sizeof (lh));
diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c
index ee74a4b46..468349f84 100644
--- a/grub-core/loader/i386/multiboot_mbi.c
+++ b/grub-core/loader/i386/multiboot_mbi.c
@@ -174,8 +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();
+ // TODO figure out the GRUB_VERIFY_ equivalent for this one
+ //grub_tpm_measure((unsigned char*)buffer, len, GRUB_BINARY_PCR, filename);
+ //grub_print_error();
header = find_header (buffer, len);
diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
index 7493e7341..c25e0dad1 100644
--- a/grub-core/loader/i386/pc/linux.c
+++ b/grub-core/loader/i386/pc/linux.c
@@ -161,8 +161,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
- grub_tpm_measure (kernel, len, GRUB_BINARY_PCR, "grub_linux16", "Kernel");
- grub_print_error();
+ // TODO figure out the GRUB_VERIFY_ equivalent for this one
+ //grub_tpm_measure (kernel, len, GRUB_BINARY_PCR, "Kernel");
+ //grub_print_error();
grub_memcpy (&lh, kernel, sizeof (lh));
kernel_offset = sizeof (lh);
diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
index e1079f140..4b185cb15 100644
--- a/grub-core/loader/linux.c
+++ b/grub-core/loader/linux.c
@@ -289,8 +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();
+ // TODO figure out the GRUB_VERIFY_ equivalent for this one
+ //grub_tpm_measure (ptr, cursize, GRUB_BINARY_PCR, "Initrd");
+ //grub_print_error();
ptr += cursize;
}
diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
index d0f045628..c16489de9 100644
--- a/grub-core/loader/multiboot.c
+++ b/grub-core/loader/multiboot.c
@@ -438,8 +438,9 @@ 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();
+ // TODO figure out the GRUB_VERIFY_ equivalent for this one
+ //grub_tpm_measure (module, size, GRUB_BINARY_PCR, 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 1a48305fa..ab8d99c28 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -132,8 +132,9 @@ 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();
+ // TODO figure out the GRUB_VERIFY_ equivalent for this one
+ //grub_tpm_measure ((unsigned char *)mld.buffer, len, GRUB_BINARY_PCR, filename);
+ //grub_print_error();
header = find_header (mld.buffer, len);
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index 9da5b10a5..0144c5698 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -960,9 +960,6 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
argv.args[i]);
}
cmdstring[cmdlen - 1] = '\0';
- grub_tpm_measure ((unsigned char *)cmdstring, cmdlen, GRUB_ASCII_PCR,
- "grub_cmd", cmdstring);
- grub_print_error();
grub_verify_string (cmdstring, GRUB_VERIFY_COMMAND);
grub_free (cmdstring);
invert = 0;
diff --git a/include/grub/efi/tpm.h b/include/grub/efi/tpm.h
index 63d8a0fe7..2d7630137 100644
--- a/include/grub/efi/tpm.h
+++ b/include/grub/efi/tpm.h
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2015 Free Software Foundation, Inc.
+ * Copyright (C) 2018 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
@@ -22,37 +22,54 @@
#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 {
+#define TCG_ALG_SHA 0x00000004
+
+/* These structs are as defined in the TCG EFI Protocol Specification, family 2.0. */
+
+struct __TCG_VERSION
+{
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_VERSION 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;
+struct __TCG_EFI_BOOT_SERVICE_CAPABILITY
+{
+ /* Size of this structure. */
+ grub_efi_uint8_t Size;
+ TCG_VERSION StructureVersion;
+ TCG_VERSION ProtocolSpecVersion;
+ /* Hash algorithms supported by this TPM. */
+ grub_efi_uint8_t HashAlgorithmBitmap;
+ /* 1 if TPM present. */
+ char TPMPresentFlag;
+ /* 1 if TPM deactivated. */
+ char TPMDeactivatedFlag;
+};
+typedef struct __TCG_EFI_BOOT_SERVICE_CAPABILITY TCG_EFI_BOOT_SERVICE_CAPABILITY;
-typedef struct {
+struct tdTCG_PCR_EVENT
+{
grub_efi_uint32_t PCRIndex;
grub_efi_uint32_t EventType;
- grub_efi_uint8_t digest[20];
+ grub_efi_uint8_t digest[20];
grub_efi_uint32_t EventSize;
grub_efi_uint8_t Event[1];
-} TCG_PCR_EVENT;
+};
+typedef struct tdTCG_PCR_EVENT 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,
+ 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_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,
@@ -63,18 +80,24 @@ struct grub_efi_tpm_protocol
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 (*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);
+ grub_efi_physical_address_t *
+ EventLogLastEntry);
};
typedef struct grub_efi_tpm_protocol grub_efi_tpm_protocol_t;
@@ -83,24 +106,28 @@ 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 {
+struct tdEFI_TCG2_VERSION
+{
grub_efi_uint8_t Major;
grub_efi_uint8_t Minor;
-} GRUB_PACKED EFI_TCG2_VERSION;
+} GRUB_PACKED;
+typedef struct tdEFI_TCG2_VERSION EFI_TCG2_VERSION;
-typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
- grub_efi_uint8_t Size;
- EFI_TCG2_VERSION StructureVersion;
- EFI_TCG2_VERSION ProtocolVersion;
+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_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 struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY EFI_TCG2_BOOT_SERVICE_CAPABILITY;
typedef grub_efi_uint32_t TCG_PCRINDEX;
typedef grub_efi_uint32_t TCG_EVENTTYPE;
@@ -112,42 +139,58 @@ typedef struct tdEFI_TCG2_EVENT_HEADER {
TCG_EVENTTYPE EventType;
} GRUB_PACKED EFI_TCG2_EVENT_HEADER;
-typedef struct tdEFI_TCG2_EVENT {
- grub_efi_uint32_t Size;
+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;
+ grub_efi_uint8_t Event[1];
+} GRUB_PACKED;
+typedef struct tdEFI_TCG2_EVENT 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);
+ 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,
+ 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,
- grub_efi_physical_address_t DataToHash,
+ grub_efi_status_t (*hash_log_extend_event) (struct grub_efi_tpm2_protocol *
+ this, grub_efi_uint64_t Flags,
+ grub_efi_physical_address_t *
+ DataToHash,
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_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);
+ 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
index 972a5edc8..dfcbe8372 100644
--- a/include/grub/tpm.h
+++ b/include/grub/tpm.h
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2015 Free Software Foundation, Inc.
+ * Copyright (C) 2018 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
@@ -19,76 +19,64 @@
#ifndef GRUB_TPM_HEADER
#define GRUB_TPM_HEADER 1
+#define GRUB_STRING_PCR 8
+#define GRUB_BINARY_PCR 9
+
#define SHA1_DIGEST_SIZE 20
-#define TPM_BASE 0x0
-#define TPM_SUCCESS TPM_BASE
+#define TPM_BASE 0x0
+#define TPM_SUCCESS TPM_BASE
#define TPM_AUTHFAIL (TPM_BASE + 0x1)
#define TPM_BADINDEX (TPM_BASE + 0x2)
-#define GRUB_ASCII_PCR 8
-#define GRUB_BINARY_PCR 9
-
#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];
+/* 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];
+/* 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. */
+typedef struct
+{
+ grub_uint16_t tag;
+ grub_uint32_t paramSize;
+ grub_uint32_t ordinal;
+ grub_uint32_t pcrNum;
+ /* The 160 bit value representing the event to be recorded. */
+ grub_uint8_t inDigest[SHA1_DIGEST_SIZE];
} 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. */
+/* TPM_Extend Outgoing Operand. */
+typedef struct
+{
+ grub_uint16_t tag;
+ grub_uint32_t paramSize;
+ grub_uint32_t returnCode;
+ /* The PCR value after execution of the command. */
+ grub_uint8_t outDigest[SHA1_DIGEST_SIZE];
} GRUB_PACKED ExtendOutgoing;
-grub_err_t EXPORT_FUNC(grub_tpm_measure) (unsigned char *buf, grub_size_t size,
- grub_uint8_t pcr, const char *kind,
- const char *description);
-#if defined (GRUB_MACHINE_EFI) || defined (GRUB_MACHINE_PCBIOS)
-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
-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)))
-{
- return 0;
-};
-#endif
-
+grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size,
+ grub_uint8_t pcr, const char *description);
+grub_err_t grub_tpm_init (void);
+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);
#endif