Accepting request 1032598 from Base:System
OBS-URL: https://build.opensuse.org/request/show/1032598 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/grub2?expand=0&rev=272
This commit is contained in:
commit
f981d91789
39
0001-commands-efi-tpm-Refine-the-status-of-log-event.patch
Normal file
39
0001-commands-efi-tpm-Refine-the-status-of-log-event.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From d2c0426b3f0f91b941037263c83859a46ebb0c4f Mon Sep 17 00:00:00 2001
|
||||
From: Lu Ken <ken.lu@intel.com>
|
||||
Date: Wed, 13 Jul 2022 10:06:10 +0800
|
||||
Subject: [PATCH 1/3] commands/efi/tpm: Refine the status of log event
|
||||
|
||||
1. Use macro GRUB_ERR_NONE instead of hard code 0.
|
||||
2. Keep lowercase of the first char for the status string of log event.
|
||||
|
||||
Signed-off-by: Lu Ken <ken.lu@intel.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/efi/tpm.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c
|
||||
index f296b8698..19737b462 100644
|
||||
--- a/grub-core/commands/efi/tpm.c
|
||||
+++ b/grub-core/commands/efi/tpm.c
|
||||
@@ -136,13 +136,13 @@ grub_efi_log_event_status (grub_efi_status_t status)
|
||||
switch (status)
|
||||
{
|
||||
case GRUB_EFI_SUCCESS:
|
||||
- return 0;
|
||||
+ return GRUB_ERR_NONE;
|
||||
case GRUB_EFI_DEVICE_ERROR:
|
||||
- return grub_error (GRUB_ERR_IO, N_("Command failed"));
|
||||
+ return grub_error (GRUB_ERR_IO, N_("command failed"));
|
||||
case GRUB_EFI_INVALID_PARAMETER:
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("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"));
|
||||
+ 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:
|
||||
--
|
||||
2.35.3
|
||||
|
33
0001-crytodisk-fix-cryptodisk-module-looking-up.patch
Normal file
33
0001-crytodisk-fix-cryptodisk-module-looking-up.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From 822f71318a69c150da3ad7df5fe8667dfa6e8069 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 31 Mar 2022 15:45:35 +0800
|
||||
Subject: [PATCH] crytodisk: fix cryptodisk module looking up
|
||||
|
||||
The error "no cryptodisk module can handle this device" may happen even
|
||||
encrypted disk were correctly formatted and required modules were loaded.
|
||||
|
||||
It is casued by missing break to the loop in which cryptodisk modules are
|
||||
iterated to find the one matching target's disk format. With the break
|
||||
statement, the loop will be always ended with testing last cryptodisk module on
|
||||
the list that may not be able to handle the format of encrypted disk's.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 00c44773fb..6d22bf871c 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1021,6 +1021,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
if (!dev)
|
||||
continue;
|
||||
crd = cr;
|
||||
+ break;
|
||||
}
|
||||
|
||||
if (!dev)
|
||||
--
|
||||
2.34.1
|
||||
|
53
0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch
Normal file
53
0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From ebe4ac49e800b18b539564169593ab1c6f163378 Mon Sep 17 00:00:00 2001
|
||||
From: Josselin Poiret via Grub-devel <grub-devel@gnu.org>
|
||||
Date: Tue, 14 Jun 2022 15:47:29 +0200
|
||||
Subject: [PATCH 01/10] devmapper/getroot: Have devmapper recognize LUKS2
|
||||
|
||||
Changes UUID comparisons so that LUKS1 and LUKS2 are both recognized
|
||||
as being LUKS cryptodisks.
|
||||
---
|
||||
grub-core/osdep/devmapper/getroot.c | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/devmapper/getroot.c b/grub-core/osdep/devmapper/getroot.c
|
||||
index 9ba5c98655..2bf4264cf0 100644
|
||||
--- a/grub-core/osdep/devmapper/getroot.c
|
||||
+++ b/grub-core/osdep/devmapper/getroot.c
|
||||
@@ -138,7 +138,8 @@ grub_util_get_dm_abstraction (const char *os_dev)
|
||||
grub_free (uuid);
|
||||
return GRUB_DEV_ABSTRACTION_LVM;
|
||||
}
|
||||
- if (strncmp (uuid, "CRYPT-LUKS1-", 12) == 0)
|
||||
+ if (strncmp (uuid, "CRYPT-LUKS1-", sizeof ("CRYPT-LUKS1-") - 1) == 0
|
||||
+ || strncmp (uuid, "CRYPT-LUKS2-", sizeof ("CRYPT-LUKS2-") - 1) == 0)
|
||||
{
|
||||
grub_free (uuid);
|
||||
return GRUB_DEV_ABSTRACTION_LUKS;
|
||||
@@ -179,7 +180,9 @@ grub_util_pull_devmapper (const char *os_dev)
|
||||
grub_util_pull_device (subdev);
|
||||
}
|
||||
}
|
||||
- if (uuid && strncmp (uuid, "CRYPT-LUKS1-", sizeof ("CRYPT-LUKS1-") - 1) == 0
|
||||
+ if (uuid
|
||||
+ && (strncmp (uuid, "CRYPT-LUKS1-", sizeof ("CRYPT-LUKS1-") - 1) == 0
|
||||
+ || strncmp (uuid, "CRYPT-LUKS2-", sizeof ("CRYPT-LUKS2-") - 1) == 0)
|
||||
&& lastsubdev)
|
||||
{
|
||||
char *grdev = grub_util_get_grub_dev (lastsubdev);
|
||||
@@ -253,11 +256,11 @@ grub_util_get_devmapper_grub_dev (const char *os_dev)
|
||||
{
|
||||
char *dash;
|
||||
|
||||
- dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS1-") - 1, '-');
|
||||
+ dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS*-") - 1, '-');
|
||||
if (dash)
|
||||
*dash = 0;
|
||||
grub_dev = grub_xasprintf ("cryptouuid/%s",
|
||||
- uuid + sizeof ("CRYPT-LUKS1-") - 1);
|
||||
+ uuid + sizeof ("CRYPT-LUKS*-") - 1);
|
||||
grub_free (uuid);
|
||||
return grub_dev;
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,32 @@
|
||||
From grub-devel-bounces@gnu.org Thu Aug 25 08:11:08 2022
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 25 Aug 2022 14:05:01 +0800
|
||||
Subject: [PATCH] grub-install: set point of no return for powerpc-ieee1275
|
||||
install
|
||||
|
||||
The point of no return is used to define a point where no change should
|
||||
be reverted in a wake of fatal error that consequently aborts the
|
||||
process. The powerpc-ieee1275 install apparently missed this point of no
|
||||
return defintion that newly installed modules could be inadvertently
|
||||
reverted after successful image embedding so that boot failure is
|
||||
incurred due to inconsistent state.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
[iluceno@suse.de: Backported to SLES-15-SP4]
|
||||
Signed-off-by: Ismael Luceno <iluceno@suse.de>
|
||||
---
|
||||
util/grub-install.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
Index: grub-2.06/util/grub-install.c
|
||||
===================================================================
|
||||
--- grub-2.06.orig/util/grub-install.c
|
||||
+++ grub-2.06/util/grub-install.c
|
||||
@@ -2160,6 +2160,7 @@ main (int argc, char *argv[])
|
||||
{
|
||||
grub_util_error ("%s", _("failed to copy Grub to the PReP partition"));
|
||||
}
|
||||
+ grub_set_install_backup_ponr ();
|
||||
|
||||
if ((signed_grub_mode >= SIGNED_GRUB_FORCE) || ((signed_grub_mode == SIGNED_GRUB_AUTO) && (ppc_sb_state > 0)))
|
||||
{
|
239
0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch
Normal file
239
0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch
Normal file
@ -0,0 +1,239 @@
|
||||
From f86bd28391e6d92f8084f0b789ba4a8f6d789dfa 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 1/2] 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>
|
||||
---
|
||||
docs/grub.texi | 3 +-
|
||||
grub-core/Makefile.core.def | 7 ++
|
||||
grub-core/commands/ieee1275/ibmvtpm.c | 152 ++++++++++++++++++++++++++
|
||||
include/grub/ieee1275/ieee1275.h | 3 +
|
||||
4 files changed, 164 insertions(+), 1 deletion(-)
|
||||
create mode 100644 grub-core/commands/ieee1275/ibmvtpm.c
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 4504bcabe..026aacacf 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -6204,7 +6204,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 cee596872..54733425c 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1141,6 +1141,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..e68b8448b
|
||||
--- /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 591f4f12c..8a621af7c 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;
|
||||
--
|
||||
2.35.3
|
||||
|
250
0001-ieee1275-add-support-for-NVMeoFC.patch
Normal file
250
0001-ieee1275-add-support-for-NVMeoFC.patch
Normal file
@ -0,0 +1,250 @@
|
||||
From c125cb45a7885d7bf168a05cfa4da3e681244649 Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegodo@br.ibm.com>
|
||||
Date: Tue, 15 Feb 2022 13:11:48 -0500
|
||||
Subject: [PATCH 1/4] ieee1275: add support for NVMeoFC
|
||||
|
||||
Implements the functions to scan and discovery of NVMeoFC.
|
||||
---
|
||||
grub-core/disk/ieee1275/ofdisk.c | 217 ++++++++++++++++++++++++++++++-
|
||||
1 file changed, 213 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
||||
index 410f4b849..852bb95be 100644
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -206,12 +206,10 @@ dev_iterate_real (const char *name, const char *path)
|
||||
return;
|
||||
}
|
||||
|
||||
+
|
||||
static void
|
||||
-dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
+dev_iterate_fcp_disks(const struct grub_ieee1275_devalias *alias)
|
||||
{
|
||||
- if (grub_strcmp (alias->type, "fcp") == 0)
|
||||
- {
|
||||
-
|
||||
/* If we are dealing with fcp devices, we need
|
||||
* to find the WWPNs and LUNs to iterate them */
|
||||
grub_ieee1275_ihandle_t ihandle;
|
||||
@@ -323,6 +321,217 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
grub_free (buf);
|
||||
return;
|
||||
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+dev_iterate_fcp_nvmeof (const struct grub_ieee1275_devalias *alias)
|
||||
+{
|
||||
+
|
||||
+
|
||||
+ char *bufptr;
|
||||
+ grub_ieee1275_ihandle_t ihandle;
|
||||
+
|
||||
+
|
||||
+ // Create the structs for the parameters passing to PFW
|
||||
+ struct nvme_args_
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t method;
|
||||
+ grub_ieee1275_cell_t ihandle;
|
||||
+ grub_ieee1275_cell_t catch_result;
|
||||
+ grub_ieee1275_cell_t nentries;
|
||||
+ grub_ieee1275_cell_t table;
|
||||
+ } nvme_discovery_controllers_args, nvme_controllers_args, nvme_namespaces_args;
|
||||
+
|
||||
+
|
||||
+ // Create the structs for the results from PFW
|
||||
+
|
||||
+ struct discovery_controllers_table_struct_
|
||||
+ {
|
||||
+ grub_uint64_t table[256];
|
||||
+ grub_uint32_t len;
|
||||
+ } discovery_controllers_table;
|
||||
+
|
||||
+ /* struct nvme_controllers_table_entry
|
||||
+ * this the return of nvme-controllers method tables, containing:
|
||||
+ * - 2-byte controller ID
|
||||
+ * - 256-byte transport address string
|
||||
+ * - 256-byte field containing null-terminated NVM subsystem NQN string up to 223 characters
|
||||
+ */
|
||||
+ struct nvme_controllers_table_entry_
|
||||
+ {
|
||||
+ grub_uint16_t id;
|
||||
+ char wwpn[256];
|
||||
+ char nqn[256];
|
||||
+ };
|
||||
+
|
||||
+ struct nvme_controllers_table_entry_* nvme_controllers_table = grub_malloc(sizeof(struct nvme_controllers_table_entry_)*256);
|
||||
+
|
||||
+ grub_uint32_t nvme_controllers_table_entries;
|
||||
+
|
||||
+ struct nvme_controllers_table_entry_real
|
||||
+ {
|
||||
+ grub_uint16_t id;
|
||||
+ char wwpn[256];
|
||||
+ char nqn[256];
|
||||
+ };
|
||||
+
|
||||
+ /* Allocate memory for building the NVMeoF path */
|
||||
+ char *buf = grub_malloc (grub_strlen (alias->path) + 512);
|
||||
+ if (!buf)
|
||||
+ {
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Copy the alias->path to buf so we can work with */
|
||||
+ bufptr = grub_stpcpy (buf, alias->path);
|
||||
+ grub_snprintf (bufptr, 32, "/nvme-of");
|
||||
+
|
||||
+ /*
|
||||
+ * Open the nvme-of layer
|
||||
+ * Ex. /pci@bus/fibre-channel@@dev,func/nvme-of
|
||||
+ */
|
||||
+ if(grub_ieee1275_open (buf, &ihandle))
|
||||
+ {
|
||||
+ grub_dprintf("disk", "failed to open the disk while iterating FCP disk path=%s\n", buf);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Call to nvme-discovery-controllers method from the nvme-of layer
|
||||
+ * to get a list of the NVMe discovery controllers per the binding
|
||||
+ */
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&nvme_discovery_controllers_args.common, "call-method", 2, 2);
|
||||
+ nvme_discovery_controllers_args.method = (grub_ieee1275_cell_t) "nvme-discovery-controllers";
|
||||
+ nvme_discovery_controllers_args.ihandle = ihandle;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_discovery_controllers_args) == -1)
|
||||
+ {
|
||||
+ grub_dprintf("disk", "failed to get the targets while iterating FCP disk path=%s\n", buf);
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* After closing the device, the info is lost. So lets copy each buffer in the buffers table */
|
||||
+
|
||||
+ discovery_controllers_table.len = (grub_uint32_t) nvme_discovery_controllers_args.nentries;
|
||||
+
|
||||
+ unsigned int i=0;
|
||||
+ for(i = 0; i < discovery_controllers_table.len; i++){
|
||||
+ discovery_controllers_table.table[i] = ((grub_uint64_t*)nvme_discovery_controllers_args.table)[i];
|
||||
+ }
|
||||
+
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+
|
||||
+ grub_dprintf("ofdisk","NVMeoF: Found %d discovery controllers\n",discovery_controllers_table.len);
|
||||
+
|
||||
+ /* For each nvme discovery controller */
|
||||
+ int current_buffer_index;
|
||||
+ for(current_buffer_index = 0; current_buffer_index < (int) discovery_controllers_table.len; current_buffer_index++){
|
||||
+
|
||||
+
|
||||
+ grub_snprintf (bufptr, 64, "/nvme-of/controller@%" PRIxGRUB_UINT64_T ",ffff",
|
||||
+ discovery_controllers_table.table[current_buffer_index]);
|
||||
+
|
||||
+ grub_dprintf("ofdisk","nvmeof controller=%s\n",buf);
|
||||
+
|
||||
+ if(grub_ieee1275_open (buf, &ihandle))
|
||||
+ {
|
||||
+ grub_dprintf("ofdisk", "failed to open the disk while getting nvme-controllers path=%s\n", buf);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&nvme_controllers_args.common, "call-method", 2, 2);
|
||||
+ nvme_controllers_args.method = (grub_ieee1275_cell_t) "nvme-controllers";
|
||||
+ nvme_controllers_args.ihandle = ihandle;
|
||||
+ nvme_controllers_args.catch_result = 0;
|
||||
+
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_controllers_args) == -1)
|
||||
+ {
|
||||
+ grub_dprintf("ofdisk", "failed to get the nvme-controllers while iterating FCP disk path\n");
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ /* Copy the buffer list to nvme_controllers_table */
|
||||
+ nvme_controllers_table_entries = ((grub_uint32_t) nvme_controllers_args.nentries);
|
||||
+ struct nvme_controllers_table_entry_* nvme_controllers_table_ = (struct nvme_controllers_table_entry_*) nvme_controllers_args.table;
|
||||
+
|
||||
+ for(i = 0; i < nvme_controllers_table_entries; i++){
|
||||
+ nvme_controllers_table[i].id = (grub_uint16_t) nvme_controllers_table_[i].id;
|
||||
+ grub_strcpy(nvme_controllers_table[i].wwpn, nvme_controllers_table_[i].wwpn);
|
||||
+ grub_strcpy(nvme_controllers_table[i].nqn, nvme_controllers_table_[i].nqn);
|
||||
+ }
|
||||
+
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+
|
||||
+ int nvme_controller_index;
|
||||
+ int bufptr_pos2;
|
||||
+ grub_dprintf("ofdisk","NVMeoF: found %d nvme controllers\n",(int) nvme_controllers_args.nentries);
|
||||
+
|
||||
+ /* For each nvme controller */
|
||||
+ for(nvme_controller_index = 0; nvme_controller_index < (int) nvme_controllers_args.nentries; nvme_controller_index++){
|
||||
+ /* Open the nvme controller
|
||||
+ * /pci@bus/fibre-channel@dev,func/nvme-of/controller@transport-addr,ctlr-id:nqn=tgt-subsystem-nqn
|
||||
+ */
|
||||
+
|
||||
+ bufptr_pos2 = grub_snprintf (bufptr, 512, "/nvme-of/controller@%s,ffff:nqn=%s",
|
||||
+ nvme_controllers_table[nvme_controller_index].wwpn, nvme_controllers_table[nvme_controller_index].nqn);
|
||||
+
|
||||
+ grub_dprintf("ofdisk","NVMeoF: nvmeof controller=%s\n",buf);
|
||||
+
|
||||
+ if(grub_ieee1275_open (buf, &ihandle)){
|
||||
+ grub_dprintf("ofdisk","failed to open the path=%s\n",buf);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&nvme_namespaces_args.common, "call-method", 2, 2);
|
||||
+ nvme_namespaces_args.method = (grub_ieee1275_cell_t) "get-namespace-list";
|
||||
+ nvme_namespaces_args.ihandle = ihandle;
|
||||
+ nvme_namespaces_args.catch_result = 0;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_namespaces_args) == -1)
|
||||
+ {
|
||||
+ grub_dprintf("ofdisk", "failed to get the nvme-namespace-list while iterating FCP disk path\n");
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ grub_uint32_t *namespaces = (grub_uint32_t*) nvme_namespaces_args.table;
|
||||
+ grub_dprintf("ofdisk","NVMeoF: found %d namespaces\n",(int)nvme_namespaces_args.nentries);
|
||||
+
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+
|
||||
+ grub_uint32_t namespace_index = 0;
|
||||
+ for(namespace_index=0; namespace_index < nvme_namespaces_args.nentries; namespace_index++){
|
||||
+ grub_snprintf (bufptr+bufptr_pos2, 512, "/namespace@%"PRIxGRUB_UINT32_T,namespaces[namespace_index]);
|
||||
+ grub_dprintf("ofdisk","NVMeoF: namespace=%s\n",buf);
|
||||
+ dev_iterate_real(buf,buf);
|
||||
+ }
|
||||
+
|
||||
+ dev_iterate_real(buf,buf);
|
||||
+ }
|
||||
+ }
|
||||
+ grub_free(buf);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
+{
|
||||
+ if (grub_strcmp (alias->type, "fcp") == 0)
|
||||
+ {
|
||||
+ // Iterate disks
|
||||
+ dev_iterate_fcp_disks(alias);
|
||||
+
|
||||
+ // Iterate NVMeoF
|
||||
+ dev_iterate_fcp_nvmeof(alias);
|
||||
+
|
||||
}
|
||||
else if (grub_strcmp (alias->type, "vscsi") == 0)
|
||||
{
|
||||
--
|
||||
2.35.3
|
||||
|
32
0001-kern-efi-mm-Enlarge-the-default-heap-size.patch
Normal file
32
0001-kern-efi-mm-Enlarge-the-default-heap-size.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 3e08d9afd273b5dade84fec5f7f17113c47b6b75 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Fri, 2 Sep 2022 11:26:39 +0800
|
||||
Subject: [PATCH 1/2] kern/efi/mm: Enlarge the default heap size
|
||||
|
||||
The default heap size (0x100000, 1MB) is not enough for the
|
||||
openSUSE/SUSE theme, and the additional dynamical allocation of memory
|
||||
regions significantly slows down the loading of the grub2 menu theme.
|
||||
This commit increases the default heap size to 0x2000000, 32MB, and this
|
||||
should be enough to cover the theme files.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/kern/efi/mm.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
|
||||
index 48380d3..70d3e3d 100644
|
||||
--- a/grub-core/kern/efi/mm.c
|
||||
+++ b/grub-core/kern/efi/mm.c
|
||||
@@ -39,7 +39,7 @@
|
||||
#define MEMORY_MAP_SIZE 0x3000
|
||||
|
||||
/* The default heap size for GRUB itself in bytes. */
|
||||
-#define DEFAULT_HEAP_SIZE 0x100000
|
||||
+#define DEFAULT_HEAP_SIZE 0x2000000
|
||||
|
||||
static void *finish_mmap_buf = 0;
|
||||
static grub_efi_uintn_t finish_mmap_size = 0;
|
||||
--
|
||||
2.35.3
|
||||
|
182
0001-linux-fix-efi_relocate_kernel-failure.patch
Normal file
182
0001-linux-fix-efi_relocate_kernel-failure.patch
Normal file
@ -0,0 +1,182 @@
|
||||
From 80487d82ee1c179c01fad1a23f26fcca79c0ace5 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 26 Sep 2022 12:04:41 +0800
|
||||
Subject: [PATCH] linux: fix efi_relocate_kernel failure
|
||||
|
||||
With the dynamic allocated heap in new memory manager, it could use up all
|
||||
usable memory with no reservation on subsequent kernel loading leading to
|
||||
following error:
|
||||
|
||||
EFI stub: ERROR: Failed to allocate usable memory for kernel
|
||||
EFI stub: ERROR: efi_relocate_kernel() failed!
|
||||
EFI stub: ERROR: efi_main failed!
|
||||
|
||||
The patch tries to returning the memory pages allocated by grub to the firmware
|
||||
before handing over to linux kernel. This could eliminate the worry that we
|
||||
have no limited amount of memory exclusively set for grub to guarentee the
|
||||
memory requirement for booting subsequent component can be met.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.am | 7 +++++++
|
||||
grub-core/Makefile.core.def | 2 +-
|
||||
grub-core/loader/efi/linux.c | 16 ++++++++++++++++
|
||||
grub-core/loader/i386/efi/linux.c | 13 ++++++++++---
|
||||
4 files changed, 34 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index dc07ba6f8..3b1f101fd 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -124,6 +124,7 @@ if COND_i386_efi
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
|
||||
@@ -185,6 +186,7 @@ if COND_x86_64_efi
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
@@ -194,6 +196,7 @@ endif
|
||||
if COND_ia64_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
endif
|
||||
|
||||
@@ -281,6 +284,7 @@ endif
|
||||
if COND_arm_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
endif
|
||||
@@ -288,18 +292,21 @@ endif
|
||||
if COND_arm64_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
endif
|
||||
|
||||
if COND_riscv32_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
endif
|
||||
|
||||
if COND_riscv64_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
|
||||
endif
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 211d2166b..a8c5684dd 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -392,6 +392,7 @@ kernel = {
|
||||
extra_dist = kern/i386/realmode.S;
|
||||
extra_dist = boot/i386/pc/lzma_decode.S;
|
||||
extra_dist = kern/mips/cache_flush.S;
|
||||
+ efi = loader/efi/linux.c;
|
||||
};
|
||||
|
||||
program = {
|
||||
@@ -1855,7 +1856,6 @@ module = {
|
||||
riscv64 = loader/riscv/linux.c;
|
||||
emu = loader/emu/linux.c;
|
||||
common = loader/linux.c;
|
||||
- efi = loader/efi/linux.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
|
||||
index 9265cf420..6ee0ca966 100644
|
||||
--- a/grub-core/loader/efi/linux.c
|
||||
+++ b/grub-core/loader/efi/linux.c
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/efi/pe32.h>
|
||||
#include <grub/efi/linux.h>
|
||||
+#include <grub/kernel.h>
|
||||
+#include <grub/loader.h>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
@@ -38,6 +40,8 @@ grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset,
|
||||
int offset = 0;
|
||||
|
||||
#ifdef __x86_64__
|
||||
+ grub_efi_simple_text_output_interface_t *o;
|
||||
+ o = grub_efi_system_table->con_out;
|
||||
offset = 512;
|
||||
#endif
|
||||
|
||||
@@ -55,9 +59,21 @@ grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset,
|
||||
grub_dprintf ("linux", "kernel_addr: %p handover_offset: %p params: %p\n",
|
||||
kernel_addr, (void *)(grub_efi_uintn_t)handover_offset, kernel_params);
|
||||
hf = (handover_func)((char *)kernel_addr + handover_offset + offset);
|
||||
+#ifdef __x86_64__
|
||||
+ grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
|
||||
+#endif
|
||||
hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
||||
|
||||
+#ifdef __x86_64__
|
||||
+ efi_call_2 (o->output_string, o, L"cannot boot linux kernel via efi handover\r\n"
|
||||
+ L"rebooting in 5 seconds... *\r\n");
|
||||
+ efi_call_1 (grub_efi_system_table->boot_services->stall, 5000000);
|
||||
+ efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
|
||||
+ GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
|
||||
+ for (;;) ;
|
||||
+#else
|
||||
return GRUB_ERR_BUG;
|
||||
+#endif
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index 6b06a8f2f..b9b0d4a5f 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -90,6 +90,8 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
|
||||
{
|
||||
grub_uint64_t max = max_addresses[i].addr;
|
||||
grub_efi_uintn_t pages;
|
||||
+ grub_efi_status_t status;
|
||||
+ grub_efi_boot_services_t *b;
|
||||
|
||||
/*
|
||||
* When we're *not* loading the kernel, or >4GB allocations aren't
|
||||
@@ -104,9 +106,14 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
|
||||
pages, (void *)(grub_addr_t)max);
|
||||
|
||||
prev_max = max;
|
||||
- addr = grub_efi_allocate_pages_real (max, pages,
|
||||
- max_addresses[i].alloc_type,
|
||||
- GRUB_EFI_LOADER_DATA);
|
||||
+ b = grub_efi_system_table->boot_services;
|
||||
+ status = efi_call_4 (b->allocate_pages, max_addresses[i].alloc_type, GRUB_EFI_LOADER_DATA, pages, &max);
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+ max = 0;
|
||||
+ }
|
||||
+ addr = (void *) ((grub_addr_t) max);
|
||||
if (addr)
|
||||
grub_dprintf ("linux", "Allocated at %p\n", addr);
|
||||
}
|
||||
--
|
||||
2.37.3
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 8eae4c33a32d9951641e289d2809a92a223b1642 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
Date: Thu, 9 Dec 2021 11:14:50 -0600
|
||||
Subject: [PATCH 01/14] luks2: Add debug message to align with luks and geli
|
||||
modules
|
||||
|
||||
Signed-off-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/disk/luks2.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
|
||||
index 371a53b837..fea196dd4a 100644
|
||||
--- a/grub-core/disk/luks2.c
|
||||
+++ b/grub-core/disk/luks2.c
|
||||
@@ -370,7 +370,10 @@ luks2_scan (grub_disk_t disk, const char *check_uuid, int check_boot)
|
||||
uuid[j] = '\0';
|
||||
|
||||
if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0)
|
||||
- return NULL;
|
||||
+ {
|
||||
+ grub_dprintf ("luks2", "%s != %s\n", uuid, check_uuid);
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
cryptodisk = grub_zalloc (sizeof (*cryptodisk));
|
||||
if (!cryptodisk)
|
||||
--
|
||||
2.34.1
|
||||
|
133
0001-mm-Allow-dynamically-requesting-additional-memory-re.patch
Normal file
133
0001-mm-Allow-dynamically-requesting-additional-memory-re.patch
Normal file
@ -0,0 +1,133 @@
|
||||
From 23bca58a68264657f176885c3564d07c9938b7f6 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
Date: Thu, 21 Apr 2022 15:24:18 +1000
|
||||
Subject: [PATCH 1/5] mm: Allow dynamically requesting additional memory
|
||||
regions
|
||||
|
||||
Currently, all platforms will set up their heap on initialization of the
|
||||
platform code. While this works mostly fine, it poses some limitations
|
||||
on memory management on us. Most notably, allocating big chunks of
|
||||
memory in the gigabyte range would require us to pre-request this many
|
||||
bytes from the firmware and add it to the heap from the beginning on
|
||||
some platforms like EFI. As this isn't needed for most configurations,
|
||||
it is inefficient and may even negatively impact some usecases when,
|
||||
e.g., chainloading. Nonetheless, allocating big chunks of memory is
|
||||
required sometimes, where one example is the upcoming support for the
|
||||
Argon2 key derival function in LUKS2.
|
||||
|
||||
In order to avoid pre-allocating big chunks of memory, this commit
|
||||
implements a runtime mechanism to add more pages to the system. When
|
||||
a given allocation cannot be currently satisfied, we'll call a given
|
||||
callback set up by the platform's own memory management subsystem,
|
||||
asking it to add a memory area with at least "n" bytes. If this
|
||||
succeeds, we retry searching for a valid memory region, which should
|
||||
now succeed.
|
||||
|
||||
If this fails, we try asking for "n" bytes, possibly spread across
|
||||
multiple regions, in hopes that region merging means that we end up
|
||||
with enough memory for things to work out.
|
||||
|
||||
Signed-off-by: Patrick Steinhardt <ps@pks.im>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Patrick Steinhardt <ps@pks.im>
|
||||
---
|
||||
grub-core/kern/mm.c | 30 ++++++++++++++++++++++++++++++
|
||||
include/grub/mm.h | 18 ++++++++++++++++++
|
||||
2 files changed, 48 insertions(+)
|
||||
|
||||
diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c
|
||||
index 5c0a624..0bd9f75 100644
|
||||
--- a/grub-core/kern/mm.c
|
||||
+++ b/grub-core/kern/mm.c
|
||||
@@ -28,6 +28,9 @@
|
||||
- multiple regions may be used as free space. They may not be
|
||||
contiguous.
|
||||
|
||||
+ - if existing regions are insufficient to satisfy an allocation, a new
|
||||
+ region can be requested from firmware.
|
||||
+
|
||||
Regions are managed by a singly linked list, and the meta information is
|
||||
stored in the beginning of each region. Space after the meta information
|
||||
is used to allocate memory.
|
||||
@@ -77,6 +80,7 @@
|
||||
|
||||
|
||||
grub_mm_region_t grub_mm_base;
|
||||
+grub_mm_add_region_func_t grub_mm_add_region_fn;
|
||||
|
||||
/* Get a header from the pointer PTR, and set *P and *R to a pointer
|
||||
to the header and a pointer to its region, respectively. PTR must
|
||||
@@ -364,6 +368,32 @@ grub_memalign (grub_size_t align, grub_size_t size)
|
||||
goto again;
|
||||
#endif
|
||||
|
||||
+ case 1:
|
||||
+ /* Request additional pages, contiguous */
|
||||
+ count++;
|
||||
+
|
||||
+ if (grub_mm_add_region_fn != NULL &&
|
||||
+ grub_mm_add_region_fn (size, GRUB_MM_ADD_REGION_CONSECUTIVE) == GRUB_ERR_NONE)
|
||||
+ goto again;
|
||||
+
|
||||
+ /* fallthrough */
|
||||
+
|
||||
+ case 2:
|
||||
+ /* Request additional pages, anything at all */
|
||||
+ count++;
|
||||
+
|
||||
+ if (grub_mm_add_region_fn != NULL)
|
||||
+ {
|
||||
+ /*
|
||||
+ * Try again even if this fails, in case it was able to partially
|
||||
+ * satisfy the request
|
||||
+ */
|
||||
+ grub_mm_add_region_fn (size, GRUB_MM_ADD_REGION_NONE);
|
||||
+ goto again;
|
||||
+ }
|
||||
+
|
||||
+ /* fallthrough */
|
||||
+
|
||||
default:
|
||||
break;
|
||||
}
|
||||
diff --git a/include/grub/mm.h b/include/grub/mm.h
|
||||
index 1754635..67faebf 100644
|
||||
--- a/include/grub/mm.h
|
||||
+++ b/include/grub/mm.h
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef GRUB_MM_H
|
||||
#define GRUB_MM_H 1
|
||||
|
||||
+#include <grub/err.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <config.h>
|
||||
@@ -28,6 +29,23 @@
|
||||
# define NULL ((void *) 0)
|
||||
#endif
|
||||
|
||||
+#define GRUB_MM_ADD_REGION_NONE 0
|
||||
+#define GRUB_MM_ADD_REGION_CONSECUTIVE (1 << 0)
|
||||
+
|
||||
+/*
|
||||
+ * Function used to request memory regions of `grub_size_t` bytes. The second
|
||||
+ * parameter is a bitfield of `GRUB_MM_ADD_REGION` flags.
|
||||
+ */
|
||||
+typedef grub_err_t (*grub_mm_add_region_func_t) (grub_size_t, unsigned int);
|
||||
+
|
||||
+/*
|
||||
+ * Set this function pointer to enable adding memory-regions at runtime in case
|
||||
+ * a memory allocation cannot be satisfied with existing regions.
|
||||
+ */
|
||||
+#ifndef GRUB_MACHINE_EMU
|
||||
+extern grub_mm_add_region_func_t EXPORT_VAR(grub_mm_add_region_fn);
|
||||
+#endif
|
||||
+
|
||||
void grub_mm_init_region (void *addr, grub_size_t size);
|
||||
void *EXPORT_FUNC(grub_malloc) (grub_size_t size);
|
||||
void *EXPORT_FUNC(grub_zalloc) (grub_size_t size);
|
||||
--
|
||||
2.35.3
|
||||
|
88
0001-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch
Normal file
88
0001-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch
Normal file
@ -0,0 +1,88 @@
|
||||
From 12378be5243c1c02ce28de2e5703e87197c69157 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 29 Aug 2022 11:28:28 +0800
|
||||
Subject: [PATCH] tpm: Disable tpm verifier if tpm is not present
|
||||
|
||||
This helps to prevent out of memory error when reading large files via disablig
|
||||
tpm device as verifier has to read all content into memory in one chunk to
|
||||
measure the hash and extend to tpm.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/efi/tpm.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||
grub-core/commands/tpm.c | 4 ++++
|
||||
include/grub/tpm.h | 1 +
|
||||
3 files changed, 42 insertions(+)
|
||||
|
||||
--- a/grub-core/commands/efi/tpm.c
|
||||
+++ b/grub-core/commands/efi/tpm.c
|
||||
@@ -349,3 +349,40 @@
|
||||
|
||||
return result;
|
||||
}
|
||||
+
|
||||
+int
|
||||
+grub_tpm_present ()
|
||||
+{
|
||||
+ 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)
|
||||
+ {
|
||||
+ grub_efi_tpm_protocol_t *tpm;
|
||||
+
|
||||
+ tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid,
|
||||
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
+ if (!tpm)
|
||||
+ {
|
||||
+ grub_dprintf ("tpm", "Cannot open TPM protocol\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return grub_tpm1_present (tpm);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ grub_efi_tpm2_protocol_t *tpm;
|
||||
+
|
||||
+ tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
|
||||
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
+ if (!tpm)
|
||||
+ {
|
||||
+ grub_dprintf ("tpm", "Cannot open TPM protocol\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return grub_tpm2_present (tpm);
|
||||
+ }
|
||||
+}
|
||||
--- a/grub-core/commands/tpm.c
|
||||
+++ b/grub-core/commands/tpm.c
|
||||
@@ -291,6 +291,8 @@
|
||||
|
||||
GRUB_MOD_INIT (tpm)
|
||||
{
|
||||
+ if (!grub_tpm_present())
|
||||
+ return;
|
||||
grub_verifier_register (&grub_tpm_verifier);
|
||||
|
||||
cmd = grub_register_extcmd ("tpm_record_pcrs", grub_tpm_record_pcrs, 0,
|
||||
@@ -301,6 +303,8 @@
|
||||
|
||||
GRUB_MOD_FINI (tpm)
|
||||
{
|
||||
+ if (!grub_tpm_present())
|
||||
+ return;
|
||||
grub_verifier_unregister (&grub_tpm_verifier);
|
||||
grub_unregister_extcmd (cmd);
|
||||
}
|
||||
--- a/include/grub/tpm.h
|
||||
+++ b/include/grub/tpm.h
|
||||
@@ -44,5 +44,6 @@
|
||||
grub_uint8_t pcr, const char *description);
|
||||
struct grub_tpm_digest *grub_tpm_read_pcr (grub_uint8_t index, const char *algo);
|
||||
void grub_tpm_digest_free (struct grub_tpm_digest *d);
|
||||
+int grub_tpm_present (void);
|
||||
|
||||
#endif
|
@ -0,0 +1,40 @@
|
||||
From 1f41f020f73131574cd7aee4e0e09d4c56277d1e Mon Sep 17 00:00:00 2001
|
||||
From: Lu Ken <ken.lu@intel.com>
|
||||
Date: Wed, 13 Jul 2022 10:06:11 +0800
|
||||
Subject: [PATCH 2/3] commands/efi/tpm: Use grub_strcpy() instead of
|
||||
grub_memcpy()
|
||||
|
||||
The event description is a string, so using grub_strcpy() is cleaner than
|
||||
using grub_memcpy().
|
||||
|
||||
Signed-off-by: Lu Ken <ken.lu@intel.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/efi/tpm.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c
|
||||
index 19737b462..e032617d8 100644
|
||||
--- a/grub-core/commands/efi/tpm.c
|
||||
+++ b/grub-core/commands/efi/tpm.c
|
||||
@@ -177,7 +177,7 @@ grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
|
||||
event->PCRIndex = pcr;
|
||||
event->EventType = EV_IPL;
|
||||
event->EventSize = grub_strlen (description) + 1;
|
||||
- grub_memcpy (event->Event, description, event->EventSize);
|
||||
+ grub_strcpy ((char *) event->Event, description);
|
||||
|
||||
algorithm = TCG_ALG_SHA;
|
||||
status = efi_call_7 (tpm->log_extend_event, tpm, (grub_addr_t) buf, (grub_uint64_t) size,
|
||||
@@ -299,7 +299,7 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
|
||||
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);
|
||||
+ grub_strcpy ((char *) event->Event, description);
|
||||
|
||||
status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, (grub_addr_t) buf,
|
||||
(grub_uint64_t) size, event);
|
||||
--
|
||||
2.35.3
|
||||
|
187
0002-cryptodisk-Refactor-to-discard-have_it-global.patch
Normal file
187
0002-cryptodisk-Refactor-to-discard-have_it-global.patch
Normal file
@ -0,0 +1,187 @@
|
||||
From 4ace73cc192bc63a00f4208b34981a6d91947811 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
Date: Thu, 9 Dec 2021 11:14:51 -0600
|
||||
Subject: [PATCH 02/14] cryptodisk: Refactor to discard have_it global
|
||||
|
||||
The global "have_it" was never used by the crypto-backends, but was used to
|
||||
determine if a crypto-backend successfully mounted a cryptodisk with a given
|
||||
UUID. This is not needed however, because grub_device_iterate() will return
|
||||
1 if and only if grub_cryptodisk_scan_device() returns 1. And
|
||||
grub_cryptodisk_scan_device() will now only return 1 if a search_uuid has
|
||||
been specified and a cryptodisk was successfully setup by a crypto-backend or
|
||||
a cryptodisk of the requested UUID is already open.
|
||||
|
||||
To implement this grub_cryptodisk_scan_device_real() is modified to return
|
||||
a cryptodisk or NULL on failure and having the appropriate grub_errno set to
|
||||
indicated failure. Note that grub_cryptodisk_scan_device_real() will fail now
|
||||
with a new errno GRUB_ERR_BAD_MODULE when none of the cryptodisk backend
|
||||
modules succeed in identifying the source disk.
|
||||
|
||||
With this change grub_device_iterate() will return 1 when a crypto device is
|
||||
successfully decrypted or when the source device has already been successfully
|
||||
opened. Prior to this change, trying to mount an already successfully opened
|
||||
device would trigger an error with the message "no such cryptodisk found",
|
||||
which is at best misleading. The mount should silently succeed in this case,
|
||||
which is what happens with this patch.
|
||||
|
||||
Signed-off-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 56 +++++++++++++++++++++++--------------
|
||||
1 file changed, 35 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 90f82b2d39..9df3d310fe 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -983,7 +983,7 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk)
|
||||
|
||||
#endif
|
||||
|
||||
-static int check_boot, have_it;
|
||||
+static int check_boot;
|
||||
static char *search_uuid;
|
||||
|
||||
static void
|
||||
@@ -995,7 +995,7 @@ cryptodisk_close (grub_cryptodisk_t dev)
|
||||
grub_free (dev);
|
||||
}
|
||||
|
||||
-static grub_err_t
|
||||
+static grub_cryptodisk_t
|
||||
grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
|
||||
{
|
||||
grub_err_t err;
|
||||
@@ -1005,13 +1005,13 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
|
||||
dev = grub_cryptodisk_get_by_source_disk (source);
|
||||
|
||||
if (dev)
|
||||
- return GRUB_ERR_NONE;
|
||||
+ return dev;
|
||||
|
||||
FOR_CRYPTODISK_DEVS (cr)
|
||||
{
|
||||
dev = cr->scan (source, search_uuid, check_boot);
|
||||
if (grub_errno)
|
||||
- return grub_errno;
|
||||
+ return NULL;
|
||||
if (!dev)
|
||||
continue;
|
||||
|
||||
@@ -1019,16 +1019,16 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
|
||||
if (err)
|
||||
{
|
||||
cryptodisk_close (dev);
|
||||
- return err;
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
grub_cryptodisk_insert (dev, name, source);
|
||||
|
||||
- have_it = 1;
|
||||
-
|
||||
- return GRUB_ERR_NONE;
|
||||
+ return dev;
|
||||
}
|
||||
- return GRUB_ERR_NONE;
|
||||
+
|
||||
+ grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device");
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
@@ -1082,8 +1082,10 @@ static int
|
||||
grub_cryptodisk_scan_device (const char *name,
|
||||
void *data __attribute__ ((unused)))
|
||||
{
|
||||
- grub_err_t err;
|
||||
+ int ret = 0;
|
||||
grub_disk_t source;
|
||||
+ grub_cryptodisk_t dev;
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
/* Try to open disk. */
|
||||
source = grub_disk_open (name);
|
||||
@@ -1093,13 +1095,26 @@ grub_cryptodisk_scan_device (const char *name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
- err = grub_cryptodisk_scan_device_real (name, source);
|
||||
+ dev = grub_cryptodisk_scan_device_real (name, source);
|
||||
+ if (dev)
|
||||
+ {
|
||||
+ ret = (search_uuid != NULL && grub_strcasecmp (search_uuid, dev->uuid) == 0);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
|
||||
- grub_disk_close (source);
|
||||
-
|
||||
- if (err)
|
||||
+ /*
|
||||
+ * Do not print error when err is GRUB_ERR_BAD_MODULE to avoid many unhelpful
|
||||
+ * error messages.
|
||||
+ */
|
||||
+ if (grub_errno == GRUB_ERR_BAD_MODULE)
|
||||
+ grub_error_pop ();
|
||||
+
|
||||
+ if (grub_errno != GRUB_ERR_NONE)
|
||||
grub_print_error ();
|
||||
- return have_it && search_uuid ? 1 : 0;
|
||||
+
|
||||
+ cleanup:
|
||||
+ grub_disk_close (source);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -1110,9 +1125,9 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (argc < 1 && !state[1].set && !state[2].set)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
|
||||
|
||||
- have_it = 0;
|
||||
if (state[0].set)
|
||||
{
|
||||
+ int found_uuid;
|
||||
grub_cryptodisk_t dev;
|
||||
|
||||
dev = grub_cryptodisk_get_by_uuid (args[0]);
|
||||
@@ -1125,10 +1140,10 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
|
||||
check_boot = state[2].set;
|
||||
search_uuid = args[0];
|
||||
- grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
|
||||
+ found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
|
||||
search_uuid = NULL;
|
||||
|
||||
- if (!have_it)
|
||||
+ if (!found_uuid)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found");
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -1142,7 +1157,6 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
}
|
||||
else
|
||||
{
|
||||
- grub_err_t err;
|
||||
grub_disk_t disk;
|
||||
grub_cryptodisk_t dev;
|
||||
char *diskname;
|
||||
@@ -1178,13 +1192,13 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
- err = grub_cryptodisk_scan_device_real (diskname, disk);
|
||||
+ dev = grub_cryptodisk_scan_device_real (diskname, disk);
|
||||
|
||||
grub_disk_close (disk);
|
||||
if (disklast)
|
||||
*disklast = ')';
|
||||
|
||||
- return err;
|
||||
+ return (dev == NULL) ? grub_errno : GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
127
0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch
Normal file
127
0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch
Normal file
@ -0,0 +1,127 @@
|
||||
From a25627c13b7e1e6998a14b5dd23b04b28465d737 Mon Sep 17 00:00:00 2001
|
||||
From: Josselin Poiret via Grub-devel <grub-devel@gnu.org>
|
||||
Date: Tue, 14 Jun 2022 15:47:30 +0200
|
||||
Subject: [PATCH 02/10] devmapper/getroot: Set up cheated LUKS2 cryptodisk
|
||||
mount from DM parameters
|
||||
|
||||
This lets a LUKS2 cryptodisk have its cipher and hash filled out,
|
||||
otherwise they wouldn't be initialized if cheat mounted.
|
||||
---
|
||||
grub-core/osdep/devmapper/getroot.c | 91 +++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 90 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/grub-core/osdep/devmapper/getroot.c
|
||||
+++ b/grub-core/osdep/devmapper/getroot.c
|
||||
@@ -51,6 +51,8 @@
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
|
||||
+#include <grub/cryptodisk.h>
|
||||
+
|
||||
static int
|
||||
grub_util_open_dm (const char *os_dev, struct dm_tree **tree,
|
||||
struct dm_tree_node **node)
|
||||
@@ -186,7 +188,6 @@
|
||||
&& lastsubdev)
|
||||
{
|
||||
char *grdev = grub_util_get_grub_dev (lastsubdev);
|
||||
- dm_tree_free (tree);
|
||||
if (grdev)
|
||||
{
|
||||
grub_err_t err;
|
||||
@@ -194,7 +195,95 @@
|
||||
if (err)
|
||||
grub_util_error (_("can't mount encrypted volume `%s': %s"),
|
||||
lastsubdev, grub_errmsg);
|
||||
+ if (strncmp (uuid, "CRYPT-LUKS2-", sizeof ("CRYPT-LUKS2-") - 1) == 0)
|
||||
+ {
|
||||
+ /* set LUKS2 cipher from dm parameters, since it is not
|
||||
+ * possible to determine the correct one without
|
||||
+ * unlocking, as there might be multiple segments.
|
||||
+ */
|
||||
+ grub_disk_t source;
|
||||
+ grub_cryptodisk_t cryptodisk;
|
||||
+ grub_uint64_t start, length;
|
||||
+ char *target_type;
|
||||
+ char *params;
|
||||
+ const char *name;
|
||||
+ char *cipher, *cipher_mode;
|
||||
+ struct dm_task *dmt;
|
||||
+ char *seek_head, *c;
|
||||
+ unsigned int remaining;
|
||||
+
|
||||
+ source = grub_disk_open (grdev);
|
||||
+ cryptodisk = grub_cryptodisk_get_by_source_disk (source);
|
||||
+ grub_disk_close (source);
|
||||
+
|
||||
+ name = dm_tree_node_get_name (node);
|
||||
+
|
||||
+ grub_util_info ("populating parameters of cryptomount `%s' from DM device `%s'",
|
||||
+ uuid, name);
|
||||
+
|
||||
+ dmt = dm_task_create (DM_DEVICE_TABLE);
|
||||
+ if (dmt == 0)
|
||||
+ grub_util_error (_("can't create dm task DM_DEVICE_TABLE"));
|
||||
+ if (dm_task_set_name (dmt, name) == 0)
|
||||
+ grub_util_error (_("can't set dm task name to `%s'"), name);
|
||||
+ if (dm_task_run (dmt) == 0)
|
||||
+ grub_util_error (_("can't run dm task for `%s'"), name);
|
||||
+ /* dm_get_next_target doesn't have any error modes, everything has
|
||||
+ * been handled by dm_task_run.
|
||||
+ */
|
||||
+ dm_get_next_target (dmt, NULL, &start, &length,
|
||||
+ &target_type, ¶ms);
|
||||
+ if (strncmp (target_type, "crypt", sizeof ("crypt")) != 0)
|
||||
+ grub_util_error (_("dm target of type `%s' is not `crypt'"),
|
||||
+ target_type);
|
||||
+
|
||||
+ /* dm target parameters for dm-crypt is
|
||||
+ * <cipher> <key> <iv_offset> <device path> <offset> [<#opt_params> <opt_param1> ...]
|
||||
+ */
|
||||
+ c = params;
|
||||
+ remaining = grub_strlen (c);
|
||||
+
|
||||
+ /* first, get the cipher name from the cipher */
|
||||
+ if (!(seek_head = grub_memchr (c, '-', remaining)))
|
||||
+ grub_util_error (_("can't get cipher from dm-crypt parameters `%s'"),
|
||||
+ params);
|
||||
+ cipher = grub_strndup (c, seek_head - c);
|
||||
+ remaining -= seek_head - c + 1;
|
||||
+ c = seek_head + 1;
|
||||
+
|
||||
+ /* now, the cipher mode */
|
||||
+ if (!(seek_head = grub_memchr (c, ' ', remaining)))
|
||||
+ grub_util_error (_("can't get cipher mode from dm-crypt parameters `%s'"),
|
||||
+ params);
|
||||
+ cipher_mode = grub_strndup (c, seek_head - c);
|
||||
+ remaining -= seek_head - c + 1;
|
||||
+ c = seek_head + 1;
|
||||
+
|
||||
+ err = grub_cryptodisk_setcipher (cryptodisk, cipher, cipher_mode);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_util_error (_("can't set cipher of cryptodisk `%s' to `%s' with mode `%s'"),
|
||||
+ uuid, cipher, cipher_mode);
|
||||
+ }
|
||||
+
|
||||
+ grub_free (cipher);
|
||||
+ grub_free (cipher_mode);
|
||||
+
|
||||
+ /* This is the only hash usable by PBKDF2, and we don't
|
||||
+ * have Argon2 support yet, so set it by default,
|
||||
+ * otherwise grub-probe would miss the required
|
||||
+ * abstraction
|
||||
+ */
|
||||
+ cryptodisk->hash = grub_crypto_lookup_md_by_name ("sha256");
|
||||
+ if (cryptodisk->hash == 0)
|
||||
+ {
|
||||
+ grub_util_error (_("can't lookup hash sha256 by name"));
|
||||
+ }
|
||||
+
|
||||
+ dm_task_destroy (dmt);
|
||||
+ }
|
||||
}
|
||||
+ dm_tree_free (tree);
|
||||
grub_free (grdev);
|
||||
}
|
||||
else
|
73
0002-ieee1275-implement-vec5-for-cas-negotiation.patch
Normal file
73
0002-ieee1275-implement-vec5-for-cas-negotiation.patch
Normal file
@ -0,0 +1,73 @@
|
||||
From 6c7c4007ad621029295797b439158d36d0f62487 Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegodo@linux.vnet.ibm.com>
|
||||
Date: Thu, 25 Aug 2022 11:37:56 -0400
|
||||
Subject: [PATCH 2/2] ieee1275: implement vec5 for cas negotiation
|
||||
|
||||
As a legacy support, if the vector 5 is not implemented, Power
|
||||
Hypervisor will consider the max CPUs as 64 instead 256 currently
|
||||
supported during client-architecture-support negotiation.
|
||||
|
||||
This patch implements the vector 5 and set the MAX CPUs to 256 while
|
||||
setting the others values to 0 (default).
|
||||
|
||||
Signed-off-by: Diego Domingos <diegodo@linux.vnet.ibm.com>
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
grub-core/kern/ieee1275/init.c | 20 +++++++++++++++++++-
|
||||
1 file changed, 19 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index 7d7178d3e..3aa40313f 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -311,6 +311,18 @@ struct option_vector2 {
|
||||
grub_uint8_t max_pft_size;
|
||||
} __attribute__((packed));
|
||||
|
||||
+struct option_vector5 {
|
||||
+ grub_uint8_t byte1;
|
||||
+ grub_uint8_t byte2;
|
||||
+ grub_uint8_t byte3;
|
||||
+ grub_uint8_t cmo;
|
||||
+ grub_uint8_t associativity;
|
||||
+ grub_uint8_t bin_opts;
|
||||
+ grub_uint8_t micro_checkpoint;
|
||||
+ grub_uint8_t reserved0;
|
||||
+ grub_uint32_t max_cpus;
|
||||
+} __attribute__((packed));
|
||||
+
|
||||
struct pvr_entry {
|
||||
grub_uint32_t mask;
|
||||
grub_uint32_t entry;
|
||||
@@ -329,6 +341,8 @@ struct cas_vector {
|
||||
grub_uint16_t vec3;
|
||||
grub_uint8_t vec4_size;
|
||||
grub_uint16_t vec4;
|
||||
+ grub_uint8_t vec5_size;
|
||||
+ struct option_vector5 vec5;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Call ibm,client-architecture-support to try to get more RMA.
|
||||
@@ -349,7 +363,7 @@ grub_ieee1275_ibm_cas (void)
|
||||
} args;
|
||||
struct cas_vector vector = {
|
||||
.pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */
|
||||
- .num_vecs = 4 - 1,
|
||||
+ .num_vecs = 5 - 1,
|
||||
.vec1_size = 0,
|
||||
.vec1 = 0x80, /* ignore */
|
||||
.vec2_size = 1 + sizeof(struct option_vector2) - 2,
|
||||
@@ -360,6 +374,10 @@ grub_ieee1275_ibm_cas (void)
|
||||
.vec3 = 0x00e0, // ask for FP + VMX + DFP but don't halt if unsatisfied
|
||||
.vec4_size = 2 - 1,
|
||||
.vec4 = 0x0001, // set required minimum capacity % to the lowest value
|
||||
+ .vec5_size = 1 + sizeof(struct option_vector5) - 2,
|
||||
+ .vec5 = {
|
||||
+ 0, 0, 0, 0, 0, 0, 0, 0, 256
|
||||
+ }
|
||||
};
|
||||
|
||||
INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2);
|
||||
--
|
||||
2.35.3
|
||||
|
373
0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch
Normal file
373
0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch
Normal file
@ -0,0 +1,373 @@
|
||||
From 9e61624db77e5073961126457f599bc70e877fd1 Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegodo@br.ibm.com>
|
||||
Date: Tue, 15 Mar 2022 15:59:41 -0400
|
||||
Subject: [PATCH 2/4] ieee1275/ofpath: enable NVMeoF logical device translation
|
||||
|
||||
This patch add code to enable the translation of logical devices to the of NVMeoFC paths.
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 260 +++++++++++++++++++++++++++++++--
|
||||
include/grub/util/ofpath.h | 29 ++++
|
||||
2 files changed, 280 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 89beceef4..212782d3f 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -137,7 +137,7 @@ trim_newline (char *path)
|
||||
*end-- = '\0';
|
||||
}
|
||||
|
||||
-#define MAX_DISK_CAT 64
|
||||
+#define MAX_DISK_CAT 512
|
||||
|
||||
static char *
|
||||
find_obppath (const char *sysfs_path_orig)
|
||||
@@ -313,6 +313,69 @@ get_basename(char *p)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+
|
||||
+void
|
||||
+add_filename_to_pile(char *filename, struct ofpath_files_list_root* root){
|
||||
+ struct ofpath_files_list_node* file;
|
||||
+
|
||||
+ file = malloc(sizeof(struct ofpath_files_list_node));
|
||||
+
|
||||
+ file->filename = filename;
|
||||
+
|
||||
+ if(root->first == NULL){
|
||||
+ root->items = 1;
|
||||
+ root->first = file;
|
||||
+ file->next = NULL;
|
||||
+ } else {
|
||||
+ root->items++;
|
||||
+ file->next = root->first;
|
||||
+ root->first = file;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void
|
||||
+find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth){
|
||||
+ struct dirent *ep;
|
||||
+ struct stat statbuf;
|
||||
+ DIR *dp;
|
||||
+
|
||||
+ if(depth > max_depth){
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if((dp = opendir(directory)) == NULL){
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ while((ep = readdir(dp)) != NULL){
|
||||
+
|
||||
+ char* full_path = malloc(1024*sizeof(char));
|
||||
+ snprintf(full_path,1024,"%s/%s",directory,ep->d_name);
|
||||
+
|
||||
+ lstat(full_path,&statbuf);
|
||||
+
|
||||
+ if(S_ISLNK(statbuf.st_mode)){
|
||||
+
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if(!strcmp(ep->d_name,".") || !strcmp(ep->d_name,"..")){
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if(!strcmp(ep->d_name,filename)){
|
||||
+ add_filename_to_pile(full_path, root);
|
||||
+ }
|
||||
+
|
||||
+ find_file(filename, full_path, root, max_depth, depth+1);
|
||||
+
|
||||
+ }
|
||||
+ closedir(dp);
|
||||
+}
|
||||
+
|
||||
+
|
||||
static char *
|
||||
of_path_of_vdisk(const char *sys_devname __attribute__((unused)),
|
||||
const char *device,
|
||||
@@ -351,7 +414,142 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi
|
||||
return ret;
|
||||
}
|
||||
|
||||
-#ifdef __sparc__
|
||||
+char*
|
||||
+of_find_fc_host(char* host_wwpn){
|
||||
+
|
||||
+ FILE* fp;
|
||||
+ char *buf;
|
||||
+ char portname_filename[sizeof("port_name")] = "port_name";
|
||||
+ char devices_path[sizeof("/sys/devices")] = "/sys/devices";
|
||||
+
|
||||
+ struct ofpath_files_list_root* portnames_file_list;
|
||||
+
|
||||
+ portnames_file_list=malloc(sizeof(portnames_file_list));
|
||||
+ portnames_file_list->items=0;
|
||||
+ portnames_file_list->first=NULL;
|
||||
+
|
||||
+ find_file(portname_filename, devices_path, portnames_file_list, 10, 0);
|
||||
+
|
||||
+ struct ofpath_files_list_node* node = portnames_file_list->first;
|
||||
+ while(node != NULL){
|
||||
+ fp = fopen(node->filename,"r");
|
||||
+ buf = malloc(sizeof(char)*512);
|
||||
+ fscanf(fp, "%s", buf);
|
||||
+ fclose(fp);
|
||||
+ if((strcmp(buf,host_wwpn) == 0) && grub_strstr(node->filename, "fc_host")){
|
||||
+ return node->filename;
|
||||
+ }
|
||||
+ node = node->next;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+of_path_get_nvmeof_adapter_info(char* sysfs_path,
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info){
|
||||
+
|
||||
+ FILE *fp;
|
||||
+ char *buf, *buf2, *buf3;
|
||||
+
|
||||
+ nvmeof_info->host_wwpn = malloc(sizeof(char)*256);
|
||||
+ nvmeof_info->target_wwpn = malloc(sizeof(char)*256);
|
||||
+ nvmeof_info->nqn = malloc(sizeof(char)*256);
|
||||
+
|
||||
+ buf = malloc(sizeof(char)*512);
|
||||
+ snprintf(buf,512,"%s/subsysnqn",sysfs_path);
|
||||
+ fp = fopen(buf,"r");
|
||||
+ fscanf(fp, "%s", nvmeof_info->nqn);
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ snprintf(buf,512,"%s/cntlid",sysfs_path);
|
||||
+ fp = fopen(buf,"r");
|
||||
+ fscanf(fp, "%u", &(nvmeof_info->cntlid));
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ //snprintf(buf,512,"%s/nsid",sysfs_path);
|
||||
+ //fp = fopen(buf,"r");
|
||||
+ //fscanf(fp, "%u", &(nvmeof_info->nsid));
|
||||
+ //fclose(fp);
|
||||
+
|
||||
+ snprintf(buf,512,"%s/address",sysfs_path);
|
||||
+ fp = fopen(buf,"r");
|
||||
+ buf2 = malloc(sizeof(char)*512);
|
||||
+ fscanf(fp, "%s", buf2);
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ nvmeof_info->host_wwpn = strrchr(buf2,'-')+1;
|
||||
+
|
||||
+ buf3=strchr(buf2,'-')+1;
|
||||
+ buf3=strchr(buf3,'-')+1;
|
||||
+ nvmeof_info->target_wwpn = buf3;
|
||||
+ buf3 = strchr(nvmeof_info->target_wwpn,',');
|
||||
+ *buf3 = '\0';
|
||||
+
|
||||
+
|
||||
+ free(buf);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+#define MAX_NVME_NSID_DIGITS 6
|
||||
+
|
||||
+static char *
|
||||
+of_path_get_nvme_controller_name_node(const char* devname)
|
||||
+{
|
||||
+ char *controller_node, *end;
|
||||
+
|
||||
+ controller_node = strdup(devname);
|
||||
+
|
||||
+ end = grub_strchr(controller_node+1, 'n');
|
||||
+
|
||||
+ if(end != NULL){
|
||||
+ *end = '\0';
|
||||
+ }
|
||||
+
|
||||
+ return controller_node;
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+of_path_get_nvme_nsid(const char* devname)
|
||||
+{
|
||||
+ unsigned int nsid;
|
||||
+ char *sysfs_path, *buf;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ buf=malloc(sizeof(char)*512);
|
||||
+
|
||||
+ sysfs_path = block_device_get_sysfs_path_and_link (devname);
|
||||
+
|
||||
+ snprintf(buf,512,"%s/%s/nsid",sysfs_path,devname);
|
||||
+ fp = fopen(buf,"r");
|
||||
+ fscanf(fp, "%u", &(nsid));
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ free(sysfs_path);
|
||||
+ free(buf);
|
||||
+
|
||||
+ return nsid;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static char *
|
||||
+nvme_get_syspath(const char *nvmedev)
|
||||
+{
|
||||
+ char *sysfs_path, *controller_node;
|
||||
+ sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
|
||||
+
|
||||
+ if(strstr(sysfs_path,"nvme-subsystem")){
|
||||
+ controller_node = of_path_get_nvme_controller_name_node(nvmedev);
|
||||
+ strcat(sysfs_path,"/");
|
||||
+ strcat(sysfs_path,controller_node);
|
||||
+ sysfs_path = xrealpath(sysfs_path);
|
||||
+ }
|
||||
+
|
||||
+ return sysfs_path;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static char *
|
||||
of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
const char *device,
|
||||
@@ -360,6 +558,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
{
|
||||
char *sysfs_path, *of_path, disk[MAX_DISK_CAT];
|
||||
const char *digit_string, *part_end;
|
||||
+ int chars_written;
|
||||
|
||||
digit_string = trailing_digits (device);
|
||||
part_end = devicenode + strlen (devicenode) - 1;
|
||||
@@ -379,15 +578,61 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
/* Remove the p. */
|
||||
*end = '\0';
|
||||
sscanf (digit_string, "%d", &part);
|
||||
- snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1));
|
||||
- sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
|
||||
+
|
||||
+ sysfs_path = nvme_get_syspath(nvmedev);
|
||||
+
|
||||
+ /* If is a NVMeoF */
|
||||
+ if(strstr(sysfs_path,"nvme-fabrics")){
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info;
|
||||
+ nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
+
|
||||
+ of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info);
|
||||
+
|
||||
+ sysfs_path = of_find_fc_host(nvmeof_info->host_wwpn);
|
||||
+
|
||||
+ chars_written = snprintf(disk,sizeof(disk),"/nvme-of/controller@%s,%x:nqn=%s",
|
||||
+ nvmeof_info->target_wwpn,
|
||||
+ 0xffff,
|
||||
+ nvmeof_info->nqn);
|
||||
+
|
||||
+ unsigned int nsid = of_path_get_nvme_nsid(nvmedev);
|
||||
+
|
||||
+ if(nsid){
|
||||
+ snprintf(disk+chars_written,sizeof(disk) - chars_written,
|
||||
+ "/namespace@%x:%d",nsid, part);
|
||||
+ }
|
||||
+
|
||||
+ } else {
|
||||
+ snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1));
|
||||
+ }
|
||||
free (nvmedev);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We do not have the parition. */
|
||||
- snprintf (disk, sizeof (disk), "/disk@1");
|
||||
- sysfs_path = block_device_get_sysfs_path_and_link (device);
|
||||
+ sysfs_path = nvme_get_syspath (device);
|
||||
+ if(strstr(sysfs_path,"nvme-fabrics")){
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info;
|
||||
+ nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
+
|
||||
+ of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info);
|
||||
+
|
||||
+ sysfs_path = of_find_fc_host(nvmeof_info->host_wwpn);
|
||||
+
|
||||
+ chars_written = snprintf(disk,sizeof(disk),"/nvme-of/controller@%s,%x:nqn=%s",
|
||||
+ nvmeof_info->target_wwpn,
|
||||
+ 0xffff,
|
||||
+ nvmeof_info->nqn);
|
||||
+
|
||||
+ unsigned int nsid = of_path_get_nvme_nsid(device);
|
||||
+ if(nsid){
|
||||
+ snprintf(disk+chars_written,sizeof(disk) - chars_written,
|
||||
+ "/namespace@%x",nsid);
|
||||
+ }
|
||||
+ } else {
|
||||
+ snprintf (disk, sizeof (disk), "/disk@1");
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
of_path = find_obppath (sysfs_path);
|
||||
@@ -398,7 +643,6 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
free (sysfs_path);
|
||||
return of_path;
|
||||
}
|
||||
-#endif
|
||||
|
||||
static void
|
||||
of_fc_port_name(const char *path, const char *subpath, char *port_name)
|
||||
@@ -840,11 +1084,9 @@ grub_util_devname_to_ofpath (const char *sys_devname)
|
||||
/* All the models I've seen have a devalias "floppy".
|
||||
New models have no floppy at all. */
|
||||
ofpath = xstrdup ("floppy");
|
||||
-#ifdef __sparc__
|
||||
else if (device[0] == 'n' && device[1] == 'v' && device[2] == 'm'
|
||||
&& device[3] == 'e')
|
||||
ofpath = of_path_of_nvme (name_buf, device, devnode, devicenode);
|
||||
-#endif
|
||||
else
|
||||
{
|
||||
grub_util_warn (_("unknown device type %s"), device);
|
||||
diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h
|
||||
index b43c523cb..a0ec30620 100644
|
||||
--- a/include/grub/util/ofpath.h
|
||||
+++ b/include/grub/util/ofpath.h
|
||||
@@ -3,4 +3,33 @@
|
||||
|
||||
char *grub_util_devname_to_ofpath (const char *devname);
|
||||
|
||||
+struct ofpath_files_list_node {
|
||||
+ char* filename;
|
||||
+ struct ofpath_files_list_node* next;
|
||||
+};
|
||||
+
|
||||
+struct ofpath_files_list_root {
|
||||
+ int items;
|
||||
+ struct ofpath_files_list_node* first;
|
||||
+};
|
||||
+
|
||||
+struct ofpath_nvmeof_info {
|
||||
+ char* host_wwpn;
|
||||
+ char* target_wwpn;
|
||||
+ char* nqn;
|
||||
+ int cntlid;
|
||||
+ int nsid;
|
||||
+};
|
||||
+
|
||||
+void of_path_get_nvmeof_adapter_info(char* sysfs_path,
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info);
|
||||
+
|
||||
+unsigned int of_path_get_nvme_nsid(const char* devname);
|
||||
+
|
||||
+void add_filename_to_pile(char *filename, struct ofpath_files_list_root* root);
|
||||
+
|
||||
+void find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth);
|
||||
+
|
||||
+char* of_find_fc_host(char* host_wwpn);
|
||||
+
|
||||
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
|
||||
--
|
||||
2.35.3
|
||||
|
106
0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch
Normal file
106
0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From 834cb2ca9ed2d9d7a6926e598accdfe280b615da Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
Date: Thu, 21 Apr 2022 15:24:19 +1000
|
||||
Subject: [PATCH 2/5] kern/efi/mm: Always request a fixed number of pages on
|
||||
init
|
||||
|
||||
When initializing the EFI memory subsystem, we will by default request
|
||||
a quarter of the available memory, bounded by a minimum/maximum value.
|
||||
Given that we're about to extend the EFI memory system to dynamically
|
||||
request additional pages from the firmware as required, this scaling of
|
||||
requested memory based on available memory will not make a lot of sense
|
||||
anymore.
|
||||
|
||||
Remove this logic as a preparatory patch such that we'll instead defer
|
||||
to the runtime memory allocator. Note that ideally, we'd want to change
|
||||
this after dynamic requesting of pages has been implemented for the EFI
|
||||
platform. But because we'll need to split up initialization of the
|
||||
memory subsystem and the request of pages from the firmware, we'd have
|
||||
to duplicate quite some logic at first only to remove it afterwards
|
||||
again. This seems quite pointless, so we instead have patches slightly
|
||||
out of order.
|
||||
|
||||
Signed-off-by: Patrick Steinhardt <ps@pks.im>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Patrick Steinhardt <ps@pks.im>
|
||||
---
|
||||
grub-core/kern/efi/mm.c | 35 +++--------------------------------
|
||||
1 file changed, 3 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
|
||||
index 67a691d..2874522 100644
|
||||
--- a/grub-core/kern/efi/mm.c
|
||||
+++ b/grub-core/kern/efi/mm.c
|
||||
@@ -38,9 +38,8 @@
|
||||
a multiplier of 4KB. */
|
||||
#define MEMORY_MAP_SIZE 0x3000
|
||||
|
||||
-/* The minimum and maximum heap size for GRUB itself. */
|
||||
-#define MIN_HEAP_SIZE 0x100000
|
||||
-#define MAX_HEAP_SIZE (1600 * 0x100000)
|
||||
+/* The default heap size for GRUB itself in bytes. */
|
||||
+#define DEFAULT_HEAP_SIZE 0x100000
|
||||
|
||||
static void *finish_mmap_buf = 0;
|
||||
static grub_efi_uintn_t finish_mmap_size = 0;
|
||||
@@ -514,23 +513,6 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
|
||||
return filtered_desc;
|
||||
}
|
||||
|
||||
-/* Return the total number of pages. */
|
||||
-static grub_efi_uint64_t
|
||||
-get_total_pages (grub_efi_memory_descriptor_t *memory_map,
|
||||
- grub_efi_uintn_t desc_size,
|
||||
- grub_efi_memory_descriptor_t *memory_map_end)
|
||||
-{
|
||||
- grub_efi_memory_descriptor_t *desc;
|
||||
- grub_efi_uint64_t total = 0;
|
||||
-
|
||||
- for (desc = memory_map;
|
||||
- desc < memory_map_end;
|
||||
- desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||
- total += desc->num_pages;
|
||||
-
|
||||
- return total;
|
||||
-}
|
||||
-
|
||||
/* Add memory regions. */
|
||||
static void
|
||||
add_memory_regions (grub_efi_memory_descriptor_t *memory_map,
|
||||
@@ -619,8 +601,6 @@ grub_efi_mm_init (void)
|
||||
grub_efi_memory_descriptor_t *filtered_memory_map_end;
|
||||
grub_efi_uintn_t map_size;
|
||||
grub_efi_uintn_t desc_size;
|
||||
- grub_efi_uint64_t total_pages;
|
||||
- grub_efi_uint64_t required_pages;
|
||||
int mm_status;
|
||||
|
||||
/* Prepare a memory region to store two memory maps. */
|
||||
@@ -660,22 +640,13 @@ grub_efi_mm_init (void)
|
||||
filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map,
|
||||
desc_size, memory_map_end);
|
||||
|
||||
- /* By default, request a quarter of the available memory. */
|
||||
- total_pages = get_total_pages (filtered_memory_map, desc_size,
|
||||
- filtered_memory_map_end);
|
||||
- required_pages = (total_pages >> 2);
|
||||
- if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE))
|
||||
- required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE);
|
||||
- else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE))
|
||||
- required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE);
|
||||
-
|
||||
/* Sort the filtered descriptors, so that GRUB can allocate pages
|
||||
from smaller regions. */
|
||||
sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end);
|
||||
|
||||
/* Allocate memory regions for GRUB's memory management. */
|
||||
add_memory_regions (filtered_memory_map, desc_size,
|
||||
- filtered_memory_map_end, required_pages);
|
||||
+ filtered_memory_map_end, BYTES_TO_PAGES (DEFAULT_HEAP_SIZE));
|
||||
|
||||
#if 0
|
||||
/* For debug. */
|
||||
--
|
||||
2.35.3
|
||||
|
68
0002-mm-Defer-the-disk-cache-invalidation.patch
Normal file
68
0002-mm-Defer-the-disk-cache-invalidation.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From 4284d40799aaf5aab11c690f232ce0a191dcfbdb Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Fri, 16 Sep 2022 10:59:55 +0800
|
||||
Subject: [PATCH 2/2] mm: Defer the disk cache invalidation
|
||||
|
||||
When the heap memory is used up, the memory management code invalidates
|
||||
the disk caches first and then requests the additional memory regioins.
|
||||
Although this could minimize the memory usage, it hurts the loading time
|
||||
since the disk caches may always miss.
|
||||
|
||||
This patch defers the disk cache invalidation to avoid the possible
|
||||
delays.
|
||||
|
||||
Signen-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/kern/mm.c | 22 +++++++---------------
|
||||
1 file changed, 7 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c
|
||||
index 0bd9f75..5280e8c 100644
|
||||
--- a/grub-core/kern/mm.c
|
||||
+++ b/grub-core/kern/mm.c
|
||||
@@ -355,20 +355,6 @@ grub_memalign (grub_size_t align, grub_size_t size)
|
||||
switch (count)
|
||||
{
|
||||
case 0:
|
||||
- /* Invalidate disk caches. */
|
||||
- grub_disk_cache_invalidate_all ();
|
||||
- count++;
|
||||
- goto again;
|
||||
-
|
||||
-#if 0
|
||||
- case 1:
|
||||
- /* Unload unneeded modules. */
|
||||
- grub_dl_unload_unneeded ();
|
||||
- count++;
|
||||
- goto again;
|
||||
-#endif
|
||||
-
|
||||
- case 1:
|
||||
/* Request additional pages, contiguous */
|
||||
count++;
|
||||
|
||||
@@ -378,7 +364,7 @@ grub_memalign (grub_size_t align, grub_size_t size)
|
||||
|
||||
/* fallthrough */
|
||||
|
||||
- case 2:
|
||||
+ case 1:
|
||||
/* Request additional pages, anything at all */
|
||||
count++;
|
||||
|
||||
@@ -394,6 +380,12 @@ grub_memalign (grub_size_t align, grub_size_t size)
|
||||
|
||||
/* fallthrough */
|
||||
|
||||
+ case 2:
|
||||
+ /* Invalidate disk caches. */
|
||||
+ grub_disk_cache_invalidate_all ();
|
||||
+ count++;
|
||||
+ goto again;
|
||||
+
|
||||
default:
|
||||
break;
|
||||
}
|
||||
--
|
||||
2.35.3
|
||||
|
@ -0,0 +1,32 @@
|
||||
From 86fe3bbbf75e62387cc9842654fd6c852e9457a6 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
Date: Thu, 9 Dec 2021 11:14:52 -0600
|
||||
Subject: [PATCH 03/14] cryptodisk: Return failure in cryptomount when no
|
||||
cryptodisk modules are loaded
|
||||
|
||||
This displays an error notifying the user that they'll want to load
|
||||
a backend module to make cryptomount useful.
|
||||
|
||||
Signed-off-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 9df3d310fe..27491871a5 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1125,6 +1125,9 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (argc < 1 && !state[1].set && !state[2].set)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
|
||||
|
||||
+ if (grub_cryptodisk_list == NULL)
|
||||
+ return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded");
|
||||
+
|
||||
if (state[0].set)
|
||||
{
|
||||
int found_uuid;
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,71 @@
|
||||
From 5b694a13545224c2d21afc3e94831be1bcc85770 Mon Sep 17 00:00:00 2001
|
||||
From: Fabian Vogt <fvogt@suse.de>
|
||||
Date: Tue, 14 Jun 2022 15:55:21 +0200
|
||||
Subject: [PATCH 03/10] disk/cryptodisk: When cheatmounting, use the sector
|
||||
info of the cheat device
|
||||
|
||||
When using grub-probe with cryptodisk, the mapped block device from the host
|
||||
is used directly instead of decrypting the source device in GRUB code.
|
||||
In that case, the sector size and count of the host device needs to be used.
|
||||
This is especially important when using luks2, which does not assign
|
||||
total_sectors and log_sector_size when scanning, but only later when the
|
||||
segments in the JSON area are evaluated. With an unset log_sector_size,
|
||||
grub_open_device complains.
|
||||
|
||||
This fixes grub-probe failing with
|
||||
"error: sector sizes of 1 bytes aren't supported yet."
|
||||
|
||||
Signed-off-by: Fabian Vogt <fvogt@suse.de>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 20 ++++++++++++++++++--
|
||||
1 file changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 6d22bf871c..ae8790f10f 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -698,16 +698,31 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk)
|
||||
if (!dev)
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device");
|
||||
|
||||
- disk->log_sector_size = dev->log_sector_size;
|
||||
-
|
||||
#ifdef GRUB_UTIL
|
||||
if (dev->cheat)
|
||||
{
|
||||
+ grub_uint64_t cheat_dev_size;
|
||||
+ unsigned int cheat_log_sector_size;
|
||||
+
|
||||
if (!GRUB_UTIL_FD_IS_VALID (dev->cheat_fd))
|
||||
dev->cheat_fd = grub_util_fd_open (dev->cheat, GRUB_UTIL_FD_O_RDONLY);
|
||||
if (!GRUB_UTIL_FD_IS_VALID (dev->cheat_fd))
|
||||
return grub_error (GRUB_ERR_IO, N_("cannot open `%s': %s"),
|
||||
dev->cheat, grub_util_fd_strerror ());
|
||||
+
|
||||
+ /* Use the sector size and count of the cheat device */
|
||||
+ cheat_dev_size = grub_util_get_fd_size (dev->cheat_fd, dev->cheat, &cheat_log_sector_size);
|
||||
+ if (cheat_dev_size == -1)
|
||||
+ {
|
||||
+ const char *errmsg = grub_util_fd_strerror ();
|
||||
+ grub_util_fd_close (dev->cheat_fd);
|
||||
+ dev->cheat_fd = GRUB_UTIL_FD_INVALID;
|
||||
+ return grub_error (GRUB_ERR_IO, N_("failed to query size of device `%s': %s"),
|
||||
+ dev->cheat, errmsg);
|
||||
+ }
|
||||
+
|
||||
+ dev->log_sector_size = cheat_log_sector_size;
|
||||
+ dev->total_sectors = cheat_dev_size >> cheat_log_sector_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -721,6 +736,7 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk)
|
||||
}
|
||||
|
||||
disk->data = dev;
|
||||
+ disk->log_sector_size = dev->log_sector_size;
|
||||
disk->total_sectors = dev->total_sectors;
|
||||
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||
disk->id = dev->id;
|
||||
--
|
||||
2.34.1
|
||||
|
260
0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch
Normal file
260
0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch
Normal file
@ -0,0 +1,260 @@
|
||||
From 029c952f37dedb086c85bfb5fbc0de15cd4dbf0f Mon Sep 17 00:00:00 2001
|
||||
From: Lu Ken <ken.lu@intel.com>
|
||||
Date: Wed, 13 Jul 2022 10:06:12 +0800
|
||||
Subject: [PATCH 3/3] efi/tpm: Add EFI_CC_MEASUREMENT_PROTOCOL support
|
||||
|
||||
The EFI_CC_MEASUREMENT_PROTOCOL abstracts the measurement for virtual firmware
|
||||
in confidential computing environment. It is similar to the EFI_TCG2_PROTOCOL.
|
||||
It was proposed by Intel and ARM and approved by UEFI organization.
|
||||
|
||||
It is defined in Intel GHCI specification: https://cdrdv2.intel.com/v1/dl/getContent/726790 .
|
||||
The EDKII header file is available at https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Protocol/CcMeasurement.h .
|
||||
|
||||
Signed-off-by: Lu Ken <ken.lu@intel.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/commands/efi/tpm.c | 48 +++++++++++
|
||||
include/grub/efi/cc.h | 151 +++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 199 insertions(+)
|
||||
create mode 100644 include/grub/efi/cc.h
|
||||
|
||||
diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c
|
||||
index e032617d8..630fd8a82 100644
|
||||
--- a/grub-core/commands/efi/tpm.c
|
||||
+++ b/grub-core/commands/efi/tpm.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/cc.h>
|
||||
#include <grub/efi/tpm.h>
|
||||
#include <grub/tpm2/tpm2.h>
|
||||
#include <grub/mm.h>
|
||||
@@ -32,6 +33,7 @@ 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_guid_t cc_measurement_guid = GRUB_EFI_CC_MEASUREMENT_PROTOCOL_GUID;
|
||||
|
||||
static grub_efi_handle_t *grub_tpm_handle;
|
||||
static grub_uint8_t grub_tpm_version;
|
||||
@@ -308,6 +310,50 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
|
||||
return grub_efi_log_event_status (status);
|
||||
}
|
||||
|
||||
+static void
|
||||
+grub_cc_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
+ const char *description)
|
||||
+{
|
||||
+ grub_efi_cc_event_t *event;
|
||||
+ grub_efi_status_t status;
|
||||
+ grub_efi_cc_protocol_t *cc;
|
||||
+ grub_efi_cc_mr_index_t mr;
|
||||
+
|
||||
+ cc = grub_efi_locate_protocol (&cc_measurement_guid, NULL);
|
||||
+ if (cc == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ status = efi_call_3 (cc->map_pcr_to_mr_index, cc, pcr, &mr);
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ {
|
||||
+ grub_efi_log_event_status (status);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ event = grub_zalloc (sizeof (grub_efi_cc_event_t) +
|
||||
+ grub_strlen (description) + 1);
|
||||
+ if (event == NULL)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate CC event buffer"));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ event->Header.HeaderSize = sizeof (grub_efi_cc_event_header_t);
|
||||
+ event->Header.HeaderVersion = GRUB_EFI_CC_EVENT_HEADER_VERSION;
|
||||
+ event->Header.MrIndex = mr;
|
||||
+ event->Header.EventType = EV_IPL;
|
||||
+ event->Size = sizeof (*event) + grub_strlen (description) + 1;
|
||||
+ grub_strcpy ((char *) event->Event, description);
|
||||
+
|
||||
+ status = efi_call_5 (cc->hash_log_extend_event, cc, 0,
|
||||
+ (grub_efi_physical_address_t)(grub_addr_t) buf,
|
||||
+ (grub_efi_uint64_t) size, event);
|
||||
+ grub_free (event);
|
||||
+
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ grub_efi_log_event_status (status);
|
||||
+}
|
||||
+
|
||||
grub_err_t
|
||||
grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
const char *description)
|
||||
@@ -315,6 +361,8 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
grub_efi_handle_t tpm_handle;
|
||||
grub_efi_uint8_t protocol_version;
|
||||
|
||||
+ grub_cc_log_event(buf, size, pcr, description);
|
||||
+
|
||||
if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
|
||||
return 0;
|
||||
|
||||
diff --git a/include/grub/efi/cc.h b/include/grub/efi/cc.h
|
||||
new file mode 100644
|
||||
index 000000000..896030689
|
||||
--- /dev/null
|
||||
+++ b/include/grub/efi/cc.h
|
||||
@@ -0,0 +1,151 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2022 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 <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef GRUB_EFI_CC_H
|
||||
+#define GRUB_EFI_CC_H 1
|
||||
+
|
||||
+#include <grub/efi/api.h>
|
||||
+#include <grub/efi/efi.h>
|
||||
+#include <grub/err.h>
|
||||
+
|
||||
+#define GRUB_EFI_CC_MEASUREMENT_PROTOCOL_GUID \
|
||||
+ { 0x96751a3d, 0x72f4, 0x41a6, \
|
||||
+ { 0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b } \
|
||||
+ };
|
||||
+
|
||||
+struct grub_efi_cc_version
|
||||
+{
|
||||
+ grub_efi_uint8_t Major;
|
||||
+ grub_efi_uint8_t Minor;
|
||||
+};
|
||||
+typedef struct grub_efi_cc_version grub_efi_cc_version_t;
|
||||
+
|
||||
+/* EFI_CC Type/SubType definition. */
|
||||
+#define GRUB_EFI_CC_TYPE_NONE 0
|
||||
+#define GRUB_EFI_CC_TYPE_SEV 1
|
||||
+#define GRUB_EFI_CC_TYPE_TDX 2
|
||||
+
|
||||
+struct grub_efi_cc_type
|
||||
+{
|
||||
+ grub_efi_uint8_t Type;
|
||||
+ grub_efi_uint8_t SubType;
|
||||
+};
|
||||
+typedef struct grub_efi_cc_type grub_efi_cc_type_t;
|
||||
+
|
||||
+typedef grub_efi_uint32_t grub_efi_cc_event_log_bitmap_t;
|
||||
+typedef grub_efi_uint32_t grub_efi_cc_event_log_format_t;
|
||||
+typedef grub_efi_uint32_t grub_efi_cc_event_algorithm_bitmap_t;
|
||||
+typedef grub_efi_uint32_t grub_efi_cc_mr_index_t;
|
||||
+
|
||||
+/* Intel TDX measure register index. */
|
||||
+#define GRUB_TDX_MR_INDEX_MRTD 0
|
||||
+#define GRUB_TDX_MR_INDEX_RTMR0 1
|
||||
+#define GRUB_TDX_MR_INDEX_RTMR1 2
|
||||
+#define GRUB_TDX_MR_INDEX_RTMR2 3
|
||||
+#define GRUB_TDX_MR_INDEX_RTMR3 4
|
||||
+
|
||||
+#define GRUB_EFI_CC_EVENT_LOG_FORMAT_TCG_2 0x00000002
|
||||
+#define GRUB_EFI_CC_BOOT_HASH_ALG_SHA384 0x00000004
|
||||
+#define GRUB_EFI_CC_EVENT_HEADER_VERSION 1
|
||||
+
|
||||
+struct grub_efi_cc_event_header
|
||||
+{
|
||||
+ /* Size of the event header itself (sizeof(EFI_TD_EVENT_HEADER)). */
|
||||
+ grub_efi_uint32_t HeaderSize;
|
||||
+
|
||||
+ /*
|
||||
+ * Header version. For this version of this specification,
|
||||
+ * the value shall be 1.
|
||||
+ */
|
||||
+ grub_efi_uint16_t HeaderVersion;
|
||||
+
|
||||
+ /* Index of the MR that shall be extended. */
|
||||
+ grub_efi_cc_mr_index_t MrIndex;
|
||||
+
|
||||
+ /* Type of the event that shall be extended (and optionally logged). */
|
||||
+ grub_efi_uint32_t EventType;
|
||||
+} GRUB_PACKED;
|
||||
+typedef struct grub_efi_cc_event_header grub_efi_cc_event_header_t;
|
||||
+
|
||||
+struct grub_efi_cc_event
|
||||
+{
|
||||
+ /* Total size of the event including the Size component, the header and the Event data. */
|
||||
+ grub_efi_uint32_t Size;
|
||||
+ grub_efi_cc_event_header_t Header;
|
||||
+ grub_efi_uint8_t Event[0];
|
||||
+} GRUB_PACKED;
|
||||
+typedef struct grub_efi_cc_event grub_efi_cc_event_t;
|
||||
+
|
||||
+struct grub_efi_cc_boot_service_capability
|
||||
+{
|
||||
+ /* Allocated size of the structure. */
|
||||
+ grub_efi_uint8_t Size;
|
||||
+
|
||||
+ /*
|
||||
+ * Version of the grub_efi_cc_boot_service_capability_t structure itself.
|
||||
+ * For this version of the protocol, the Major version shall be set to 1
|
||||
+ * and the Minor version shall be set to 1.
|
||||
+ */
|
||||
+ grub_efi_cc_version_t StructureVersion;
|
||||
+
|
||||
+ /*
|
||||
+ * Version of the EFI TD protocol.
|
||||
+ * For this version of the protocol, the Major version shall be set to 1
|
||||
+ * and the Minor version shall be set to 1.
|
||||
+ */
|
||||
+ grub_efi_cc_version_t ProtocolVersion;
|
||||
+
|
||||
+ /* Supported hash algorithms. */
|
||||
+ grub_efi_cc_event_algorithm_bitmap_t HashAlgorithmBitmap;
|
||||
+
|
||||
+ /* Bitmap of supported event log formats. */
|
||||
+ grub_efi_cc_event_log_bitmap_t SupportedEventLogs;
|
||||
+
|
||||
+ /* Indicates the CC type. */
|
||||
+ grub_efi_cc_type_t CcType;
|
||||
+};
|
||||
+typedef struct grub_efi_cc_boot_service_capability grub_efi_cc_boot_service_capability_t;
|
||||
+
|
||||
+struct grub_efi_cc_protocol
|
||||
+{
|
||||
+ grub_efi_status_t
|
||||
+ (*get_capability) (struct grub_efi_cc_protocol *this,
|
||||
+ grub_efi_cc_boot_service_capability_t *ProtocolCapability);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (*get_event_log) (struct grub_efi_cc_protocol *this,
|
||||
+ grub_efi_cc_event_log_format_t 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_cc_protocol *this,
|
||||
+ grub_efi_uint64_t Flags,
|
||||
+ grub_efi_physical_address_t DataToHash,
|
||||
+ grub_efi_uint64_t DataToHashLen,
|
||||
+ grub_efi_cc_event_t *EfiCcEvent);
|
||||
+
|
||||
+ grub_efi_status_t
|
||||
+ (*map_pcr_to_mr_index) (struct grub_efi_cc_protocol *this,
|
||||
+ grub_efi_uint32_t PcrIndex,
|
||||
+ grub_efi_cc_mr_index_t *MrIndex);
|
||||
+};
|
||||
+typedef struct grub_efi_cc_protocol grub_efi_cc_protocol_t;
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.35.3
|
||||
|
62
0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch
Normal file
62
0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch
Normal file
@ -0,0 +1,62 @@
|
||||
From 1729400ab816804a28ebf50cb1310607b2c4b75e Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegodo@br.ibm.com>
|
||||
Date: Fri, 25 Feb 2022 12:49:51 -0500
|
||||
Subject: [PATCH 3/4] ieee1275: change the logic of ieee1275_get_devargs()
|
||||
|
||||
Usually grub will parse the PFW arguments by searching for the first occurence of the character ':'.
|
||||
However, we can have this char more than once on NQN.
|
||||
This patch changes the logic to find the last occurence of this char so we can get the proper values
|
||||
for NVMeoFC
|
||||
---
|
||||
grub-core/kern/ieee1275/openfw.c | 21 ++++++++++++++++++++-
|
||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c
|
||||
index f819bd106..655a71310 100644
|
||||
--- a/grub-core/kern/ieee1275/openfw.c
|
||||
+++ b/grub-core/kern/ieee1275/openfw.c
|
||||
@@ -354,6 +354,13 @@ static char *
|
||||
grub_ieee1275_get_devargs (const char *path)
|
||||
{
|
||||
char *colon = grub_strchr (path, ':');
|
||||
+ char *colon_check = colon;
|
||||
+
|
||||
+ /* Find the last occurence of colon */
|
||||
+ while(colon_check){
|
||||
+ colon = colon_check;
|
||||
+ colon_check = grub_strchr (colon+1, ':');
|
||||
+ }
|
||||
|
||||
if (! colon)
|
||||
return 0;
|
||||
@@ -368,6 +375,18 @@ grub_ieee1275_get_devname (const char *path)
|
||||
char *colon = grub_strchr (path, ':');
|
||||
int pathlen = grub_strlen (path);
|
||||
struct grub_ieee1275_devalias curalias;
|
||||
+
|
||||
+ /* Check some special cases */
|
||||
+ if(grub_strstr(path, "nvme-of")){
|
||||
+ char *namespace_split = grub_strstr(path,"/namespace@");
|
||||
+ if(namespace_split){
|
||||
+ colon = grub_strchr (namespace_split, ':');
|
||||
+ } else {
|
||||
+ colon = NULL;
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
if (colon)
|
||||
pathlen = (int)(colon - path);
|
||||
|
||||
@@ -693,7 +712,7 @@ grub_ieee1275_get_boot_dev (void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64);
|
||||
+ bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64 + 256);
|
||||
if (! bootpath)
|
||||
{
|
||||
grub_print_error ();
|
||||
--
|
||||
2.35.3
|
||||
|
@ -0,0 +1,86 @@
|
||||
From b4500ff77efe3b36256fae1e456ded65fd77cf04 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
Date: Thu, 21 Apr 2022 15:24:20 +1000
|
||||
Subject: [PATCH 3/5] kern/efi/mm: Extract function to add memory regions
|
||||
|
||||
In preparation of support for runtime-allocating additional memory
|
||||
region, this patch extracts the function to retrieve the EFI memory
|
||||
map and add a subset of it to GRUB's own memory regions.
|
||||
|
||||
Signed-off-by: Patrick Steinhardt <ps@pks.im>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Patrick Steinhardt <ps@pks.im>
|
||||
---
|
||||
grub-core/kern/efi/mm.c | 21 +++++++++++++++------
|
||||
1 file changed, 15 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
|
||||
index 2874522..087272f 100644
|
||||
--- a/grub-core/kern/efi/mm.c
|
||||
+++ b/grub-core/kern/efi/mm.c
|
||||
@@ -592,8 +592,8 @@ print_memory_map (grub_efi_memory_descriptor_t *memory_map,
|
||||
}
|
||||
#endif
|
||||
|
||||
-void
|
||||
-grub_efi_mm_init (void)
|
||||
+static grub_err_t
|
||||
+grub_efi_mm_add_regions (grub_size_t required_bytes)
|
||||
{
|
||||
grub_efi_memory_descriptor_t *memory_map;
|
||||
grub_efi_memory_descriptor_t *memory_map_end;
|
||||
@@ -606,7 +606,7 @@ grub_efi_mm_init (void)
|
||||
/* Prepare a memory region to store two memory maps. */
|
||||
memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
|
||||
if (! memory_map)
|
||||
- grub_fatal ("cannot allocate memory");
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory for memory map");
|
||||
|
||||
/* Obtain descriptors for available memory. */
|
||||
map_size = MEMORY_MAP_SIZE;
|
||||
@@ -624,14 +624,14 @@ grub_efi_mm_init (void)
|
||||
|
||||
memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (map_size));
|
||||
if (! memory_map)
|
||||
- grub_fatal ("cannot allocate memory");
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory for new memory map");
|
||||
|
||||
mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0,
|
||||
&desc_size, 0);
|
||||
}
|
||||
|
||||
if (mm_status < 0)
|
||||
- grub_fatal ("cannot get memory map");
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "error fetching memory map from EFI");
|
||||
|
||||
memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size);
|
||||
|
||||
@@ -646,7 +646,7 @@ grub_efi_mm_init (void)
|
||||
|
||||
/* Allocate memory regions for GRUB's memory management. */
|
||||
add_memory_regions (filtered_memory_map, desc_size,
|
||||
- filtered_memory_map_end, BYTES_TO_PAGES (DEFAULT_HEAP_SIZE));
|
||||
+ filtered_memory_map_end, BYTES_TO_PAGES (required_bytes));
|
||||
|
||||
#if 0
|
||||
/* For debug. */
|
||||
@@ -664,6 +664,15 @@ grub_efi_mm_init (void)
|
||||
/* Release the memory maps. */
|
||||
grub_efi_free_pages ((grub_addr_t) memory_map,
|
||||
2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_efi_mm_init (void)
|
||||
+{
|
||||
+ if (grub_efi_mm_add_regions (DEFAULT_HEAP_SIZE) != GRUB_ERR_NONE)
|
||||
+ grub_fatal ("%s", grub_errmsg);
|
||||
}
|
||||
|
||||
#if defined (__aarch64__) || defined (__arm__) || defined (__riscv)
|
||||
--
|
||||
2.35.3
|
||||
|
@ -0,0 +1,58 @@
|
||||
From f41488d0e361a34f4d3f8fb6c92729a2901a5c76 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
Date: Thu, 9 Dec 2021 11:14:53 -0600
|
||||
Subject: [PATCH 04/14] cryptodisk: Improve error messaging in cryptomount
|
||||
invocations
|
||||
|
||||
Update such that "cryptomount -u UUID" will not print two error messages
|
||||
when an invalid passphrase is given and the most relevant error message
|
||||
will be displayed.
|
||||
|
||||
Signed-off-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 21 +++++++++++++++++----
|
||||
1 file changed, 17 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 27491871a5..3a896c6634 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1109,7 +1109,10 @@ grub_cryptodisk_scan_device (const char *name,
|
||||
if (grub_errno == GRUB_ERR_BAD_MODULE)
|
||||
grub_error_pop ();
|
||||
|
||||
- if (grub_errno != GRUB_ERR_NONE)
|
||||
+ if (search_uuid != NULL)
|
||||
+ /* Push error onto stack to save for cryptomount. */
|
||||
+ grub_error_push ();
|
||||
+ else
|
||||
grub_print_error ();
|
||||
|
||||
cleanup:
|
||||
@@ -1146,9 +1149,19 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
|
||||
search_uuid = NULL;
|
||||
|
||||
- if (!found_uuid)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found");
|
||||
- return GRUB_ERR_NONE;
|
||||
+ if (found_uuid)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ else if (grub_errno == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ /*
|
||||
+ * Try to pop the next error on the stack. If there is not one, then
|
||||
+ * no device matched the given UUID.
|
||||
+ */
|
||||
+ grub_error_pop ();
|
||||
+ if (grub_errno == GRUB_ERR_NONE)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found");
|
||||
+ }
|
||||
+ return grub_errno;
|
||||
}
|
||||
else if (state[1].set || (argc == 0 && state[2].set))
|
||||
{
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,89 @@
|
||||
From 4287786dde414d9b0517d12762904b4b2be19d2a Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
Date: Thu, 21 Apr 2022 15:24:21 +1000
|
||||
Subject: [PATCH 4/5] kern/efi/mm: Pass up errors from add_memory_regions()
|
||||
|
||||
The function add_memory_regions() is currently only called on system
|
||||
initialization to allocate a fixed amount of pages. As such, it didn't
|
||||
need to return any errors: in case it failed, we cannot proceed anyway.
|
||||
This will change with the upcoming support for requesting more memory
|
||||
from the firmware at runtime, where it doesn't make sense anymore to
|
||||
fail hard.
|
||||
|
||||
Refactor the function to return an error to prepare for this. Note that
|
||||
this does not change the behaviour when initializing the memory system
|
||||
because grub_efi_mm_init() knows to call grub_fatal() in case
|
||||
grub_efi_mm_add_regions() returns an error.
|
||||
|
||||
Signed-off-by: Patrick Steinhardt <ps@pks.im>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Patrick Steinhardt <ps@pks.im>
|
||||
---
|
||||
grub-core/kern/efi/mm.c | 22 +++++++++++++++-------
|
||||
1 file changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
|
||||
index 087272f..45ea6d5 100644
|
||||
--- a/grub-core/kern/efi/mm.c
|
||||
+++ b/grub-core/kern/efi/mm.c
|
||||
@@ -514,7 +514,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
|
||||
}
|
||||
|
||||
/* Add memory regions. */
|
||||
-static void
|
||||
+static grub_err_t
|
||||
add_memory_regions (grub_efi_memory_descriptor_t *memory_map,
|
||||
grub_efi_uintn_t desc_size,
|
||||
grub_efi_memory_descriptor_t *memory_map_end,
|
||||
@@ -542,9 +542,9 @@ add_memory_regions (grub_efi_memory_descriptor_t *memory_map,
|
||||
GRUB_EFI_ALLOCATE_ADDRESS,
|
||||
GRUB_EFI_LOADER_CODE);
|
||||
if (! addr)
|
||||
- grub_fatal ("cannot allocate conventional memory %p with %u pages",
|
||||
- (void *) ((grub_addr_t) start),
|
||||
- (unsigned) pages);
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
+ "Memory starting at %p (%u pages) marked as free, but EFI would not allocate",
|
||||
+ (void *) ((grub_addr_t) start), (unsigned) pages);
|
||||
|
||||
grub_mm_init_region (addr, PAGES_TO_BYTES (pages));
|
||||
|
||||
@@ -554,7 +554,11 @@ add_memory_regions (grub_efi_memory_descriptor_t *memory_map,
|
||||
}
|
||||
|
||||
if (required_pages > 0)
|
||||
- grub_fatal ("too little memory");
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
+ "could not allocate all requested memory: %" PRIuGRUB_UINT64_T " pages still required after iterating EFI memory map",
|
||||
+ required_pages);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -601,6 +605,7 @@ grub_efi_mm_add_regions (grub_size_t required_bytes)
|
||||
grub_efi_memory_descriptor_t *filtered_memory_map_end;
|
||||
grub_efi_uintn_t map_size;
|
||||
grub_efi_uintn_t desc_size;
|
||||
+ grub_err_t err;
|
||||
int mm_status;
|
||||
|
||||
/* Prepare a memory region to store two memory maps. */
|
||||
@@ -645,8 +650,11 @@ grub_efi_mm_add_regions (grub_size_t required_bytes)
|
||||
sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end);
|
||||
|
||||
/* Allocate memory regions for GRUB's memory management. */
|
||||
- add_memory_regions (filtered_memory_map, desc_size,
|
||||
- filtered_memory_map_end, BYTES_TO_PAGES (required_bytes));
|
||||
+ err = add_memory_regions (filtered_memory_map, desc_size,
|
||||
+ filtered_memory_map_end,
|
||||
+ BYTES_TO_PAGES (required_bytes));
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
|
||||
#if 0
|
||||
/* For debug. */
|
||||
--
|
||||
2.35.3
|
||||
|
@ -0,0 +1,93 @@
|
||||
From d4eb747f831d8b011c712f4335f12b572d6f32d9 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Fri, 28 Jan 2022 11:30:32 +0100
|
||||
Subject: [PATCH 04/10] normal/menu: Don't show "Booting `%s'" msg when
|
||||
auto-booting with TIMEOUT_STYLE_HIDDEN
|
||||
|
||||
When the user has asked the menu code to be hidden/quiet and the current
|
||||
entry is being autobooted because the timeout has expired don't show
|
||||
the "Booting `%s'" msg.
|
||||
|
||||
This is necessary to let flicker-free boots really be flicker free,
|
||||
otherwise the "Booting `%s'" msg will kick the EFI fb into text mode
|
||||
and show the msg, breaking the flicker-free experience.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
grub-core/normal/menu.c | 24 ++++++++++++++++--------
|
||||
1 file changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
||||
index 47fc12551f..470bfc839b 100644
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -651,13 +651,15 @@ workaround_snapshot_menu_default_entry (grub_menu_t menu, const char *name, int
|
||||
entry to be executed is a result of an automatic default selection because
|
||||
of the timeout. */
|
||||
static int
|
||||
-run_menu (grub_menu_t menu, int nested, int *auto_boot)
|
||||
+run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
{
|
||||
grub_uint64_t saved_time;
|
||||
int default_entry, current_entry;
|
||||
int timeout;
|
||||
enum timeout_style timeout_style;
|
||||
|
||||
+ *notify_boot = 1;
|
||||
+
|
||||
default_entry = get_entry_number (menu, "default");
|
||||
|
||||
workaround_snapshot_menu_default_entry (menu, "default", &default_entry);
|
||||
@@ -734,6 +736,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
|
||||
if (timeout == 0)
|
||||
{
|
||||
*auto_boot = 1;
|
||||
+ *notify_boot = timeout_style != TIMEOUT_STYLE_HIDDEN;
|
||||
return default_entry;
|
||||
}
|
||||
|
||||
@@ -894,12 +897,16 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
|
||||
|
||||
/* Callback invoked immediately before a menu entry is executed. */
|
||||
static void
|
||||
-notify_booting (grub_menu_entry_t entry,
|
||||
- void *userdata __attribute__((unused)))
|
||||
+notify_booting (grub_menu_entry_t entry, void *userdata)
|
||||
{
|
||||
- grub_printf (" ");
|
||||
- grub_printf_ (N_("Booting `%s'"), entry->title);
|
||||
- grub_printf ("\n\n");
|
||||
+ int *notify_boot = userdata;
|
||||
+
|
||||
+ if (*notify_boot)
|
||||
+ {
|
||||
+ grub_printf (" ");
|
||||
+ grub_printf_ (N_("Booting `%s'"), entry->title);
|
||||
+ grub_printf ("\n\n");
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Callback invoked when a default menu entry executed because of a timeout
|
||||
@@ -947,8 +954,9 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
|
||||
int boot_entry;
|
||||
grub_menu_entry_t e;
|
||||
int auto_boot;
|
||||
+ int notify_boot;
|
||||
|
||||
- boot_entry = run_menu (menu, nested, &auto_boot);
|
||||
+ boot_entry = run_menu (menu, nested, &auto_boot, ¬ify_boot);
|
||||
if (boot_entry < 0)
|
||||
break;
|
||||
|
||||
@@ -960,7 +968,7 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
|
||||
|
||||
if (auto_boot)
|
||||
grub_menu_execute_with_fallback (menu, e, autobooted,
|
||||
- &execution_callback, 0);
|
||||
+ &execution_callback, ¬ify_boot);
|
||||
else
|
||||
grub_menu_execute_entry (e, 0);
|
||||
if (autobooted)
|
||||
--
|
||||
2.34.1
|
||||
|
28
0004-ofpath-controller-name-update.patch
Normal file
28
0004-ofpath-controller-name-update.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 7717cd9c27f18703287403af1a955588e3d0261f Mon Sep 17 00:00:00 2001
|
||||
From: mamatha <mainamdar@in.ibm.com>
|
||||
Date: Sat, 24 Sep 2022 11:22:39 +0530
|
||||
Subject: [PATCH 4/4] ofpath controller name update
|
||||
|
||||
patch to update ofpath controller name
|
||||
|
||||
Signed-off-by: mamatha <mainamdar@in.ibm.com>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 212782d3f..7d31cfd0f 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -483,6 +483,8 @@ of_path_get_nvmeof_adapter_info(char* sysfs_path,
|
||||
buf3=strchr(buf2,'-')+1;
|
||||
buf3=strchr(buf3,'-')+1;
|
||||
nvmeof_info->target_wwpn = buf3;
|
||||
+ buf3=strchr(buf3,'x')+1;
|
||||
+ nvmeof_info->target_wwpn = buf3;
|
||||
buf3 = strchr(nvmeof_info->target_wwpn,',');
|
||||
*buf3 = '\0';
|
||||
|
||||
--
|
||||
2.35.3
|
||||
|
@ -0,0 +1,45 @@
|
||||
From d9c7bfe88ce7391618192401c426c218d2a17795 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Fri, 28 Jan 2022 11:30:33 +0100
|
||||
Subject: [PATCH 05/10] EFI: suppress the "Welcome to GRUB!" message in EFI
|
||||
builds
|
||||
|
||||
Grub EFI builds are now often used in combination with flicker-free
|
||||
boot, but this breaks with upstream grub because the "Welcome to GRUB!"
|
||||
message will kick the EFI fb into text mode and show the msg,
|
||||
breaking the flicker-free experience.
|
||||
|
||||
EFI systems are so fast, that when the menu or the countdown are enabled
|
||||
the message will be immediately overwritten, so in these cases not
|
||||
printing the message does not matter.
|
||||
|
||||
And in case when the timeout_style is set to TIMEOUT_STYLE_HIDDEN,
|
||||
the user has asked grub to be quiet (for example to allow flickfree
|
||||
boot) annd thus the message should not be printed.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
grub-core/kern/main.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index 42ea96e39e..35dee404e8 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -272,10 +272,13 @@ grub_main (void)
|
||||
|
||||
grub_boot_time ("After machine init.");
|
||||
|
||||
+ /* This breaks flicker-free boot on EFI systems, so disable it there. */
|
||||
+#ifndef GRUB_MACHINE_EFI
|
||||
/* Hello. */
|
||||
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
|
||||
grub_printf ("Welcome to GRUB!\n\n");
|
||||
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
|
||||
+#endif
|
||||
|
||||
#ifndef GRUB_MACHINE_PCBIOS
|
||||
/* Init verifiers API. */
|
||||
--
|
||||
2.34.1
|
||||
|
31
0005-cryptodisk-Improve-cryptomount-u-error-message.patch
Normal file
31
0005-cryptodisk-Improve-cryptomount-u-error-message.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From 9ef619a7c1d38988f6d91496ea5c59062dcf6013 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
Date: Thu, 9 Dec 2021 11:14:54 -0600
|
||||
Subject: [PATCH 05/14] cryptodisk: Improve cryptomount -u error message
|
||||
|
||||
When a cryptmount is specified with a UUID, but no cryptodisk backends find
|
||||
a disk with that UUID, return a more detailed message giving telling the
|
||||
user that they might not have a needed cryptobackend module loaded.
|
||||
|
||||
Signed-off-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 3a896c6634..5a9780b14c 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1159,7 +1159,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
*/
|
||||
grub_error_pop ();
|
||||
if (grub_errno == GRUB_ERR_NONE)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found");
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found, perhaps a needed disk or cryptodisk module is not loaded");
|
||||
}
|
||||
return grub_errno;
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
77
0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch
Normal file
77
0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch
Normal file
@ -0,0 +1,77 @@
|
||||
From 3a2119e11b9c216f3b008a2c61aca52b91ad7547 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
Date: Thu, 21 Apr 2022 15:24:22 +1000
|
||||
Subject: [PATCH 5/5] kern/efi/mm: Implement runtime addition of pages
|
||||
|
||||
Adjust the interface of grub_efi_mm_add_regions() to take a set of
|
||||
GRUB_MM_ADD_REGION_* flags, which most notably is currently only the
|
||||
GRUB_MM_ADD_REGION_CONSECUTIVE flag. This allows us to set the function
|
||||
up as callback for the memory subsystem and have it call out to us in
|
||||
case there's not enough pages available in the current heap.
|
||||
|
||||
Signed-off-by: Patrick Steinhardt <ps@pks.im>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Patrick Steinhardt <ps@pks.im>
|
||||
---
|
||||
grub-core/kern/efi/mm.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
|
||||
index 45ea6d5..48380d3 100644
|
||||
--- a/grub-core/kern/efi/mm.c
|
||||
+++ b/grub-core/kern/efi/mm.c
|
||||
@@ -518,7 +518,8 @@ static grub_err_t
|
||||
add_memory_regions (grub_efi_memory_descriptor_t *memory_map,
|
||||
grub_efi_uintn_t desc_size,
|
||||
grub_efi_memory_descriptor_t *memory_map_end,
|
||||
- grub_efi_uint64_t required_pages)
|
||||
+ grub_efi_uint64_t required_pages,
|
||||
+ unsigned int flags)
|
||||
{
|
||||
grub_efi_memory_descriptor_t *desc;
|
||||
|
||||
@@ -532,6 +533,10 @@ add_memory_regions (grub_efi_memory_descriptor_t *memory_map,
|
||||
|
||||
start = desc->physical_start;
|
||||
pages = desc->num_pages;
|
||||
+
|
||||
+ if (pages < required_pages && (flags & GRUB_MM_ADD_REGION_CONSECUTIVE))
|
||||
+ continue;
|
||||
+
|
||||
if (pages > required_pages)
|
||||
{
|
||||
start += PAGES_TO_BYTES (pages - required_pages);
|
||||
@@ -597,7 +602,7 @@ print_memory_map (grub_efi_memory_descriptor_t *memory_map,
|
||||
#endif
|
||||
|
||||
static grub_err_t
|
||||
-grub_efi_mm_add_regions (grub_size_t required_bytes)
|
||||
+grub_efi_mm_add_regions (grub_size_t required_bytes, unsigned int flags)
|
||||
{
|
||||
grub_efi_memory_descriptor_t *memory_map;
|
||||
grub_efi_memory_descriptor_t *memory_map_end;
|
||||
@@ -652,7 +657,8 @@ grub_efi_mm_add_regions (grub_size_t required_bytes)
|
||||
/* Allocate memory regions for GRUB's memory management. */
|
||||
err = add_memory_regions (filtered_memory_map, desc_size,
|
||||
filtered_memory_map_end,
|
||||
- BYTES_TO_PAGES (required_bytes));
|
||||
+ BYTES_TO_PAGES (required_bytes),
|
||||
+ flags);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
@@ -679,8 +685,9 @@ grub_efi_mm_add_regions (grub_size_t required_bytes)
|
||||
void
|
||||
grub_efi_mm_init (void)
|
||||
{
|
||||
- if (grub_efi_mm_add_regions (DEFAULT_HEAP_SIZE) != GRUB_ERR_NONE)
|
||||
+ if (grub_efi_mm_add_regions (DEFAULT_HEAP_SIZE, GRUB_MM_ADD_REGION_NONE) != GRUB_ERR_NONE)
|
||||
grub_fatal ("%s", grub_errmsg);
|
||||
+ grub_mm_add_region_fn = grub_efi_mm_add_regions;
|
||||
}
|
||||
|
||||
#if defined (__aarch64__) || defined (__arm__) || defined (__riscv)
|
||||
--
|
||||
2.35.3
|
||||
|
@ -0,0 +1,54 @@
|
||||
From 81339347bc10ec609227361434f75c5e36b85b9f Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Fri, 28 Jan 2022 12:43:48 +0100
|
||||
Subject: [PATCH 06/10] EFI: console: Do not set colorstate until the first
|
||||
text output
|
||||
|
||||
GRUB_MOD_INIT(normal) does an unconditional:
|
||||
|
||||
grub_env_set ("color_normal", "light-gray/black");
|
||||
|
||||
which triggers a grub_term_setcolorstate() call. The original version
|
||||
of the "efi/console: Do not set text-mode until we actually need it" patch:
|
||||
https://lists.gnu.org/archive/html/grub-devel/2018-03/msg00125.html
|
||||
|
||||
Protected against this by caching the requested state in
|
||||
grub_console_setcolorstate () and then only applying it when the first
|
||||
text output actually happens. During refactoring to move the
|
||||
grub_console_setcolorstate () up higher in the grub-core/term/efi/console.c
|
||||
file the code to cache the color-state + bail early was accidentally
|
||||
dropped.
|
||||
|
||||
Restore the cache the color-state + bail early behavior from the original.
|
||||
|
||||
Cc: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Fixes: 2d7c3abd871f ("efi/console: Do not set text-mode until we actually need it")
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
grub-core/term/efi/console.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c
|
||||
index 2f1ae85ba7..c44b2ac318 100644
|
||||
--- a/grub-core/term/efi/console.c
|
||||
+++ b/grub-core/term/efi/console.c
|
||||
@@ -82,6 +82,16 @@ grub_console_setcolorstate (struct grub_term_output *term
|
||||
{
|
||||
grub_efi_simple_text_output_interface_t *o;
|
||||
|
||||
+ if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE)
|
||||
+ {
|
||||
+ /*
|
||||
+ * Cache colorstate changes before the first text-output, this avoids
|
||||
+ * "color_normal" environment writes causing a switch to textmode.
|
||||
+ */
|
||||
+ text_colorstate = state;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (grub_efi_is_finished)
|
||||
return;
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
252
0006-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch
Normal file
252
0006-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch
Normal file
@ -0,0 +1,252 @@
|
||||
From 0a5619abd170b3ad43e44cb8036062506d8623cc Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
Date: Thu, 9 Dec 2021 11:14:55 -0600
|
||||
Subject: [PATCH 06/14] cryptodisk: Add infrastructure to pass data from
|
||||
cryptomount to cryptodisk modules
|
||||
|
||||
Previously, the cryptomount arguments were passed by global variable and
|
||||
function call argument, neither of which are ideal. This change passes data
|
||||
via a grub_cryptomount_args struct, which can be added to over time as
|
||||
opposed to continually adding arguments to the cryptodisk scan and
|
||||
recover_key.
|
||||
|
||||
As an example, passing a password as a cryptomount argument is implemented.
|
||||
However, the backends are not implemented, so testing this will return a not
|
||||
implemented error.
|
||||
|
||||
Also, add comments to cryptomount argument parsing to make it more obvious
|
||||
which argument states are being handled.
|
||||
|
||||
Signed-off-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 31 +++++++++++++++++++++----------
|
||||
grub-core/disk/geli.c | 6 +++++-
|
||||
grub-core/disk/luks.c | 7 ++++++-
|
||||
grub-core/disk/luks2.c | 7 ++++++-
|
||||
include/grub/cryptodisk.h | 9 ++++++++-
|
||||
5 files changed, 46 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 5a9780b14c..14c661a86e 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] =
|
||||
/* TRANSLATORS: It's still restricted to cryptodisks only. */
|
||||
{"all", 'a', 0, N_("Mount all."), 0, 0},
|
||||
{"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0},
|
||||
+ {"password", 'p', 0, N_("Password to open volumes."), 0, ARG_TYPE_STRING},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -996,7 +997,9 @@ cryptodisk_close (grub_cryptodisk_t dev)
|
||||
}
|
||||
|
||||
static grub_cryptodisk_t
|
||||
-grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
|
||||
+grub_cryptodisk_scan_device_real (const char *name,
|
||||
+ grub_disk_t source,
|
||||
+ grub_cryptomount_args_t cargs)
|
||||
{
|
||||
grub_err_t err;
|
||||
grub_cryptodisk_t dev;
|
||||
@@ -1015,7 +1018,7 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
|
||||
if (!dev)
|
||||
continue;
|
||||
|
||||
- err = cr->recover_key (source, dev);
|
||||
+ err = cr->recover_key (source, dev, cargs);
|
||||
if (err)
|
||||
{
|
||||
cryptodisk_close (dev);
|
||||
@@ -1080,11 +1083,12 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat)
|
||||
|
||||
static int
|
||||
grub_cryptodisk_scan_device (const char *name,
|
||||
- void *data __attribute__ ((unused)))
|
||||
+ void *data)
|
||||
{
|
||||
int ret = 0;
|
||||
grub_disk_t source;
|
||||
grub_cryptodisk_t dev;
|
||||
+ grub_cryptomount_args_t cargs = data;
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
/* Try to open disk. */
|
||||
@@ -1095,7 +1099,7 @@ grub_cryptodisk_scan_device (const char *name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
- dev = grub_cryptodisk_scan_device_real (name, source);
|
||||
+ dev = grub_cryptodisk_scan_device_real (name, source, cargs);
|
||||
if (dev)
|
||||
{
|
||||
ret = (search_uuid != NULL && grub_strcasecmp (search_uuid, dev->uuid) == 0);
|
||||
@@ -1124,6 +1128,7 @@ static grub_err_t
|
||||
grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
+ struct grub_cryptomount_args cargs = {0};
|
||||
|
||||
if (argc < 1 && !state[1].set && !state[2].set)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
|
||||
@@ -1131,7 +1136,13 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (grub_cryptodisk_list == NULL)
|
||||
return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded");
|
||||
|
||||
- if (state[0].set)
|
||||
+ if (state[3].set) /* password */
|
||||
+ {
|
||||
+ cargs.key_data = (grub_uint8_t *) state[3].arg;
|
||||
+ cargs.key_len = grub_strlen (state[3].arg);
|
||||
+ }
|
||||
+
|
||||
+ if (state[0].set) /* uuid */
|
||||
{
|
||||
int found_uuid;
|
||||
grub_cryptodisk_t dev;
|
||||
@@ -1146,7 +1157,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
|
||||
check_boot = state[2].set;
|
||||
search_uuid = args[0];
|
||||
- found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
|
||||
+ found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
||||
search_uuid = NULL;
|
||||
|
||||
if (found_uuid)
|
||||
@@ -1163,11 +1174,11 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
}
|
||||
return grub_errno;
|
||||
}
|
||||
- else if (state[1].set || (argc == 0 && state[2].set))
|
||||
+ else if (state[1].set || (argc == 0 && state[2].set)) /* -a|-b */
|
||||
{
|
||||
search_uuid = NULL;
|
||||
check_boot = state[2].set;
|
||||
- grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
|
||||
+ grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
||||
search_uuid = NULL;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -1208,7 +1219,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
- dev = grub_cryptodisk_scan_device_real (diskname, disk);
|
||||
+ dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs);
|
||||
|
||||
grub_disk_close (disk);
|
||||
if (disklast)
|
||||
@@ -1347,7 +1358,7 @@ GRUB_MOD_INIT (cryptodisk)
|
||||
{
|
||||
grub_disk_dev_register (&grub_cryptodisk_dev);
|
||||
cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
|
||||
- N_("SOURCE|-u UUID|-a|-b"),
|
||||
+ N_("[-p password] <SOURCE|-u UUID|-a|-b>"),
|
||||
N_("Mount a crypto device."), options);
|
||||
grub_procfs_register ("luks_script", &luks_script);
|
||||
}
|
||||
diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c
|
||||
index 2f34a35e6b..777da3a055 100644
|
||||
--- a/grub-core/disk/geli.c
|
||||
+++ b/grub-core/disk/geli.c
|
||||
@@ -398,7 +398,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-recover_key (grub_disk_t source, grub_cryptodisk_t dev)
|
||||
+recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs)
|
||||
{
|
||||
grub_size_t keysize;
|
||||
grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN];
|
||||
@@ -414,6 +414,10 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev)
|
||||
grub_disk_addr_t sector;
|
||||
grub_err_t err;
|
||||
|
||||
+ /* Keyfiles are not implemented yet */
|
||||
+ if (cargs->key_data != NULL || cargs->key_len)
|
||||
+ return GRUB_ERR_NOT_IMPLEMENTED_YET;
|
||||
+
|
||||
if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
|
||||
return grub_error (GRUB_ERR_BUG, "cipher block is too long");
|
||||
|
||||
diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
|
||||
index 13103ea6a2..c5858fcf8a 100644
|
||||
--- a/grub-core/disk/luks.c
|
||||
+++ b/grub-core/disk/luks.c
|
||||
@@ -152,7 +152,8 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
||||
|
||||
static grub_err_t
|
||||
luks_recover_key (grub_disk_t source,
|
||||
- grub_cryptodisk_t dev)
|
||||
+ grub_cryptodisk_t dev,
|
||||
+ grub_cryptomount_args_t cargs)
|
||||
{
|
||||
struct grub_luks_phdr header;
|
||||
grub_size_t keysize;
|
||||
@@ -165,6 +166,10 @@ luks_recover_key (grub_disk_t source,
|
||||
grub_size_t max_stripes = 1;
|
||||
char *tmp;
|
||||
|
||||
+ /* Keyfiles are not implemented yet */
|
||||
+ if (cargs->key_data != NULL || cargs->key_len)
|
||||
+ return GRUB_ERR_NOT_IMPLEMENTED_YET;
|
||||
+
|
||||
err = grub_disk_read (source, 0, 0, sizeof (header), &header);
|
||||
if (err)
|
||||
return err;
|
||||
diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
|
||||
index fea196dd4a..2cbec8acc2 100644
|
||||
--- a/grub-core/disk/luks2.c
|
||||
+++ b/grub-core/disk/luks2.c
|
||||
@@ -545,7 +545,8 @@ luks2_decrypt_key (grub_uint8_t *out_key,
|
||||
|
||||
static grub_err_t
|
||||
luks2_recover_key (grub_disk_t source,
|
||||
- grub_cryptodisk_t crypt)
|
||||
+ grub_cryptodisk_t crypt,
|
||||
+ grub_cryptomount_args_t cargs)
|
||||
{
|
||||
grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
|
||||
char passphrase[MAX_PASSPHRASE], cipher[32];
|
||||
@@ -559,6 +560,10 @@ luks2_recover_key (grub_disk_t source,
|
||||
grub_json_t *json = NULL, keyslots;
|
||||
grub_err_t ret;
|
||||
|
||||
+ /* Keyfiles are not implemented yet */
|
||||
+ if (cargs->key_data != NULL || cargs->key_len)
|
||||
+ return GRUB_ERR_NOT_IMPLEMENTED_YET;
|
||||
+
|
||||
ret = luks2_read_header (source, &header);
|
||||
if (ret)
|
||||
return ret;
|
||||
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
|
||||
index dcf17fbb3a..282f8ac456 100644
|
||||
--- a/include/grub/cryptodisk.h
|
||||
+++ b/include/grub/cryptodisk.h
|
||||
@@ -66,6 +66,13 @@ typedef gcry_err_code_t
|
||||
(*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev,
|
||||
grub_uint64_t zoneno);
|
||||
|
||||
+struct grub_cryptomount_args
|
||||
+{
|
||||
+ grub_uint8_t *key_data;
|
||||
+ grub_size_t key_len;
|
||||
+};
|
||||
+typedef struct grub_cryptomount_args *grub_cryptomount_args_t;
|
||||
+
|
||||
struct grub_cryptodisk
|
||||
{
|
||||
struct grub_cryptodisk *next;
|
||||
@@ -119,7 +126,7 @@ struct grub_cryptodisk_dev
|
||||
|
||||
grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid,
|
||||
int boot_only);
|
||||
- grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev);
|
||||
+ grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs);
|
||||
};
|
||||
typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t;
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
@ -0,0 +1,75 @@
|
||||
From 9b12dc80d4254e22c41805cecf2494a8e6a50e3e Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Fri, 28 Jan 2022 12:43:49 +0100
|
||||
Subject: [PATCH 07/10] EFI: console: Do not set cursor until the first text
|
||||
output
|
||||
|
||||
To allow flickerfree boot the EFI console code does not call
|
||||
grub_efi_set_text_mode (1) until some text is actually output.
|
||||
|
||||
Depending on if the output text is because of an error loading
|
||||
e.g. the .cfg file; or because of showing the menu the cursor needs
|
||||
to be on or off when the first text is shown.
|
||||
|
||||
So far the cursor was hardcoded to being on, but this is causing
|
||||
drawing artifacts + slow drawing of the menu as reported here:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1946969
|
||||
|
||||
Handle the cursorstate in the same way as the colorstate to fix this,
|
||||
when no text has been output yet, just cache the cursorstate and
|
||||
then use the last set value when the first text is output.
|
||||
|
||||
Fixes: 2d7c3abd871f ("efi/console: Do not set text-mode until we actually need it")
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
grub-core/term/efi/console.c | 19 ++++++++++++++++---
|
||||
1 file changed, 16 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c
|
||||
index c44b2ac318..a3622e4fe5 100644
|
||||
--- a/grub-core/term/efi/console.c
|
||||
+++ b/grub-core/term/efi/console.c
|
||||
@@ -31,7 +31,15 @@ typedef enum {
|
||||
}
|
||||
grub_text_mode;
|
||||
|
||||
+typedef enum {
|
||||
+ GRUB_CURSOR_MODE_UNDEFINED = -1,
|
||||
+ GRUB_CURSOR_MODE_OFF = 0,
|
||||
+ GRUB_CURSUR_MODE_ON
|
||||
+}
|
||||
+grub_cursor_mode;
|
||||
+
|
||||
static grub_text_mode text_mode = GRUB_TEXT_MODE_UNDEFINED;
|
||||
+static grub_cursor_mode cursor_mode = GRUB_CURSOR_MODE_UNDEFINED;
|
||||
static grub_term_color_state text_colorstate = GRUB_TERM_COLOR_UNDEFINED;
|
||||
|
||||
static grub_uint32_t
|
||||
@@ -119,8 +127,12 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
|
||||
{
|
||||
grub_efi_simple_text_output_interface_t *o;
|
||||
|
||||
- if (grub_efi_is_finished)
|
||||
- return;
|
||||
+ if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE)
|
||||
+ {
|
||||
+ /* Cache cursor changes before the first text-output */
|
||||
+ cursor_mode = on;
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
o = grub_efi_system_table->con_out;
|
||||
efi_call_2 (o->enable_cursor, o, on);
|
||||
@@ -143,7 +155,8 @@ grub_prepare_for_text_output (struct grub_term_output *term)
|
||||
return GRUB_ERR_BAD_DEVICE;
|
||||
}
|
||||
|
||||
- grub_console_setcursor (term, 1);
|
||||
+ if (cursor_mode != GRUB_CURSOR_MODE_UNDEFINED)
|
||||
+ grub_console_setcursor (term, cursor_mode);
|
||||
if (text_colorstate != GRUB_TERM_COLOR_UNDEFINED)
|
||||
grub_console_setcolorstate (term, text_colorstate);
|
||||
text_mode = GRUB_TEXT_MODE_AVAILABLE;
|
||||
--
|
||||
2.34.1
|
||||
|
342
0007-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch
Normal file
342
0007-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch
Normal file
@ -0,0 +1,342 @@
|
||||
From a3ae3f800f6aa3f6036351133ed69fa47c9fa371 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
Date: Thu, 9 Dec 2021 11:14:56 -0600
|
||||
Subject: [PATCH 07/14] cryptodisk: Refactor password input out of crypto dev
|
||||
modules into cryptodisk
|
||||
|
||||
The crypto device modules should only be setting up the crypto devices and
|
||||
not getting user input. This has the added benefit of simplifying the code
|
||||
such that three essentially duplicate pieces of code are merged into one.
|
||||
|
||||
Add documentation of passphrase option for cryptomount as it is now usable.
|
||||
|
||||
Signed-off-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 8 ++++--
|
||||
grub-core/disk/cryptodisk.c | 56 +++++++++++++++++++++++++++++--------
|
||||
grub-core/disk/geli.c | 26 ++++-------------
|
||||
grub-core/disk/luks.c | 27 +++---------------
|
||||
grub-core/disk/luks2.c | 25 +++--------------
|
||||
include/grub/cryptodisk.h | 1 +
|
||||
6 files changed, 64 insertions(+), 79 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index f4794fddac..4504bcabec 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -4310,9 +4310,11 @@ Alias for @code{hashsum --hash crc32 arg @dots{}}. See command @command{hashsum}
|
||||
@node cryptomount
|
||||
@subsection cryptomount
|
||||
|
||||
-@deffn Command cryptomount device|@option{-u} uuid|@option{-a}|@option{-b}
|
||||
-Setup access to encrypted device. If necessary, passphrase
|
||||
-is requested interactively. Option @var{device} configures specific grub device
|
||||
+@deffn Command cryptomount [@option{-p} password] device|@option{-u} uuid|@option{-a}|@option{-b}
|
||||
+Setup access to encrypted device. If @option{-p} is not given, a passphrase
|
||||
+is requested interactively. Otherwise, the given @var{password} will be used and
|
||||
+no passphrase will be requested interactively.
|
||||
+Option @var{device} configures specific grub device
|
||||
(@pxref{Naming convention}); option @option{-u} @var{uuid} configures device
|
||||
with specified @var{uuid}; option @option{-a} configures all detected encrypted
|
||||
devices; option @option{-b} configures all geli containers that have boot flag set.
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 14c661a86e..d12368a1f7 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1001,9 +1001,11 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
grub_disk_t source,
|
||||
grub_cryptomount_args_t cargs)
|
||||
{
|
||||
- grub_err_t err;
|
||||
+ grub_err_t ret = GRUB_ERR_NONE;
|
||||
grub_cryptodisk_t dev;
|
||||
grub_cryptodisk_dev_t cr;
|
||||
+ int askpass = 0;
|
||||
+ char *part = NULL;
|
||||
|
||||
dev = grub_cryptodisk_get_by_source_disk (source);
|
||||
|
||||
@@ -1017,21 +1019,53 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
return NULL;
|
||||
if (!dev)
|
||||
continue;
|
||||
-
|
||||
- err = cr->recover_key (source, dev, cargs);
|
||||
- if (err)
|
||||
- {
|
||||
- cryptodisk_close (dev);
|
||||
- return NULL;
|
||||
- }
|
||||
+
|
||||
+ if (!cargs->key_len)
|
||||
+ {
|
||||
+ /* Get the passphrase from the user, if no key data. */
|
||||
+ askpass = 1;
|
||||
+ if (source->partition != NULL)
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
+ source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : "",
|
||||
+ dev->uuid);
|
||||
+ grub_free (part);
|
||||
+
|
||||
+ cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
||||
+ if (cargs->key_data == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||
+ goto error;
|
||||
+ }
|
||||
+ cargs->key_len = grub_strlen ((char *) cargs->key_data);
|
||||
+ }
|
||||
+
|
||||
+ ret = cr->recover_key (source, dev, cargs);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ goto error;
|
||||
|
||||
grub_cryptodisk_insert (dev, name, source);
|
||||
|
||||
- return dev;
|
||||
+ goto cleanup;
|
||||
}
|
||||
-
|
||||
grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device");
|
||||
- return NULL;
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ error:
|
||||
+ cryptodisk_close (dev);
|
||||
+ dev = NULL;
|
||||
+
|
||||
+ cleanup:
|
||||
+ if (askpass)
|
||||
+ {
|
||||
+ cargs->key_len = 0;
|
||||
+ grub_free (cargs->key_data);
|
||||
+ }
|
||||
+ return dev;
|
||||
}
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c
|
||||
index 777da3a055..7299a47d19 100644
|
||||
--- a/grub-core/disk/geli.c
|
||||
+++ b/grub-core/disk/geli.c
|
||||
@@ -135,8 +135,6 @@ const char *algorithms[] = {
|
||||
[0x16] = "aes"
|
||||
};
|
||||
|
||||
-#define MAX_PASSPHRASE 256
|
||||
-
|
||||
static gcry_err_code_t
|
||||
geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno)
|
||||
{
|
||||
@@ -406,17 +404,14 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t
|
||||
grub_uint8_t verify_key[GRUB_CRYPTO_MAX_MDLEN];
|
||||
grub_uint8_t zero[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE];
|
||||
grub_uint8_t geli_cipher_key[64];
|
||||
- char passphrase[MAX_PASSPHRASE] = "";
|
||||
unsigned i;
|
||||
gcry_err_code_t gcry_err;
|
||||
struct grub_geli_phdr header;
|
||||
- char *tmp;
|
||||
grub_disk_addr_t sector;
|
||||
grub_err_t err;
|
||||
|
||||
- /* Keyfiles are not implemented yet */
|
||||
- if (cargs->key_data != NULL || cargs->key_len)
|
||||
- return GRUB_ERR_NOT_IMPLEMENTED_YET;
|
||||
+ if (cargs->key_data == NULL || cargs->key_len == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data");
|
||||
|
||||
if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
|
||||
return grub_error (GRUB_ERR_BUG, "cipher block is too long");
|
||||
@@ -438,23 +433,12 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t
|
||||
|
||||
grub_puts_ (N_("Attempting to decrypt master key..."));
|
||||
|
||||
- /* Get the passphrase from the user. */
|
||||
- tmp = NULL;
|
||||
- if (source->partition)
|
||||
- tmp = grub_partition_get_name (source->partition);
|
||||
- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
- source->partition ? "," : "", tmp ? : "",
|
||||
- dev->uuid);
|
||||
- grub_free (tmp);
|
||||
- if (!grub_password_get (passphrase, MAX_PASSPHRASE))
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
|
||||
-
|
||||
/* Calculate the PBKDF2 of the user supplied passphrase. */
|
||||
if (grub_le_to_cpu32 (header.niter) != 0)
|
||||
{
|
||||
grub_uint8_t pbkdf_key[64];
|
||||
- gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase,
|
||||
- grub_strlen (passphrase),
|
||||
+ gcry_err = grub_crypto_pbkdf2 (dev->hash, cargs->key_data,
|
||||
+ cargs->key_len,
|
||||
header.salt,
|
||||
sizeof (header.salt),
|
||||
grub_le_to_cpu32 (header.niter),
|
||||
@@ -477,7 +461,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t
|
||||
return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY);
|
||||
|
||||
grub_crypto_hmac_write (hnd, header.salt, sizeof (header.salt));
|
||||
- grub_crypto_hmac_write (hnd, passphrase, grub_strlen (passphrase));
|
||||
+ grub_crypto_hmac_write (hnd, cargs->key_data, cargs->key_len);
|
||||
|
||||
gcry_err = grub_crypto_hmac_fini (hnd, geomkey);
|
||||
if (gcry_err)
|
||||
diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
|
||||
index c5858fcf8a..39a7af6a43 100644
|
||||
--- a/grub-core/disk/luks.c
|
||||
+++ b/grub-core/disk/luks.c
|
||||
@@ -29,8 +29,6 @@
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
-#define MAX_PASSPHRASE 256
|
||||
-
|
||||
#define LUKS_KEY_ENABLED 0x00AC71F3
|
||||
|
||||
/* On disk LUKS header */
|
||||
@@ -158,17 +156,14 @@ luks_recover_key (grub_disk_t source,
|
||||
struct grub_luks_phdr header;
|
||||
grub_size_t keysize;
|
||||
grub_uint8_t *split_key = NULL;
|
||||
- char passphrase[MAX_PASSPHRASE] = "";
|
||||
grub_uint8_t candidate_digest[sizeof (header.mkDigest)];
|
||||
unsigned i;
|
||||
grub_size_t length;
|
||||
grub_err_t err;
|
||||
grub_size_t max_stripes = 1;
|
||||
- char *tmp;
|
||||
|
||||
- /* Keyfiles are not implemented yet */
|
||||
- if (cargs->key_data != NULL || cargs->key_len)
|
||||
- return GRUB_ERR_NOT_IMPLEMENTED_YET;
|
||||
+ if (cargs->key_data == NULL || cargs->key_len == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data");
|
||||
|
||||
err = grub_disk_read (source, 0, 0, sizeof (header), &header);
|
||||
if (err)
|
||||
@@ -188,20 +183,6 @@ luks_recover_key (grub_disk_t source,
|
||||
if (!split_key)
|
||||
return grub_errno;
|
||||
|
||||
- /* Get the passphrase from the user. */
|
||||
- tmp = NULL;
|
||||
- if (source->partition)
|
||||
- tmp = grub_partition_get_name (source->partition);
|
||||
- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
- source->partition ? "," : "", tmp ? : "",
|
||||
- dev->uuid);
|
||||
- grub_free (tmp);
|
||||
- if (!grub_password_get (passphrase, MAX_PASSPHRASE))
|
||||
- {
|
||||
- grub_free (split_key);
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
|
||||
- }
|
||||
-
|
||||
/* Try to recover master key from each active keyslot. */
|
||||
for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
|
||||
{
|
||||
@@ -216,8 +197,8 @@ luks_recover_key (grub_disk_t source,
|
||||
grub_dprintf ("luks", "Trying keyslot %d\n", i);
|
||||
|
||||
/* Calculate the PBKDF2 of the user supplied passphrase. */
|
||||
- gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase,
|
||||
- grub_strlen (passphrase),
|
||||
+ gcry_err = grub_crypto_pbkdf2 (dev->hash, cargs->key_data,
|
||||
+ cargs->key_len,
|
||||
header.keyblock[i].passwordSalt,
|
||||
sizeof (header.keyblock[i].passwordSalt),
|
||||
grub_be_to_cpu32 (header.keyblock[i].
|
||||
diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
|
||||
index 2cbec8acc2..09740b53f9 100644
|
||||
--- a/grub-core/disk/luks2.c
|
||||
+++ b/grub-core/disk/luks2.c
|
||||
@@ -35,8 +35,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
#define LUKS_MAGIC_1ST "LUKS\xBA\xBE"
|
||||
#define LUKS_MAGIC_2ND "SKUL\xBA\xBE"
|
||||
|
||||
-#define MAX_PASSPHRASE 256
|
||||
-
|
||||
enum grub_luks2_kdf_type
|
||||
{
|
||||
LUKS2_KDF_TYPE_ARGON2I,
|
||||
@@ -549,8 +547,7 @@ luks2_recover_key (grub_disk_t source,
|
||||
grub_cryptomount_args_t cargs)
|
||||
{
|
||||
grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
|
||||
- char passphrase[MAX_PASSPHRASE], cipher[32];
|
||||
- char *json_header = NULL, *part = NULL, *ptr;
|
||||
+ char cipher[32], *json_header = NULL, *ptr;
|
||||
grub_size_t candidate_key_len = 0, json_idx, size;
|
||||
grub_luks2_header_t header;
|
||||
grub_luks2_keyslot_t keyslot;
|
||||
@@ -560,9 +557,8 @@ luks2_recover_key (grub_disk_t source,
|
||||
grub_json_t *json = NULL, keyslots;
|
||||
grub_err_t ret;
|
||||
|
||||
- /* Keyfiles are not implemented yet */
|
||||
- if (cargs->key_data != NULL || cargs->key_len)
|
||||
- return GRUB_ERR_NOT_IMPLEMENTED_YET;
|
||||
+ if (cargs->key_data == NULL || cargs->key_len == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data");
|
||||
|
||||
ret = luks2_read_header (source, &header);
|
||||
if (ret)
|
||||
@@ -589,18 +585,6 @@ luks2_recover_key (grub_disk_t source,
|
||||
goto err;
|
||||
}
|
||||
|
||||
- /* Get the passphrase from the user. */
|
||||
- if (source->partition)
|
||||
- part = grub_partition_get_name (source->partition);
|
||||
- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
- source->partition ? "," : "", part ? : "",
|
||||
- crypt->uuid);
|
||||
- if (!grub_password_get (passphrase, MAX_PASSPHRASE))
|
||||
- {
|
||||
- ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
if (grub_json_getvalue (&keyslots, json, "keyslots") ||
|
||||
grub_json_getsize (&size, &keyslots))
|
||||
{
|
||||
@@ -725,7 +709,7 @@ luks2_recover_key (grub_disk_t source,
|
||||
}
|
||||
|
||||
ret = luks2_decrypt_key (candidate_key, source, crypt, &keyslot,
|
||||
- (const grub_uint8_t *) passphrase, grub_strlen (passphrase));
|
||||
+ cargs->key_data, cargs->key_len);
|
||||
if (ret)
|
||||
{
|
||||
grub_dprintf ("luks2", "Decryption with keyslot \"%" PRIuGRUB_UINT64_T "\" failed: %s\n",
|
||||
@@ -777,7 +761,6 @@ luks2_recover_key (grub_disk_t source,
|
||||
}
|
||||
|
||||
err:
|
||||
- grub_free (part);
|
||||
grub_free (json_header);
|
||||
grub_json_free (json);
|
||||
return ret;
|
||||
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
|
||||
index 282f8ac456..5bd970692f 100644
|
||||
--- a/include/grub/cryptodisk.h
|
||||
+++ b/include/grub/cryptodisk.h
|
||||
@@ -59,6 +59,7 @@ typedef enum
|
||||
#define GRUB_CRYPTODISK_GF_LOG_BYTES (GRUB_CRYPTODISK_GF_LOG_SIZE - 3)
|
||||
#define GRUB_CRYPTODISK_GF_BYTES (1U << GRUB_CRYPTODISK_GF_LOG_BYTES)
|
||||
#define GRUB_CRYPTODISK_MAX_KEYLEN 128
|
||||
+#define GRUB_CRYPTODISK_MAX_PASSPHRASE 256
|
||||
|
||||
struct grub_cryptodisk;
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
248
0008-cryptodisk-Move-global-variables-into-grub_cryptomou.patch
Normal file
248
0008-cryptodisk-Move-global-variables-into-grub_cryptomou.patch
Normal file
@ -0,0 +1,248 @@
|
||||
From 5323778d84a7289acba0e50d84fb1afd45fff596 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
Date: Thu, 9 Dec 2021 11:14:57 -0600
|
||||
Subject: [PATCH 08/14] cryptodisk: Move global variables into
|
||||
grub_cryptomount_args struct
|
||||
|
||||
Note that cargs.search_uuid does not need to be initialized in various parts
|
||||
of the cryptomount argument parsing, just once when cargs is declared with
|
||||
a struct initializer. The previous code used a global variable which would
|
||||
retain the value across cryptomount invocations.
|
||||
|
||||
Signed-off-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 24 +++++++++---------------
|
||||
grub-core/disk/geli.c | 9 ++++-----
|
||||
grub-core/disk/luks.c | 9 ++++-----
|
||||
grub-core/disk/luks2.c | 8 ++++----
|
||||
include/grub/cryptodisk.h | 9 +++++++--
|
||||
5 files changed, 28 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index d12368a1f7..7ca880402d 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -984,9 +984,6 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk)
|
||||
|
||||
#endif
|
||||
|
||||
-static int check_boot;
|
||||
-static char *search_uuid;
|
||||
-
|
||||
static void
|
||||
cryptodisk_close (grub_cryptodisk_t dev)
|
||||
{
|
||||
@@ -1014,7 +1011,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
|
||||
FOR_CRYPTODISK_DEVS (cr)
|
||||
{
|
||||
- dev = cr->scan (source, search_uuid, check_boot);
|
||||
+ dev = cr->scan (source, cargs);
|
||||
if (grub_errno)
|
||||
return NULL;
|
||||
if (!dev)
|
||||
@@ -1077,6 +1074,7 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat)
|
||||
grub_cryptodisk_t dev;
|
||||
grub_cryptodisk_dev_t cr;
|
||||
grub_disk_t source;
|
||||
+ struct grub_cryptomount_args cargs = {0};
|
||||
|
||||
/* Try to open disk. */
|
||||
source = grub_disk_open (sourcedev);
|
||||
@@ -1093,7 +1091,7 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat)
|
||||
|
||||
FOR_CRYPTODISK_DEVS (cr)
|
||||
{
|
||||
- dev = cr->scan (source, search_uuid, check_boot);
|
||||
+ dev = cr->scan (source, &cargs);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
if (!dev)
|
||||
@@ -1136,7 +1134,7 @@ grub_cryptodisk_scan_device (const char *name,
|
||||
dev = grub_cryptodisk_scan_device_real (name, source, cargs);
|
||||
if (dev)
|
||||
{
|
||||
- ret = (search_uuid != NULL && grub_strcasecmp (search_uuid, dev->uuid) == 0);
|
||||
+ ret = (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, dev->uuid) == 0);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -1147,7 +1145,7 @@ grub_cryptodisk_scan_device (const char *name,
|
||||
if (grub_errno == GRUB_ERR_BAD_MODULE)
|
||||
grub_error_pop ();
|
||||
|
||||
- if (search_uuid != NULL)
|
||||
+ if (cargs->search_uuid != NULL)
|
||||
/* Push error onto stack to save for cryptomount. */
|
||||
grub_error_push ();
|
||||
else
|
||||
@@ -1189,10 +1187,9 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
- check_boot = state[2].set;
|
||||
- search_uuid = args[0];
|
||||
+ cargs.check_boot = state[2].set;
|
||||
+ cargs.search_uuid = args[0];
|
||||
found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
||||
- search_uuid = NULL;
|
||||
|
||||
if (found_uuid)
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -1210,10 +1207,8 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
}
|
||||
else if (state[1].set || (argc == 0 && state[2].set)) /* -a|-b */
|
||||
{
|
||||
- search_uuid = NULL;
|
||||
- check_boot = state[2].set;
|
||||
+ cargs.check_boot = state[2].set;
|
||||
grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
||||
- search_uuid = NULL;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
else
|
||||
@@ -1224,8 +1219,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
char *disklast = NULL;
|
||||
grub_size_t len;
|
||||
|
||||
- search_uuid = NULL;
|
||||
- check_boot = state[2].set;
|
||||
+ cargs.check_boot = state[2].set;
|
||||
diskname = args[0];
|
||||
len = grub_strlen (diskname);
|
||||
if (len && diskname[0] == '(' && diskname[len - 1] == ')')
|
||||
diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c
|
||||
index 7299a47d19..23789c43f3 100644
|
||||
--- a/grub-core/disk/geli.c
|
||||
+++ b/grub-core/disk/geli.c
|
||||
@@ -240,8 +240,7 @@ grub_util_get_geli_uuid (const char *dev)
|
||||
#endif
|
||||
|
||||
static grub_cryptodisk_t
|
||||
-configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
||||
- int boot_only)
|
||||
+configure_ciphers (grub_disk_t disk, grub_cryptomount_args_t cargs)
|
||||
{
|
||||
grub_cryptodisk_t newdev;
|
||||
struct grub_geli_phdr header;
|
||||
@@ -289,7 +288,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- if (boot_only && !(grub_le_to_cpu32 (header.flags) & GRUB_GELI_FLAGS_BOOT))
|
||||
+ if (cargs->check_boot && !(grub_le_to_cpu32 (header.flags) & GRUB_GELI_FLAGS_BOOT))
|
||||
{
|
||||
grub_dprintf ("geli", "not a boot volume\n");
|
||||
return NULL;
|
||||
@@ -302,9 +301,9 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0)
|
||||
+ if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0)
|
||||
{
|
||||
- grub_dprintf ("geli", "%s != %s\n", uuid, check_uuid);
|
||||
+ grub_dprintf ("geli", "%s != %s\n", uuid, cargs->search_uuid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
|
||||
index 39a7af6a43..f0feb38447 100644
|
||||
--- a/grub-core/disk/luks.c
|
||||
+++ b/grub-core/disk/luks.c
|
||||
@@ -63,8 +63,7 @@ gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src,
|
||||
grub_size_t blocknumbers);
|
||||
|
||||
static grub_cryptodisk_t
|
||||
-configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
||||
- int check_boot)
|
||||
+configure_ciphers (grub_disk_t disk, grub_cryptomount_args_t cargs)
|
||||
{
|
||||
grub_cryptodisk_t newdev;
|
||||
const char *iptr;
|
||||
@@ -76,7 +75,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
||||
char hashspec[sizeof (header.hashSpec) + 1];
|
||||
grub_err_t err;
|
||||
|
||||
- if (check_boot)
|
||||
+ if (cargs->check_boot)
|
||||
return NULL;
|
||||
|
||||
/* Read the LUKS header. */
|
||||
@@ -103,9 +102,9 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
||||
}
|
||||
*optr = 0;
|
||||
|
||||
- if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0)
|
||||
+ if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0)
|
||||
{
|
||||
- grub_dprintf ("luks", "%s != %s\n", uuid, check_uuid);
|
||||
+ grub_dprintf ("luks", "%s != %s\n", uuid, cargs->search_uuid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
|
||||
index 09740b53f9..ccfacb63a3 100644
|
||||
--- a/grub-core/disk/luks2.c
|
||||
+++ b/grub-core/disk/luks2.c
|
||||
@@ -346,14 +346,14 @@ luks2_read_header (grub_disk_t disk, grub_luks2_header_t *outhdr)
|
||||
}
|
||||
|
||||
static grub_cryptodisk_t
|
||||
-luks2_scan (grub_disk_t disk, const char *check_uuid, int check_boot)
|
||||
+luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
|
||||
{
|
||||
grub_cryptodisk_t cryptodisk;
|
||||
grub_luks2_header_t header;
|
||||
char uuid[sizeof (header.uuid) + 1];
|
||||
grub_size_t i, j;
|
||||
|
||||
- if (check_boot)
|
||||
+ if (cargs->check_boot)
|
||||
return NULL;
|
||||
|
||||
if (luks2_read_header (disk, &header))
|
||||
@@ -367,9 +367,9 @@ luks2_scan (grub_disk_t disk, const char *check_uuid, int check_boot)
|
||||
uuid[j++] = header.uuid[i];
|
||||
uuid[j] = '\0';
|
||||
|
||||
- if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0)
|
||||
+ if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0)
|
||||
{
|
||||
- grub_dprintf ("luks2", "%s != %s\n", uuid, check_uuid);
|
||||
+ grub_dprintf ("luks2", "%s != %s\n", uuid, cargs->search_uuid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
|
||||
index 5bd970692f..c6524c9ea9 100644
|
||||
--- a/include/grub/cryptodisk.h
|
||||
+++ b/include/grub/cryptodisk.h
|
||||
@@ -69,7 +69,13 @@ typedef gcry_err_code_t
|
||||
|
||||
struct grub_cryptomount_args
|
||||
{
|
||||
+ /* scan: Flag to indicate that only bootable volumes should be decrypted */
|
||||
+ grub_uint32_t check_boot : 1;
|
||||
+ /* scan: Only volumes matching this UUID should be decrpyted */
|
||||
+ char *search_uuid;
|
||||
+ /* recover_key: Key data used to decrypt voume */
|
||||
grub_uint8_t *key_data;
|
||||
+ /* recover_key: Length of key_data */
|
||||
grub_size_t key_len;
|
||||
};
|
||||
typedef struct grub_cryptomount_args *grub_cryptomount_args_t;
|
||||
@@ -125,8 +131,7 @@ struct grub_cryptodisk_dev
|
||||
struct grub_cryptodisk_dev *next;
|
||||
struct grub_cryptodisk_dev **prev;
|
||||
|
||||
- grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid,
|
||||
- int boot_only);
|
||||
+ grub_cryptodisk_t (*scan) (grub_disk_t disk, grub_cryptomount_args_t cargs);
|
||||
grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs);
|
||||
};
|
||||
typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t;
|
||||
--
|
||||
2.34.1
|
||||
|
156
0008-linuxefi-Use-common-grub_initrd_load.patch
Normal file
156
0008-linuxefi-Use-common-grub_initrd_load.patch
Normal file
@ -0,0 +1,156 @@
|
||||
From adf486860fe0d395579be8b01d4fda8b93377768 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 8 Jun 2022 16:04:12 +0800
|
||||
Subject: [PATCH 08/10] linuxefi: Use common grub_initrd_load
|
||||
|
||||
By using the common initrd loading routine factored out allows to share between
|
||||
features like concatenating initramfs component.
|
||||
|
||||
For eg.
|
||||
|
||||
initrdefi /initrd-5.16.15-1-default newc:grub.cfg:/grub2/grub.cfg
|
||||
|
||||
The file /grub2/grub.cfg read off from root disk will be available to use as
|
||||
/grub.cfg in the target initramfs loaded by grub.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/loader/i386/efi/linux.c | 87 ++++---------------------------
|
||||
1 file changed, 10 insertions(+), 77 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index 6b06a8f2ff..f93395fc62 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <grub/cpu/efi/memory.h>
|
||||
#include <grub/tpm.h>
|
||||
#include <grub/safemath.h>
|
||||
+#include <grub/linux.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -146,44 +147,6 @@ grub_linuxefi_unload (void)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
-#define BOUNCE_BUFFER_MAX 0x1000000ull
|
||||
-
|
||||
-static grub_ssize_t
|
||||
-read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len)
|
||||
-{
|
||||
- grub_ssize_t bufpos = 0;
|
||||
- static grub_size_t bbufsz = 0;
|
||||
- static char *bbuf = NULL;
|
||||
-
|
||||
- if (bbufsz == 0)
|
||||
- bbufsz = MIN(BOUNCE_BUFFER_MAX, len);
|
||||
-
|
||||
- while (!bbuf && bbufsz)
|
||||
- {
|
||||
- bbuf = grub_malloc(bbufsz);
|
||||
- if (!bbuf)
|
||||
- bbufsz >>= 1;
|
||||
- }
|
||||
- if (!bbuf)
|
||||
- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate bounce buffer"));
|
||||
-
|
||||
- while (bufpos < (long long)len)
|
||||
- {
|
||||
- grub_ssize_t sz;
|
||||
-
|
||||
- sz = grub_file_read (file, bbuf, MIN(bbufsz, len - bufpos));
|
||||
- if (sz < 0)
|
||||
- return sz;
|
||||
- if (sz == 0)
|
||||
- break;
|
||||
-
|
||||
- grub_memcpy(bufp + bufpos, bbuf, sz);
|
||||
- bufpos += sz;
|
||||
- }
|
||||
-
|
||||
- return bufpos;
|
||||
-}
|
||||
-
|
||||
#define LOW_U32(val) ((grub_uint32_t)(((grub_addr_t)(val)) & 0xffffffffull))
|
||||
#define HIGH_U32(val) ((grub_uint32_t)(((grub_addr_t)(val) >> 32) & 0xffffffffull))
|
||||
|
||||
@@ -191,10 +154,8 @@ static grub_err_t
|
||||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
- grub_file_t *files = 0;
|
||||
- int i, nfiles = 0;
|
||||
+ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
|
||||
grub_size_t size = 0;
|
||||
- grub_uint8_t *ptr;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
@@ -208,24 +169,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- files = grub_calloc (argc, sizeof (files[0]));
|
||||
- if (!files)
|
||||
+ if (grub_initrd_init (argc, argv, &initrd_ctx))
|
||||
goto fail;
|
||||
|
||||
- for (i = 0; i < argc; i++)
|
||||
- {
|
||||
- files[i] = grub_file_open (argv[i], GRUB_FILE_TYPE_LINUX_INITRD
|
||||
- | GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
- if (! files[i])
|
||||
- goto fail;
|
||||
- nfiles++;
|
||||
- if (grub_add (size, ALIGN_UP (grub_file_size (files[i]), 4), &size))
|
||||
- {
|
||||
- grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
- goto fail;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
+ size = grub_get_initrd_size (&initrd_ctx);
|
||||
initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
|
||||
if (initrd_mem == NULL)
|
||||
goto fail;
|
||||
@@ -238,30 +185,16 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
params->ext_ramdisk_image = HIGH_U32(initrd_mem);
|
||||
#endif
|
||||
|
||||
- ptr = initrd_mem;
|
||||
-
|
||||
- for (i = 0; i < nfiles; i++)
|
||||
- {
|
||||
- grub_ssize_t cursize = grub_file_size (files[i]);
|
||||
- if (read (files[i], ptr, cursize) != cursize)
|
||||
- {
|
||||
- if (!grub_errno)
|
||||
- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
- argv[i]);
|
||||
- goto fail;
|
||||
- }
|
||||
- ptr += cursize;
|
||||
- grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
|
||||
- ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||
- }
|
||||
+ /* FIXME: Use bounce buffers as many UEFI machines apparently can't DMA
|
||||
+ * correctly above 4GB
|
||||
+ */
|
||||
+ if (grub_initrd_load (&initrd_ctx, argv, initrd_mem))
|
||||
+ goto fail;
|
||||
|
||||
params->ramdisk_size = size;
|
||||
|
||||
fail:
|
||||
- for (i = 0; i < nfiles; i++)
|
||||
- grub_file_close (files[i]);
|
||||
- grub_free (files);
|
||||
-
|
||||
+ grub_initrd_close (&initrd_ctx);
|
||||
if (initrd_mem && grub_errno)
|
||||
grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, BYTES_TO_PAGES(size));
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
328
0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch
Normal file
328
0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch
Normal file
@ -0,0 +1,328 @@
|
||||
From 749f7dee6f63217e536663aebb817aec72a65d5a Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 9 Jun 2022 21:06:00 +0800
|
||||
Subject: [PATCH 09/10] Add crypttab_entry to obviate the need to input
|
||||
password twice
|
||||
|
||||
This patch adds crypttab_entry command to hint grub where to put the key file
|
||||
automatically loaded by linux cryptsetup. It's syntax is similar to
|
||||
/etc/crypttab so that it is relatively straightforward to import.
|
||||
|
||||
crypttab_entry <volume-name> <encrypted-device> <key-file>
|
||||
|
||||
For eg:
|
||||
|
||||
crypttab_entry cr_root 5e1dd109e39343f984da57fd742d3f23 none
|
||||
|
||||
Please note the "encrypted-device" only accepts UUID without dashes as it is
|
||||
the only identification used by grub's cryptodisk device. The crypttab_entry
|
||||
can also be used multiple times to specify encrypted volumes unlocked by
|
||||
"cryptomount -a".
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 5 +
|
||||
grub-core/commands/crypttab.c | 42 ++++++++++++
|
||||
grub-core/disk/cryptodisk.c | 6 +
|
||||
grub-core/loader/linux.c | 137 ++++++++++++++++++++++++++++++++++++++++--
|
||||
include/grub/linux.h | 3
|
||||
5 files changed, 188 insertions(+), 5 deletions(-)
|
||||
create mode 100644 grub-core/commands/crypttab.c
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -2643,3 +2643,8 @@
|
||||
cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
|
||||
cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
|
||||
};
|
||||
+
|
||||
+module = {
|
||||
+ name = crypttab;
|
||||
+ common = commands/crypttab.c;
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -0,0 +1,42 @@
|
||||
+
|
||||
+#include <grub/dl.h>
|
||||
+#include <grub/command.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/i18n.h>
|
||||
+#include <grub/linux.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
+ int argc, char **argv)
|
||||
+{
|
||||
+ char buf[64];
|
||||
+ const char *path = argv[2];
|
||||
+
|
||||
+ if (argc != 3)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("three arguments expected"));
|
||||
+
|
||||
+ if (grub_strcmp (argv[2], "none") == 0
|
||||
+ || grub_strcmp (argv[2], "-") == 0)
|
||||
+ {
|
||||
+ grub_snprintf (buf, sizeof (buf), "/etc/cryptsetup-keys.d/%s.key", argv[0]);
|
||||
+ path = buf;
|
||||
+ }
|
||||
+
|
||||
+ /*FIXME: Validate UUID string*/
|
||||
+ return grub_initrd_publish_key (argv[1], NULL, 0, path);
|
||||
+}
|
||||
+
|
||||
+static grub_command_t cmd;
|
||||
+
|
||||
+GRUB_MOD_INIT(crypttab)
|
||||
+{
|
||||
+ cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry,
|
||||
+ N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description"));
|
||||
+}
|
||||
+
|
||||
+GRUB_MOD_FINI(crypttab)
|
||||
+{
|
||||
+ grub_unregister_command (cmd);
|
||||
+}
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
#include <grub/emu/hostdisk.h>
|
||||
+#else
|
||||
+#include <grub/linux.h>
|
||||
#endif
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
@@ -1146,6 +1148,10 @@
|
||||
dev = NULL;
|
||||
|
||||
cleanup:
|
||||
+#ifndef GRUB_UTIL
|
||||
+ if (cargs->key_data && dev)
|
||||
+ grub_initrd_publish_key (dev->uuid, (const char *)cargs->key_data, cargs->key_len, NULL);
|
||||
+#endif
|
||||
if (askpass)
|
||||
{
|
||||
cargs->key_len = 0;
|
||||
--- a/grub-core/loader/linux.c
|
||||
+++ b/grub-core/loader/linux.c
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <grub/file.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/safemath.h>
|
||||
+#include <grub/list.h>
|
||||
|
||||
struct newc_head
|
||||
{
|
||||
@@ -27,6 +28,7 @@
|
||||
struct grub_linux_initrd_component
|
||||
{
|
||||
grub_file_t file;
|
||||
+ char *buf;
|
||||
char *newc_name;
|
||||
grub_off_t size;
|
||||
};
|
||||
@@ -38,6 +40,18 @@
|
||||
struct dir *child;
|
||||
};
|
||||
|
||||
+struct grub_key_publisher
|
||||
+{
|
||||
+ struct grub_key_publisher *next;
|
||||
+ struct grub_key_publisher **prev;
|
||||
+ char *name; /* UUID */
|
||||
+ char *path;
|
||||
+ char *key;
|
||||
+ grub_size_t key_len;
|
||||
+};
|
||||
+
|
||||
+static struct grub_key_publisher *kpuber;
|
||||
+
|
||||
static char
|
||||
hex (grub_uint8_t val)
|
||||
{
|
||||
@@ -149,6 +163,65 @@
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+grub_initrd_component (const char *buf, int bufsz, const char *newc_name,
|
||||
+ struct grub_linux_initrd_context *initrd_ctx)
|
||||
+{
|
||||
+ struct dir *root = 0;
|
||||
+ struct grub_linux_initrd_component *comp = initrd_ctx->components + initrd_ctx->nfiles;
|
||||
+ grub_size_t dir_size, name_len;
|
||||
+
|
||||
+ while (*newc_name == '/')
|
||||
+ newc_name++;
|
||||
+
|
||||
+ initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
|
||||
+ comp->newc_name = grub_strdup (newc_name);
|
||||
+ if (!comp->newc_name ||
|
||||
+ insert_dir (comp->newc_name, &root, 0, &dir_size))
|
||||
+ {
|
||||
+ /* FIXME: Check NULL file pointer before close */
|
||||
+ grub_initrd_close (initrd_ctx);
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+ /* Should name_len count terminating null ? */
|
||||
+ name_len = grub_strlen (comp->newc_name) + 1;
|
||||
+ if (grub_add (initrd_ctx->size,
|
||||
+ ALIGN_UP (sizeof (struct newc_head) + name_len, 4),
|
||||
+ &initrd_ctx->size) ||
|
||||
+ grub_add (initrd_ctx->size, dir_size, &initrd_ctx->size))
|
||||
+ goto overflow;
|
||||
+
|
||||
+ comp->buf = grub_malloc (bufsz);
|
||||
+ if (!comp->buf)
|
||||
+ {
|
||||
+ free_dir (root);
|
||||
+ grub_initrd_close (initrd_ctx);
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+ grub_memcpy (comp->buf, buf, bufsz);
|
||||
+ initrd_ctx->nfiles++;
|
||||
+ comp->size = bufsz;
|
||||
+ if (grub_add (initrd_ctx->size, comp->size,
|
||||
+ &initrd_ctx->size))
|
||||
+ goto overflow;
|
||||
+
|
||||
+ initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
|
||||
+ if (grub_add (initrd_ctx->size,
|
||||
+ ALIGN_UP (sizeof (struct newc_head)
|
||||
+ + sizeof ("TRAILER!!!") - 1, 4),
|
||||
+ &initrd_ctx->size))
|
||||
+ goto overflow;
|
||||
+
|
||||
+ free_dir (root);
|
||||
+ root = 0;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ overflow:
|
||||
+ free_dir (root);
|
||||
+ grub_initrd_close (initrd_ctx);
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
+}
|
||||
+
|
||||
grub_err_t
|
||||
grub_initrd_init (int argc, char *argv[],
|
||||
struct grub_linux_initrd_context *initrd_ctx)
|
||||
@@ -156,11 +229,17 @@
|
||||
int i;
|
||||
int newc = 0;
|
||||
struct dir *root = 0;
|
||||
+ struct grub_key_publisher *pk;
|
||||
+ int numkey = 0;
|
||||
|
||||
initrd_ctx->nfiles = 0;
|
||||
initrd_ctx->components = 0;
|
||||
|
||||
- initrd_ctx->components = grub_calloc (argc, sizeof (initrd_ctx->components[0]));
|
||||
+ FOR_LIST_ELEMENTS (pk, kpuber)
|
||||
+ if (pk->key && pk->path)
|
||||
+ numkey++;
|
||||
+
|
||||
+ initrd_ctx->components = grub_calloc (argc + numkey, sizeof (initrd_ctx->components[0]));
|
||||
if (!initrd_ctx->components)
|
||||
return grub_errno;
|
||||
|
||||
@@ -239,7 +318,10 @@
|
||||
free_dir (root);
|
||||
root = 0;
|
||||
}
|
||||
-
|
||||
+
|
||||
+ FOR_LIST_ELEMENTS (pk, kpuber)
|
||||
+ if (pk->key && pk->path)
|
||||
+ grub_initrd_component (pk->key, pk->key_len, pk->path, initrd_ctx);
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
overflow:
|
||||
@@ -263,7 +345,9 @@
|
||||
for (i = 0; i < initrd_ctx->nfiles; i++)
|
||||
{
|
||||
grub_free (initrd_ctx->components[i].newc_name);
|
||||
- grub_file_close (initrd_ctx->components[i].file);
|
||||
+ if (initrd_ctx->components[i].file)
|
||||
+ grub_file_close (initrd_ctx->components[i].file);
|
||||
+ grub_free (initrd_ctx->components[i].buf);
|
||||
}
|
||||
grub_free (initrd_ctx->components);
|
||||
initrd_ctx->components = 0;
|
||||
@@ -297,7 +381,7 @@
|
||||
}
|
||||
ptr += dir_size;
|
||||
ptr = make_header (ptr, initrd_ctx->components[i].newc_name,
|
||||
- grub_strlen (initrd_ctx->components[i].newc_name),
|
||||
+ grub_strlen (initrd_ctx->components[i].newc_name) + 1,
|
||||
0100777,
|
||||
initrd_ctx->components[i].size);
|
||||
newc = 1;
|
||||
@@ -312,7 +396,12 @@
|
||||
}
|
||||
|
||||
cursize = initrd_ctx->components[i].size;
|
||||
- if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize)
|
||||
+ if (initrd_ctx->components[i].buf)
|
||||
+ {
|
||||
+ grub_memcpy (ptr, initrd_ctx->components[i].buf, cursize);
|
||||
+ newc = 1;
|
||||
+ }
|
||||
+ else if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize)
|
||||
!= cursize)
|
||||
{
|
||||
if (!grub_errno)
|
||||
@@ -333,3 +422,41 @@
|
||||
root = 0;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path)
|
||||
+{
|
||||
+ struct grub_key_publisher *cur = grub_named_list_find (GRUB_AS_NAMED_LIST (kpuber), uuid);
|
||||
+
|
||||
+ if (!cur)
|
||||
+ cur = grub_zalloc (sizeof (*cur));
|
||||
+ if (!cur)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ if (key && key_len)
|
||||
+ {
|
||||
+ grub_free (cur->key);
|
||||
+ cur->key = grub_malloc (key_len);
|
||||
+ if (!cur->key)
|
||||
+ {
|
||||
+ grub_free (cur);
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+ grub_memcpy (cur->key, key, key_len);
|
||||
+ cur->key_len = key_len;
|
||||
+ }
|
||||
+
|
||||
+ if (path)
|
||||
+ {
|
||||
+ grub_free (cur->path);
|
||||
+ cur->path = grub_strdup (path);
|
||||
+ }
|
||||
+
|
||||
+ if (!cur->name)
|
||||
+ {
|
||||
+ cur->name = grub_strdup (uuid);
|
||||
+ grub_list_push (GRUB_AS_LIST_P (&kpuber), GRUB_AS_LIST (cur));
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
--- a/include/grub/linux.h
|
||||
+++ b/include/grub/linux.h
|
||||
@@ -22,3 +22,6 @@
|
||||
grub_err_t
|
||||
grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
|
||||
char *argv[], void *target);
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path);
|
@ -0,0 +1,39 @@
|
||||
From b1acd971fa648fa3c6f3a54db4fdf45fae02ce54 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
Date: Thu, 9 Dec 2021 11:14:58 -0600
|
||||
Subject: [PATCH 09/14] cryptodisk: Improve handling of partition name in
|
||||
cryptomount password prompt
|
||||
|
||||
Call grub_partition_get_name() unconditionally to initialize the part
|
||||
variable. Then part will only be NULL when grub_partition_get_name() errors.
|
||||
Note that when source->partition is NULL, then grub_partition_get_name()
|
||||
returns an allocated empty string. So no comma or partition will be printed,
|
||||
as desired.
|
||||
|
||||
Signed-off-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 7ca880402d..497097394f 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1021,11 +1021,10 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
{
|
||||
/* Get the passphrase from the user, if no key data. */
|
||||
askpass = 1;
|
||||
- if (source->partition != NULL)
|
||||
- part = grub_partition_get_name (source->partition);
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
source->partition != NULL ? "," : "",
|
||||
- part != NULL ? part : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"),
|
||||
dev->uuid);
|
||||
grub_free (part);
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
189
0010-protectors-Add-key-protectors-framework.patch
Normal file
189
0010-protectors-Add-key-protectors-framework.patch
Normal file
@ -0,0 +1,189 @@
|
||||
From 2d959549857305d5e4d95a19a0850885f85179d6 Mon Sep 17 00:00:00 2001
|
||||
From: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Date: Tue, 1 Feb 2022 05:02:53 -0800
|
||||
Subject: [PATCH 10/14] protectors: Add key protectors framework
|
||||
|
||||
A key protector encapsulates functionality to retrieve an unlocking key for a
|
||||
fully-encrypted disk from a specific source. A key protector module registers
|
||||
itself with the key protectors framework when it is loaded and unregisters when
|
||||
unloaded. Additionally, a key protector may accept parameters that describe how
|
||||
it should operate.
|
||||
|
||||
The key protectors framework, besides offering registration and unregistration
|
||||
functions, also offers a one-stop routine for finding and invoking a key
|
||||
protector by name. If a key protector with the specified name exists and if an
|
||||
unlocking key is successfully retrieved by it, the function returns to the
|
||||
caller the retrieved key and its length.
|
||||
|
||||
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
---
|
||||
grub-core/Makefile.am | 1 +
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/kern/protectors.c | 75 +++++++++++++++++++++++++++++++++++++
|
||||
include/grub/protector.h | 48 ++++++++++++++++++++++++
|
||||
4 files changed, 125 insertions(+)
|
||||
create mode 100644 grub-core/kern/protectors.c
|
||||
create mode 100644 include/grub/protector.h
|
||||
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index de241f0d04..dc07ba6f87 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -90,6 +90,7 @@ endif
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/protector.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index f3140815b8..b0001a33cf 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -138,6 +138,7 @@ kernel = {
|
||||
common = kern/misc.c;
|
||||
common = kern/parser.c;
|
||||
common = kern/partition.c;
|
||||
+ common = kern/protectors.c;
|
||||
common = kern/rescue_parser.c;
|
||||
common = kern/rescue_reader.c;
|
||||
common = kern/term.c;
|
||||
diff --git a/grub-core/kern/protectors.c b/grub-core/kern/protectors.c
|
||||
new file mode 100644
|
||||
index 0000000000..21954dfa48
|
||||
--- /dev/null
|
||||
+++ b/grub-core/kern/protectors.c
|
||||
@@ -0,0 +1,75 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2022 Microsoft 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/list.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/protector.h>
|
||||
+
|
||||
+struct grub_key_protector *grub_key_protectors = NULL;
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_register (struct grub_key_protector *protector)
|
||||
+{
|
||||
+ if (!protector || !protector->name || !grub_strlen(protector->name))
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ if (grub_key_protectors &&
|
||||
+ grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors),
|
||||
+ protector->name))
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors),
|
||||
+ GRUB_AS_LIST (protector));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_unregister (struct grub_key_protector *protector)
|
||||
+{
|
||||
+ if (!protector)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ grub_list_remove (GRUB_AS_LIST (protector));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_recover_key (const char *protector, grub_uint8_t **key,
|
||||
+ grub_size_t *key_size)
|
||||
+{
|
||||
+ struct grub_key_protector *kp = NULL;
|
||||
+
|
||||
+ if (!grub_key_protectors)
|
||||
+ return GRUB_ERR_OUT_OF_RANGE;
|
||||
+
|
||||
+ if (!protector || !grub_strlen (protector))
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors),
|
||||
+ protector);
|
||||
+ if (!kp)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("A key protector with name '%s' could not be found. "
|
||||
+ "Is the name spelled correctly and is the "
|
||||
+ "corresponding module loaded?"), protector);
|
||||
+
|
||||
+ return kp->recover_key (key, key_size);
|
||||
+}
|
||||
diff --git a/include/grub/protector.h b/include/grub/protector.h
|
||||
new file mode 100644
|
||||
index 0000000000..179020a344
|
||||
--- /dev/null
|
||||
+++ b/include/grub/protector.h
|
||||
@@ -0,0 +1,48 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2022 Microsoft 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/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef GRUB_PROTECTOR_HEADER
|
||||
+#define GRUB_PROTECTOR_HEADER 1
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/types.h>
|
||||
+
|
||||
+struct grub_key_protector
|
||||
+{
|
||||
+ struct grub_key_protector *next;
|
||||
+ struct grub_key_protector **prev;
|
||||
+
|
||||
+ const char *name;
|
||||
+
|
||||
+ grub_err_t (*recover_key) (grub_uint8_t **key, grub_size_t *key_size);
|
||||
+};
|
||||
+
|
||||
+extern struct grub_key_protector *EXPORT_VAR (grub_key_protectors);
|
||||
+
|
||||
+grub_err_t
|
||||
+EXPORT_FUNC (grub_key_protector_register) (struct grub_key_protector *protector);
|
||||
+
|
||||
+grub_err_t
|
||||
+EXPORT_FUNC (grub_key_protector_unregister) (struct grub_key_protector *protector);
|
||||
+
|
||||
+grub_err_t
|
||||
+EXPORT_FUNC (grub_key_protector_recover_key) (const char *protector,
|
||||
+ grub_uint8_t **key,
|
||||
+ grub_size_t *key_size);
|
||||
+
|
||||
+#endif /* ! GRUB_PROTECTOR_HEADER */
|
||||
--
|
||||
2.34.1
|
||||
|
81
0010-templates-import-etc-crypttab-to-grub.cfg.patch
Normal file
81
0010-templates-import-etc-crypttab-to-grub.cfg.patch
Normal file
@ -0,0 +1,81 @@
|
||||
From 2d3130c289b293269dcf558a26674f83f77729a6 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 14 Jun 2022 17:10:01 +0800
|
||||
Subject: [PATCH 10/10] templates: import /etc/crypttab to grub.cfg
|
||||
|
||||
The /etc/crypptab is used to setup location of encryption key files during
|
||||
boot, among other things. It is useful to make use the information by grub to
|
||||
determine where keys are being looked up.
|
||||
|
||||
This script can be used to import relevant /etc/crypptab entry to grub.cfg.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
Makefile.util.def | 7 +++++++
|
||||
util/grub.d/05_crypttab.in | 36 ++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 43 insertions(+)
|
||||
create mode 100644 util/grub.d/05_crypttab.in
|
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def
|
||||
index 08f681cd8b..5e0ba22f3d 100644
|
||||
--- a/Makefile.util.def
|
||||
+++ b/Makefile.util.def
|
||||
@@ -476,6 +476,13 @@ script = {
|
||||
installdir = grubconf;
|
||||
};
|
||||
|
||||
+script = {
|
||||
+ name = '05_crypttab';
|
||||
+ common = util/grub.d/05_crypttab.in;
|
||||
+ installdir = grubconf;
|
||||
+ condition = COND_HOST_LINUX;
|
||||
+};
|
||||
+
|
||||
script = {
|
||||
name = '10_windows';
|
||||
common = util/grub.d/10_windows.in;
|
||||
diff --git a/util/grub.d/05_crypttab.in b/util/grub.d/05_crypttab.in
|
||||
new file mode 100644
|
||||
index 0000000000..c539bc061e
|
||||
--- /dev/null
|
||||
+++ b/util/grub.d/05_crypttab.in
|
||||
@@ -0,0 +1,36 @@
|
||||
+#! /bin/sh
|
||||
+set -e
|
||||
+
|
||||
+# grub-mkconfig helper script.
|
||||
+# Copyright (C) 2022 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 <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+prefix="@prefix@"
|
||||
+exec_prefix="@exec_prefix@"
|
||||
+datarootdir="@datarootdir@"
|
||||
+
|
||||
+export TEXTDOMAIN=@PACKAGE@
|
||||
+export TEXTDOMAINDIR="@localedir@"
|
||||
+
|
||||
+. "$pkgdatadir/grub-mkconfig_lib"
|
||||
+
|
||||
+CRYPTTAB=/etc/crypttab
|
||||
+
|
||||
+if [ -r "$CRYPTTAB" ]; then
|
||||
+ awk '/UUID=/ { sub(/UUID=/,"",$2); \
|
||||
+ gsub(/-/,"",$2); \
|
||||
+ printf("crypttab_entry %s %s %s\n",$1,$2,$3) \
|
||||
+ }' "$CRYPTTAB"
|
||||
+fi
|
||||
--
|
||||
2.34.1
|
||||
|
3523
0011-tpm2-Add-TPM-Software-Stack-TSS.patch
Normal file
3523
0011-tpm2-Add-TPM-Software-Stack-TSS.patch
Normal file
File diff suppressed because it is too large
Load Diff
977
0012-protectors-Add-TPM2-Key-Protector.patch
Normal file
977
0012-protectors-Add-TPM2-Key-Protector.patch
Normal file
@ -0,0 +1,977 @@
|
||||
From b173db7537920ee5706e1c961fea3086ada6b6dd Mon Sep 17 00:00:00 2001
|
||||
From: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Date: Tue, 1 Feb 2022 05:02:55 -0800
|
||||
Subject: [PATCH 12/14] protectors: Add TPM2 Key Protector
|
||||
|
||||
The TPM2 key protector is a module that enables the automatic retrieval of a
|
||||
fully-encrypted disk's unlocking key from a TPM 2.0.
|
||||
|
||||
The theory of operation is such that the module accepts various arguments, most
|
||||
of which are optional and therefore possess reasonable defaults. One of these
|
||||
arguments is the keyfile parameter, which is mandatory.
|
||||
|
||||
The value of this parameter must be a path to a sealed key file (e.g.,
|
||||
(hd0,gpt1)/boot/grub2/sealed_key). This sealed key file is created via the
|
||||
grub-protect tool. The tool utilizes the TPM's sealing functionality to seal
|
||||
(i.e., encrypt) an unlocking key using a Storage Root Key (SRK) to the values of
|
||||
various Platform Configuration Registers (PCRs). These PCRs reflect the state of
|
||||
the system as it boots. If the values are as expected, the system may be
|
||||
considered trustworthy, at which point the TPM allows for a caller to utilize
|
||||
the private component of the SRK to unseal (i.e., decrypt) the sealed key file.
|
||||
The caller, in this case, is this key protector.
|
||||
|
||||
The TPM2 key protector registers two commands:
|
||||
|
||||
- tpm2_key_protector_init: Initializes the state of the TPM2 key protector for
|
||||
later usage, clearing any previous state, too, if
|
||||
any.
|
||||
|
||||
- tpm2_key_protector_clear: Clears any state set by tpm2_key_protector_init.
|
||||
|
||||
The way this is expected to be used requires the user to, either interactively
|
||||
or, normally, via a boot script, initialize (i.e., configure) the key protector
|
||||
and then specify that it be used by the cryptomount command (modifications to
|
||||
this command are in a different patch).
|
||||
|
||||
For instance:
|
||||
|
||||
tpm2_key_protector_init --keyfile=KEYFILE1
|
||||
cryptomount DISK1 -k tpm2
|
||||
|
||||
tpm2_key_protector_init --keyfile=KEYFILE2 --pcrs=7,11
|
||||
cryptomount DISK2 -k tpm2
|
||||
|
||||
If a user does not initialize the key protector and attempts to use it anyway,
|
||||
the protector returns an error.
|
||||
|
||||
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 10 +
|
||||
grub-core/tpm2/args.c | 129 ++++++
|
||||
grub-core/tpm2/module.c | 710 ++++++++++++++++++++++++++++++
|
||||
include/grub/tpm2/internal/args.h | 39 ++
|
||||
4 files changed, 888 insertions(+)
|
||||
create mode 100644 grub-core/tpm2/args.c
|
||||
create mode 100644 grub-core/tpm2/module.c
|
||||
create mode 100644 include/grub/tpm2/internal/args.h
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index b0001a33cf..850cee2b13 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -2561,6 +2561,16 @@ module = {
|
||||
enable = efi;
|
||||
};
|
||||
|
||||
+module = {
|
||||
+ name = tpm2;
|
||||
+ common = tpm2/args.c;
|
||||
+ common = tpm2/buffer.c;
|
||||
+ common = tpm2/module.c;
|
||||
+ common = tpm2/mu.c;
|
||||
+ common = tpm2/tpm2.c;
|
||||
+ efi = tpm2/tcg2.c;
|
||||
+};
|
||||
+
|
||||
module = {
|
||||
name = tr;
|
||||
common = commands/tr.c;
|
||||
diff --git a/grub-core/tpm2/args.c b/grub-core/tpm2/args.c
|
||||
new file mode 100644
|
||||
index 0000000000..90c7cd8991
|
||||
--- /dev/null
|
||||
+++ b/grub-core/tpm2/args.c
|
||||
@@ -0,0 +1,129 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2022 Microsoft 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/tpm2/internal/args.h>
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs,
|
||||
+ grub_uint8_t *pcr_count)
|
||||
+{
|
||||
+ char *current_pcr = value;
|
||||
+ char *next_pcr;
|
||||
+ unsigned long pcr;
|
||||
+ grub_uint8_t i;
|
||||
+
|
||||
+ if (grub_strlen (value) == 0)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ *pcr_count = 0;
|
||||
+ for (i = 0; i < TPM_MAX_PCRS; i++)
|
||||
+ {
|
||||
+ next_pcr = grub_strchr (current_pcr, ',');
|
||||
+ if (next_pcr == current_pcr)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("Empty entry in PCR list"));
|
||||
+ if (next_pcr)
|
||||
+ *next_pcr = '\0';
|
||||
+
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ pcr = grub_strtoul (current_pcr, NULL, 10);
|
||||
+ if (grub_errno != GRUB_ERR_NONE)
|
||||
+ return grub_error (grub_errno,
|
||||
+ N_("Entry '%s' in PCR list is not a number"),
|
||||
+ current_pcr);
|
||||
+
|
||||
+ if (pcr > TPM_MAX_PCRS)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("Entry %lu in PCR list is too large to be a PCR "
|
||||
+ "number, PCR numbers range from 0 to %u"),
|
||||
+ pcr, TPM_MAX_PCRS);
|
||||
+
|
||||
+ pcrs[i] = (grub_uint8_t)pcr;
|
||||
+ *pcr_count += 1;
|
||||
+
|
||||
+ if (!next_pcr)
|
||||
+ break;
|
||||
+
|
||||
+ current_pcr = next_pcr + 1;
|
||||
+ if (*current_pcr == '\0')
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("Trailing comma at the end of PCR list"));
|
||||
+ }
|
||||
+
|
||||
+ if (i == TPM_MAX_PCRS)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("Too many PCRs in PCR list, the maximum number of "
|
||||
+ "PCRs is %u"), TPM_MAX_PCRS);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_tpm2_protector_parse_asymmetric (const char *value, TPM_ALG_ID *asymmetric)
|
||||
+{
|
||||
+ if (grub_strcasecmp (value, "ECC") == 0)
|
||||
+ *asymmetric = TPM_ALG_ECC;
|
||||
+ else if (grub_strcasecmp (value, "RSA") == 0)
|
||||
+ *asymmetric = TPM_ALG_RSA;
|
||||
+ else
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("Value '%s' is not a valid asymmetric key type"),
|
||||
+ value);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID *bank)
|
||||
+{
|
||||
+ if (grub_strcasecmp (value, "SHA1") == 0)
|
||||
+ *bank = TPM_ALG_SHA1;
|
||||
+ else if (grub_strcasecmp (value, "SHA256") == 0)
|
||||
+ *bank = TPM_ALG_SHA256;
|
||||
+ else if (grub_strcasecmp (value, "SHA384") == 0)
|
||||
+ *bank = TPM_ALG_SHA384;
|
||||
+ else
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("Value '%s' is not a valid PCR bank"), value);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE *handle)
|
||||
+{
|
||||
+ unsigned long num;
|
||||
+
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ num = grub_strtoul (value, NULL, 0);
|
||||
+ if (grub_errno != GRUB_ERR_NONE)
|
||||
+ return grub_error (grub_errno, N_("TPM handle value '%s' is not a number"),
|
||||
+ value);
|
||||
+
|
||||
+ if (num > GRUB_UINT_MAX)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("Value %lu is too large to be a TPM handle, TPM "
|
||||
+ "handles are unsigned 32-bit integers"), num);
|
||||
+
|
||||
+ *handle = (TPM_HANDLE)num;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
|
||||
new file mode 100644
|
||||
index 0000000000..3f2f386f7e
|
||||
--- /dev/null
|
||||
+++ b/grub-core/tpm2/module.c
|
||||
@@ -0,0 +1,710 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2022 Microsoft 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/dl.h>
|
||||
+#include <grub/extcmd.h>
|
||||
+#include <grub/file.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/protector.h>
|
||||
+#include <grub/tpm2/buffer.h>
|
||||
+#include <grub/tpm2/internal/args.h>
|
||||
+#include <grub/tpm2/mu.h>
|
||||
+#include <grub/tpm2/tpm2.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
+
|
||||
+typedef enum grub_tpm2_protector_mode
|
||||
+{
|
||||
+ GRUB_TPM2_PROTECTOR_MODE_UNSET,
|
||||
+ GRUB_TPM2_PROTECTOR_MODE_SRK,
|
||||
+ GRUB_TPM2_PROTECTOR_MODE_NV
|
||||
+} grub_tpm2_protector_mode_t;
|
||||
+
|
||||
+struct grub_tpm2_protector_context
|
||||
+{
|
||||
+ grub_tpm2_protector_mode_t mode;
|
||||
+ grub_uint8_t pcrs[TPM_MAX_PCRS];
|
||||
+ grub_uint8_t pcr_count;
|
||||
+ TPM_ALG_ID asymmetric;
|
||||
+ TPM_ALG_ID bank;
|
||||
+ const char *keyfile;
|
||||
+ TPM_HANDLE srk;
|
||||
+ TPM_HANDLE nv;
|
||||
+};
|
||||
+
|
||||
+static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
|
||||
+ {
|
||||
+ /* Options for all modes */
|
||||
+ {
|
||||
+ .longarg = "mode",
|
||||
+ .shortarg = 'm',
|
||||
+ .flags = 0,
|
||||
+ .arg = NULL,
|
||||
+ .type = ARG_TYPE_STRING,
|
||||
+ .doc =
|
||||
+ N_("Unseal key using SRK ('srk') (default) or retrieve it from an NV "
|
||||
+ "Index ('nv')."),
|
||||
+ },
|
||||
+ {
|
||||
+ .longarg = "pcrs",
|
||||
+ .shortarg = 'p',
|
||||
+ .flags = 0,
|
||||
+ .arg = NULL,
|
||||
+ .type = ARG_TYPE_STRING,
|
||||
+ .doc =
|
||||
+ N_("Comma-separated list of PCRs used to authorize key release "
|
||||
+ "(e.g., '7,11', default is 7."),
|
||||
+ },
|
||||
+ {
|
||||
+ .longarg = "bank",
|
||||
+ .shortarg = 'b',
|
||||
+ .flags = 0,
|
||||
+ .arg = NULL,
|
||||
+ .type = ARG_TYPE_STRING,
|
||||
+ .doc =
|
||||
+ N_("Bank of PCRs used to authorize key release: "
|
||||
+ "SHA1, SHA256 (default), or SHA384."),
|
||||
+ },
|
||||
+ /* SRK-mode options */
|
||||
+ {
|
||||
+ .longarg = "keyfile",
|
||||
+ .shortarg = 'k',
|
||||
+ .flags = 0,
|
||||
+ .arg = NULL,
|
||||
+ .type = ARG_TYPE_STRING,
|
||||
+ .doc =
|
||||
+ N_("Required in SRK mode, path to the sealed key file to unseal using "
|
||||
+ "the TPM (e.g., (hd0,gpt1)/boot/grub2/sealed_key)."),
|
||||
+ },
|
||||
+ {
|
||||
+ .longarg = "srk",
|
||||
+ .shortarg = 's',
|
||||
+ .flags = 0,
|
||||
+ .arg = NULL,
|
||||
+ .type = ARG_TYPE_STRING,
|
||||
+ .doc =
|
||||
+ N_("In SRK mode, the SRK handle if the SRK is persistent "
|
||||
+ "(default is 0x81000001)."),
|
||||
+ },
|
||||
+ {
|
||||
+ .longarg = "asymmetric",
|
||||
+ .shortarg = 'a',
|
||||
+ .flags = 0,
|
||||
+ .arg = NULL,
|
||||
+ .type = ARG_TYPE_STRING,
|
||||
+ .doc =
|
||||
+ N_("In SRK mode, the type of SRK: RSA (default) or ECC."),
|
||||
+ },
|
||||
+ /* NV Index-mode options */
|
||||
+ {
|
||||
+ .longarg = "nvindex",
|
||||
+ .shortarg = 'n',
|
||||
+ .flags = 0,
|
||||
+ .arg = NULL,
|
||||
+ .type = ARG_TYPE_STRING,
|
||||
+ .doc =
|
||||
+ N_("Required in NV Index mode, the NV handle to read which must "
|
||||
+ "readily exist on the TPM and which contains the key."),
|
||||
+ },
|
||||
+ /* End of list */
|
||||
+ {0, 0, 0, 0, 0, 0}
|
||||
+ };
|
||||
+
|
||||
+static grub_extcmd_t grub_tpm2_protector_init_cmd;
|
||||
+static grub_extcmd_t grub_tpm2_protector_clear_cmd;
|
||||
+static struct grub_tpm2_protector_context grub_tpm2_protector_ctx = { 0 };
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_srk_read_keyfile (const char *filepath, void **buffer,
|
||||
+ grub_size_t *buffer_size)
|
||||
+{
|
||||
+ grub_file_t sealed_key_file;
|
||||
+ grub_off_t sealed_key_size;
|
||||
+ void *sealed_key_buffer;
|
||||
+ grub_off_t sealed_key_read;
|
||||
+
|
||||
+ sealed_key_file = grub_file_open (filepath, GRUB_FILE_TYPE_NONE);
|
||||
+ if (!sealed_key_file)
|
||||
+ {
|
||||
+ grub_dprintf ("tpm2", "Could not open sealed key file.\n");
|
||||
+ /* grub_file_open sets grub_errno on error, and if we do no unset it,
|
||||
+ * future calls to grub_file_open will fail (and so will anybody up the
|
||||
+ * stack who checks the value, if any). */
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ return GRUB_ERR_FILE_NOT_FOUND;
|
||||
+ }
|
||||
+
|
||||
+ sealed_key_size = grub_file_size (sealed_key_file);
|
||||
+ if (!sealed_key_size)
|
||||
+ {
|
||||
+ grub_dprintf ("tpm2", "Could not read sealed key file size.\n");
|
||||
+ grub_file_close (sealed_key_file);
|
||||
+ return GRUB_ERR_OUT_OF_RANGE;
|
||||
+ }
|
||||
+
|
||||
+ sealed_key_buffer = grub_malloc (sealed_key_size);
|
||||
+ if (!sealed_key_buffer)
|
||||
+ {
|
||||
+ grub_dprintf ("tpm2", "Could not allocate buffer for sealed key.\n");
|
||||
+ grub_file_close (sealed_key_file);
|
||||
+ return GRUB_ERR_OUT_OF_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ sealed_key_read = grub_file_read (sealed_key_file, sealed_key_buffer,
|
||||
+ sealed_key_size);
|
||||
+ if (sealed_key_read != sealed_key_size)
|
||||
+ {
|
||||
+ grub_dprintf ("tpm2", "Could not retrieve sealed key file contents.\n");
|
||||
+ grub_free (sealed_key_buffer);
|
||||
+ grub_file_close (sealed_key_file);
|
||||
+ return GRUB_ERR_FILE_READ_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ grub_file_close (sealed_key_file);
|
||||
+
|
||||
+ *buffer = sealed_key_buffer;
|
||||
+ *buffer_size = sealed_key_size;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_srk_unmarshal_keyfile (void *sealed_key,
|
||||
+ grub_size_t sealed_key_size,
|
||||
+ TPM2_SEALED_KEY *sk)
|
||||
+{
|
||||
+ struct grub_tpm2_buffer buf;
|
||||
+
|
||||
+ grub_tpm2_buffer_init (&buf);
|
||||
+ if (sealed_key_size > buf.cap)
|
||||
+ {
|
||||
+ grub_dprintf ("tpm2", "Sealed key file is larger than decode buffer "
|
||||
+ "(%lu vs %lu bytes).\n", sealed_key_size, buf.cap);
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ grub_memcpy (buf.data, sealed_key, sealed_key_size);
|
||||
+ buf.size = sealed_key_size;
|
||||
+
|
||||
+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public);
|
||||
+ grub_tpm2_mu_TPM2B_Unmarshal (&buf, (TPM2B *)&sk->private);
|
||||
+
|
||||
+ if (buf.error)
|
||||
+ {
|
||||
+ grub_dprintf ("tpm2", "Could not unmarshal sealed key file, it is likely "
|
||||
+ "malformed.\n");
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_srk_get (const struct grub_tpm2_protector_context *ctx,
|
||||
+ TPM_HANDLE *srk)
|
||||
+{
|
||||
+ TPM_RC rc;
|
||||
+ TPM2B_PUBLIC public;
|
||||
+ TPMS_AUTH_COMMAND authCommand = { 0 };
|
||||
+ TPM2B_SENSITIVE_CREATE inSensitive = { 0 };
|
||||
+ TPM2B_PUBLIC inPublic = { 0 };
|
||||
+ TPM2B_DATA outsideInfo = { 0 };
|
||||
+ TPML_PCR_SELECTION creationPcr = { 0 };
|
||||
+ TPM2B_PUBLIC outPublic = { 0 };
|
||||
+ TPM2B_CREATION_DATA creationData = { 0 };
|
||||
+ TPM2B_DIGEST creationHash = { 0 };
|
||||
+ TPMT_TK_CREATION creationTicket = { 0 };
|
||||
+ TPM2B_NAME srkName = { 0 };
|
||||
+ TPM_HANDLE srkHandle;
|
||||
+
|
||||
+ /* Find SRK */
|
||||
+ rc = TPM2_ReadPublic (ctx->srk, NULL, &public);
|
||||
+ if (rc == TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ *srk = ctx->srk;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
+ /* The handle exists but its public area could not be read. */
|
||||
+ if ((rc & ~TPM_RC_N_MASK) != TPM_RC_HANDLE)
|
||||
+ {
|
||||
+ grub_dprintf ("tpm2", "The SRK handle (0x%x) exists on the TPM but its "
|
||||
+ "public area could not be read (TPM2_ReadPublic "
|
||||
+ "failed with TSS/TPM error %u).\n", ctx->srk, rc);
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+ }
|
||||
+
|
||||
+ /* Create SRK */
|
||||
+ authCommand.sessionHandle = TPM_RS_PW;
|
||||
+ inPublic.publicArea.type = ctx->asymmetric;
|
||||
+ inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
|
||||
+ inPublic.publicArea.objectAttributes.restricted = 1;
|
||||
+ inPublic.publicArea.objectAttributes.userWithAuth = 1;
|
||||
+ inPublic.publicArea.objectAttributes.decrypt = 1;
|
||||
+ inPublic.publicArea.objectAttributes.fixedTPM = 1;
|
||||
+ inPublic.publicArea.objectAttributes.fixedParent = 1;
|
||||
+ inPublic.publicArea.objectAttributes.sensitiveDataOrigin = 1;
|
||||
+ inPublic.publicArea.objectAttributes.noDA = 1;
|
||||
+
|
||||
+ if (ctx->asymmetric == TPM_ALG_RSA)
|
||||
+ {
|
||||
+ inPublic.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES;
|
||||
+ inPublic.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128;
|
||||
+ inPublic.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CFB;
|
||||
+ inPublic.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
|
||||
+ inPublic.publicArea.parameters.rsaDetail.keyBits = 2048;
|
||||
+ inPublic.publicArea.parameters.rsaDetail.exponent = 0;
|
||||
+ }
|
||||
+ else if (ctx->asymmetric == TPM_ALG_ECC)
|
||||
+ {
|
||||
+ inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_AES;
|
||||
+ inPublic.publicArea.parameters.eccDetail.symmetric.keyBits.aes = 128;
|
||||
+ inPublic.publicArea.parameters.eccDetail.symmetric.mode.aes = TPM_ALG_CFB;
|
||||
+ inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_NULL;
|
||||
+ inPublic.publicArea.parameters.eccDetail.curveID = TPM_ECC_NIST_P256;
|
||||
+ inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL;
|
||||
+ }
|
||||
+ else
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ rc = TPM2_CreatePrimary (TPM_RH_OWNER, &authCommand, &inSensitive, &inPublic,
|
||||
+ &outsideInfo, &creationPcr, &srkHandle, &outPublic,
|
||||
+ &creationData, &creationHash, &creationTicket,
|
||||
+ &srkName, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ grub_dprintf ("tpm2", "Could not create SRK (TPM2_CreatePrimary failed "
|
||||
+ "with TSS/TPM error %u).\n", rc);
|
||||
+ return GRUB_ERR_BAD_DEVICE;
|
||||
+ }
|
||||
+
|
||||
+ *srk = srkHandle;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx,
|
||||
+ grub_uint8_t **key, grub_size_t *key_size)
|
||||
+{
|
||||
+ TPM_RC rc;
|
||||
+ TPM2_SEALED_KEY sealed_key;
|
||||
+ void *sealed_key_bytes;
|
||||
+ grub_size_t sealed_key_size;
|
||||
+ TPM_HANDLE srk_handle;
|
||||
+ TPM2B_NONCE nonceCaller = { 0 };
|
||||
+ TPM2B_ENCRYPTED_SECRET salt = { 0 };
|
||||
+ TPMT_SYM_DEF symmetric = { 0 };
|
||||
+ TPM2B_NONCE nonceTPM = { 0 };
|
||||
+ TPMI_SH_AUTH_SESSION session;
|
||||
+ TPML_PCR_SELECTION pcrSel = {
|
||||
+ .count = 1,
|
||||
+ .pcrSelections = {
|
||||
+ {
|
||||
+ .hash = ctx->bank,
|
||||
+ .sizeOfSelect = 3,
|
||||
+ .pcrSelect = { 0 }
|
||||
+ },
|
||||
+ }
|
||||
+ };
|
||||
+ TPMS_AUTH_COMMAND authCmd = { 0 };
|
||||
+ TPM_HANDLE sealed_key_handle;
|
||||
+ TPM2B_NAME name;
|
||||
+ TPMS_AUTH_RESPONSE authResponse;
|
||||
+ TPM2B_SENSITIVE_DATA data;
|
||||
+ grub_uint8_t *key_out;
|
||||
+ grub_uint8_t i;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ /* Retrieve Sealed Key */
|
||||
+ err = grub_tpm2_protector_srk_read_keyfile (ctx->keyfile, &sealed_key_bytes,
|
||||
+ &sealed_key_size);
|
||||
+ if (err)
|
||||
+ return grub_error (err, N_("Failed to read key file %s"), ctx->keyfile);
|
||||
+
|
||||
+ err = grub_tpm2_protector_srk_unmarshal_keyfile (sealed_key_bytes,
|
||||
+ sealed_key_size,
|
||||
+ &sealed_key);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_error (err, N_("Failed to unmarshal key, ensure the key file is in "
|
||||
+ "TPM wire format"));
|
||||
+ goto exit1;
|
||||
+ }
|
||||
+
|
||||
+ /* Get SRK */
|
||||
+ err = grub_tpm2_protector_srk_get (ctx, &srk_handle);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_error (err, N_("Failed to retrieve the SRK"));
|
||||
+ goto exit1;
|
||||
+ }
|
||||
+
|
||||
+ err = GRUB_ERR_BAD_DEVICE;
|
||||
+
|
||||
+ /* Start Auth Session */
|
||||
+ nonceCaller.size = TPM_SHA256_DIGEST_SIZE;
|
||||
+ symmetric.algorithm = TPM_ALG_NULL;
|
||||
+
|
||||
+ rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, 0, &nonceCaller, &salt,
|
||||
+ TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256,
|
||||
+ &session, &nonceTPM, 0);
|
||||
+ if (rc)
|
||||
+ {
|
||||
+ grub_error (err, N_("Failed to start auth session (TPM2_StartAuthSession "
|
||||
+ "failed with TSS/TPM error %u)"), rc);
|
||||
+ goto exit2;
|
||||
+ }
|
||||
+
|
||||
+ /* Policy PCR */
|
||||
+ for (i = 0; i < ctx->pcr_count; i++)
|
||||
+ pcrSel
|
||||
+ .pcrSelections[0]
|
||||
+ .pcrSelect[TPM2_PCR_TO_SELECT(ctx->pcrs[i])]
|
||||
+ |= TPM2_PCR_TO_BIT(ctx->pcrs[i]);
|
||||
+
|
||||
+ rc = TPM2_PolicyPCR (session, NULL, NULL, &pcrSel, NULL);
|
||||
+ if (rc)
|
||||
+ {
|
||||
+ grub_error (err, N_("Failed to submit PCR policy (TPM2_PolicyPCR failed "
|
||||
+ "with TSS/TPM error %u)"), rc);
|
||||
+ goto exit3;
|
||||
+ }
|
||||
+
|
||||
+ /* Load Sealed Key */
|
||||
+ authCmd.sessionHandle = TPM_RS_PW;
|
||||
+ rc = TPM2_Load (srk_handle, &authCmd, &sealed_key.private, &sealed_key.public,
|
||||
+ &sealed_key_handle, &name, &authResponse);
|
||||
+ if (rc)
|
||||
+ {
|
||||
+ grub_error (err, N_("Failed to load sealed key (TPM2_Load failed with "
|
||||
+ "TSS/TPM error %u)"), rc);
|
||||
+ goto exit3;
|
||||
+ }
|
||||
+
|
||||
+ /* Unseal Sealed Key */
|
||||
+ authCmd.sessionHandle = session;
|
||||
+ grub_memset (&authResponse, 0, sizeof (authResponse));
|
||||
+
|
||||
+ rc = TPM2_Unseal (sealed_key_handle, &authCmd, &data, &authResponse);
|
||||
+ if (rc)
|
||||
+ {
|
||||
+ grub_error (err, N_("Failed to unseal sealed key (TPM2_Unseal failed "
|
||||
+ "with TSS/TPM error %u)"), rc);
|
||||
+ goto exit4;
|
||||
+ }
|
||||
+
|
||||
+ /* Epilogue */
|
||||
+ key_out = grub_malloc (data.size);
|
||||
+ if (!key_out)
|
||||
+ {
|
||||
+ err = GRUB_ERR_OUT_OF_MEMORY;
|
||||
+ grub_error (err, N_("No memory left to allocate unlock key buffer"));
|
||||
+ goto exit4;
|
||||
+ }
|
||||
+
|
||||
+ grub_memcpy (key_out, data.buffer, data.size);
|
||||
+
|
||||
+ *key = key_out;
|
||||
+ *key_size = data.size;
|
||||
+
|
||||
+ err = GRUB_ERR_NONE;
|
||||
+
|
||||
+exit4:
|
||||
+ TPM2_FlushContext (sealed_key_handle);
|
||||
+
|
||||
+exit3:
|
||||
+ TPM2_FlushContext (session);
|
||||
+
|
||||
+exit2:
|
||||
+ TPM2_FlushContext (srk_handle);
|
||||
+
|
||||
+exit1:
|
||||
+ grub_free (sealed_key_bytes);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context *ctx,
|
||||
+ grub_uint8_t **key, grub_size_t *key_size)
|
||||
+{
|
||||
+ (void)ctx;
|
||||
+ (void)key;
|
||||
+ (void)key_size;
|
||||
+
|
||||
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
+ N_("NV Index mode is not implemented yet"));
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_recover (const struct grub_tpm2_protector_context *ctx,
|
||||
+ grub_uint8_t **key, grub_size_t *key_size)
|
||||
+{
|
||||
+ switch (ctx->mode)
|
||||
+ {
|
||||
+ case GRUB_TPM2_PROTECTOR_MODE_SRK:
|
||||
+ return grub_tpm2_protector_srk_recover (ctx, key, key_size);
|
||||
+ case GRUB_TPM2_PROTECTOR_MODE_NV:
|
||||
+ return grub_tpm2_protector_nv_recover (ctx, key, key_size);
|
||||
+ default:
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_recover_key (grub_uint8_t **key, grub_size_t *key_size)
|
||||
+{
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ /* Expect a call to tpm2_protector_init before anybody tries to use us */
|
||||
+ if (grub_tpm2_protector_ctx.mode == GRUB_TPM2_PROTECTOR_MODE_UNSET)
|
||||
+ return grub_error (GRUB_ERR_INVALID_COMMAND,
|
||||
+ N_("Cannot use TPM2 key protector without initializing "
|
||||
+ "it, call tpm2_protector_init first"));
|
||||
+
|
||||
+ if (!key)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ err = grub_tpm2_protector_recover (&grub_tpm2_protector_ctx, key, key_size);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_check_args (struct grub_tpm2_protector_context *ctx)
|
||||
+{
|
||||
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_UNSET)
|
||||
+ ctx->mode = GRUB_TPM2_PROTECTOR_MODE_SRK;
|
||||
+
|
||||
+ /* Checks for SRK mode */
|
||||
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && !ctx->keyfile)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("In SRK mode, a key file must be specified: "
|
||||
+ "--keyfile or -k"));
|
||||
+
|
||||
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ctx->nv)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("In SRK mode, an NV Index cannot be specified"));
|
||||
+
|
||||
+ /* Checks for NV mode */
|
||||
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && !ctx->nv)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("In NV Index mode, an NV Index must be specified: "
|
||||
+ "--nvindex or -n"));
|
||||
+
|
||||
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->keyfile)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("In NV Index mode, a keyfile cannot be specified"));
|
||||
+
|
||||
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->srk)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("In NV Index mode, an SRK cannot be specified"));
|
||||
+
|
||||
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->asymmetric)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("In NV Index mode, an asymmetric key type cannot be "
|
||||
+ "specified"));
|
||||
+
|
||||
+ /* Defaults assignment */
|
||||
+ if (!ctx->bank)
|
||||
+ ctx->bank = TPM_ALG_SHA256;
|
||||
+
|
||||
+ if (!ctx->pcr_count)
|
||||
+ {
|
||||
+ ctx->pcrs[0] = 7;
|
||||
+ ctx->pcr_count = 1;
|
||||
+ }
|
||||
+
|
||||
+ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK)
|
||||
+ {
|
||||
+ if (!ctx->srk)
|
||||
+ ctx->srk = TPM2_SRK_HANDLE;
|
||||
+
|
||||
+ if (!ctx->asymmetric)
|
||||
+ ctx->asymmetric = TPM_ALG_RSA;
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_parse_keyfile (const char *value, const char **keyfile)
|
||||
+{
|
||||
+ if (grub_strlen (value) == 0)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ *keyfile = grub_strdup (value);
|
||||
+ if (!*keyfile)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
+ N_("No memory to duplicate keyfile path"));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_parse_mode (const char *value,
|
||||
+ grub_tpm2_protector_mode_t *mode)
|
||||
+{
|
||||
+ if (grub_strcmp (value, "srk") == 0)
|
||||
+ *mode = GRUB_TPM2_PROTECTOR_MODE_SRK;
|
||||
+ else if (grub_strcmp (value, "nv") == 0)
|
||||
+ *mode = GRUB_TPM2_PROTECTOR_MODE_NV;
|
||||
+ else
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("Value '%s' is not a valid TPM2 key protector mode"),
|
||||
+ value);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_init_cmd_handler (grub_extcmd_context_t ctxt, int argc,
|
||||
+ char **args __attribute__ ((unused)))
|
||||
+{
|
||||
+ struct grub_arg_list *state = ctxt->state;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ if (argc)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("The TPM2 key protector does not accept any "
|
||||
+ "non-option arguments (i.e., like -o and/or --option "
|
||||
+ "only)"));
|
||||
+
|
||||
+ grub_free ((void *) grub_tpm2_protector_ctx.keyfile);
|
||||
+ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx));
|
||||
+
|
||||
+ if (state[0].set) /* mode */
|
||||
+ {
|
||||
+ err = grub_tpm2_protector_parse_mode (state[0].arg,
|
||||
+ &grub_tpm2_protector_ctx.mode);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ if (state[1].set) /* pcrs */
|
||||
+ {
|
||||
+ err = grub_tpm2_protector_parse_pcrs (state[1].arg,
|
||||
+ grub_tpm2_protector_ctx.pcrs,
|
||||
+ &grub_tpm2_protector_ctx.pcr_count);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ if (state[2].set) /* bank */
|
||||
+ {
|
||||
+ err = grub_tpm2_protector_parse_bank (state[2].arg,
|
||||
+ &grub_tpm2_protector_ctx.bank);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ if (state[3].set) /* keyfile */
|
||||
+ {
|
||||
+ err = grub_tpm2_protector_parse_keyfile (state[3].arg,
|
||||
+ &grub_tpm2_protector_ctx.keyfile);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ if (state[4].set) /* srk */
|
||||
+ {
|
||||
+ err = grub_tpm2_protector_parse_tpm_handle (state[4].arg,
|
||||
+ &grub_tpm2_protector_ctx.srk);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ if (state[5].set) /* asymmetric */
|
||||
+ {
|
||||
+ err = grub_tpm2_protector_parse_asymmetric (state[5].arg,
|
||||
+ &grub_tpm2_protector_ctx.asymmetric);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ if (state[6].set) /* nvindex */
|
||||
+ {
|
||||
+ err = grub_tpm2_protector_parse_tpm_handle (state[6].arg,
|
||||
+ &grub_tpm2_protector_ctx.nv);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ err = grub_tpm2_protector_check_args (&grub_tpm2_protector_ctx);
|
||||
+
|
||||
+ /* This command only initializes the protector, so nothing else to do. */
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_clear_cmd_handler (grub_extcmd_context_t ctxt __attribute__ ((unused)),
|
||||
+ int argc,
|
||||
+ char **args __attribute__ ((unused)))
|
||||
+{
|
||||
+ if (argc)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("tpm2_key_protector_clear accepts no arguments"));
|
||||
+
|
||||
+ grub_free ((void *) grub_tpm2_protector_ctx.keyfile);
|
||||
+ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static struct grub_key_protector grub_tpm2_key_protector =
|
||||
+ {
|
||||
+ .name = "tpm2",
|
||||
+ .recover_key = grub_tpm2_protector_recover_key
|
||||
+ };
|
||||
+
|
||||
+GRUB_MOD_INIT (tpm2)
|
||||
+{
|
||||
+ grub_tpm2_protector_init_cmd =
|
||||
+ grub_register_extcmd ("tpm2_key_protector_init",
|
||||
+ grub_tpm2_protector_init_cmd_handler, 0,
|
||||
+ N_("[-m mode] "
|
||||
+ "[-p pcr_list] "
|
||||
+ "[-b pcr_bank] "
|
||||
+ "[-k sealed_key_file_path] "
|
||||
+ "[-s srk_handle] "
|
||||
+ "[-a asymmetric_key_type] "
|
||||
+ "[-n nv_index]"),
|
||||
+ N_("Initialize the TPM2 key protector."),
|
||||
+ grub_tpm2_protector_init_cmd_options);
|
||||
+ grub_tpm2_protector_clear_cmd =
|
||||
+ grub_register_extcmd ("tpm2_key_protector_clear",
|
||||
+ grub_tpm2_protector_clear_cmd_handler, 0, NULL,
|
||||
+ N_("Clear the TPM2 key protector if previously initialized."),
|
||||
+ NULL);
|
||||
+ grub_key_protector_register (&grub_tpm2_key_protector);
|
||||
+}
|
||||
+
|
||||
+GRUB_MOD_FINI (tpm2)
|
||||
+{
|
||||
+ grub_free ((void *) grub_tpm2_protector_ctx.keyfile);
|
||||
+ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx));
|
||||
+
|
||||
+ grub_key_protector_unregister (&grub_tpm2_key_protector);
|
||||
+ grub_unregister_extcmd (grub_tpm2_protector_clear_cmd);
|
||||
+ grub_unregister_extcmd (grub_tpm2_protector_init_cmd);
|
||||
+}
|
||||
diff --git a/include/grub/tpm2/internal/args.h b/include/grub/tpm2/internal/args.h
|
||||
new file mode 100644
|
||||
index 0000000000..6341fce1c5
|
||||
--- /dev/null
|
||||
+++ b/include/grub/tpm2/internal/args.h
|
||||
@@ -0,0 +1,39 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2022 Microsoft 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/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef GRUB_TPM2_INTERNAL_ARGS_HEADER
|
||||
+#define GRUB_TPM2_INTERNAL_ARGS_HEADER 1
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/tpm2/tpm2.h>
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs,
|
||||
+ grub_uint8_t *pcr_count);
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_tpm2_protector_parse_asymmetric (const char *value,
|
||||
+ TPM_ALG_ID *asymmetric);
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID *bank);
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE *handle);
|
||||
+
|
||||
+#endif /* ! GRUB_TPM2_INTERNAL_ARGS_HEADER */
|
||||
--
|
||||
2.34.1
|
||||
|
336
0013-cryptodisk-Support-key-protectors.patch
Normal file
336
0013-cryptodisk-Support-key-protectors.patch
Normal file
@ -0,0 +1,336 @@
|
||||
From 9888bf40d960339a59dc18fb6e1df5f65b4668e3 Mon Sep 17 00:00:00 2001
|
||||
From: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Date: Tue, 1 Feb 2022 05:02:56 -0800
|
||||
Subject: [PATCH 13/14] cryptodisk: Support key protectors
|
||||
|
||||
Add a new parameter to cryptomount to support the key protectors framework: -k.
|
||||
The parameter is used to automatically retrieve a key from specified key
|
||||
protectors. The parameter may be repeated to specify any number of key
|
||||
protectors. These are tried in order until one provides a usable key for any
|
||||
given disk.
|
||||
|
||||
Signed-off-by: <Hernan Gatta hegatta@linux.microsoft.com>
|
||||
---
|
||||
Makefile.util.def | 1 +
|
||||
grub-core/disk/cryptodisk.c | 166 +++++++++++++++++++++++++++++-------
|
||||
include/grub/cryptodisk.h | 14 +++
|
||||
3 files changed, 151 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def
|
||||
index ef5c818e0e..b3ec2a4bb6 100644
|
||||
--- a/Makefile.util.def
|
||||
+++ b/Makefile.util.def
|
||||
@@ -35,6 +35,7 @@ library = {
|
||||
common = grub-core/kern/list.c;
|
||||
common = grub-core/kern/misc.c;
|
||||
common = grub-core/kern/partition.c;
|
||||
+ common = grub-core/kern/protectors.c;
|
||||
common = grub-core/lib/crypto.c;
|
||||
common = grub-core/lib/json/json.c;
|
||||
common = grub-core/disk/luks.c;
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 497097394f..00c44773fb 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <grub/file.h>
|
||||
#include <grub/procfs.h>
|
||||
#include <grub/partition.h>
|
||||
+#include <grub/protector.h>
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
#include <grub/emu/hostdisk.h>
|
||||
@@ -42,6 +43,8 @@ static const struct grub_arg_option options[] =
|
||||
{"all", 'a', 0, N_("Mount all."), 0, 0},
|
||||
{"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0},
|
||||
{"password", 'p', 0, N_("Password to open volumes."), 0, ARG_TYPE_STRING},
|
||||
+ {"protector", 'k', GRUB_ARG_OPTION_REPEATABLE,
|
||||
+ N_("Unlock volume(s) using key protector(s)."), 0, ARG_TYPE_STRING},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -1000,7 +1003,8 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
{
|
||||
grub_err_t ret = GRUB_ERR_NONE;
|
||||
grub_cryptodisk_t dev;
|
||||
- grub_cryptodisk_dev_t cr;
|
||||
+ grub_cryptodisk_dev_t cr, crd = NULL;
|
||||
+ int i;
|
||||
int askpass = 0;
|
||||
char *part = NULL;
|
||||
|
||||
@@ -1016,39 +1020,108 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
return NULL;
|
||||
if (!dev)
|
||||
continue;
|
||||
+ crd = cr;
|
||||
+ }
|
||||
|
||||
- if (!cargs->key_len)
|
||||
- {
|
||||
- /* Get the passphrase from the user, if no key data. */
|
||||
- askpass = 1;
|
||||
- part = grub_partition_get_name (source->partition);
|
||||
- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
- source->partition != NULL ? "," : "",
|
||||
- part != NULL ? part : N_("UNKNOWN"),
|
||||
- dev->uuid);
|
||||
- grub_free (part);
|
||||
-
|
||||
- cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
||||
- if (cargs->key_data == NULL)
|
||||
- return NULL;
|
||||
-
|
||||
- if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||
- {
|
||||
- grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||
- goto error;
|
||||
- }
|
||||
- cargs->key_len = grub_strlen ((char *) cargs->key_data);
|
||||
- }
|
||||
+ if (!dev)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_MODULE,
|
||||
+ "no cryptodisk module can handle this device");
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- ret = cr->recover_key (source, dev, cargs);
|
||||
- if (ret != GRUB_ERR_NONE)
|
||||
+ if (cargs->protectors)
|
||||
+ {
|
||||
+ for (i = 0; cargs->protectors[i]; i++)
|
||||
+ {
|
||||
+ if (cargs->key_cache[i].invalid)
|
||||
+ continue;
|
||||
+
|
||||
+ if (!cargs->key_cache[i].key)
|
||||
+ {
|
||||
+ ret = grub_key_protector_recover_key (cargs->protectors[i],
|
||||
+ &cargs->key_cache[i].key,
|
||||
+ &cargs->key_cache[i].key_len);
|
||||
+ if (ret)
|
||||
+ {
|
||||
+ if (grub_errno)
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("cryptodisk",
|
||||
+ "failed to recover a key from key protector "
|
||||
+ "%s, will not try it again for any other "
|
||||
+ "disks, if any, during this invocation of "
|
||||
+ "cryptomount\n",
|
||||
+ cargs->protectors[i]);
|
||||
+
|
||||
+ cargs->key_cache[i].invalid = 1;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ cargs->key_data = cargs->key_cache[i].key;
|
||||
+ cargs->key_len = cargs->key_cache[i].key_len;
|
||||
+
|
||||
+ ret = crd->recover_key (source, dev, cargs);
|
||||
+ if (ret)
|
||||
+ {
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_dprintf ("cryptodisk",
|
||||
+ "recovered a key from key protector %s but it "
|
||||
+ "failed to unlock %s%s%s (%s)\n",
|
||||
+ cargs->protectors[i], source->name,
|
||||
+ source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||
+ grub_free (part);
|
||||
+ continue;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ grub_cryptodisk_insert (dev, name, source);
|
||||
+ goto cleanup;
|
||||
+ };
|
||||
+ }
|
||||
+
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED,
|
||||
+ N_("no key protector provided a usable key for %s%s%s (%s)"),
|
||||
+ source->name, source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||
+ grub_free (part);
|
||||
goto error;
|
||||
+ }
|
||||
|
||||
- grub_cryptodisk_insert (dev, name, source);
|
||||
+ if (!cargs->key_len)
|
||||
+ {
|
||||
+ /* Get the passphrase from the user, if no key data. */
|
||||
+ askpass = 1;
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
+ source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||
+ grub_free (part);
|
||||
+
|
||||
+ cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
||||
+ if (cargs->key_data == NULL)
|
||||
+ goto error;
|
||||
+
|
||||
+ if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||
+ goto error;
|
||||
+ }
|
||||
+ cargs->key_len = grub_strlen ((char *) cargs->key_data);
|
||||
+ }
|
||||
+
|
||||
+ ret = crd->recover_key (source, dev, cargs);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ goto error;
|
||||
+
|
||||
+ grub_cryptodisk_insert (dev, name, source);
|
||||
|
||||
- goto cleanup;
|
||||
- }
|
||||
- grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device");
|
||||
goto cleanup;
|
||||
|
||||
error:
|
||||
@@ -1155,6 +1228,20 @@ grub_cryptodisk_scan_device (const char *name,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static void
|
||||
+grub_cryptodisk_clear_key_cache (struct grub_cryptomount_args *cargs)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ if (!cargs->key_cache)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; cargs->protectors[i]; i++)
|
||||
+ grub_free (cargs->key_cache[i].key);
|
||||
+
|
||||
+ grub_free (cargs->key_cache);
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
@@ -1167,12 +1254,25 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (grub_cryptodisk_list == NULL)
|
||||
return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded");
|
||||
|
||||
+ if (state[3].set && state[4].set) /* password and key protector */
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ "a password and a key protector cannot both be set");
|
||||
+
|
||||
if (state[3].set) /* password */
|
||||
{
|
||||
cargs.key_data = (grub_uint8_t *) state[3].arg;
|
||||
cargs.key_len = grub_strlen (state[3].arg);
|
||||
}
|
||||
|
||||
+ if (state[4].set) /* key protector(s) */
|
||||
+ {
|
||||
+ cargs.key_cache = grub_zalloc (state[4].set * sizeof (*cargs.key_cache));
|
||||
+ if (!cargs.key_cache)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
+ "no memory for key protector key cache");
|
||||
+ cargs.protectors = state[4].args;
|
||||
+ }
|
||||
+
|
||||
if (state[0].set) /* uuid */
|
||||
{
|
||||
int found_uuid;
|
||||
@@ -1181,6 +1281,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
dev = grub_cryptodisk_get_by_uuid (args[0]);
|
||||
if (dev)
|
||||
{
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
grub_dprintf ("cryptodisk",
|
||||
"already mounted as crypto%lu\n", dev->id);
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -1189,6 +1290,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
cargs.check_boot = state[2].set;
|
||||
cargs.search_uuid = args[0];
|
||||
found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
|
||||
if (found_uuid)
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -1208,6 +1310,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
cargs.check_boot = state[2].set;
|
||||
grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
else
|
||||
@@ -1231,6 +1334,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
disk = grub_disk_open (diskname);
|
||||
if (!disk)
|
||||
{
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
if (disklast)
|
||||
*disklast = ')';
|
||||
return grub_errno;
|
||||
@@ -1241,12 +1345,14 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id);
|
||||
grub_disk_close (disk);
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
if (disklast)
|
||||
*disklast = ')';
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs);
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
|
||||
grub_disk_close (disk);
|
||||
if (disklast)
|
||||
@@ -1385,7 +1491,7 @@ GRUB_MOD_INIT (cryptodisk)
|
||||
{
|
||||
grub_disk_dev_register (&grub_cryptodisk_dev);
|
||||
cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
|
||||
- N_("[-p password] <SOURCE|-u UUID|-a|-b>"),
|
||||
+ N_("[-p password] [-k protector [-k protector ...]] <SOURCE|-u UUID|-a|-b>"),
|
||||
N_("Mount a crypto device."), options);
|
||||
grub_procfs_register ("luks_script", &luks_script);
|
||||
}
|
||||
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
|
||||
index c6524c9ea9..b556498fba 100644
|
||||
--- a/include/grub/cryptodisk.h
|
||||
+++ b/include/grub/cryptodisk.h
|
||||
@@ -67,6 +67,16 @@ typedef gcry_err_code_t
|
||||
(*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev,
|
||||
grub_uint64_t zoneno);
|
||||
|
||||
+struct grub_cryptomount_cached_key
|
||||
+{
|
||||
+ grub_uint8_t *key;
|
||||
+ grub_size_t key_len;
|
||||
+
|
||||
+ /* The key protector associated with this cache entry failed, so avoid it
|
||||
+ * even if the cached entry (an instance of this structure) is empty. */
|
||||
+ int invalid;
|
||||
+};
|
||||
+
|
||||
struct grub_cryptomount_args
|
||||
{
|
||||
/* scan: Flag to indicate that only bootable volumes should be decrypted */
|
||||
@@ -77,6 +87,10 @@ struct grub_cryptomount_args
|
||||
grub_uint8_t *key_data;
|
||||
/* recover_key: Length of key_data */
|
||||
grub_size_t key_len;
|
||||
+ /* recover_key: Names of the key protectors to use (NULL-terminated) */
|
||||
+ char **protectors;
|
||||
+ /* recover_key: Key cache to avoid invoking the same key protector twice */
|
||||
+ struct grub_cryptomount_cached_key *key_cache;
|
||||
};
|
||||
typedef struct grub_cryptomount_args *grub_cryptomount_args_t;
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
1408
0014-util-grub-protect-Add-new-tool.patch
Normal file
1408
0014-util-grub-protect-Add-new-tool.patch
Normal file
File diff suppressed because it is too large
Load Diff
51
efi-set-variable-with-attrs.patch
Normal file
51
efi-set-variable-with-attrs.patch
Normal file
@ -0,0 +1,51 @@
|
||||
Index: grub-2.06/include/grub/efi/efi.h
|
||||
===================================================================
|
||||
--- grub-2.06.orig/include/grub/efi/efi.h
|
||||
+++ grub-2.06/include/grub/efi/efi.h
|
||||
@@ -86,6 +86,11 @@ grub_efi_status_t EXPORT_FUNC (grub_efi_
|
||||
const grub_efi_guid_t *guid,
|
||||
grub_size_t *datasize_out,
|
||||
void **data_out);
|
||||
+grub_err_t EXPORT_FUNC (grub_efi_set_variable_with_attributes) (const char *var,
|
||||
+ const grub_efi_guid_t *guid,
|
||||
+ grub_efi_uint32_t attributes,
|
||||
+ void *data,
|
||||
+ grub_size_t datasize);
|
||||
grub_err_t
|
||||
EXPORT_FUNC (grub_efi_set_variable) (const char *var,
|
||||
const grub_efi_guid_t *guid,
|
||||
Index: grub-2.06/grub-core/kern/efi/efi.c
|
||||
===================================================================
|
||||
--- grub-2.06.orig/grub-core/kern/efi/efi.c
|
||||
+++ grub-2.06/grub-core/kern/efi/efi.c
|
||||
@@ -196,6 +196,17 @@ grub_err_t
|
||||
grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
|
||||
void *data, grub_size_t datasize)
|
||||
{
|
||||
+ return grub_efi_set_variable_with_attributes(var, guid,
|
||||
+ (GRUB_EFI_VARIABLE_NON_VOLATILE
|
||||
+ | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||||
+ | GRUB_EFI_VARIABLE_RUNTIME_ACCESS),
|
||||
+ data, datasize);
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_efi_set_variable_with_attributes(const char *var, const grub_efi_guid_t *guid, grub_efi_uint32_t attributes,
|
||||
+ void *data, grub_size_t datasize)
|
||||
+{
|
||||
grub_efi_status_t status;
|
||||
grub_efi_runtime_services_t *r;
|
||||
grub_efi_char16_t *var16;
|
||||
@@ -211,10 +222,8 @@ grub_efi_set_variable(const char *var, c
|
||||
|
||||
r = grub_efi_system_table->runtime_services;
|
||||
|
||||
- status = efi_call_5 (r->set_variable, var16, guid,
|
||||
- (GRUB_EFI_VARIABLE_NON_VOLATILE
|
||||
- | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||||
- | GRUB_EFI_VARIABLE_RUNTIME_ACCESS),
|
||||
+ status = efi_call_5 (r->set_variable, var16, guid,
|
||||
+ attributes,
|
||||
datasize, data);
|
||||
grub_free (var16);
|
||||
if (status == GRUB_EFI_SUCCESS)
|
38
fix-tpm2-build.patch
Normal file
38
fix-tpm2-build.patch
Normal file
@ -0,0 +1,38 @@
|
||||
---
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/tpm2/module.c | 2 +-
|
||||
util/grub-protect.c | 2 +-
|
||||
3 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -2569,6 +2569,7 @@
|
||||
common = tpm2/mu.c;
|
||||
common = tpm2/tpm2.c;
|
||||
efi = tpm2/tcg2.c;
|
||||
+ enable = efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
--- a/util/grub-protect.c
|
||||
+++ b/util/grub-protect.c
|
||||
@@ -542,7 +542,7 @@
|
||||
if (pcr_values.digests[i].size != pcr_digest_len)
|
||||
{
|
||||
fprintf (stderr,
|
||||
- _("Bad PCR value size: expected %lu bytes but got %u bytes.\n"),
|
||||
+ _("Bad PCR value size: expected %" PRIuGRUB_SIZE " bytes but got %u bytes.\n"),
|
||||
pcr_digest_len, pcr_values.digests[i].size);
|
||||
goto exit2;
|
||||
}
|
||||
--- a/grub-core/tpm2/module.c
|
||||
+++ b/grub-core/tpm2/module.c
|
||||
@@ -195,7 +195,7 @@
|
||||
if (sealed_key_size > buf.cap)
|
||||
{
|
||||
grub_dprintf ("tpm2", "Sealed key file is larger than decode buffer "
|
||||
- "(%lu vs %lu bytes).\n", sealed_key_size, buf.cap);
|
||||
+ "(%" PRIuGRUB_SIZE " vs %" PRIuGRUB_SIZE " bytes).\n", sealed_key_size, buf.cap);
|
||||
return GRUB_ERR_BAD_ARGUMENT;
|
||||
}
|
||||
|
18
grub-install-record-pcrs.patch
Normal file
18
grub-install-record-pcrs.patch
Normal file
@ -0,0 +1,18 @@
|
||||
Index: grub-2.06/util/grub-install.c
|
||||
===================================================================
|
||||
--- grub-2.06.orig/util/grub-install.c
|
||||
+++ grub-2.06/util/grub-install.c
|
||||
@@ -1457,6 +1457,13 @@ main (int argc, char *argv[])
|
||||
|
||||
grub_util_unlink (load_cfg);
|
||||
|
||||
+ if (1)
|
||||
+ {
|
||||
+ load_cfg_f = grub_util_fopen (load_cfg, "wb");
|
||||
+ have_load_cfg = 1;
|
||||
+ fprintf (load_cfg_f, "tpm_record_pcrs 0-9\n");
|
||||
+ }
|
||||
+
|
||||
if (debug_image && debug_image[0])
|
||||
{
|
||||
load_cfg_f = grub_util_fopen (load_cfg, "wb");
|
151
grub-read-pcr.patch
Normal file
151
grub-read-pcr.patch
Normal file
@ -0,0 +1,151 @@
|
||||
Index: grub-2.06/include/grub/tpm.h
|
||||
===================================================================
|
||||
--- grub-2.06.orig/include/grub/tpm.h
|
||||
+++ grub-2.06/include/grub/tpm.h
|
||||
@@ -34,6 +34,15 @@
|
||||
|
||||
#define EV_IPL 0x0d
|
||||
|
||||
+struct grub_tpm_digest {
|
||||
+ const char * algorithm;
|
||||
+ unsigned int size;
|
||||
+ unsigned char value[1]; /* variable length */
|
||||
+};
|
||||
+
|
||||
grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size,
|
||||
grub_uint8_t pcr, const char *description);
|
||||
+struct grub_tpm_digest *grub_tpm_read_pcr (grub_uint8_t index, const char *algo);
|
||||
+void grub_tpm_digest_free (struct grub_tpm_digest *d);
|
||||
+
|
||||
#endif
|
||||
Index: grub-2.06/grub-core/commands/efi/tpm.c
|
||||
===================================================================
|
||||
--- grub-2.06.orig/grub-core/commands/efi/tpm.c
|
||||
+++ grub-2.06/grub-core/commands/efi/tpm.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/efi/tpm.h>
|
||||
+#include <grub/tpm2/tpm2.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/tpm.h>
|
||||
#include <grub/term.h>
|
||||
@@ -186,6 +187,91 @@ grub_tpm1_log_event (grub_efi_handle_t t
|
||||
return grub_efi_log_event_status (status);
|
||||
}
|
||||
|
||||
+static void
|
||||
+grub_tpm2_select_pcr(TPML_PCR_SELECTION *o, unsigned int pcrIndex, unsigned int algo)
|
||||
+{
|
||||
+ TPMS_PCR_SELECTION *pcr;
|
||||
+
|
||||
+ pcr = &o->pcrSelections[o->count++];
|
||||
+ pcr->hash = algo;
|
||||
+ pcr->sizeOfSelect = 3;
|
||||
+ pcr->pcrSelect[TPM2_PCR_TO_SELECT(pcrIndex)] |= TPM2_PCR_TO_BIT(pcrIndex);
|
||||
+}
|
||||
+
|
||||
+struct grub_tpm_hash_info {
|
||||
+ const char *name;
|
||||
+ grub_size_t size;
|
||||
+ int id;
|
||||
+};
|
||||
+
|
||||
+static const struct grub_tpm_hash_info *
|
||||
+grub_tpm2_get_digest_info (const char *algo)
|
||||
+{
|
||||
+ static struct grub_tpm_hash_info __hashes[] = {
|
||||
+ { "sha256", 32, TPM_ALG_SHA256 }, /* first entry is the default */
|
||||
+ { "sha512", 64, TPM_ALG_SHA512 },
|
||||
+ { "sha1", 20, TPM_ALG_SHA1 },
|
||||
+ { NULL }
|
||||
+ };
|
||||
+ struct grub_tpm_hash_info *h;
|
||||
+
|
||||
+ if (algo == NULL)
|
||||
+ return &__hashes[0];
|
||||
+
|
||||
+ for (h = __hashes; h->name; ++h)
|
||||
+ if (!grub_strcmp(h->name, algo))
|
||||
+ return h;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_read_pcr (grub_int8_t pcrIndex, const char *algo, struct grub_tpm_digest **ret)
|
||||
+{
|
||||
+ const struct grub_tpm_hash_info *info;
|
||||
+ TPML_PCR_SELECTION inSelection, outSelection;
|
||||
+ grub_uint32_t pcrUpdateCounter;
|
||||
+ TPML_DIGEST digests = { 0 };
|
||||
+ TPM2B_DIGEST *d;
|
||||
+ struct grub_tpm_digest *result;
|
||||
+ int rc;
|
||||
+
|
||||
+ info = grub_tpm2_get_digest_info (algo);
|
||||
+ if (info == NULL)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Unknown digest algorithm %s"), algo);
|
||||
+
|
||||
+ grub_memset(&inSelection, 0, sizeof(inSelection));
|
||||
+ grub_memset(&outSelection, 0, sizeof(outSelection));
|
||||
+ grub_tpm2_select_pcr(&inSelection, pcrIndex, info->id);
|
||||
+
|
||||
+ rc = TPM2_PCR_Read(
|
||||
+ NULL,
|
||||
+ &inSelection,
|
||||
+ &pcrUpdateCounter,
|
||||
+ &outSelection,
|
||||
+ &digests,
|
||||
+ NULL
|
||||
+ );
|
||||
+
|
||||
+ if (rc != 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE, "TPM2_PCR_Read failed, status=%d", rc);
|
||||
+
|
||||
+ d = &digests.digests[0];
|
||||
+
|
||||
+ *ret = result = grub_malloc (sizeof (*result) + d->size);
|
||||
+ grub_memcpy (result->value, d->buffer, d->size);
|
||||
+ result->algorithm = info->name;
|
||||
+ result->size = d->size;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm_digest_free (struct grub_tpm_digest *d)
|
||||
+{
|
||||
+ grub_free (d);
|
||||
+}
|
||||
+
|
||||
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,
|
||||
@@ -240,3 +326,26 @@ grub_tpm_measure (unsigned char *buf, gr
|
||||
else
|
||||
return grub_tpm2_log_event (tpm_handle, buf, size, pcr, description);
|
||||
}
|
||||
+
|
||||
+struct grub_tpm_digest *
|
||||
+grub_tpm_read_pcr (grub_uint8_t pcr, const char *algo)
|
||||
+{
|
||||
+ grub_efi_handle_t tpm_handle;
|
||||
+ grub_efi_uint8_t protocol_version;
|
||||
+ struct grub_tpm_digest *result = NULL;
|
||||
+
|
||||
+
|
||||
+ if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (protocol_version != 2)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_DEVICE, N_("%s: TPM version %d not implemented"), __func__, protocol_version);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_tpm2_read_pcr (pcr, algo, &result))
|
||||
+ return NULL;
|
||||
+
|
||||
+ return result;
|
||||
+}
|
41
grub-unseal-debug.patch
Normal file
41
grub-unseal-debug.patch
Normal file
@ -0,0 +1,41 @@
|
||||
Index: grub-2.06/grub-core/tpm2/module.c
|
||||
===================================================================
|
||||
--- grub-2.06.orig/grub-core/tpm2/module.c
|
||||
+++ grub-2.06/grub-core/tpm2/module.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/protector.h>
|
||||
+#include <grub/time.h>
|
||||
#include <grub/tpm2/buffer.h>
|
||||
#include <grub/tpm2/internal/args.h>
|
||||
#include <grub/tpm2/mu.h>
|
||||
@@ -449,6 +450,7 @@ grub_tpm2_protector_srk_recover (const s
|
||||
{
|
||||
grub_error (err, N_("Failed to unseal sealed key (TPM2_Unseal failed "
|
||||
"with TSS/TPM error %u)"), rc);
|
||||
+ grub_millisleep(500);
|
||||
goto exit4;
|
||||
}
|
||||
|
||||
@@ -461,6 +463,8 @@ grub_tpm2_protector_srk_recover (const s
|
||||
goto exit4;
|
||||
}
|
||||
|
||||
+ grub_printf("TPM2: unsealed %u bytes of key material\n", data.size);
|
||||
+
|
||||
if (ctx->efivar)
|
||||
{
|
||||
rc = grub_tpm2_protector_publish_key (data.buffer, data.size, ctx->efivar);
|
||||
Index: grub-2.06/grub-core/loader/linux.c
|
||||
===================================================================
|
||||
--- grub-2.06.orig/grub-core/loader/linux.c
|
||||
+++ grub-2.06/grub-core/loader/linux.c
|
||||
@@ -171,6 +171,7 @@ grub_initrd_component (const char *buf,
|
||||
struct grub_linux_initrd_component *comp = initrd_ctx->components + initrd_ctx->nfiles;
|
||||
grub_size_t dir_size, name_len;
|
||||
|
||||
+ grub_printf("Creating initrd component \"%s\" with %u bytes\n", newc_name, bufsz);
|
||||
while (*newc_name == '/')
|
||||
newc_name++;
|
||||
|
134
grub2.changes
134
grub2.changes
@ -1,3 +1,137 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Oct 28 04:58:28 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- NVMeoFC support on grub (jsc#PED-996)
|
||||
* 0001-ieee1275-add-support-for-NVMeoFC.patch
|
||||
* 0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch
|
||||
* 0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch
|
||||
* 0004-ofpath-controller-name-update.patch
|
||||
- TDX: Enhance grub2 measurement to TD RTMR (jsc#PED-1265)
|
||||
* 0001-commands-efi-tpm-Refine-the-status-of-log-event.patch
|
||||
* 0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch
|
||||
* 0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch
|
||||
- Measure the kernel on POWER10 and extend TPM PCRs (PED-1990)
|
||||
* 0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch
|
||||
* 0002-ieee1275-implement-vec5-for-cas-negotiation.patch
|
||||
- Fix efi pcr snapshot related funtion is defined but not used on powerpc
|
||||
platform.
|
||||
* safe_tpm_pcr_snapshot.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Oct 24 01:58:08 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Include loopback into signed grub2 image (jsc#PED-2150)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Oct 6 07:13:23 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix firmware oops after disk decrypting failure (bsc#1204037)
|
||||
* 0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Sep 23 10:13:54 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Add patch to fix kernel relocation error in low memory
|
||||
* 0001-linux-fix-efi_relocate_kernel-failure.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Sep 19 04:07:36 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Add safety measure to pcr snapshot by checking platform and tpm status
|
||||
* safe_tpm_pcr_snapshot.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Sep 16 03:56:14 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix installation failure due to unavailable nvram device on
|
||||
ppc64le (bsc#1201361)
|
||||
* 0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Sep 16 03:12:36 UTC 2022 - Gary Ching-Pang Lin <glin@suse.com>
|
||||
|
||||
- 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
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Sep 15 09:51:07 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- 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
|
||||
* grub-read-pcr.patch
|
||||
* efi-set-variable-with-attrs.patch
|
||||
* tpm-record-pcrs.patch
|
||||
* tpm-protector-dont-measure-sealed-key.patch
|
||||
* tpm-protector-export-secret-key.patch
|
||||
* grub-install-record-pcrs.patch
|
||||
* grub-unseal-debug.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Aug 29 03:48:55 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix out of memory error cannot be prevented via disabling tpm (bsc#1202438)
|
||||
* 0001-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Aug 18 02:47:28 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix tpm error stop tumbleweed from booting (bsc#1202374)
|
||||
* 0001-tpm-Pass-unknown-error-as-non-fatal-but-debug-print-.patch
|
||||
- Patch Removed
|
||||
* 0001-tpm-Log-EFI_VOLUME_FULL-and-continue.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jun 8 03:25:26 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Add tpm, tpm2, luks2 and gcry_sha512 to default grub.efi (bsc#1197625)
|
||||
- Make grub-tpm.efi a symlink to grub.efi
|
||||
* grub2.spec
|
||||
- Log error when tpm event log is full and continue
|
||||
* 0001-tpm-Log-EFI_VOLUME_FULL-and-continue.patch
|
||||
- Patch superseded
|
||||
* 0001-tpm-Pass-unknown-error-as-non-fatal-but-debug-print-.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jun 8 03:17:29 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Add patches for automatic TPM disk unlock (jsc#SLE-24018) (bsc#1196668)
|
||||
* 0001-luks2-Add-debug-message-to-align-with-luks-and-geli-.patch
|
||||
* 0002-cryptodisk-Refactor-to-discard-have_it-global.patch
|
||||
* 0003-cryptodisk-Return-failure-in-cryptomount-when-no-cry.patch
|
||||
* 0004-cryptodisk-Improve-error-messaging-in-cryptomount-in.patch
|
||||
* 0005-cryptodisk-Improve-cryptomount-u-error-message.patch
|
||||
* 0006-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch
|
||||
* 0007-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch
|
||||
* 0008-cryptodisk-Move-global-variables-into-grub_cryptomou.patch
|
||||
* 0009-cryptodisk-Improve-handling-of-partition-name-in-cry.patch
|
||||
* 0010-protectors-Add-key-protectors-framework.patch
|
||||
* 0011-tpm2-Add-TPM-Software-Stack-TSS.patch
|
||||
* 0012-protectors-Add-TPM2-Key-Protector.patch
|
||||
* 0013-cryptodisk-Support-key-protectors.patch
|
||||
* 0014-util-grub-protect-Add-new-tool.patch
|
||||
- Fix no disk unlocking happen (bsc#1196668)
|
||||
* 0001-crytodisk-fix-cryptodisk-module-looking-up.patch
|
||||
- Fix build error
|
||||
* fix-tpm2-build.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue May 31 04:44:18 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
|
76
grub2.spec
76
grub2.spec
@ -407,6 +407,65 @@ Patch881: 0029-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch
|
||||
Patch882: 0030-fs-btrfs-Fix-more-ASAN-and-SEGV-issues-found-with-fu.patch
|
||||
Patch883: 0031-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch
|
||||
Patch884: 0032-Use-grub_loader_set_ex-for-secureboot-chainloader.patch
|
||||
Patch885: 0001-luks2-Add-debug-message-to-align-with-luks-and-geli-.patch
|
||||
Patch886: 0002-cryptodisk-Refactor-to-discard-have_it-global.patch
|
||||
Patch887: 0003-cryptodisk-Return-failure-in-cryptomount-when-no-cry.patch
|
||||
Patch888: 0004-cryptodisk-Improve-error-messaging-in-cryptomount-in.patch
|
||||
Patch889: 0005-cryptodisk-Improve-cryptomount-u-error-message.patch
|
||||
Patch890: 0006-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch
|
||||
Patch891: 0007-cryptodisk-Refactor-password-input-out-of-crypto-dev.patch
|
||||
Patch892: 0008-cryptodisk-Move-global-variables-into-grub_cryptomou.patch
|
||||
Patch893: 0009-cryptodisk-Improve-handling-of-partition-name-in-cry.patch
|
||||
Patch894: 0010-protectors-Add-key-protectors-framework.patch
|
||||
Patch895: 0011-tpm2-Add-TPM-Software-Stack-TSS.patch
|
||||
Patch896: 0012-protectors-Add-TPM2-Key-Protector.patch
|
||||
Patch897: 0013-cryptodisk-Support-key-protectors.patch
|
||||
Patch898: 0014-util-grub-protect-Add-new-tool.patch
|
||||
Patch899: fix-tpm2-build.patch
|
||||
Patch900: 0001-crytodisk-fix-cryptodisk-module-looking-up.patch
|
||||
# fde
|
||||
Patch901: 0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch
|
||||
Patch902: 0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch
|
||||
Patch903: 0003-disk-cryptodisk-When-cheatmounting-use-the-sector-in.patch
|
||||
Patch904: 0004-normal-menu-Don-t-show-Booting-s-msg-when-auto-booti.patch
|
||||
Patch905: 0005-EFI-suppress-the-Welcome-to-GRUB-message-in-EFI-buil.patch
|
||||
Patch906: 0006-EFI-console-Do-not-set-colorstate-until-the-first-te.patch
|
||||
Patch907: 0007-EFI-console-Do-not-set-cursor-until-the-first-text-o.patch
|
||||
Patch908: 0008-linuxefi-Use-common-grub_initrd_load.patch
|
||||
Patch909: 0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch
|
||||
Patch910: 0010-templates-import-etc-crypttab-to-grub.cfg.patch
|
||||
Patch911: grub-read-pcr.patch
|
||||
Patch912: efi-set-variable-with-attrs.patch
|
||||
Patch913: tpm-record-pcrs.patch
|
||||
Patch914: tpm-protector-dont-measure-sealed-key.patch
|
||||
Patch915: tpm-protector-export-secret-key.patch
|
||||
Patch916: grub-install-record-pcrs.patch
|
||||
Patch917: grub-unseal-debug.patch
|
||||
# efi mm
|
||||
Patch918: 0001-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch
|
||||
Patch919: 0001-mm-Allow-dynamically-requesting-additional-memory-re.patch
|
||||
Patch920: 0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch
|
||||
Patch921: 0003-kern-efi-mm-Extract-function-to-add-memory-regions.patch
|
||||
Patch922: 0004-kern-efi-mm-Pass-up-errors-from-add_memory_regions.patch
|
||||
Patch923: 0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch
|
||||
Patch924: 0001-kern-efi-mm-Enlarge-the-default-heap-size.patch
|
||||
Patch925: 0002-mm-Defer-the-disk-cache-invalidation.patch
|
||||
# powerpc-ieee1275
|
||||
Patch926: 0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch
|
||||
Patch927: safe_tpm_pcr_snapshot.patch
|
||||
Patch928: 0001-linux-fix-efi_relocate_kernel-failure.patch
|
||||
# (PED-996) NVMeoFC support on Grub (grub2)
|
||||
Patch929: 0001-ieee1275-add-support-for-NVMeoFC.patch
|
||||
Patch930: 0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch
|
||||
Patch931: 0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch
|
||||
Patch932: 0004-ofpath-controller-name-update.patch
|
||||
# (PED-1265) TDX: Enhance grub2 measurement to TD RTMR
|
||||
Patch933: 0001-commands-efi-tpm-Refine-the-status-of-log-event.patch
|
||||
Patch934: 0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch
|
||||
Patch935: 0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch
|
||||
# (PED-1990) GRUB2: Measure the kernel on POWER10 and extend TPM PCRs
|
||||
Patch936: 0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch
|
||||
Patch937: 0002-ieee1275-implement-vec5-for-cas-negotiation.patch
|
||||
|
||||
Requires: gettext-runtime
|
||||
%if 0%{?suse_version} >= 1140
|
||||
@ -673,11 +732,11 @@ CD_MODULES="all_video boot cat configfile echo true \
|
||||
font gfxmenu gfxterm gzio halt iso9660 \
|
||||
jpeg minicmd normal part_apple part_msdos part_gpt \
|
||||
password password_pbkdf2 png reboot search search_fs_uuid \
|
||||
search_fs_file search_label sleep test video fat loadenv"
|
||||
search_fs_file search_label sleep test video fat loadenv loopback"
|
||||
PXE_MODULES="tftp http"
|
||||
CRYPTO_MODULES="luks gcry_rijndael gcry_sha1 gcry_sha256"
|
||||
CRYPTO_MODULES="luks luks2 gcry_rijndael gcry_sha1 gcry_sha256 gcry_sha512 crypttab"
|
||||
%ifarch %{efi}
|
||||
CD_MODULES="${CD_MODULES} chain efifwsetup efinet read"
|
||||
CD_MODULES="${CD_MODULES} chain efifwsetup efinet read tpm tpm2"
|
||||
PXE_MODULES="${PXE_MODULES} efinet"
|
||||
%else
|
||||
CD_MODULES="${CD_MODULES} net"
|
||||
@ -715,10 +774,6 @@ echo "grub.%{sbat_distro},%{sbat_generation},%{sbat_distro_summary},%{name},%{ve
|
||||
|
||||
./grub-mkimage -O %{grubefiarch} -o grub.efi --prefix= %{?sbat_generation:--sbat sbat.csv} \
|
||||
-d grub-core ${GRUB_MODULES}
|
||||
%ifarch x86_64
|
||||
./grub-mkimage -O %{grubefiarch} -o grub-tpm.efi --prefix= %{?sbat_generation:--sbat sbat.csv} \
|
||||
-d grub-core ${GRUB_MODULES} tpm
|
||||
%endif
|
||||
|
||||
%ifarch x86_64 aarch64
|
||||
if test -e %{_sourcedir}/_projectcert.crt ; then
|
||||
@ -898,7 +953,7 @@ cd build-efi
|
||||
%make_install
|
||||
install -m 644 grub.efi %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/.
|
||||
%ifarch x86_64
|
||||
install -m 644 grub-tpm.efi %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/.
|
||||
ln -srf %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/grub.efi %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/grub-tpm.efi
|
||||
%endif
|
||||
|
||||
# Create grub.efi link to system efi directory
|
||||
@ -920,9 +975,6 @@ EoM
|
||||
|
||||
%ifarch x86_64 aarch64
|
||||
export BRP_PESIGN_FILES="%{_datadir}/%{name}/%{grubefiarch}/grub.efi"
|
||||
%ifarch x86_64
|
||||
BRP_PESIGN_FILES="${BRP_PESIGN_FILES} %{_datadir}/%{name}/%{grubefiarch}/grub-tpm.efi"
|
||||
%endif
|
||||
install -m 444 grub.der %{buildroot}/%{sysefidir}/
|
||||
%endif
|
||||
|
||||
@ -1205,6 +1257,7 @@ fi
|
||||
%dir %{_sysconfdir}/grub.d
|
||||
%{_sysconfdir}/grub.d/README
|
||||
%config(noreplace) %{_sysconfdir}/grub.d/00_header
|
||||
%config(noreplace) %{_sysconfdir}/grub.d/05_crypttab
|
||||
%config(noreplace) %{_sysconfdir}/grub.d/10_linux
|
||||
%config(noreplace) %{_sysconfdir}/grub.d/20_linux_xen
|
||||
%config(noreplace) %{_sysconfdir}/grub.d/30_uefi-firmware
|
||||
@ -1249,6 +1302,7 @@ fi
|
||||
%{_bindir}/%{name}-render-label
|
||||
%{_bindir}/%{name}-script-check
|
||||
%{_bindir}/%{name}-syslinux2cfg
|
||||
%{_bindir}/%{name}-protect
|
||||
%if 0%{?has_systemd:1}
|
||||
%{_unitdir}/grub2-once.service
|
||||
%endif
|
||||
|
125
safe_tpm_pcr_snapshot.patch
Normal file
125
safe_tpm_pcr_snapshot.patch
Normal file
@ -0,0 +1,125 @@
|
||||
---
|
||||
grub-core/commands/tpm.c | 46 ++++++++++++++++++++++++++++++++++++----------
|
||||
util/grub-install.c | 6 ++++--
|
||||
2 files changed, 40 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/grub-core/commands/tpm.c
|
||||
+++ b/grub-core/commands/tpm.c
|
||||
@@ -27,8 +27,10 @@
|
||||
#include <grub/verify.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/extcmd.h>
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
#include <grub/tpm2/tpm2.h>
|
||||
#include <grub/efi/efi.h>
|
||||
+#endif
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -87,12 +89,6 @@
|
||||
.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[] =
|
||||
{
|
||||
{
|
||||
@@ -108,6 +104,14 @@
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+
|
||||
+/*
|
||||
+ * 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 grub_err_t
|
||||
grub_tpm_parse_pcr_index (const char *word, const char **end_ret, unsigned int *index)
|
||||
{
|
||||
@@ -259,6 +263,10 @@
|
||||
grub_size_t size = 0;
|
||||
int n, rv = 1;
|
||||
|
||||
+ /* To prevent error: unable to read PCR from TPM, if no TPM device available */
|
||||
+ if (!grub_tpm_present())
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
if (argc == 0)
|
||||
pcr_bitmask = GRUB2_PCR_BITMASK_DEFAULT;
|
||||
else
|
||||
@@ -287,13 +295,28 @@
|
||||
return rv;
|
||||
}
|
||||
|
||||
+#else
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm_record_pcrs (grub_extcmd_context_t ctxt __attribute__((unused)),
|
||||
+ int argc __attribute__((unused)),
|
||||
+ char **args __attribute__((unused)))
|
||||
+{
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
static grub_extcmd_t cmd;
|
||||
|
||||
GRUB_MOD_INIT (tpm)
|
||||
{
|
||||
- if (!grub_tpm_present())
|
||||
- return;
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ if (grub_tpm_present())
|
||||
+ grub_verifier_register (&grub_tpm_verifier);
|
||||
+#else
|
||||
grub_verifier_register (&grub_tpm_verifier);
|
||||
+#endif
|
||||
|
||||
cmd = grub_register_extcmd ("tpm_record_pcrs", grub_tpm_record_pcrs, 0,
|
||||
N_("LIST_OF_PCRS"),
|
||||
@@ -303,8 +326,11 @@
|
||||
|
||||
GRUB_MOD_FINI (tpm)
|
||||
{
|
||||
- if (!grub_tpm_present())
|
||||
- return;
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ if (grub_tpm_present())
|
||||
+ grub_verifier_unregister (&grub_tpm_verifier);
|
||||
+#else
|
||||
grub_verifier_unregister (&grub_tpm_verifier);
|
||||
+#endif
|
||||
grub_unregister_extcmd (cmd);
|
||||
}
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -1457,8 +1457,9 @@
|
||||
|
||||
grub_util_unlink (load_cfg);
|
||||
|
||||
- if (1)
|
||||
+ if (platform == GRUB_INSTALL_PLATFORM_X86_64_EFI && have_cryptodisk)
|
||||
{
|
||||
+ grub_install_push_module ("tpm");
|
||||
load_cfg_f = grub_util_fopen (load_cfg, "wb");
|
||||
have_load_cfg = 1;
|
||||
fprintf (load_cfg_f, "tpm_record_pcrs 0-9\n");
|
||||
@@ -1466,7 +1467,8 @@
|
||||
|
||||
if (debug_image && debug_image[0])
|
||||
{
|
||||
- load_cfg_f = grub_util_fopen (load_cfg, "wb");
|
||||
+ if (!load_cfg_f)
|
||||
+ load_cfg_f = grub_util_fopen (load_cfg, "wb");
|
||||
have_load_cfg = 1;
|
||||
fprintf (load_cfg_f, "set debug='%s'\n",
|
||||
debug_image);
|
15
tpm-protector-dont-measure-sealed-key.patch
Normal file
15
tpm-protector-dont-measure-sealed-key.patch
Normal file
@ -0,0 +1,15 @@
|
||||
Index: grub-2.06/grub-core/tpm2/module.c
|
||||
===================================================================
|
||||
--- grub-2.06.orig/grub-core/tpm2/module.c
|
||||
+++ grub-2.06/grub-core/tpm2/module.c
|
||||
@@ -139,7 +139,9 @@ grub_tpm2_protector_srk_read_keyfile (co
|
||||
void *sealed_key_buffer;
|
||||
grub_off_t sealed_key_read;
|
||||
|
||||
- sealed_key_file = grub_file_open (filepath, GRUB_FILE_TYPE_NONE);
|
||||
+ /* Using GRUB_FILE_TYPE_SIGNATURE ensures we do not hash the keyfile into PCR9
|
||||
+ * otherwise we'll never be able to predict the value of PCR9 at unseal time */
|
||||
+ sealed_key_file = grub_file_open (filepath, GRUB_FILE_TYPE_SIGNATURE);
|
||||
if (!sealed_key_file)
|
||||
{
|
||||
grub_dprintf ("tpm2", "Could not open sealed key file.\n");
|
138
tpm-protector-export-secret-key.patch
Normal file
138
tpm-protector-export-secret-key.patch
Normal file
@ -0,0 +1,138 @@
|
||||
Index: grub-2.06/grub-core/tpm2/module.c
|
||||
===================================================================
|
||||
--- grub-2.06.orig/grub-core/tpm2/module.c
|
||||
+++ grub-2.06/grub-core/tpm2/module.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <grub/tpm2/internal/args.h>
|
||||
#include <grub/tpm2/mu.h>
|
||||
#include <grub/tpm2/tpm2.h>
|
||||
+#include <grub/efi/efi.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -46,6 +47,7 @@ struct grub_tpm2_protector_context
|
||||
const char *keyfile;
|
||||
TPM_HANDLE srk;
|
||||
TPM_HANDLE nv;
|
||||
+ const char *efivar;
|
||||
};
|
||||
|
||||
static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
|
||||
@@ -122,6 +124,16 @@ static const struct grub_arg_option grub
|
||||
N_("Required in NV Index mode, the NV handle to read which must "
|
||||
"readily exist on the TPM and which contains the key."),
|
||||
},
|
||||
+ /* When publishing the unsealed key to a UEFI variable */
|
||||
+ {
|
||||
+ .longarg = "efivar",
|
||||
+ .shortarg = 'E',
|
||||
+ .flags = 0,
|
||||
+ .arg = NULL,
|
||||
+ .type = ARG_TYPE_STRING,
|
||||
+ .doc =
|
||||
+ N_("Publish the unsealed key to the indicated UEFI variable."),
|
||||
+ },
|
||||
/* End of list */
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
@@ -302,6 +314,34 @@ grub_tpm2_protector_srk_get (const struc
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
+grub_tpm2_protector_publish_key (grub_uint8_t *key, grub_size_t key_size,
|
||||
+ const char *var_name)
|
||||
+{
|
||||
+ grub_efi_guid_t vendor_guid = { 0x58aca851, 0x8af7, 0x4738, { 0xa5, 0x42, 0x26, 0x6e, 0x21, 0xf5, 0xca, 0xd9 }};
|
||||
+ grub_uint8_t *tmp_key;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ /* It appears that EFI's set_var function overwrites the key. */
|
||||
+ tmp_key = grub_malloc (key_size);
|
||||
+ if (!tmp_key)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("No memory left to allocate temporary key buffer"));
|
||||
+ return GRUB_ERR_OUT_OF_MEMORY;
|
||||
+ }
|
||||
+
|
||||
+ grub_memcpy(tmp_key, key, key_size);
|
||||
+
|
||||
+ err = grub_efi_set_variable_with_attributes(var_name, &vendor_guid,
|
||||
+ GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | GRUB_EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
+ tmp_key, key_size);
|
||||
+ if (err)
|
||||
+ grub_error (err, N_("Failed to export LUKS key as EFI variable %s"), var_name);
|
||||
+
|
||||
+ grub_free (tmp_key);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx,
|
||||
grub_uint8_t **key, grub_size_t *key_size)
|
||||
{
|
||||
@@ -421,6 +461,13 @@ grub_tpm2_protector_srk_recover (const s
|
||||
goto exit4;
|
||||
}
|
||||
|
||||
+ if (ctx->efivar)
|
||||
+ {
|
||||
+ rc = grub_tpm2_protector_publish_key (data.buffer, data.size, ctx->efivar);
|
||||
+ if (rc)
|
||||
+ goto exit4;
|
||||
+ }
|
||||
+
|
||||
grub_memcpy (key_out, data.buffer, data.size);
|
||||
|
||||
*key = key_out;
|
||||
@@ -549,20 +596,32 @@ grub_tpm2_protector_check_args (struct g
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_tpm2_protector_parse_keyfile (const char *value, const char **keyfile)
|
||||
+grub_tpm2_protector_parse_string (const char *value, const char **var, const char *arg_name)
|
||||
{
|
||||
if (grub_strlen (value) == 0)
|
||||
return GRUB_ERR_BAD_ARGUMENT;
|
||||
|
||||
- *keyfile = grub_strdup (value);
|
||||
- if (!*keyfile)
|
||||
+ *var = grub_strdup (value);
|
||||
+ if (!*var)
|
||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
- N_("No memory to duplicate keyfile path"));
|
||||
+ N_("No memory to duplicate %s argument"), arg_name);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
+grub_tpm2_protector_parse_keyfile (const char *value, const char **keyfile)
|
||||
+{
|
||||
+ return grub_tpm2_protector_parse_string (value, keyfile, "keyfile");
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_parse_efivar (const char *value, const char **efivar)
|
||||
+{
|
||||
+ return grub_tpm2_protector_parse_string (value, efivar, "efivar");
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
grub_tpm2_protector_parse_mode (const char *value,
|
||||
grub_tpm2_protector_mode_t *mode)
|
||||
{
|
||||
@@ -650,6 +709,14 @@ grub_tpm2_protector_init_cmd_handler (gr
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
+
|
||||
+ if (state[7].set) /* efivar */
|
||||
+ {
|
||||
+ err = grub_tpm2_protector_parse_efivar (state[7].arg,
|
||||
+ &grub_tpm2_protector_ctx.efivar);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
|
||||
err = grub_tpm2_protector_check_args (&grub_tpm2_protector_ctx);
|
||||
|
235
tpm-record-pcrs.patch
Normal file
235
tpm-record-pcrs.patch
Normal file
@ -0,0 +1,235 @@
|
||||
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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user