3e026f665c
- Add safety measure to pcr snapshot by checking platform and tpm status * safe_tpm_pcr_snapshot.patch - Fix installation failure due to unavailable nvram device on ppc64le (bsc#1201361) * 0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch - Add patches to dynamically allocate additional memory regions for EFI systems (bsc#1202438) * 0001-mm-Allow-dynamically-requesting-additional-memory-re.patch * 0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch * 0003-kern-efi-mm-Extract-function-to-add-memory-regions.patch * 0004-kern-efi-mm-Pass-up-errors-from-add_memory_regions.patch * 0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch - Enlarge the default heap size and defer the disk cache invalidation (bsc#1202438) * 0001-kern-efi-mm-Enlarge-the-default-heap-size.patch * 0002-mm-Defer-the-disk-cache-invalidation.patch - Add patches for ALP FDE support * 0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch * 0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch * 0003-disk-cryptodisk-When-cheatmounting-use-the-sector-in.patch * 0004-normal-menu-Don-t-show-Booting-s-msg-when-auto-booti.patch * 0005-EFI-suppress-the-Welcome-to-GRUB-message-in-EFI-buil.patch * 0006-EFI-console-Do-not-set-colorstate-until-the-first-te.patch * 0007-EFI-console-Do-not-set-cursor-until-the-first-text-o.patch * 0008-linuxefi-Use-common-grub_initrd_load.patch * 0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch * 0010-templates-import-etc-crypttab-to-grub.cfg.patch OBS-URL: https://build.opensuse.org/request/show/1004537 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=419
236 lines
5.6 KiB
Diff
236 lines
5.6 KiB
Diff
Index: grub-2.06/grub-core/commands/tpm.c
|
|
===================================================================
|
|
--- grub-2.06.orig/grub-core/commands/tpm.c
|
|
+++ grub-2.06/grub-core/commands/tpm.c
|
|
@@ -26,6 +26,9 @@
|
|
#include <grub/term.h>
|
|
#include <grub/verify.h>
|
|
#include <grub/dl.h>
|
|
+#include <grub/extcmd.h>
|
|
+#include <grub/tpm2/tpm2.h>
|
|
+#include <grub/efi/efi.h>
|
|
|
|
GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
|
@@ -84,12 +87,220 @@ struct grub_file_verifier grub_tpm_verif
|
|
.verify_string = grub_tpm_verify_string,
|
|
};
|
|
|
|
+/*
|
|
+ * Preserve current PCR values and record them to an EFI variable
|
|
+ */
|
|
+#define GRUB2_PCR_BITMASK_DEFAULT ((1 << 16) - 1)
|
|
+#define GRUB2_PCR_BITMASK_ALL ((1 << 24) - 1)
|
|
+
|
|
+static const struct grub_arg_option grub_tpm_record_pcrs_options[] =
|
|
+ {
|
|
+ {
|
|
+ .longarg = "efivar",
|
|
+ .shortarg = 'E',
|
|
+ .flags = 0,
|
|
+ .arg = NULL,
|
|
+ .type = ARG_TYPE_STRING,
|
|
+ .doc =
|
|
+ N_("The EFI variable to publish the PCRs to (default GrubPcrSnapshot)"),
|
|
+ },
|
|
+
|
|
+ {0, 0, 0, 0, 0, 0}
|
|
+ };
|
|
+
|
|
+static grub_err_t
|
|
+grub_tpm_parse_pcr_index (const char *word, const char **end_ret, unsigned int *index)
|
|
+{
|
|
+ const char *end;
|
|
+
|
|
+ if (!grub_isdigit (word[0]))
|
|
+ return GRUB_ERR_BAD_NUMBER;
|
|
+
|
|
+ *index = grub_strtoul(word, &end, 0);
|
|
+ if (*index > 32)
|
|
+ return GRUB_ERR_BAD_NUMBER;
|
|
+
|
|
+ *end_ret = end;
|
|
+ return GRUB_ERR_NONE;
|
|
+}
|
|
+
|
|
+static grub_err_t
|
|
+grub_tpm_parse_pcr_list (const char *arg, grub_uint32_t *bitmask)
|
|
+{
|
|
+ const char *word, *end;
|
|
+ unsigned int index, last_index;
|
|
+
|
|
+ if (!grub_strcmp (arg, "all"))
|
|
+ {
|
|
+ *bitmask = GRUB2_PCR_BITMASK_ALL;
|
|
+ return GRUB_ERR_NONE;
|
|
+ }
|
|
+
|
|
+ word = arg;
|
|
+ while (1)
|
|
+ {
|
|
+ if (grub_tpm_parse_pcr_index (word, &end, &index))
|
|
+ goto bad_pcr_index;
|
|
+
|
|
+ if (*end == '-')
|
|
+ {
|
|
+ if (grub_tpm_parse_pcr_index (end + 1, &end, &last_index) || last_index < index)
|
|
+ goto bad_pcr_index;
|
|
+
|
|
+ while (index <= last_index)
|
|
+ *bitmask |= (1 << (index++));
|
|
+ }
|
|
+ else
|
|
+ *bitmask |= (1 << index);
|
|
+
|
|
+ if (*end == '\0')
|
|
+ break;
|
|
+
|
|
+ if (*end != ',')
|
|
+ goto bad_pcr_index;
|
|
+
|
|
+ word = end + 1;
|
|
+ }
|
|
+
|
|
+ return GRUB_ERR_NONE;
|
|
+
|
|
+bad_pcr_index:
|
|
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot parse PCR list \"%s\""), arg);
|
|
+}
|
|
+
|
|
+static inline unsigned int
|
|
+nbits(grub_uint32_t mask)
|
|
+{
|
|
+ unsigned int r = 0;
|
|
+
|
|
+ for (; mask != 0; mask >>= 1)
|
|
+ r += (mask & 1);
|
|
+ return r;
|
|
+}
|
|
+
|
|
+static grub_err_t
|
|
+grub_tpm_snapshot_pcrs (grub_uint32_t pcr_bitmask, const char *algo,
|
|
+ void **buffer_ret, grub_size_t *size_ret)
|
|
+{
|
|
+ char *buffer;
|
|
+ grub_size_t size = 65536;
|
|
+ unsigned int wpos = 0;
|
|
+ grub_uint8_t pcr;
|
|
+
|
|
+ buffer = grub_malloc (size);
|
|
+ for (pcr = 0; pcr < 32; ++pcr)
|
|
+ {
|
|
+ struct grub_tpm_digest *d;
|
|
+ unsigned int need, k;
|
|
+
|
|
+ if (!(pcr_bitmask & (1 << pcr)))
|
|
+ continue;
|
|
+
|
|
+ d = grub_tpm_read_pcr (pcr, algo);
|
|
+ if (d == NULL)
|
|
+ {
|
|
+ grub_error (GRUB_ERR_BAD_DEVICE, N_("unable to read PCR %d from TPM"), pcr);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ /* We need room for the PCR index, 2 spaces, newline, NUL. 16 should be enough. */
|
|
+ need = 16 + grub_strlen(d->algorithm) + 2 * d->size;
|
|
+ if (wpos + need > size)
|
|
+ {
|
|
+ buffer = grub_realloc (buffer, size + need);
|
|
+ if (buffer == NULL)
|
|
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("Not enough memory when dumping PCR registers"));
|
|
+ }
|
|
+
|
|
+ grub_snprintf (buffer + wpos, size - wpos, "%02d %s ", pcr, d->algorithm);
|
|
+ wpos = grub_strlen(buffer);
|
|
+
|
|
+ for (k = 0; k < d->size; ++k)
|
|
+ {
|
|
+ grub_snprintf (buffer + wpos, size - wpos, "%02x", d->value[k]);
|
|
+ wpos += 2;
|
|
+ }
|
|
+
|
|
+ buffer[wpos++] = '\n';
|
|
+ buffer[wpos] = '\0';
|
|
+
|
|
+ grub_tpm_digest_free (d);
|
|
+ }
|
|
+
|
|
+ *buffer_ret = buffer;
|
|
+ *size_ret = wpos;
|
|
+
|
|
+ return GRUB_ERR_NONE;
|
|
+}
|
|
+
|
|
+static grub_err_t
|
|
+grub_tpm_write_pcrs_to_efi (void *data, grub_size_t size, const char *var_name)
|
|
+{
|
|
+ grub_efi_guid_t vendor_guid = { 0x7ce323f2, 0xb841, 0x4d30, { 0xa0, 0xe9, 0x54, 0x74, 0xa7, 0x6c, 0x9a, 0x3f }};
|
|
+ grub_err_t rc;
|
|
+
|
|
+ rc = grub_efi_set_variable_with_attributes(var_name, &vendor_guid,
|
|
+ GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | GRUB_EFI_VARIABLE_RUNTIME_ACCESS,
|
|
+ data, size);
|
|
+
|
|
+ if (rc)
|
|
+ return grub_error (GRUB_ERR_BAD_DEVICE, N_("Failed to publish PCR snapshot to UEFI variable %s"), var_name);
|
|
+
|
|
+ return GRUB_ERR_NONE;
|
|
+}
|
|
+
|
|
+static grub_err_t
|
|
+grub_tpm_record_pcrs (grub_extcmd_context_t ctxt, int argc, char **args)
|
|
+{
|
|
+ struct grub_arg_list *state = ctxt->state;
|
|
+ grub_uint32_t pcr_bitmask = 0;
|
|
+ const char *efivar;
|
|
+ void *buffer = NULL;
|
|
+ grub_size_t size = 0;
|
|
+ int n, rv = 1;
|
|
+
|
|
+ if (argc == 0)
|
|
+ pcr_bitmask = GRUB2_PCR_BITMASK_DEFAULT;
|
|
+ else
|
|
+ {
|
|
+ for (n = 0; n < argc; ++n)
|
|
+ if (grub_tpm_parse_pcr_list (args[n], &pcr_bitmask))
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ if (grub_tpm_snapshot_pcrs (pcr_bitmask, NULL, &buffer, &size))
|
|
+ goto out;
|
|
+
|
|
+ if (state[0].set)
|
|
+ efivar = state[0].arg;
|
|
+ else
|
|
+ efivar = "GrubPcrSnapshot";
|
|
+
|
|
+ if (grub_tpm_write_pcrs_to_efi (buffer, size, efivar))
|
|
+ goto out;
|
|
+
|
|
+ rv = 0;
|
|
+
|
|
+out:
|
|
+ if (buffer)
|
|
+ grub_free (buffer);
|
|
+ return rv;
|
|
+}
|
|
+
|
|
+static grub_extcmd_t cmd;
|
|
+
|
|
GRUB_MOD_INIT (tpm)
|
|
{
|
|
grub_verifier_register (&grub_tpm_verifier);
|
|
+
|
|
+ cmd = grub_register_extcmd ("tpm_record_pcrs", grub_tpm_record_pcrs, 0,
|
|
+ N_("LIST_OF_PCRS"),
|
|
+ N_("Snapshot one or more PCR values and record them in an EFI variable."),
|
|
+ grub_tpm_record_pcrs_options);
|
|
}
|
|
|
|
GRUB_MOD_FINI (tpm)
|
|
{
|
|
grub_verifier_unregister (&grub_tpm_verifier);
|
|
+ grub_unregister_extcmd (cmd);
|
|
}
|