On Thu, Dec 01, 2022 at 04:12:01PM -0500, Stefan Berger wrote: > 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.snowb...@oracle.com> > Signed-off-by: Stefan Berger <stef...@linux.ibm.com> > Signed-off-by: Daniel Axtens <d...@axtens.net> > --- > docs/grub.texi | 3 +- > grub-core/Makefile.core.def | 7 ++ > grub-core/commands/ieee1275/ibmvtpm.c | 151 ++++++++++++++++++++++++++ > include/grub/ieee1275/ieee1275.h | 3 + > 4 files changed, 163 insertions(+), 1 deletion(-) > create mode 100644 grub-core/commands/ieee1275/ibmvtpm.c > > diff --git a/docs/grub.texi b/docs/grub.texi > index 50c811a88..580f2a995 100644 > --- a/docs/grub.texi > +++ b/docs/grub.texi > @@ -6413,7 +6413,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 > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def > index 0ec95997d..ef6964b91 100644 > --- a/grub-core/Makefile.core.def > +++ b/grub-core/Makefile.core.def > @@ -1133,6 +1133,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 000000000..78e002c47 > --- /dev/null > +++ b/grub-core/commands/ieee1275/ibmvtpm.c > @@ -0,0 +1,151 @@ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2022 Free Software Foundation, Inc. > + * Copyright (C) 2022 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; > + }; > + struct tpm_2hash_ext_log 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 rc; > + > + rc = ibmvtpm_2hash_ext_log (pcr, EV_IPL, > + description, grub_strlen(description) + 1, > + buf, size); > + if (rc && !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 ();
This should happen on module load. Then code in tpm_init() and here should be much simpler. > + /* 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; > +} Daniel _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel