You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
237 lines
7.2 KiB
237 lines
7.2 KiB
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> |
|
(cherry picked from commit d3e5a8e6ecb8b87701135d97f45d27bbfbf731a2) |
|
--- |
|
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 97abc01f06..407d68f917 100644 |
|
--- a/grub-core/Makefile.core.def |
|
+++ b/grub-core/Makefile.core.def |
|
@@ -1172,6 +1172,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
|
|
|