237 lines
7.1 KiB
Diff
237 lines
7.1 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Stefan Berger <stefanb@linux.ibm.com>
|
||
|
Date: Sun, 15 Mar 2020 12:37:10 -0400
|
||
|
Subject: [PATCH] ibmvtpm: Add support for trusted boot using a vTPM 2.0
|
||
|
|
||
|
Add support for trusted boot using a vTPM 2.0 on the IBM IEEE1275
|
||
|
PowerPC platform. With this patch grub now measures text and binary data
|
||
|
into the TPM's PCRs 8 and 9 in the same way as the x86_64 platform
|
||
|
does.
|
||
|
|
||
|
This patch requires Daniel Axtens's patches for claiming more memory.
|
||
|
|
||
|
For vTPM support to work on PowerVM, system driver levels 1010.30
|
||
|
or 1020.00 are required.
|
||
|
|
||
|
Note: Previous versions of firmware levels with the 2hash-ext-log
|
||
|
API call have a bug that, once this API call is invoked, has the
|
||
|
effect of disabling the vTPM driver under Linux causing an error
|
||
|
message to be displayed in the Linux kernel log. Those users will
|
||
|
have to update their machines to the firmware levels mentioned
|
||
|
above.
|
||
|
|
||
|
Cc: Eric Snowberg <eric.snowberg@oracle.com>
|
||
|
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||
|
---
|
||
|
grub-core/Makefile.core.def | 7 ++
|
||
|
grub-core/commands/ieee1275/ibmvtpm.c | 152 ++++++++++++++++++++++++++++++++++
|
||
|
include/grub/ieee1275/ieee1275.h | 3 +
|
||
|
docs/grub.texi | 3 +-
|
||
|
4 files changed, 164 insertions(+), 1 deletion(-)
|
||
|
create mode 100644 grub-core/commands/ieee1275/ibmvtpm.c
|
||
|
|
||
|
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||
|
index 3c0ac3b7bd..2c1608bca4 100644
|
||
|
--- a/grub-core/Makefile.core.def
|
||
|
+++ b/grub-core/Makefile.core.def
|
||
|
@@ -1175,6 +1175,13 @@ module = {
|
||
|
enable = powerpc_ieee1275;
|
||
|
};
|
||
|
|
||
|
+module = {
|
||
|
+ name = tpm;
|
||
|
+ common = commands/tpm.c;
|
||
|
+ ieee1275 = commands/ieee1275/ibmvtpm.c;
|
||
|
+ enable = powerpc_ieee1275;
|
||
|
+};
|
||
|
+
|
||
|
module = {
|
||
|
name = terminal;
|
||
|
common = commands/terminal.c;
|
||
|
diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c
|
||
|
new file mode 100644
|
||
|
index 0000000000..e68b8448bc
|
||
|
--- /dev/null
|
||
|
+++ b/grub-core/commands/ieee1275/ibmvtpm.c
|
||
|
@@ -0,0 +1,152 @@
|
||
|
+/*
|
||
|
+ * GRUB -- GRand Unified Bootloader
|
||
|
+ * Copyright (C) 2021 Free Software Foundation, Inc.
|
||
|
+ * Copyright (C) 2021 IBM Corporation
|
||
|
+ *
|
||
|
+ * 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/>.
|
||
|
+ *
|
||
|
+ * IBM vTPM support code.
|
||
|
+ */
|
||
|
+
|
||
|
+#include <grub/err.h>
|
||
|
+#include <grub/types.h>
|
||
|
+#include <grub/tpm.h>
|
||
|
+#include <grub/ieee1275/ieee1275.h>
|
||
|
+#include <grub/mm.h>
|
||
|
+#include <grub/misc.h>
|
||
|
+
|
||
|
+static grub_ieee1275_ihandle_t tpm_ihandle;
|
||
|
+static grub_uint8_t tpm_version;
|
||
|
+
|
||
|
+#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t)0)
|
||
|
+
|
||
|
+static void
|
||
|
+tpm_get_tpm_version (void)
|
||
|
+{
|
||
|
+ grub_ieee1275_phandle_t vtpm;
|
||
|
+ char buffer[20];
|
||
|
+
|
||
|
+ if (!grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) &&
|
||
|
+ !grub_ieee1275_get_property (vtpm, "compatible", buffer,
|
||
|
+ sizeof (buffer), NULL) &&
|
||
|
+ !grub_strcmp (buffer, "IBM,vtpm20"))
|
||
|
+ tpm_version = 2;
|
||
|
+}
|
||
|
+
|
||
|
+static grub_err_t
|
||
|
+tpm_init (void)
|
||
|
+{
|
||
|
+ static int init_success = 0;
|
||
|
+
|
||
|
+ if (!init_success)
|
||
|
+ {
|
||
|
+ if (grub_ieee1275_open ("/vdevice/vtpm", &tpm_ihandle) < 0) {
|
||
|
+ tpm_ihandle = IEEE1275_IHANDLE_INVALID;
|
||
|
+ return GRUB_ERR_UNKNOWN_DEVICE;
|
||
|
+ }
|
||
|
+
|
||
|
+ init_success = 1;
|
||
|
+
|
||
|
+ tpm_get_tpm_version ();
|
||
|
+ }
|
||
|
+
|
||
|
+ return GRUB_ERR_NONE;
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
+ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex,
|
||
|
+ grub_uint32_t eventtype,
|
||
|
+ const char *description,
|
||
|
+ grub_size_t description_size,
|
||
|
+ void *buf, grub_size_t size)
|
||
|
+{
|
||
|
+ struct tpm_2hash_ext_log
|
||
|
+ {
|
||
|
+ struct grub_ieee1275_common_hdr common;
|
||
|
+ grub_ieee1275_cell_t method;
|
||
|
+ grub_ieee1275_cell_t ihandle;
|
||
|
+ grub_ieee1275_cell_t size;
|
||
|
+ grub_ieee1275_cell_t buf;
|
||
|
+ grub_ieee1275_cell_t description_size;
|
||
|
+ grub_ieee1275_cell_t description;
|
||
|
+ grub_ieee1275_cell_t eventtype;
|
||
|
+ grub_ieee1275_cell_t pcrindex;
|
||
|
+ grub_ieee1275_cell_t catch_result;
|
||
|
+ grub_ieee1275_cell_t rc;
|
||
|
+ }
|
||
|
+ args;
|
||
|
+
|
||
|
+ INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 2);
|
||
|
+ args.method = (grub_ieee1275_cell_t) "2hash-ext-log";
|
||
|
+ args.ihandle = tpm_ihandle;
|
||
|
+ args.pcrindex = pcrindex;
|
||
|
+ args.eventtype = eventtype;
|
||
|
+ args.description = (grub_ieee1275_cell_t) description;
|
||
|
+ args.description_size = description_size;
|
||
|
+ args.buf = (grub_ieee1275_cell_t) buf;
|
||
|
+ args.size = (grub_ieee1275_cell_t) size;
|
||
|
+
|
||
|
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||
|
+ return -1;
|
||
|
+
|
||
|
+ /*
|
||
|
+ * catch_result is set if firmware does not support 2hash-ext-log
|
||
|
+ * rc is GRUB_IEEE1275_CELL_FALSE (0) on failure
|
||
|
+ */
|
||
|
+ if ((args.catch_result) || args.rc == GRUB_IEEE1275_CELL_FALSE)
|
||
|
+ return -1;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static grub_err_t
|
||
|
+tpm2_log_event (unsigned char *buf,
|
||
|
+ grub_size_t size, grub_uint8_t pcr,
|
||
|
+ const char *description)
|
||
|
+{
|
||
|
+ static int error_displayed = 0;
|
||
|
+ int err;
|
||
|
+
|
||
|
+ err = ibmvtpm_2hash_ext_log (pcr, EV_IPL,
|
||
|
+ description,
|
||
|
+ grub_strlen(description) + 1,
|
||
|
+ buf, size);
|
||
|
+ if (err && !error_displayed)
|
||
|
+ {
|
||
|
+ error_displayed++;
|
||
|
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||
|
+ "2HASH-EXT-LOG failed: Firmware is likely too old.\n");
|
||
|
+ }
|
||
|
+
|
||
|
+ return GRUB_ERR_NONE;
|
||
|
+}
|
||
|
+
|
||
|
+grub_err_t
|
||
|
+grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||
|
+ const char *description)
|
||
|
+{
|
||
|
+ grub_err_t err = tpm_init();
|
||
|
+
|
||
|
+ /* Absence of a TPM isn't a failure. */
|
||
|
+ if (err != GRUB_ERR_NONE)
|
||
|
+ return GRUB_ERR_NONE;
|
||
|
+
|
||
|
+ grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n",
|
||
|
+ pcr, size, description);
|
||
|
+
|
||
|
+ if (tpm_version == 2)
|
||
|
+ return tpm2_log_event (buf, size, pcr, description);
|
||
|
+
|
||
|
+ return GRUB_ERR_NONE;
|
||
|
+}
|
||
|
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
|
||
|
index e0a6c2ce1e..f4c85265fe 100644
|
||
|
--- a/include/grub/ieee1275/ieee1275.h
|
||
|
+++ b/include/grub/ieee1275/ieee1275.h
|
||
|
@@ -24,6 +24,9 @@
|
||
|
#include <grub/types.h>
|
||
|
#include <grub/machine/ieee1275.h>
|
||
|
|
||
|
+#define GRUB_IEEE1275_CELL_FALSE ((grub_ieee1275_cell_t) 0)
|
||
|
+#define GRUB_IEEE1275_CELL_TRUE ((grub_ieee1275_cell_t) -1)
|
||
|
+
|
||
|
struct grub_ieee1275_mem_region
|
||
|
{
|
||
|
unsigned int start;
|
||
|
diff --git a/docs/grub.texi b/docs/grub.texi
|
||
|
index a4da9c2a1b..c433240f34 100644
|
||
|
--- a/docs/grub.texi
|
||
|
+++ b/docs/grub.texi
|
||
|
@@ -6221,7 +6221,8 @@ tpm module is loaded. As such it is recommended that the tpm module be built
|
||
|
into @file{core.img} in order to avoid a potential gap in measurement between
|
||
|
@file{core.img} being loaded and the tpm module being loaded.
|
||
|
|
||
|
-Measured boot is currently only supported on EFI platforms.
|
||
|
+Measured boot is currently only supported on EFI and IBM IEEE1275 PowerPC
|
||
|
+platforms.
|
||
|
|
||
|
@node Lockdown
|
||
|
@section Lockdown when booting on a secure setup
|