ieee1275: Appended signature support
Resolves: #RHEL-24742 Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
This commit is contained in:
parent
4946e4fb22
commit
4b6a3a3027
2720
0467-appended-sig-sync-d-with-upstream-code.patch
Normal file
2720
0467-appended-sig-sync-d-with-upstream-code.patch
Normal file
File diff suppressed because it is too large
Load Diff
200
0468-ieee1275-Platform-Keystore-PKS-Support.patch
Normal file
200
0468-ieee1275-Platform-Keystore-PKS-Support.patch
Normal file
@ -0,0 +1,200 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Thu, 27 Mar 2025 01:02:35 +0530
|
||||
Subject: [PATCH] ieee1275: Platform Keystore (PKS) Support
|
||||
|
||||
enhancing the infrastructure to enable the Platform Keystore (PKS) feature,
|
||||
which provides access to the SB VERSION, DB, and DBX secure boot variables
|
||||
from PKS.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/kern/powerpc/ieee1275/ieee1275.c | 140 +++++++++++++++++++++++++++++
|
||||
include/grub/powerpc/ieee1275/ieee1275.h | 14 +++
|
||||
3 files changed, 155 insertions(+)
|
||||
create mode 100644 grub-core/kern/powerpc/ieee1275/ieee1275.c
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 3740330..05b9c8d 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -320,6 +320,7 @@ kernel = {
|
||||
extra_dist = video/sis315_init.c;
|
||||
mips_loongson = commands/keylayouts.c;
|
||||
|
||||
+ powerpc_ieee1275 = kern/powerpc/ieee1275/ieee1275.c;
|
||||
powerpc_ieee1275 = kern/powerpc/cache.S;
|
||||
powerpc_ieee1275 = kern/powerpc/dl.c;
|
||||
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
|
||||
diff --git a/grub-core/kern/powerpc/ieee1275/ieee1275.c b/grub-core/kern/powerpc/ieee1275/ieee1275.c
|
||||
new file mode 100644
|
||||
index 0000000..f685afc
|
||||
--- /dev/null
|
||||
+++ b/grub-core/kern/powerpc/ieee1275/ieee1275.c
|
||||
@@ -0,0 +1,140 @@
|
||||
+/* of.c - Access the Open Firmware client interface. */
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2003,2004,2005,2007,2008,2009 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/>.
|
||||
+ */
|
||||
+#include <grub/ieee1275/ieee1275.h>
|
||||
+#include <grub/powerpc/ieee1275/ieee1275.h>
|
||||
+#include <grub/misc.h>
|
||||
+
|
||||
+#define IEEE1275_CELL_INVALID ((grub_ieee1275_cell_t) - 1)
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_test (const char *name, grub_ieee1275_cell_t *missing)
|
||||
+{
|
||||
+ struct test_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t name;
|
||||
+ grub_ieee1275_cell_t missing;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "test", 1, 1);
|
||||
+ args.name = (grub_ieee1275_cell_t) name;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.missing == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *missing = args.missing;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_pks_max_object_size (grub_size_t *result)
|
||||
+{
|
||||
+ struct mos_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t size;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "pks-max-object-size", 0, 1);
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.size == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *result = args.size;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_pks_read_object (grub_uint8_t consumer, grub_uint8_t *label,
|
||||
+ grub_size_t label_len, grub_uint8_t *buffer,
|
||||
+ grub_size_t buffer_len, grub_size_t *data_len,
|
||||
+ grub_uint32_t *policies)
|
||||
+{
|
||||
+ struct pks_read_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t consumer;
|
||||
+ grub_ieee1275_cell_t label;
|
||||
+ grub_ieee1275_cell_t label_len;
|
||||
+ grub_ieee1275_cell_t buffer;
|
||||
+ grub_ieee1275_cell_t buffer_len;
|
||||
+ grub_ieee1275_cell_t data_len;
|
||||
+ grub_ieee1275_cell_t policies;
|
||||
+ grub_ieee1275_cell_t rc;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "pks-read-object", 5, 3);
|
||||
+ args.consumer = (grub_ieee1275_cell_t) consumer;
|
||||
+ args.label = (grub_ieee1275_cell_t) label;
|
||||
+ args.label_len = (grub_ieee1275_cell_t) label_len;
|
||||
+ args.buffer = (grub_ieee1275_cell_t) buffer;
|
||||
+ args.buffer_len = (grub_ieee1275_cell_t) buffer_len;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.data_len == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *data_len = args.data_len;
|
||||
+ *policies = args.policies;
|
||||
+
|
||||
+ return (int) args.rc;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_pks_read_sbvar (grub_uint8_t sbvarflags, grub_uint8_t sbvartype,
|
||||
+ grub_uint8_t *buffer, grub_size_t buffer_len,
|
||||
+ grub_size_t *data_len)
|
||||
+{
|
||||
+ struct pks_read_sbvar_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t sbvarflags;
|
||||
+ grub_ieee1275_cell_t sbvartype;
|
||||
+ grub_ieee1275_cell_t buffer;
|
||||
+ grub_ieee1275_cell_t buffer_len;
|
||||
+ grub_ieee1275_cell_t data_len;
|
||||
+ grub_ieee1275_cell_t rc;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "pks-read-sbvar", 4, 2);
|
||||
+ args.sbvarflags = (grub_ieee1275_cell_t) sbvarflags;
|
||||
+ args.sbvartype = (grub_ieee1275_cell_t) sbvartype;
|
||||
+ args.buffer = (grub_ieee1275_cell_t) buffer;
|
||||
+ args.buffer_len = (grub_ieee1275_cell_t) buffer_len;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.data_len == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *data_len = args.data_len;
|
||||
+
|
||||
+ return (int) args.rc;
|
||||
+}
|
||||
diff --git a/include/grub/powerpc/ieee1275/ieee1275.h b/include/grub/powerpc/ieee1275/ieee1275.h
|
||||
index 3c7683f..45c7b16 100644
|
||||
--- a/include/grub/powerpc/ieee1275/ieee1275.h
|
||||
+++ b/include/grub/powerpc/ieee1275/ieee1275.h
|
||||
@@ -25,4 +25,18 @@
|
||||
#define GRUB_IEEE1275_CELL_SIZEOF 4
|
||||
typedef grub_uint32_t grub_ieee1275_cell_t;
|
||||
|
||||
+int EXPORT_FUNC (grub_ieee1275_test) (const char *name,
|
||||
+ grub_ieee1275_cell_t *missing);
|
||||
+
|
||||
+int grub_ieee1275_pks_max_object_size (grub_size_t *result);
|
||||
+
|
||||
+int grub_ieee1275_pks_read_object (grub_uint8_t consumer, grub_uint8_t *label,
|
||||
+ grub_size_t label_len, grub_uint8_t *buffer,
|
||||
+ grub_size_t buffer_len, grub_size_t *data_len,
|
||||
+ grub_uint32_t *policies);
|
||||
+
|
||||
+int grub_ieee1275_pks_read_sbvar (grub_uint8_t sbvarflags, grub_uint8_t sbvartype,
|
||||
+ grub_uint8_t *buffer, grub_size_t buffer_len,
|
||||
+ grub_size_t *data_len);
|
||||
+
|
||||
#endif /* ! GRUB_IEEE1275_MACHINE_HEADER */
|
686
0469-ieee1275-Read-the-DB-and-DBX-secure-boot-variables.patch
Normal file
686
0469-ieee1275-Read-the-DB-and-DBX-secure-boot-variables.patch
Normal file
@ -0,0 +1,686 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Thu, 27 Mar 2025 01:02:36 +0530
|
||||
Subject: [PATCH] ieee1275: Read the DB and DBX secure boot variables
|
||||
|
||||
If secure boot is enabled with PKS, it will read secure boot variables
|
||||
such as db and dbx from PKS and extract ESL's from it.
|
||||
The ESL's would be saved in the platform keystore buffer, and
|
||||
the appendedsig (module) would read it later to extract
|
||||
the certificate's details from ESL.
|
||||
|
||||
In the following scenarios, static key mode will be activated:
|
||||
1. When Secure Boot is enabled with static keys
|
||||
2. When SB Version is unavailable but Secure Boot is enabled
|
||||
3. When PKS support is unavailable but Secure Boot is enabled
|
||||
|
||||
Note:-
|
||||
|
||||
SB Version - Secure Boot mode
|
||||
1 - PKS
|
||||
0 - static key (embeded key)
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/Makefile.am | 1 +
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/kern/ieee1275/init.c | 15 +-
|
||||
.../kern/powerpc/ieee1275/platform_keystore.c | 332 +++++++++++++++++++++
|
||||
include/grub/powerpc/ieee1275/platform_keystore.h | 225 ++++++++++++++
|
||||
include/grub/types.h | 8 +
|
||||
6 files changed, 580 insertions(+), 2 deletions(-)
|
||||
create mode 100644 grub-core/kern/powerpc/ieee1275/platform_keystore.c
|
||||
create mode 100644 include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index dd49939..a398a04 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -245,6 +245,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
endif
|
||||
|
||||
if COND_sparc64_ieee1275
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 05b9c8d..218068b 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -325,6 +325,7 @@ kernel = {
|
||||
powerpc_ieee1275 = kern/powerpc/dl.c;
|
||||
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
|
||||
powerpc_ieee1275 = kern/lockdown.c;
|
||||
+ powerpc_ieee1275 = kern/powerpc/ieee1275/platform_keystore.c;
|
||||
|
||||
sparc64_ieee1275 = kern/sparc64/cache.S;
|
||||
sparc64_ieee1275 = kern/sparc64/dl.c;
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index bb791f8..b853f04 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -47,6 +47,8 @@
|
||||
#include <grub/machine/kernel.h>
|
||||
#endif
|
||||
#include <grub/lockdown.h>
|
||||
+#include <grub/powerpc/ieee1275/ieee1275.h>
|
||||
+#include <grub/powerpc/ieee1275/platform_keystore.h>
|
||||
|
||||
/* The maximum heap size we're going to claim at boot. Not used by sparc. */
|
||||
#ifdef __i386__
|
||||
@@ -956,7 +958,7 @@ grub_get_ieee1275_secure_boot (void)
|
||||
{
|
||||
grub_ieee1275_phandle_t root;
|
||||
int rc;
|
||||
- grub_uint32_t is_sb;
|
||||
+ grub_uint32_t is_sb = 0;
|
||||
|
||||
grub_ieee1275_finddevice ("/", &root);
|
||||
|
||||
@@ -972,7 +974,16 @@ grub_get_ieee1275_secure_boot (void)
|
||||
* We only support enforce.
|
||||
*/
|
||||
if (rc >= 0 && is_sb >= 2)
|
||||
- grub_lockdown ();
|
||||
+ {
|
||||
+ grub_dprintf ("ieee1275", "Secure Boot Enabled\n");
|
||||
+ rc = grub_pks_keystore_init ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_error (rc, "Initialization of the Platform Keystore failed!\n");
|
||||
+
|
||||
+ grub_lockdown ();
|
||||
+ }
|
||||
+ else
|
||||
+ grub_dprintf ("ieee1275", "Secure Boot Disabled\n");
|
||||
}
|
||||
|
||||
grub_addr_t grub_modbase;
|
||||
diff --git a/grub-core/kern/powerpc/ieee1275/platform_keystore.c b/grub-core/kern/powerpc/ieee1275/platform_keystore.c
|
||||
new file mode 100644
|
||||
index 0000000..cf1d055
|
||||
--- /dev/null
|
||||
+++ b/grub-core/kern/powerpc/ieee1275/platform_keystore.c
|
||||
@@ -0,0 +1,332 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2024 Free Software Foundation, Inc.
|
||||
+ * Copyright (C) 2024 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/powerpc/ieee1275/ieee1275.h>
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/lockdown.h>
|
||||
+#include <grub/powerpc/ieee1275/platform_keystore.h>
|
||||
+
|
||||
+#define PKS_CONSUMER_FW 1
|
||||
+#define SB_VERSION_KEY_NAME ((grub_uint8_t *) "SB_VERSION")
|
||||
+#define SB_VERSION_KEY_LEN 10
|
||||
+#define DB 1
|
||||
+#define DBX 2
|
||||
+#define PKS_OBJECT_NOT_FOUND ((grub_err_t) - 7)
|
||||
+
|
||||
+/* Platform Keystore */
|
||||
+static grub_size_t pks_max_object_size;
|
||||
+grub_uint8_t grub_pks_use_keystore = 0;
|
||||
+grub_pks_t grub_pks_keystore = { .db = NULL, .dbx = NULL, .db_entries = 0, .dbx_entries = 0 };
|
||||
+
|
||||
+/* Convert the esl data into the ESL */
|
||||
+static grub_esl_t *
|
||||
+convert_to_esl (const grub_uint8_t *esl_data, const grub_size_t esl_data_size)
|
||||
+{
|
||||
+ grub_esl_t *esl = NULL;
|
||||
+
|
||||
+ if (esl_data_size < sizeof (grub_esl_t) || esl_data == NULL)
|
||||
+ return esl;
|
||||
+
|
||||
+ esl = (grub_esl_t *) esl_data;
|
||||
+
|
||||
+ return esl;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Import the GUID, esd, and its size into the pks sd buffer and
|
||||
+ * pks sd entries from the EFI signature list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+esd_from_esl (const grub_uint8_t *esl_data, grub_size_t esl_size,
|
||||
+ const grub_size_t signature_size, const grub_uuid_t *guid,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_esd_t *esd = NULL;
|
||||
+ grub_pks_sd_t *signature = *pks_sd;
|
||||
+ grub_size_t entries = *pks_sd_entries;
|
||||
+ grub_size_t data_size = 0, offset = 0;
|
||||
+
|
||||
+ /* reads the esd from esl */
|
||||
+ while (esl_size > 0)
|
||||
+ {
|
||||
+ esd = (grub_esd_t *) (esl_data + offset);
|
||||
+ data_size = signature_size - sizeof (grub_esd_t);
|
||||
+
|
||||
+ signature = grub_realloc (signature, (entries + 1) * sizeof (grub_pks_sd_t));
|
||||
+ if (signature == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ signature[entries].data = grub_malloc (data_size * sizeof (grub_uint8_t));
|
||||
+ if (signature[entries].data == NULL)
|
||||
+ {
|
||||
+ /*
|
||||
+ * allocated memory will be freed by
|
||||
+ * grub_free_platform_keystore
|
||||
+ */
|
||||
+ *pks_sd = signature;
|
||||
+ *pks_sd_entries = entries + 1;
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+ }
|
||||
+
|
||||
+ grub_memcpy (signature[entries].data, esd->signaturedata, data_size);
|
||||
+ signature[entries].data_size = data_size;
|
||||
+ signature[entries].guid = *guid;
|
||||
+ entries++;
|
||||
+ esl_size -= signature_size;
|
||||
+ offset += signature_size;
|
||||
+ }
|
||||
+
|
||||
+ *pks_sd = signature;
|
||||
+ *pks_sd_entries = entries;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Extract the esd after removing the esl header from esl.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+esl_to_esd (const grub_uint8_t *esl_data, grub_size_t *next_esl,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_uuid_t guid = { 0 };
|
||||
+ grub_esl_t *esl = NULL;
|
||||
+ grub_size_t offset = 0, esl_size = 0,
|
||||
+ signature_size = 0, signature_header_size = 0;
|
||||
+
|
||||
+ esl = convert_to_esl (esl_data, *next_esl);
|
||||
+ if (esl == NULL)
|
||||
+ return grub_error (GRUB_ERR_BUG, "invalid ESL");
|
||||
+
|
||||
+ esl_size = grub_le_to_cpu32 (esl->signaturelistsize);
|
||||
+ signature_header_size = grub_le_to_cpu32 (esl->signatureheadersize);
|
||||
+ signature_size = grub_le_to_cpu32 (esl->signaturesize);
|
||||
+ guid = esl->signaturetype;
|
||||
+
|
||||
+ if (esl_size < sizeof (grub_esl_t) || esl_size > *next_esl)
|
||||
+ return grub_error (GRUB_ERR_BUG, "invalid ESL size (%u)\n", esl_size);
|
||||
+
|
||||
+ *next_esl = esl_size;
|
||||
+ offset = sizeof (grub_esl_t) + signature_header_size;
|
||||
+ esl_size = esl_size - offset;
|
||||
+
|
||||
+ return esd_from_esl (esl_data + offset, esl_size, signature_size, &guid,
|
||||
+ pks_sd, pks_sd_entries);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Import the EFI signature data and the number of esd from the esl
|
||||
+ * into the pks sd buffer and pks sd entries.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+pks_sd_from_esl (const grub_uint8_t *esl_data, grub_size_t esl_size,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t next_esl = esl_size;
|
||||
+
|
||||
+ do
|
||||
+ {
|
||||
+ rc = esl_to_esd (esl_data, &next_esl, pks_sd, pks_sd_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ break;
|
||||
+
|
||||
+ esl_data += next_esl;
|
||||
+ esl_size -= next_esl;
|
||||
+ next_esl = esl_size;
|
||||
+ }
|
||||
+ while (esl_size > 0);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Read the secure boot version from PKS as an object.
|
||||
+ * caller must free result
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+read_sbversion_from_pks (grub_uint8_t **out, grub_size_t *outlen, grub_size_t *policy)
|
||||
+{
|
||||
+ *out = grub_malloc (pks_max_object_size);
|
||||
+ if (*out == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ return grub_ieee1275_pks_read_object (PKS_CONSUMER_FW, SB_VERSION_KEY_NAME,
|
||||
+ SB_VERSION_KEY_LEN, *out, pks_max_object_size,
|
||||
+ outlen, policy);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * reads the secure boot variable from PKS.
|
||||
+ * caller must free result
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+read_sbvar_from_pks (const grub_uint8_t sbvarflags, const grub_uint8_t sbvartype,
|
||||
+ grub_uint8_t **out, grub_size_t *outlen)
|
||||
+{
|
||||
+ *out = grub_malloc (pks_max_object_size);
|
||||
+ if (*out == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ return grub_ieee1275_pks_read_sbvar (sbvarflags, sbvartype, *out,
|
||||
+ pks_max_object_size, outlen);
|
||||
+}
|
||||
+
|
||||
+/* Test the availability of PKS support. */
|
||||
+static grub_err_t
|
||||
+is_support_pks (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_ieee1275_cell_t missing = 0;
|
||||
+
|
||||
+ rc = grub_ieee1275_test ("pks-max-object-size", &missing);
|
||||
+ if (rc != GRUB_ERR_NONE || (int) missing == -1)
|
||||
+ rc = grub_error (GRUB_ERR_BAD_FIRMWARE, "Firmware doesn't have PKS support!\n");
|
||||
+ else
|
||||
+ {
|
||||
+ rc = grub_ieee1275_pks_max_object_size (&pks_max_object_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ rc = grub_error (GRUB_ERR_BAD_NUMBER, "PKS support is there but it has zero objects!\n");
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Retrieve the secure boot variable from PKS, unpacks it, read the esd
|
||||
+ * from ESL, and store the information in the pks sd buffer.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+read_secure_boot_variables (const grub_uint8_t sbvarflags, const grub_uint8_t sbvartype,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_uint8_t *esl_data = NULL;
|
||||
+ grub_size_t esl_data_size = 0;
|
||||
+
|
||||
+ rc = read_sbvar_from_pks (sbvarflags, sbvartype, &esl_data, &esl_data_size);
|
||||
+ /*
|
||||
+ * at this point we have SB_VERSION, so any error is worth
|
||||
+ * at least some user-visible info
|
||||
+ */
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ rc = grub_error (rc, "secure boot variable %s reading (%d)",
|
||||
+ (sbvartype == DB ? "db" : "dbx"), rc);
|
||||
+ else if (esl_data_size != 0)
|
||||
+ rc = pks_sd_from_esl ((const grub_uint8_t *) esl_data, esl_data_size,
|
||||
+ pks_sd, pks_sd_entries);
|
||||
+ grub_free (esl_data);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* reads secure boot version (SB_VERSION) and it supports following
|
||||
+ * SB_VERSION
|
||||
+ * 1 - PKS
|
||||
+ * 0 - static key (embeded key)
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+get_secure_boot_version (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_uint8_t *data = NULL;
|
||||
+ grub_size_t len = 0, policy = 0;
|
||||
+
|
||||
+ rc = read_sbversion_from_pks (&data, &len, &policy);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ rc = grub_error (GRUB_ERR_READ_ERROR, "SB version read failed! (%d)\n", rc);
|
||||
+ else if (len != 1 || (*data >= 2))
|
||||
+ rc = grub_error (GRUB_ERR_BAD_NUMBER, "found unexpected SB version! (%d)\n", *data);
|
||||
+
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Switch to Static Key!\n");
|
||||
+ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
|
||||
+ grub_fatal ("Secure Boot locked down");
|
||||
+ }
|
||||
+ else
|
||||
+ grub_pks_use_keystore = *data;
|
||||
+
|
||||
+ grub_free (data);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* Free allocated memory */
|
||||
+void
|
||||
+grub_pks_free_keystore (void)
|
||||
+{
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.db_entries; i++)
|
||||
+ grub_free (grub_pks_keystore.db[i].data);
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
|
||||
+ grub_free (grub_pks_keystore.dbx[i].data);
|
||||
+
|
||||
+ grub_free (grub_pks_keystore.db);
|
||||
+ grub_free (grub_pks_keystore.dbx);
|
||||
+ grub_memset (&grub_pks_keystore, 0, sizeof (grub_pks_t));
|
||||
+}
|
||||
+
|
||||
+/* Initialization of the Platform Keystore */
|
||||
+grub_err_t
|
||||
+grub_pks_keystore_init (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+
|
||||
+ grub_dprintf ("ieee1275", "trying to load Platform Keystore\n");
|
||||
+
|
||||
+ rc = is_support_pks ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Switch to Static Key!\n");
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ /* SB_VERSION */
|
||||
+ rc = get_secure_boot_version ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ return rc;
|
||||
+
|
||||
+ if (grub_pks_use_keystore)
|
||||
+ {
|
||||
+ grub_memset (&grub_pks_keystore, 0, sizeof (grub_pks_t));
|
||||
+ /* DB */
|
||||
+ rc = read_secure_boot_variables (0, DB, &grub_pks_keystore.db, &grub_pks_keystore.db_entries);
|
||||
+ if (rc == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ /* DBX */
|
||||
+ rc = read_secure_boot_variables (0, DBX, &grub_pks_keystore.dbx, &grub_pks_keystore.dbx_entries);
|
||||
+ if (rc == PKS_OBJECT_NOT_FOUND)
|
||||
+ {
|
||||
+ grub_dprintf ("ieee1275", "dbx is not found in PKS\n");
|
||||
+ rc = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_pks_free_keystore ();
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
diff --git a/include/grub/powerpc/ieee1275/platform_keystore.h b/include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
new file mode 100644
|
||||
index 0000000..0641adb
|
||||
--- /dev/null
|
||||
+++ b/include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
@@ -0,0 +1,225 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved. This
|
||||
+ * program and the accompanying materials are licensed and made available
|
||||
+ * under the terms and conditions of the 2-Clause BSD License which
|
||||
+ * accompanies this distribution.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions are met:
|
||||
+ *
|
||||
+ * 1. Redistributions of source code must retain the above copyright notice,
|
||||
+ * this list of conditions and the following disclaimer.
|
||||
+ *
|
||||
+ * 2. Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
+ * POSSIBILITY OF SUCH DAMAGE.
|
||||
+ *
|
||||
+ *
|
||||
+ * https://github.com/tianocore/edk2-staging (edk2-staging repo of tianocore),
|
||||
+ * the ImageAuthentication.h file under it, and here's the copyright and license.
|
||||
+ *
|
||||
+ * MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ *
|
||||
+ * Copyright 2024 IBM Corp.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __PLATFORM_KEYSTORE_H__
|
||||
+#define __PLATFORM_KEYSTORE_H__
|
||||
+
|
||||
+#include <grub/symbol.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/types.h>
|
||||
+
|
||||
+#if __GNUC__ >= 9
|
||||
+#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
|
||||
+#endif
|
||||
+
|
||||
+#define GRUB_MAX_HASH_SIZE 64
|
||||
+
|
||||
+typedef struct grub_esd grub_esd_t;
|
||||
+typedef struct grub_esl grub_esl_t;
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_SIGNATURE_DATA
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ *
|
||||
+ * The structure of an EFI signature database (ESD).*/
|
||||
+struct grub_esd
|
||||
+{
|
||||
+ /*
|
||||
+ * An identifier which identifies the agent which added
|
||||
+ * the signature to the list.
|
||||
+ */
|
||||
+ grub_uuid_t signatureowner;
|
||||
+ /* The format of the signature is defined by the SignatureType.*/
|
||||
+ grub_uint8_t signaturedata[];
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_SIGNATURE_LIST
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ *
|
||||
+ * The structure of an EFI signature list (ESL).*/
|
||||
+struct grub_esl
|
||||
+{
|
||||
+ /* Type of the signature. GUID signature types are defined in below.*/
|
||||
+ grub_uuid_t signaturetype;
|
||||
+ /* Total size of the signature list, including this header.*/
|
||||
+ grub_uint32_t signaturelistsize;
|
||||
+ /*
|
||||
+ * Size of the signature header which precedes
|
||||
+ * the array of signatures.
|
||||
+ */
|
||||
+ grub_uint32_t signatureheadersize;
|
||||
+ /* Size of each signature.*/
|
||||
+ grub_uint32_t signaturesize;
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_X509_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_X509_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, \
|
||||
+ 0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, \
|
||||
+ 0x5c, 0x2b, 0xf0, 0x72 \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_SHA256_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_SHA256_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x26, 0x16, 0xc4, 0xc1, 0x4c, 0x50, \
|
||||
+ 0x92, 0x40, 0xac, 0xa9, 0x41, 0xf9, \
|
||||
+ 0x36, 0x93, 0x43, 0x28 \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_SHA384_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_SHA384_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x07, 0x53, 0x3e, 0xff, 0xd0, 0x9f, \
|
||||
+ 0xc9, 0x48, 0x85, 0xf1, 0x8a, 0xd5, \
|
||||
+ 0x6c, 0x70, 0x1e, 0x1 \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_SHA512_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_SHA512_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0xae, 0x0f, 0x3e, 0x09, 0xc4, 0xa6, \
|
||||
+ 0x50, 0x4f, 0x9f, 0x1b, 0xd4, 0x1e, \
|
||||
+ 0x2b, 0x89, 0xc1, 0x9a \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_X509_SHA256_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_X509_SHA256_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x92, 0xa4, 0xd2, 0x3b, 0xc0, 0x96, \
|
||||
+ 0x79, 0x40, 0xb4, 0x20, 0xfc, 0xf9, \
|
||||
+ 0x8e, 0xf1, 0x03, 0xed \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_X509_SHA384_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_X509_SHA384_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x6e, 0x87, 0x76, 0x70, 0xc2, 0x80, \
|
||||
+ 0xe6, 0x4e, 0xaa, 0xd2, 0x28, 0xb3, \
|
||||
+ 0x49, 0xa6, 0x86, 0x5b \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+/*
|
||||
+ * It is derived from EFI_CERT_X509_SHA512_GUID
|
||||
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ */
|
||||
+#define GRUB_PKS_CERT_X509_SHA512_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x63, 0xbf, 0x6d, 0x44, 0x02, 0x25, \
|
||||
+ 0xda, 0x4c, 0xbc, 0xfa, 0x24, 0x65, \
|
||||
+ 0xd2, 0xb0, 0xfe, 0x9d \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+typedef struct grub_pks_sd grub_pks_sd_t;
|
||||
+typedef struct grub_pks grub_pks_t;
|
||||
+
|
||||
+/* The structure of a PKS signature data.*/
|
||||
+struct grub_pks_sd
|
||||
+{
|
||||
+ grub_uuid_t guid; /* signature type */
|
||||
+ grub_uint8_t *data; /* signature data */
|
||||
+ grub_size_t data_size; /* size of signature data */
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/* The structure of a PKS.*/
|
||||
+struct grub_pks
|
||||
+{
|
||||
+ grub_pks_sd_t *db; /* signature database */
|
||||
+ grub_pks_sd_t *dbx; /* forbidden signature database */
|
||||
+ grub_size_t db_entries; /* size of signature database */
|
||||
+ grub_size_t dbx_entries; /* size of forbidden signature database */
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+#ifdef __powerpc__
|
||||
+
|
||||
+/* Initialization of the Platform Keystore */
|
||||
+grub_err_t grub_pks_keystore_init (void);
|
||||
+/* Free allocated memory */
|
||||
+void EXPORT_FUNC(grub_pks_free_keystore) (void);
|
||||
+extern grub_uint8_t EXPORT_VAR(grub_pks_use_keystore);
|
||||
+extern grub_pks_t EXPORT_VAR(grub_pks_keystore);
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+#define grub_pks_use_keystore 0
|
||||
+grub_pks_t grub_pks_keystore = {NULL, NULL, 0, 0};
|
||||
+void grub_pks_free_keystore (void);
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
diff --git a/include/grub/types.h b/include/grub/types.h
|
||||
index 1587ff4..bfa7af9 100644
|
||||
--- a/include/grub/types.h
|
||||
+++ b/include/grub/types.h
|
||||
@@ -345,4 +345,12 @@ static inline void grub_set_unaligned64 (void *ptr, grub_uint64_t val)
|
||||
dd->d = val;
|
||||
}
|
||||
|
||||
+#define GRUB_UUID_SIZE 16
|
||||
+typedef struct grub_uuid grub_uuid_t;
|
||||
+/* The structure of a UUID.*/
|
||||
+struct grub_uuid
|
||||
+{
|
||||
+ grub_uint8_t b[GRUB_UUID_SIZE];
|
||||
+};
|
||||
+
|
||||
#endif /* ! GRUB_TYPES_HEADER */
|
764
0470-appendedsig-The-creation-of-trusted-and-distrusted-l.patch
Normal file
764
0470-appendedsig-The-creation-of-trusted-and-distrusted-l.patch
Normal file
@ -0,0 +1,764 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Thu, 27 Mar 2025 01:02:37 +0530
|
||||
Subject: [PATCH] appendedsig: The creation of trusted and distrusted lists
|
||||
|
||||
The trusted certificates and binary hashes, distrusted certificates and
|
||||
binary/certificate hashes will be extracted from the platform keystore buffer
|
||||
if Secure Boot is enabled with PKS.
|
||||
|
||||
In order to verify the integrity of the kernel, the extracted data
|
||||
needs to be stored stored in the buffer db and dbx.
|
||||
|
||||
The trusted certificates will be extracted from the grub ELFNOTE if Secure Boot is
|
||||
enabled with static key. In order to verify the integerity of the kernel,
|
||||
the extracted data needs to be stored in the buffer db.
|
||||
|
||||
Note:-
|
||||
|
||||
If neither the trusted certificate nor binary hash exists in the distrusted list (dbx),
|
||||
rejects it while extracting certificate/binary hash from the platform keystore buffer.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/commands/appendedsig/appendedsig.c | 584 +++++++++++++++++++++++++--
|
||||
grub-core/kern/file.c | 34 ++
|
||||
include/grub/file.h | 1 +
|
||||
3 files changed, 577 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
|
||||
index f4eefe5..994852f 100644
|
||||
--- a/grub-core/commands/appendedsig/appendedsig.c
|
||||
+++ b/grub-core/commands/appendedsig/appendedsig.c
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <grub/libtasn1.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/lockdown.h>
|
||||
-
|
||||
+#include <grub/powerpc/ieee1275/platform_keystore.h>
|
||||
#include "appendedsig.h"
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
@@ -64,8 +64,23 @@ struct grub_appended_signature
|
||||
struct pkcs7_signedData pkcs7; /* Parsed PKCS#7 data */
|
||||
};
|
||||
|
||||
-/* Trusted certificates for verifying appended signatures */
|
||||
-struct x509_certificate *grub_trusted_key;
|
||||
+/* This represents a trusted/distrusted list*/
|
||||
+struct grub_database
|
||||
+{
|
||||
+ struct x509_certificate *keys; /* Certificates */
|
||||
+ grub_size_t key_entries; /* Number of certificates */
|
||||
+ grub_uint8_t **signatures; /* Certificate/binary hashes */
|
||||
+ grub_size_t *signature_size; /* Size of certificate/binary hashes */
|
||||
+ grub_size_t signature_entries; /* Number of certificate/binary hashes */
|
||||
+};
|
||||
+
|
||||
+/* Trusted list */
|
||||
+struct grub_database db = {.keys = NULL, .key_entries = 0, .signatures = NULL,
|
||||
+ .signature_size = NULL, .signature_entries = 0};
|
||||
+
|
||||
+/* Distrusted list */
|
||||
+struct grub_database dbx = {.signatures = NULL, .signature_size = NULL,
|
||||
+ .signature_entries = 0};
|
||||
|
||||
/*
|
||||
* Force gcry_rsa to be a module dependency.
|
||||
@@ -87,6 +102,13 @@ struct x509_certificate *grub_trusted_key;
|
||||
* also resolves our concerns about loading from the filesystem.
|
||||
*/
|
||||
extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
|
||||
+extern gcry_md_spec_t _gcry_digest_spec_sha224;
|
||||
+extern gcry_md_spec_t _gcry_digest_spec_sha384;
|
||||
+
|
||||
+/* Free trusted list memory */
|
||||
+static void free_trusted_list (void);
|
||||
+/* Free distrusted list memory */
|
||||
+static void free_distrusted_list (void);
|
||||
|
||||
static enum
|
||||
{
|
||||
@@ -95,6 +117,204 @@ static enum
|
||||
check_sigs_forced = 2
|
||||
} check_sigs = check_sigs_no;
|
||||
|
||||
+/*
|
||||
+ * GUID can be used to determine the hashing function and
|
||||
+ * generate the hash using determined hashing function.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+get_hash (const grub_uuid_t *guid, const grub_uint8_t *data, const grub_size_t data_size,
|
||||
+ grub_uint8_t *hash, grub_size_t *hash_size)
|
||||
+{
|
||||
+ gcry_md_spec_t *hash_func = NULL;
|
||||
+
|
||||
+ if (guid == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "GUID is null");
|
||||
+
|
||||
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA256_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ hash_func = &_gcry_digest_spec_sha256;
|
||||
+ else if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA384_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ hash_func = &_gcry_digest_spec_sha384;
|
||||
+ else if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA512_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ hash_func = &_gcry_digest_spec_sha512;
|
||||
+ else
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "Unsupported GUID for hash");
|
||||
+
|
||||
+ grub_memset (hash, 0, GRUB_MAX_HASH_SIZE);
|
||||
+ grub_crypto_hash (hash_func, hash, data, data_size);
|
||||
+ *hash_size = hash_func->mdlen;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/* Add the certificate/binary hash into the trusted/distrusted list */
|
||||
+static grub_err_t
|
||||
+add_hash (const grub_uint8_t **data, const grub_size_t data_size,
|
||||
+ grub_uint8_t ***signature_list, grub_size_t **signature_size_list,
|
||||
+ grub_size_t *signature_list_entries)
|
||||
+{
|
||||
+ grub_uint8_t **signatures = *signature_list;
|
||||
+ grub_size_t *signature_size = *signature_size_list;
|
||||
+ grub_size_t signature_entries = *signature_list_entries;
|
||||
+
|
||||
+ if (*data == NULL || data_size == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "certificate/binary hash data/size is null");
|
||||
+
|
||||
+ signatures = grub_realloc (signatures, sizeof (grub_uint8_t *) * (signature_entries + 1));
|
||||
+ signature_size = grub_realloc (signature_size,
|
||||
+ sizeof (grub_size_t) * (signature_entries + 1));
|
||||
+
|
||||
+ if (signatures == NULL || signature_size == NULL)
|
||||
+ {
|
||||
+ /*
|
||||
+ * allocated memory will be freed by
|
||||
+ * free_trusted_list/free_distrusted_list
|
||||
+ */
|
||||
+ if (signatures != NULL)
|
||||
+ {
|
||||
+ *signature_list = signatures;
|
||||
+ *signature_list_entries = signature_entries + 1;
|
||||
+ }
|
||||
+
|
||||
+ if (signature_size != NULL)
|
||||
+ *signature_size_list = signature_size;
|
||||
+
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+ }
|
||||
+
|
||||
+ signatures[signature_entries] = (grub_uint8_t *) *data;
|
||||
+ signature_size[signature_entries] = data_size;
|
||||
+ signature_entries++;
|
||||
+ *data = NULL;
|
||||
+
|
||||
+ *signature_list = signatures;
|
||||
+ *signature_size_list = signature_size;
|
||||
+ *signature_list_entries = signature_entries;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+is_x509 (const grub_uuid_t *guid)
|
||||
+{
|
||||
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_X509_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+is_cert_match (const struct x509_certificate *distrusted_cert,
|
||||
+ const struct x509_certificate *db_cert)
|
||||
+{
|
||||
+
|
||||
+ if (grub_memcmp (distrusted_cert->subject, db_cert->subject, db_cert->subject_len) == 0
|
||||
+ && grub_memcmp (distrusted_cert->serial, db_cert->serial, db_cert->serial_len) == 0
|
||||
+ && grub_memcmp (distrusted_cert->mpis[0], db_cert->mpis[0], sizeof (db_cert->mpis[0])) == 0
|
||||
+ && grub_memcmp (distrusted_cert->mpis[1], db_cert->mpis[1], sizeof (db_cert->mpis[1])) == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Verify the certificate against the certificate from platform keystore buffer's
|
||||
+ * distrusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+is_distrusted_cert (const struct x509_certificate *db_cert)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0;
|
||||
+ struct x509_certificate *distrusted_cert = NULL;
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
|
||||
+ {
|
||||
+ if (grub_pks_keystore.dbx[i].data == NULL)
|
||||
+ continue;
|
||||
+
|
||||
+ if (is_x509 (&grub_pks_keystore.dbx[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ distrusted_cert = grub_zalloc (sizeof (struct x509_certificate));
|
||||
+ if (distrusted_cert == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ rc = parse_x509_certificate (grub_pks_keystore.dbx[i].data,
|
||||
+ grub_pks_keystore.dbx[i].data_size, distrusted_cert);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_free (distrusted_cert);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (is_cert_match (distrusted_cert, db_cert) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Warning: a trusted certificate CN='%s' is ignored "
|
||||
+ "because it is on the distrusted list (dbx).\n", db_cert->subject);
|
||||
+ grub_free (grub_pks_keystore.dbx[i].data);
|
||||
+ grub_memset (&grub_pks_keystore.dbx[i], 0, sizeof (grub_pks_sd_t));
|
||||
+ certificate_release (distrusted_cert);
|
||||
+ grub_free (distrusted_cert);
|
||||
+ return GRUB_ERR_ACCESS_DENIED;
|
||||
+ }
|
||||
+
|
||||
+ certificate_release (distrusted_cert);
|
||||
+ grub_free (distrusted_cert);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/* Add the certificate into the trusted/distrusted list */
|
||||
+static grub_err_t
|
||||
+add_certificate (const grub_uint8_t *data, const grub_size_t data_size,
|
||||
+ struct grub_database *database, const grub_size_t is_db)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t key_entries = database->key_entries;
|
||||
+ struct x509_certificate *cert = NULL;
|
||||
+
|
||||
+ if (data == NULL || data_size == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "certificate data/size is null");
|
||||
+
|
||||
+ cert = grub_zalloc (sizeof (struct x509_certificate));
|
||||
+ if (cert == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ rc = parse_x509_certificate (data, data_size, cert);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "skipping %s certificate (%d)\n",
|
||||
+ (is_db ? "trusted":"distrusted"), rc);
|
||||
+ grub_free (cert);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ if (is_db)
|
||||
+ {
|
||||
+ rc = is_distrusted_cert (cert);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ certificate_release (cert);
|
||||
+ grub_free (cert);
|
||||
+ return rc;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "add a %s certificate CN='%s'\n",
|
||||
+ (is_db ? "trusted":"distrusted"), cert->subject);
|
||||
+
|
||||
+ key_entries++;
|
||||
+ cert->next = database->keys;
|
||||
+ database->keys = cert;
|
||||
+ database->key_entries = key_entries;
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
static const char *
|
||||
grub_env_read_sec (struct grub_env_var *var __attribute__ ((unused)),
|
||||
const char *val __attribute__ ((unused)))
|
||||
@@ -248,7 +468,7 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
struct pkcs7_signerInfo *si;
|
||||
int i;
|
||||
|
||||
- if (!grub_trusted_key)
|
||||
+ if (!db.key_entries)
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("No trusted keys to verify against"));
|
||||
|
||||
err = extract_appended_signature (buf, bufsize, &sig);
|
||||
@@ -279,7 +499,7 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
datasize, i, hash[0], hash[1], hash[2], hash[3]);
|
||||
|
||||
err = GRUB_ERR_BAD_SIGNATURE;
|
||||
- for (pk = grub_trusted_key; pk; pk = pk->next)
|
||||
+ for (pk = db.keys; pk; pk = pk->next)
|
||||
{
|
||||
rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, pk->mpis[0]);
|
||||
if (rc)
|
||||
@@ -376,16 +596,16 @@ grub_cmd_distrust (grub_command_t cmd __attribute__ ((unused)), int argc, char *
|
||||
|
||||
if (cert_num == 1)
|
||||
{
|
||||
- cert = grub_trusted_key;
|
||||
- grub_trusted_key = cert->next;
|
||||
+ cert = db.keys;
|
||||
+ db.keys = cert->next;
|
||||
|
||||
certificate_release (cert);
|
||||
grub_free (cert);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
i = 2;
|
||||
- prev = grub_trusted_key;
|
||||
- cert = grub_trusted_key->next;
|
||||
+ prev = db.keys;
|
||||
+ cert = db.keys->next;
|
||||
while (cert)
|
||||
{
|
||||
if (i == cert_num)
|
||||
@@ -432,8 +652,8 @@ grub_cmd_trust (grub_command_t cmd __attribute__ ((unused)), int argc, char **ar
|
||||
}
|
||||
grub_dprintf ("appendedsig", "Loaded certificate with CN: %s\n", cert->subject);
|
||||
|
||||
- cert->next = grub_trusted_key;
|
||||
- grub_trusted_key = cert;
|
||||
+ cert->next = db.keys;
|
||||
+ db.keys = cert;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -446,7 +666,7 @@ grub_cmd_list (grub_command_t cmd __attribute__ ((unused)), int argc __attribute
|
||||
int cert_num = 1;
|
||||
grub_size_t i;
|
||||
|
||||
- for (cert = grub_trusted_key; cert; cert = cert->next)
|
||||
+ for (cert = db.keys; cert; cert = cert->next)
|
||||
{
|
||||
grub_printf (N_("Certificate %d:\n"), cert_num);
|
||||
|
||||
@@ -539,6 +759,274 @@ static struct grub_fs pseudo_fs = { .name = "pseudo", .fs_read = pseudo_read };
|
||||
|
||||
static grub_command_t cmd_verify, cmd_list, cmd_distrust, cmd_trust;
|
||||
|
||||
+/*
|
||||
+ * Verify the trusted certificate against the certificate hashes from platform keystore buffer's
|
||||
+ * distrusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+is_distrusted_cert_hash (const grub_uint8_t *data, const grub_size_t data_size)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0, cert_hash_size = 0;
|
||||
+ grub_uint8_t cert_hash[GRUB_MAX_HASH_SIZE] = { 0 };
|
||||
+
|
||||
+ if (data == NULL || data_size == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "trusted certificate data/size is null");
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
|
||||
+ {
|
||||
+ if (grub_pks_keystore.dbx[i].data == NULL ||
|
||||
+ grub_pks_keystore.dbx[i].data_size == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ rc = get_hash (&grub_pks_keystore.dbx[i].guid, data, data_size,
|
||||
+ cert_hash, &cert_hash_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+
|
||||
+ if (cert_hash_size == grub_pks_keystore.dbx[i].data_size &&
|
||||
+ grub_memcmp (grub_pks_keystore.dbx[i].data, cert_hash, cert_hash_size) == 0)
|
||||
+ {
|
||||
+ grub_printf ("Warning: a trusted certificate (%02x%02x%02x%02x) is ignored "
|
||||
+ "because this certificate hash is on the distrusted list (dbx).\n",
|
||||
+ cert_hash[0], cert_hash[1], cert_hash[2], cert_hash[3]);
|
||||
+ grub_free (grub_pks_keystore.dbx[i].data);
|
||||
+ grub_memset (&grub_pks_keystore.dbx[i], 0, sizeof (grub_pks_keystore.dbx[i]));
|
||||
+ return GRUB_ERR_BAD_SIGNATURE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Verify the trusted binary hash against the platform keystore buffer's
|
||||
+ * distrusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+is_distrusted_binary_hash (const grub_uint8_t *binary_hash,
|
||||
+ const grub_size_t binary_hash_size)
|
||||
+{
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
|
||||
+ {
|
||||
+ if (grub_pks_keystore.dbx[i].data == NULL ||
|
||||
+ grub_pks_keystore.dbx[i].data_size == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ if (binary_hash_size == grub_pks_keystore.dbx[i].data_size &&
|
||||
+ grub_memcmp (grub_pks_keystore.dbx[i].data, binary_hash, binary_hash_size) == 0)
|
||||
+ {
|
||||
+ grub_printf ("Warning: a trusted binary hash (%02x%02x%02x%02x) is ignored"
|
||||
+ " because it is on the distrusted list (dbx).\n",
|
||||
+ binary_hash[0], binary_hash[1], binary_hash[2], binary_hash[3]);
|
||||
+ grub_free (grub_pks_keystore.dbx[i].data);
|
||||
+ grub_memset (&grub_pks_keystore.dbx[i], 0, sizeof(grub_pks_keystore.dbx[i]));
|
||||
+ return GRUB_ERR_BAD_SIGNATURE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Extract the binary hashes from the platform keystore buffer,
|
||||
+ * and add it to the trusted list if it does not exist in the distrusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+add_trusted_binary_hash (const grub_uint8_t **data, const grub_size_t data_size)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+
|
||||
+ if (*data == NULL || data_size == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "trusted binary hash data/size is null");
|
||||
+
|
||||
+ rc = is_distrusted_binary_hash (*data, data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ return rc;
|
||||
+
|
||||
+ rc = add_hash (data, data_size, &db.signatures, &db.signature_size,
|
||||
+ &db.signature_entries);
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+is_hash (const grub_uuid_t *guid)
|
||||
+{
|
||||
+ /* GUID type of the binary hash */
|
||||
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ /* GUID type of the certificate hash */
|
||||
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA256_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA384_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA512_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Extract the x509 certificates/binary hashes from the platform keystore buffer,
|
||||
+ * parse it, and add it to the trusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+create_trusted_list (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.db_entries; i++)
|
||||
+ {
|
||||
+ if (is_hash (&grub_pks_keystore.db[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ rc = add_trusted_binary_hash ((const grub_uint8_t **)
|
||||
+ &grub_pks_keystore.db[i].data,
|
||||
+ grub_pks_keystore.db[i].data_size);
|
||||
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
|
||||
+ return rc;
|
||||
+ }
|
||||
+ else if (is_x509 (&grub_pks_keystore.db[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ rc = is_distrusted_cert_hash (grub_pks_keystore.db[i].data,
|
||||
+ grub_pks_keystore.db[i].data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+
|
||||
+ rc = add_certificate (grub_pks_keystore.db[i].data,
|
||||
+ grub_pks_keystore.db[i].data_size, &db, 1);
|
||||
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
|
||||
+ return rc;
|
||||
+ else if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+ }
|
||||
+ else
|
||||
+ grub_dprintf ("appendedsig", "unsupported signature data type and "
|
||||
+ "skipping trusted data (%" PRIuGRUB_SIZE ")\n", i + 1);
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Extract the certificates, certificate/binary hashes out of the platform keystore buffer,
|
||||
+ * and add it to the distrusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+create_distrusted_list (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
|
||||
+ {
|
||||
+ if (grub_pks_keystore.dbx[i].data != NULL ||
|
||||
+ grub_pks_keystore.dbx[i].data_size > 0)
|
||||
+ {
|
||||
+ if (is_x509 (&grub_pks_keystore.dbx[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ rc = add_certificate (grub_pks_keystore.dbx[i].data,
|
||||
+ grub_pks_keystore.dbx[i].data_size, &dbx, 0);
|
||||
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
|
||||
+ return rc;
|
||||
+ }
|
||||
+ else if (is_hash (&grub_pks_keystore.dbx[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ rc = add_hash ((const grub_uint8_t **) &grub_pks_keystore.dbx[i].data,
|
||||
+ grub_pks_keystore.dbx[i].data_size,
|
||||
+ &dbx.signatures, &dbx.signature_size,
|
||||
+ &dbx.signature_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ return rc;
|
||||
+ }
|
||||
+ else
|
||||
+ grub_dprintf ("appendedsig", "unsupported signature data type and "
|
||||
+ "skipping distrusted data (%" PRIuGRUB_SIZE ")\n", i + 1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Extract the x509 certificates from the ELF note header,
|
||||
+ * parse it, and add it to the trusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+build_static_trusted_list (const struct grub_module_header *header)
|
||||
+{
|
||||
+ grub_err_t err = GRUB_ERR_NONE;
|
||||
+ struct grub_file pseudo_file;
|
||||
+ grub_uint8_t *cert_data = NULL;
|
||||
+ grub_ssize_t cert_data_size = 0;
|
||||
+
|
||||
+ grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
|
||||
+ pseudo_file.fs = &pseudo_fs;
|
||||
+ pseudo_file.size = header->size - sizeof (struct grub_module_header);
|
||||
+ pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "found an x509 key, size=%" PRIuGRUB_UINT64_T "\n",
|
||||
+ pseudo_file.size);
|
||||
+
|
||||
+ err = grub_read_file (&pseudo_file, &cert_data, &cert_data_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
+
|
||||
+ err = add_certificate (cert_data, cert_data_size, &db, 1);
|
||||
+ grub_free (cert_data);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/* releasing memory */
|
||||
+static void
|
||||
+free_trusted_list (void)
|
||||
+{
|
||||
+ struct x509_certificate *cert;
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ while (db.keys != NULL)
|
||||
+ {
|
||||
+ cert = db.keys;
|
||||
+ db.keys = db.keys->next;
|
||||
+ certificate_release (cert);
|
||||
+ grub_free (cert);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < db.signature_entries; i++)
|
||||
+ grub_free (db.signatures[i]);
|
||||
+
|
||||
+ grub_free (db.signatures);
|
||||
+ grub_free (db.signature_size);
|
||||
+ grub_memset (&db, 0, sizeof (db));
|
||||
+}
|
||||
+
|
||||
+/* releasing memory */
|
||||
+static void
|
||||
+free_distrusted_list (void)
|
||||
+{
|
||||
+ struct x509_certificate *cert;
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ while (dbx.keys != NULL)
|
||||
+ {
|
||||
+ cert = dbx.keys;
|
||||
+ dbx.keys = dbx.keys->next;
|
||||
+ certificate_release (cert);
|
||||
+ grub_free (cert);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < dbx.signature_entries; i++)
|
||||
+ grub_free (dbx.signatures[i]);
|
||||
+
|
||||
+ grub_free (dbx.signatures);
|
||||
+ grub_free (dbx.signature_size);
|
||||
+ grub_memset (&dbx, 0, sizeof (dbx));
|
||||
+}
|
||||
+
|
||||
GRUB_MOD_INIT (appendedsig)
|
||||
{
|
||||
int rc;
|
||||
@@ -548,7 +1036,6 @@ GRUB_MOD_INIT (appendedsig)
|
||||
if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
|
||||
check_sigs = check_sigs_forced;
|
||||
|
||||
- grub_trusted_key = NULL;
|
||||
grub_register_variable_hook ("check_appended_signatures", grub_env_read_sec, grub_env_write_sec);
|
||||
grub_env_export ("check_appended_signatures");
|
||||
|
||||
@@ -556,37 +1043,50 @@ GRUB_MOD_INIT (appendedsig)
|
||||
if (rc)
|
||||
grub_fatal ("Error initing ASN.1 data structures: %d: %s\n", rc, asn1_strerror (rc));
|
||||
|
||||
- FOR_MODULES (header)
|
||||
- {
|
||||
- struct grub_file pseudo_file;
|
||||
- struct x509_certificate *pk = NULL;
|
||||
- grub_err_t err;
|
||||
+ if (!grub_pks_use_keystore && check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ FOR_MODULES (header)
|
||||
+ {
|
||||
+ /* Not an ELF module, skip. */
|
||||
+ if (header->type != OBJ_TYPE_X509_PUBKEY)
|
||||
+ continue;
|
||||
|
||||
- /* Not an X.509 certificate, skip. */
|
||||
- if (header->type != OBJ_TYPE_X509_PUBKEY)
|
||||
- continue;
|
||||
+ rc = build_static_trusted_list (header);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ free_trusted_list ();
|
||||
+ grub_error (rc, "static trusted list creation failed");
|
||||
+ }
|
||||
+ else
|
||||
+ grub_dprintf ("appendedsig", "the trusted list now has %" PRIuGRUB_SIZE " static keys\n",
|
||||
+ db.key_entries);
|
||||
+ }
|
||||
+ }
|
||||
+ else if (grub_pks_use_keystore && check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ rc = create_trusted_list ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ free_trusted_list ();
|
||||
+ grub_error (rc, "trusted list creation failed");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ rc = create_distrusted_list ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ free_trusted_list ();
|
||||
+ free_distrusted_list ();
|
||||
+ grub_error (rc, "distrusted list creation failed");
|
||||
+ }
|
||||
+ else
|
||||
+ grub_dprintf ("appendedsig", "the trusted list now has %" PRIuGRUB_SIZE " keys.\n"
|
||||
+ "the distrusted list now has %" PRIuGRUB_SIZE " keys.\n",
|
||||
+ db.signature_entries + db.key_entries, dbx.signature_entries);
|
||||
+ }
|
||||
|
||||
- grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
|
||||
- pseudo_file.fs = &pseudo_fs;
|
||||
- pseudo_file.size = header->size - sizeof (struct grub_module_header);
|
||||
- pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
|
||||
-
|
||||
- grub_dprintf ("appendedsig", "Found an x509 key, size=%" PRIuGRUB_UINT64_T "\n",
|
||||
- pseudo_file.size);
|
||||
-
|
||||
- pk = grub_zalloc (sizeof (struct x509_certificate));
|
||||
- if (!pk)
|
||||
- grub_fatal ("Out of memory loading initial certificates");
|
||||
-
|
||||
- err = read_cert_from_file (&pseudo_file, pk);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- grub_fatal ("Error loading initial key: %s", grub_errmsg);
|
||||
-
|
||||
- grub_dprintf ("appendedsig", "loaded certificate CN='%s'\n", pk->subject);
|
||||
-
|
||||
- pk->next = grub_trusted_key;
|
||||
- grub_trusted_key = pk;
|
||||
- }
|
||||
+ grub_pks_free_keystore ();
|
||||
+ }
|
||||
|
||||
cmd_trust = grub_register_command ("trust_certificate", grub_cmd_trust, N_("X509_CERTIFICATE"),
|
||||
N_("Add X509_CERTIFICATE to trusted certificates."));
|
||||
diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
|
||||
index 58fae17..fa73c04 100644
|
||||
--- a/grub-core/kern/file.c
|
||||
+++ b/grub-core/kern/file.c
|
||||
@@ -256,3 +256,37 @@ grub_file_seek (grub_file_t file, grub_off_t offset)
|
||||
|
||||
return old;
|
||||
}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_read_file (const grub_file_t file, grub_uint8_t **data, grub_ssize_t *data_size)
|
||||
+{
|
||||
+ grub_uint8_t *buffer = NULL;
|
||||
+ grub_ssize_t read_size = 0;
|
||||
+ grub_off_t total_read_size = 0;
|
||||
+ grub_off_t file_size = grub_file_size (file);
|
||||
+
|
||||
+ if (file_size == GRUB_FILE_SIZE_UNKNOWN)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("could not determine the size of the file."));
|
||||
+
|
||||
+ buffer = grub_zalloc (file_size);
|
||||
+ if (buffer == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+
|
||||
+ while (total_read_size < file_size)
|
||||
+ {
|
||||
+ read_size = grub_file_read (file, &buffer[total_read_size], file_size - total_read_size);
|
||||
+ if (read_size < 0)
|
||||
+ {
|
||||
+ grub_free (buffer);
|
||||
+ return grub_error (GRUB_ERR_READ_ERROR, N_("unable to read the file"));
|
||||
+ }
|
||||
+
|
||||
+ total_read_size += read_size;
|
||||
+ }
|
||||
+
|
||||
+ *data = buffer;
|
||||
+ *data_size = total_read_size;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
diff --git a/include/grub/file.h b/include/grub/file.h
|
||||
index d678de0..27e1a88 100644
|
||||
--- a/include/grub/file.h
|
||||
+++ b/include/grub/file.h
|
||||
@@ -217,6 +217,7 @@ grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, void *buf,
|
||||
grub_size_t len);
|
||||
grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset);
|
||||
grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file);
|
||||
+grub_err_t EXPORT_FUNC(grub_read_file) (const grub_file_t file, grub_uint8_t **data, grub_ssize_t *data_size);
|
||||
|
||||
/* Return value of grub_file_size() in case file size is unknown. */
|
||||
#define GRUB_FILE_SIZE_UNKNOWN 0xffffffffffffffffULL
|
250
0471-appendedsig-While-verifying-the-kernel-use-trusted-a.patch
Normal file
250
0471-appendedsig-While-verifying-the-kernel-use-trusted-a.patch
Normal file
@ -0,0 +1,250 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Thu, 27 Mar 2025 01:02:38 +0530
|
||||
Subject: [PATCH] appendedsig: While verifying the kernel, use trusted and
|
||||
distrusted lists
|
||||
|
||||
To verify the kernel's signature: verify the kernel binary against lists of binary hashes
|
||||
that are either distrusted or trusted. If it is not list in either trusted or distrusted hashes list
|
||||
then the trusted keys from the trusted key list are used to verify the signature.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/commands/appendedsig/appendedsig.c | 193 +++++++++++++++++++--------
|
||||
1 file changed, 139 insertions(+), 54 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
|
||||
index 994852f..07d6b39 100644
|
||||
--- a/grub-core/commands/appendedsig/appendedsig.c
|
||||
+++ b/grub-core/commands/appendedsig/appendedsig.c
|
||||
@@ -454,6 +454,83 @@ extract_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize,
|
||||
return parse_pkcs7_signedData (appsigdata, pkcs7_size, &sig->pkcs7);
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+get_binary_hash (const grub_size_t binary_hash_size, const grub_uint8_t *data,
|
||||
+ const grub_size_t data_size, grub_uint8_t *hash, grub_size_t *hash_size)
|
||||
+{
|
||||
+ grub_uuid_t guid = { 0 };
|
||||
+
|
||||
+ /* support SHA256, SHA384 and SHA512 for binary hash */
|
||||
+ if (binary_hash_size == 32)
|
||||
+ grub_memcpy (&guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE);
|
||||
+ else if (binary_hash_size == 48)
|
||||
+ grub_memcpy (&guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_UUID_SIZE);
|
||||
+ else if (binary_hash_size == 64)
|
||||
+ grub_memcpy (&guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_UUID_SIZE);
|
||||
+ else
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "unsupported hash type (%" PRIuGRUB_SIZE ") and skipping binary hash\n",
|
||||
+ binary_hash_size);
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+ }
|
||||
+
|
||||
+ return get_hash (&guid, data, data_size, hash, hash_size);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Verify binary hash against the list of binary hashes that are distrusted
|
||||
+ * and trusted.
|
||||
+ * The following errors can occur:
|
||||
+ * - GRUB_ERR_BAD_SIGNATURE: indicates that the hash is distrusted.
|
||||
+ * - GRUB_ERR_NONE: the hash is trusted, since it was found in the trusted hashes list
|
||||
+ * - GRUB_ERR_EOF: the hash could not be found in the hashes list
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+verify_binary_hash (const grub_uint8_t *data, const grub_size_t data_size)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0, hash_size = 0;
|
||||
+ grub_uint8_t hash[GRUB_MAX_HASH_SIZE] = { 0 };
|
||||
+
|
||||
+ for (i = 0; i < dbx.signature_entries; i++)
|
||||
+ {
|
||||
+ rc = get_binary_hash (dbx.signature_size[i], data, data_size, hash, &hash_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+
|
||||
+ if (hash_size == dbx.signature_size[i] &&
|
||||
+ grub_memcmp (dbx.signatures[i], hash, hash_size) == 0)
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "the binary hash (%02x%02x%02x%02x) was listed as distrusted\n",
|
||||
+ hash[0], hash[1], hash[2], hash[3]);
|
||||
+ return GRUB_ERR_BAD_SIGNATURE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < db.signature_entries; i++)
|
||||
+ {
|
||||
+ rc = get_binary_hash (db.signature_size[i], data, data_size, hash, &hash_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+
|
||||
+ if (hash_size == db.signature_size[i] &&
|
||||
+ grub_memcmp (db.signatures[i], hash, hash_size) == 0)
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "verified with a trusted binary hash (%02x%02x%02x%02x)\n",
|
||||
+ hash[0], hash[1], hash[2], hash[3]);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_EOF;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Verify the kernel's integrity, the trusted key will be used from
|
||||
+ * the trusted key list. If it fails, verify it against the list of binary hashes
|
||||
+ * that are distrusted and trusted.
|
||||
+ */
|
||||
static grub_err_t
|
||||
grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
{
|
||||
@@ -463,12 +540,12 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
unsigned char *hash;
|
||||
gcry_mpi_t hashmpi;
|
||||
gcry_err_code_t rc;
|
||||
- struct x509_certificate *pk;
|
||||
+ struct x509_certificate *cert;
|
||||
struct grub_appended_signature sig;
|
||||
struct pkcs7_signerInfo *si;
|
||||
int i;
|
||||
|
||||
- if (!db.key_entries)
|
||||
+ if (!db.key_entries && !db.signature_entries)
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("No trusted keys to verify against"));
|
||||
|
||||
err = extract_appended_signature (buf, bufsize, &sig);
|
||||
@@ -476,69 +553,77 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
return err;
|
||||
|
||||
datasize = bufsize - sig.signature_len;
|
||||
-
|
||||
- for (i = 0; i < sig.pkcs7.signerInfo_count; i++)
|
||||
+ err = verify_binary_hash (buf, datasize);
|
||||
+ if (err != GRUB_ERR_EOF && err != GRUB_ERR_NONE)
|
||||
{
|
||||
- /*
|
||||
- * This could be optimised in a couple of ways:
|
||||
- * - we could only compute hashes once per hash type
|
||||
- * - we could track signer information and only verify where IDs match
|
||||
- * For now we do the naive O(trusted keys * pkcs7 signers) approach.
|
||||
- */
|
||||
- si = &sig.pkcs7.signerInfos[i];
|
||||
- context = grub_zalloc (si->hash->contextsize);
|
||||
- if (!context)
|
||||
- return grub_errno;
|
||||
-
|
||||
- si->hash->init (context);
|
||||
- si->hash->write (context, buf, datasize);
|
||||
- si->hash->final (context);
|
||||
- hash = si->hash->read (context);
|
||||
-
|
||||
- grub_dprintf ("appendedsig", "data size %" PRIxGRUB_SIZE ", signer %d hash %02x%02x%02x%02x...\n",
|
||||
- datasize, i, hash[0], hash[1], hash[2], hash[3]);
|
||||
-
|
||||
- err = GRUB_ERR_BAD_SIGNATURE;
|
||||
- for (pk = db.keys; pk; pk = pk->next)
|
||||
+ err = grub_error (err, N_("failed to verify binary-hash/signature with any trusted binary-hash/key\n"));
|
||||
+ pkcs7_signedData_release (&sig.pkcs7);
|
||||
+ return err;
|
||||
+ }
|
||||
+ else if (err == GRUB_ERR_EOF)
|
||||
+ {
|
||||
+ /* Binary hash was not found in trusted and distrusted list: check signature now */
|
||||
+ for (i = 0; i < sig.pkcs7.signerInfo_count; i++)
|
||||
{
|
||||
- rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, pk->mpis[0]);
|
||||
- if (rc)
|
||||
- {
|
||||
- err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
- N_("Error padding hash for RSA verification: %d"), rc);
|
||||
- grub_free (context);
|
||||
- goto cleanup;
|
||||
- }
|
||||
+ /*
|
||||
+ * This could be optimised in a couple of ways:
|
||||
+ * - we could only compute hashes once per hash type
|
||||
+ * - we could track signer information and only verify where IDs match
|
||||
+ * For now we do the naive O(db.keys * pkcs7 signers) approach.
|
||||
+ */
|
||||
+ si = &sig.pkcs7.signerInfos[i];
|
||||
+ context = grub_zalloc (si->hash->contextsize);
|
||||
+ if (context == NULL)
|
||||
+ return grub_errno;
|
||||
|
||||
- rc = _gcry_pubkey_spec_rsa.verify (0, hashmpi, &si->sig_mpi, pk->mpis, NULL, NULL);
|
||||
- gcry_mpi_release (hashmpi);
|
||||
+ si->hash->init (context);
|
||||
+ si->hash->write (context, buf, datasize);
|
||||
+ si->hash->final (context);
|
||||
+ hash = si->hash->read (context);
|
||||
|
||||
- if (rc == 0)
|
||||
- {
|
||||
- grub_dprintf ("appendedsig", "verify signer %d with key '%s' succeeded\n",
|
||||
- i, pk->subject);
|
||||
- err = GRUB_ERR_NONE;
|
||||
- break;
|
||||
- }
|
||||
+ grub_dprintf ("appendedsig",
|
||||
+ "data size %" PRIxGRUB_SIZE ", signer %d hash %02x%02x%02x%02x...\n",
|
||||
+ datasize, i, hash[0], hash[1], hash[2], hash[3]);
|
||||
|
||||
- grub_dprintf ("appendedsig", "verify signer %d with key '%s' failed with %d\n",
|
||||
- i, pk->subject, rc);
|
||||
- }
|
||||
+ err = GRUB_ERR_BAD_SIGNATURE;
|
||||
+ for (cert = db.keys; cert; cert = cert->next)
|
||||
+ {
|
||||
+ rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, cert->mpis[0]);
|
||||
+ if (rc != 0)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
+ N_("Error padding hash for RSA verification: %d"), rc);
|
||||
+ grub_free (context);
|
||||
+ pkcs7_signedData_release (&sig.pkcs7);
|
||||
+ return err;
|
||||
+ }
|
||||
|
||||
- grub_free (context);
|
||||
+ rc = _gcry_pubkey_spec_rsa.verify (0, hashmpi, &si->sig_mpi, cert->mpis, NULL, NULL);
|
||||
+ gcry_mpi_release (hashmpi);
|
||||
+ if (rc == 0)
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "verify signer %d with key '%s' succeeded\n",
|
||||
+ i, cert->subject);
|
||||
+ err = GRUB_ERR_NONE;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (err == GRUB_ERR_NONE)
|
||||
- break;
|
||||
+ grub_dprintf ("appendedsig", "verify signer %d with key '%s' failed with %d\n",
|
||||
+ i, cert->subject, rc);
|
||||
+ }
|
||||
+ grub_free (context);
|
||||
+ if (err == GRUB_ERR_NONE)
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
- /* If we didn't verify, provide a neat message */
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
- N_("Failed to verify signature against a trusted key"));
|
||||
-
|
||||
-cleanup:
|
||||
pkcs7_signedData_release (&sig.pkcs7);
|
||||
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ err = grub_error (err, N_("failed to verify signature with any trusted key\n"));
|
||||
+ else
|
||||
+ grub_dprintf ("appendedsig", "successfully verified the signature with a trusted key\n");
|
||||
+
|
||||
return err;
|
||||
}
|
||||
|
107
0472-powerpc_ieee1275-set-use_static_keys-flag.patch
Normal file
107
0472-powerpc_ieee1275-set-use_static_keys-flag.patch
Normal file
@ -0,0 +1,107 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Thu, 27 Mar 2025 01:02:39 +0530
|
||||
Subject: [PATCH] powerpc_ieee1275: set use_static_keys flag
|
||||
|
||||
Introduce the use_static_keys flag to indicate that static keys are to be used
|
||||
rather than keys from the PKS storage's DB variable. This variable is set when
|
||||
Secure Boot is enabled with PKS but the DB variable is not present in the PKS storage.
|
||||
The appendedsig module would use this variable to extract the default DB keys from
|
||||
the ELF note and store the keys found there in the trustedlist.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/kern/powerpc/ieee1275/platform_keystore.c | 16 +++++++++++++++-
|
||||
grub-core/term/tparm.c | 1 -
|
||||
include/grub/powerpc/ieee1275/platform_keystore.h | 11 ++++++-----
|
||||
include/grub/types.h | 2 ++
|
||||
4 files changed, 23 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/powerpc/ieee1275/platform_keystore.c b/grub-core/kern/powerpc/ieee1275/platform_keystore.c
|
||||
index cf1d055..a83fcf7 100644
|
||||
--- a/grub-core/kern/powerpc/ieee1275/platform_keystore.c
|
||||
+++ b/grub-core/kern/powerpc/ieee1275/platform_keystore.c
|
||||
@@ -34,7 +34,11 @@
|
||||
/* Platform Keystore */
|
||||
static grub_size_t pks_max_object_size;
|
||||
grub_uint8_t grub_pks_use_keystore = 0;
|
||||
-grub_pks_t grub_pks_keystore = { .db = NULL, .dbx = NULL, .db_entries = 0, .dbx_entries = 0 };
|
||||
+grub_pks_t grub_pks_keystore = { .db = NULL,
|
||||
+ .dbx = NULL,
|
||||
+ .db_entries = 0,
|
||||
+ .dbx_entries = 0,
|
||||
+ .use_static_keys = false };
|
||||
|
||||
/* Convert the esl data into the ESL */
|
||||
static grub_esl_t *
|
||||
@@ -312,6 +316,16 @@ grub_pks_keystore_init (void)
|
||||
grub_memset (&grub_pks_keystore, 0, sizeof (grub_pks_t));
|
||||
/* DB */
|
||||
rc = read_secure_boot_variables (0, DB, &grub_pks_keystore.db, &grub_pks_keystore.db_entries);
|
||||
+ if (rc == PKS_OBJECT_NOT_FOUND)
|
||||
+ {
|
||||
+ rc = GRUB_ERR_NONE;
|
||||
+ /*
|
||||
+ * DB variable won't be available by default in PKS.
|
||||
+ * So, it will load the Default Keys from ELF Note
|
||||
+ */
|
||||
+ grub_pks_keystore.use_static_keys = true;
|
||||
+ }
|
||||
+
|
||||
if (rc == GRUB_ERR_NONE)
|
||||
{
|
||||
/* DBX */
|
||||
diff --git a/grub-core/term/tparm.c b/grub-core/term/tparm.c
|
||||
index fb5b15a..f2db325 100644
|
||||
--- a/grub-core/term/tparm.c
|
||||
+++ b/grub-core/term/tparm.c
|
||||
@@ -46,7 +46,6 @@
|
||||
/*
|
||||
* Common/troublesome character definitions
|
||||
*/
|
||||
-typedef char grub_bool_t;
|
||||
#ifndef FALSE
|
||||
# define FALSE (0)
|
||||
#endif
|
||||
diff --git a/include/grub/powerpc/ieee1275/platform_keystore.h b/include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
index 0641adb..870fb8c 100644
|
||||
--- a/include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
+++ b/include/grub/powerpc/ieee1275/platform_keystore.h
|
||||
@@ -199,10 +199,11 @@ struct grub_pks_sd
|
||||
/* The structure of a PKS.*/
|
||||
struct grub_pks
|
||||
{
|
||||
- grub_pks_sd_t *db; /* signature database */
|
||||
- grub_pks_sd_t *dbx; /* forbidden signature database */
|
||||
- grub_size_t db_entries; /* size of signature database */
|
||||
- grub_size_t dbx_entries; /* size of forbidden signature database */
|
||||
+ grub_pks_sd_t *db; /* signature database */
|
||||
+ grub_pks_sd_t *dbx; /* forbidden signature database */
|
||||
+ grub_size_t db_entries; /* size of signature database */
|
||||
+ grub_size_t dbx_entries; /* size of forbidden signature database */
|
||||
+ grub_bool_t use_static_keys;/* flag to indicate use of static keys */
|
||||
} GRUB_PACKED;
|
||||
|
||||
#ifdef __powerpc__
|
||||
@@ -217,7 +218,7 @@ extern grub_pks_t EXPORT_VAR(grub_pks_keystore);
|
||||
#else
|
||||
|
||||
#define grub_pks_use_keystore 0
|
||||
-grub_pks_t grub_pks_keystore = {NULL, NULL, 0, 0};
|
||||
+grub_pks_t grub_pks_keystore = {NULL, NULL, 0, 0, false};
|
||||
void grub_pks_free_keystore (void);
|
||||
|
||||
#endif
|
||||
diff --git a/include/grub/types.h b/include/grub/types.h
|
||||
index bfa7af9..32ca225 100644
|
||||
--- a/include/grub/types.h
|
||||
+++ b/include/grub/types.h
|
||||
@@ -353,4 +353,6 @@ struct grub_uuid
|
||||
grub_uint8_t b[GRUB_UUID_SIZE];
|
||||
};
|
||||
|
||||
+typedef char grub_bool_t;
|
||||
+
|
||||
#endif /* ! GRUB_TYPES_HEADER */
|
108
0473-appendedsig-Reads-the-default-DB-keys-from-ELF-Note.patch
Normal file
108
0473-appendedsig-Reads-the-default-DB-keys-from-ELF-Note.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Thu, 27 Mar 2025 01:02:40 +0530
|
||||
Subject: [PATCH] appendedsig: Reads the default DB keys from ELF Note
|
||||
|
||||
If Secure Boot is enabled with PKS and the use_static_keys flag is set,
|
||||
then read the DB default keys from the ELF note and store them in the trusted list buffer.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/commands/appendedsig/appendedsig.c | 56 ++++++++++++++++++++--------
|
||||
1 file changed, 40 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
|
||||
index 07d6b39..f51942b 100644
|
||||
--- a/grub-core/commands/appendedsig/appendedsig.c
|
||||
+++ b/grub-core/commands/appendedsig/appendedsig.c
|
||||
@@ -1041,7 +1041,7 @@ create_distrusted_list (void)
|
||||
* parse it, and add it to the trusted list.
|
||||
*/
|
||||
static grub_err_t
|
||||
-build_static_trusted_list (const struct grub_module_header *header)
|
||||
+build_static_trusted_list (const struct grub_module_header *header, const grub_bool_t is_pks)
|
||||
{
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
struct grub_file pseudo_file;
|
||||
@@ -1060,6 +1060,13 @@ build_static_trusted_list (const struct grub_module_header *header)
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
+ if (is_pks)
|
||||
+ {
|
||||
+ err = is_distrusted_cert_hash (cert_data, cert_data_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
err = add_certificate (cert_data, cert_data_size, &db, 1);
|
||||
grub_free (cert_data);
|
||||
|
||||
@@ -1112,6 +1119,22 @@ free_distrusted_list (void)
|
||||
grub_memset (&dbx, 0, sizeof (dbx));
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+load_static_keys (const struct grub_module_header *header, const grub_bool_t is_pks)
|
||||
+{
|
||||
+ int rc = GRUB_ERR_NONE;
|
||||
+ FOR_MODULES (header)
|
||||
+ {
|
||||
+ /* Not an ELF module, skip. */
|
||||
+ if (header->type != OBJ_TYPE_X509_PUBKEY)
|
||||
+ continue;
|
||||
+ rc = build_static_trusted_list (header, is_pks);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ return rc;
|
||||
+ }
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
GRUB_MOD_INIT (appendedsig)
|
||||
{
|
||||
int rc;
|
||||
@@ -1130,26 +1153,27 @@ GRUB_MOD_INIT (appendedsig)
|
||||
|
||||
if (!grub_pks_use_keystore && check_sigs == check_sigs_forced)
|
||||
{
|
||||
- FOR_MODULES (header)
|
||||
+ rc = load_static_keys (header, false);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
- /* Not an ELF module, skip. */
|
||||
- if (header->type != OBJ_TYPE_X509_PUBKEY)
|
||||
- continue;
|
||||
-
|
||||
- rc = build_static_trusted_list (header);
|
||||
- if (rc != GRUB_ERR_NONE)
|
||||
- {
|
||||
- free_trusted_list ();
|
||||
- grub_error (rc, "static trusted list creation failed");
|
||||
- }
|
||||
- else
|
||||
- grub_dprintf ("appendedsig", "the trusted list now has %" PRIuGRUB_SIZE " static keys\n",
|
||||
- db.key_entries);
|
||||
+ free_trusted_list ();
|
||||
+ grub_error (rc, "static trusted list creation failed");
|
||||
}
|
||||
+ else
|
||||
+ grub_dprintf ("appendedsig", "the trusted list now has %" PRIuGRUB_SIZE " static keys\n",
|
||||
+ db.key_entries);
|
||||
}
|
||||
else if (grub_pks_use_keystore && check_sigs == check_sigs_forced)
|
||||
{
|
||||
- rc = create_trusted_list ();
|
||||
+ if (grub_pks_keystore.use_static_keys)
|
||||
+ {
|
||||
+ grub_printf ("Warning: db variable is not available at PKS and using a static keys "
|
||||
+ "as a default key in trusted list\n");
|
||||
+ rc = load_static_keys (header, grub_pks_keystore.use_static_keys);
|
||||
+ }
|
||||
+ else
|
||||
+ rc = create_trusted_list ();
|
||||
+
|
||||
if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
free_trusted_list ();
|
660
0474-appendedsig-The-grub-command-s-trusted-and-distruste.patch
Normal file
660
0474-appendedsig-The-grub-command-s-trusted-and-distruste.patch
Normal file
@ -0,0 +1,660 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Thu, 27 Mar 2025 01:02:41 +0530
|
||||
Subject: [PATCH] appendedsig: The grub command's trusted and distrusted
|
||||
support
|
||||
|
||||
To support the following trusted and distrusted commands
|
||||
|
||||
1. trusted_list:
|
||||
It will show the list of trusted certificates and binary hashes
|
||||
2. distrusted_list:
|
||||
It will show the list of distrusted certificates and binary/certificate hashes
|
||||
3. trusted_certificate:
|
||||
It will add the trusted certificate to the trusted list
|
||||
4. trusted_signature:
|
||||
It will add the certificate/binary hash to the trusted list
|
||||
5. distrusted_certificate:
|
||||
It will remove the trusted certificate from trsuted list
|
||||
6. distrusted_signature:
|
||||
It will add the certificate/binary hash to the distrsuted list
|
||||
|
||||
Note:-
|
||||
The addition/deletion of trusted certificates and binary hashes
|
||||
are not allowed in grub command prompt while secure boot is enabled.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/commands/appendedsig/appendedsig.c | 528 ++++++++++++++++++---------
|
||||
1 file changed, 356 insertions(+), 172 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
|
||||
index f51942b..b8548f8 100644
|
||||
--- a/grub-core/commands/appendedsig/appendedsig.c
|
||||
+++ b/grub-core/commands/appendedsig/appendedsig.c
|
||||
@@ -117,6 +117,36 @@ static enum
|
||||
check_sigs_forced = 2
|
||||
} check_sigs = check_sigs_no;
|
||||
|
||||
+enum
|
||||
+{
|
||||
+ OPTION_BINARY_HASH = 0,
|
||||
+ OPTION_CERT_HASH = 1
|
||||
+};
|
||||
+
|
||||
+static const struct grub_arg_option options[] =
|
||||
+{
|
||||
+ {"binary-hash", 'b', 0, N_("hash file of the binary."), 0, ARG_TYPE_NONE},
|
||||
+ {"cert-hash", 'c', 1, N_("hash file of the certificate."), 0, ARG_TYPE_NONE},
|
||||
+ {0, 0, 0, 0, 0, 0}
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+print_hex (const grub_uint8_t *data, const grub_size_t length)
|
||||
+{
|
||||
+ grub_size_t i, count = 0;
|
||||
+ for (i = 0; i < length-1; i++)
|
||||
+ {
|
||||
+ grub_printf ("%02x:", data[i]);
|
||||
+ count++;
|
||||
+ if (count == 16)
|
||||
+ {
|
||||
+ grub_printf ("\n\t ");
|
||||
+ count = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ grub_printf ("%02x\n", data[i]);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* GUID can be used to determine the hashing function and
|
||||
* generate the hash using determined hashing function.
|
||||
@@ -344,72 +374,6 @@ grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)), const cha
|
||||
return grub_strdup (grub_env_read_sec (NULL, NULL));
|
||||
}
|
||||
|
||||
-static grub_err_t
|
||||
-file_read_all (grub_file_t file, grub_uint8_t **buf, grub_size_t *len)
|
||||
-{
|
||||
- grub_off_t full_file_size;
|
||||
- grub_size_t file_size, total_read_size = 0;
|
||||
- grub_ssize_t read_size;
|
||||
-
|
||||
- full_file_size = grub_file_size (file);
|
||||
- if (full_file_size == GRUB_FILE_SIZE_UNKNOWN)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
- N_("Cannot read a file of unknown size into a buffer"));
|
||||
-
|
||||
- if (full_file_size > GRUB_SIZE_MAX)
|
||||
- return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
- N_("File is too large to read: %" PRIuGRUB_UINT64_T " bytes"),
|
||||
- full_file_size);
|
||||
-
|
||||
- file_size = (grub_size_t) full_file_size;
|
||||
-
|
||||
- *buf = grub_malloc (file_size);
|
||||
- if (!*buf)
|
||||
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
- N_("Could not allocate file data buffer size %" PRIuGRUB_SIZE),
|
||||
- file_size);
|
||||
-
|
||||
- while (total_read_size < file_size)
|
||||
- {
|
||||
- read_size = grub_file_read (file, *buf + total_read_size, file_size - total_read_size);
|
||||
-
|
||||
- if (read_size < 0)
|
||||
- {
|
||||
- grub_free (*buf);
|
||||
- return grub_errno;
|
||||
- }
|
||||
- else if (read_size == 0)
|
||||
- {
|
||||
- grub_free (*buf);
|
||||
- return grub_error (GRUB_ERR_IO,
|
||||
- N_("Could not read full file size "
|
||||
- "(%" PRIuGRUB_SIZE "), only %" PRIuGRUB_SIZE " bytes read"),
|
||||
- file_size, total_read_size);
|
||||
- }
|
||||
-
|
||||
- total_read_size += read_size;
|
||||
- }
|
||||
- *len = file_size;
|
||||
- return GRUB_ERR_NONE;
|
||||
-}
|
||||
-
|
||||
-static grub_err_t
|
||||
-read_cert_from_file (grub_file_t f, struct x509_certificate *certificate)
|
||||
-{
|
||||
- grub_err_t err;
|
||||
- grub_uint8_t *buf;
|
||||
- grub_size_t file_size;
|
||||
-
|
||||
- err = file_read_all (f, &buf, &file_size);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- return err;
|
||||
-
|
||||
- err = parse_x509_certificate (buf, file_size, certificate);
|
||||
- grub_free (buf);
|
||||
-
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
static grub_err_t
|
||||
extract_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize,
|
||||
struct grub_appended_signature *sig)
|
||||
@@ -630,143 +594,345 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
static grub_err_t
|
||||
grub_cmd_verify_signature (grub_command_t cmd __attribute__ ((unused)), int argc, char **args)
|
||||
{
|
||||
- grub_file_t f;
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
- grub_uint8_t *data;
|
||||
- grub_size_t file_size;
|
||||
+ grub_file_t signed_file = NULL;
|
||||
+ grub_uint8_t *signed_data = NULL;
|
||||
+ grub_ssize_t signed_data_size = 0;
|
||||
|
||||
- if (argc < 1)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||
+ if (argc != 1)
|
||||
+ {
|
||||
+ grub_printf (N_("a signed file is expected\n"
|
||||
+ "Example:\n\tverify_appended <SIGNED FILE>\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
|
||||
grub_dprintf ("appendedsig", "verifying %s\n", args[0]);
|
||||
|
||||
- f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
|
||||
- if (!f)
|
||||
+ signed_file = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
|
||||
+ if (signed_file == NULL)
|
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("unable to open a signed file"));
|
||||
+
|
||||
+ err = grub_read_file (signed_file, &signed_data, &signed_data_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_file_close (signed_file);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ grub_file_close (signed_file);
|
||||
+ err = grub_verify_appended_signature (signed_data, signed_data_size);
|
||||
+ grub_free (signed_data);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_trusted_list (grub_command_t cmd __attribute__((unused)),
|
||||
+ int argc __attribute__((unused)), char **args __attribute__((unused)))
|
||||
+{
|
||||
+ struct x509_certificate *cert = NULL;
|
||||
+ grub_size_t i = 0, cert_num = 1;
|
||||
+
|
||||
+ for (cert = db.keys; cert; cert = cert->next)
|
||||
+ {
|
||||
+ grub_printf (N_("trusted certificate %" PRIuGRUB_SIZE ":\n"), cert_num);
|
||||
+ grub_printf (N_("\tserial: "));
|
||||
+
|
||||
+ for (i = 0; i < cert->serial_len - 1; i++)
|
||||
+ grub_printf ("%02x:", cert->serial[i]);
|
||||
+
|
||||
+ grub_printf ("%02x\n", cert->serial[cert->serial_len - 1]);
|
||||
+ grub_printf ("\tCN: %s\n\n", cert->subject);
|
||||
+ cert_num++;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < db.signature_entries; i++)
|
||||
+ {
|
||||
+ grub_printf (N_("trusted binary hash %" PRIuGRUB_SIZE ":\n"), i+1);
|
||||
+ grub_printf (N_("\thash: "));
|
||||
+ print_hex (db.signatures[i], db.signature_size[i]);
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_distrusted_list (grub_command_t cmd __attribute__((unused)),
|
||||
+ int argc __attribute__((unused)),
|
||||
+ char **args __attribute__((unused)))
|
||||
+{
|
||||
+ struct x509_certificate *cert = NULL;
|
||||
+ grub_size_t i = 0, cert_num = 1;
|
||||
+
|
||||
+ for (cert = dbx.keys; cert; cert = cert->next)
|
||||
+ {
|
||||
+ grub_printf (N_("distrusted certificate %" PRIuGRUB_SIZE ":\n"), cert_num);
|
||||
+ grub_printf (N_("\tserial: "));
|
||||
+
|
||||
+ for (i = 0; i < cert->serial_len - 1; i++)
|
||||
+ grub_printf ("%02x:", cert->serial[i]);
|
||||
+
|
||||
+ grub_printf ("%02x\n", cert->serial[cert->serial_len - 1]);
|
||||
+ grub_printf ("\tCN: %s\n\n", cert->subject);
|
||||
+ cert_num++;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < dbx.signature_entries; i++)
|
||||
+ {
|
||||
+ grub_printf (N_("distrusted certificate/binary hash %" PRIuGRUB_SIZE ":\n"), i+1);
|
||||
+ grub_printf (N_("\thash: "));
|
||||
+ print_hex (dbx.signatures[i], dbx.signature_size[i]);
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_trusted_cert (grub_command_t cmd __attribute__((unused)),
|
||||
+ int argc, char **args)
|
||||
+{
|
||||
+ grub_err_t err = GRUB_ERR_NONE;
|
||||
+ grub_file_t cert_file = NULL;
|
||||
+ grub_uint8_t *cert_data = NULL;
|
||||
+ grub_ssize_t cert_data_size = 0;
|
||||
+
|
||||
+ if (argc != 1)
|
||||
{
|
||||
- err = grub_errno;
|
||||
- goto cleanup;
|
||||
+ grub_printf (N_("a trusted X.509 certificate file is expected\n"
|
||||
+ "Example:\n\ttrusted_certificate <CERT FILE>\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
- err = file_read_all (f, &data, &file_size);
|
||||
+ if (check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ grub_printf ("Warning: since secure boot is enabled, "
|
||||
+ "adding of trusted X.509 certificate is not permitted!\n");
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_strlen (args[0]) == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_FILENAME,
|
||||
+ N_("missing trusted X.509 certificate file"));
|
||||
+
|
||||
+ cert_file = grub_file_open (args[0], GRUB_FILE_TYPE_CERTIFICATE_TRUST |
|
||||
+ GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
+ if (cert_file == NULL)
|
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
||||
+ N_("unable to open the trusted X.509 certificate file"));
|
||||
+
|
||||
+ err = grub_read_file (cert_file, &cert_data, &cert_data_size);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
- goto cleanup;
|
||||
+ {
|
||||
+ grub_file_close (cert_file);
|
||||
+ return err;
|
||||
+ }
|
||||
|
||||
- err = grub_verify_appended_signature (data, file_size);
|
||||
+ grub_file_close (cert_file);
|
||||
+ err = add_certificate (cert_data, cert_data_size, &db, 1);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ free_trusted_list ();
|
||||
+ free_distrusted_list ();
|
||||
+ grub_error (err, "adding of trusted certificate failed");
|
||||
+ }
|
||||
|
||||
- grub_free (data);
|
||||
+ grub_free (cert_data);
|
||||
|
||||
-cleanup:
|
||||
- if (f)
|
||||
- grub_file_close (f);
|
||||
return err;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_cmd_distrust (grub_command_t cmd __attribute__ ((unused)), int argc, char **args)
|
||||
+grub_cmd_trusted_hash (grub_command_t cmd __attribute__((unused)), int argc, char**args)
|
||||
{
|
||||
- unsigned long cert_num, i;
|
||||
- struct x509_certificate *cert, *prev;
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_file_t hash_file = NULL;
|
||||
+ grub_uint8_t *hash_data = NULL;
|
||||
+ grub_ssize_t hash_data_size = 0;
|
||||
|
||||
if (argc != 1)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("One argument expected"));
|
||||
+ {
|
||||
+ grub_printf (N_("a trusted binary hash file is expected\n"
|
||||
+ "Example:\n\ttrusted_signature <BINARY HASH FILE>\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ if (check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ grub_printf ("Warning: since secure boot is enabled, "
|
||||
+ "adding of trusted binary hash is not permitted!\n");
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_strlen (args[0]) == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_FILENAME, N_("missing trusted binary hash file"));
|
||||
+
|
||||
+ hash_file = grub_file_open (args[0], GRUB_FILE_TYPE_TO_HASH | GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
+ if (hash_file == NULL)
|
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
||||
+ N_("unable to open the trusted binary hash file"));
|
||||
+
|
||||
+ rc = grub_read_file (hash_file, &hash_data, &hash_data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_file_close (hash_file);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ grub_file_close (hash_file);
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "adding a trusted binary hash %s\n with size of %" PRIuGRUB_SIZE "\n",
|
||||
+ hash_data, hash_data_size);
|
||||
+
|
||||
+ /* only accept SHA256, SHA384 and SHA512 binary hash */
|
||||
+ if (hash_data_size != 32 && hash_data_size != 48 && hash_data_size != 64)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("unacceptable trusted binary hash type"));
|
||||
+
|
||||
+ rc = add_hash ((const grub_uint8_t **) &hash_data, hash_data_size, &db.signatures,
|
||||
+ &db.signature_size, &db.signature_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ free_trusted_list ();
|
||||
+ free_distrusted_list ();
|
||||
+ grub_error (rc, "adding of trusted binary hash failed");
|
||||
+ }
|
||||
+
|
||||
+ grub_free (hash_data);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_distrusted_cert (grub_command_t cmd __attribute__((unused)), int argc, char **args)
|
||||
+{
|
||||
+ grub_size_t cert_num = 0, i = 1;
|
||||
+ struct x509_certificate *current_cert = db.keys;
|
||||
+ struct x509_certificate *previous_cert = db.keys;
|
||||
+
|
||||
+ if (argc != 1)
|
||||
+ {
|
||||
+ grub_printf (N_("trusted certificate number is expected\n"
|
||||
+ "Example:\n\tdistrusted_certificate <CERT_NUMER>\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ if (check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ grub_printf ("Warning: since secure boot is enabled, "
|
||||
+ "removing of trusted certificate is not permitted!\n");
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
|
||||
- grub_errno = GRUB_ERR_NONE;
|
||||
cert_num = grub_strtoul (args[0], NULL, 10);
|
||||
- if (grub_errno != GRUB_ERR_NONE)
|
||||
- return grub_errno;
|
||||
-
|
||||
if (cert_num < 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
- N_("Certificate number too small - numbers start at 1"));
|
||||
+ N_("trusted certificate number should to begin with 1"));
|
||||
|
||||
- if (cert_num == 1)
|
||||
- {
|
||||
- cert = db.keys;
|
||||
- db.keys = cert->next;
|
||||
+ if (cert_num > db.key_entries)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("trusted certificate number should not exceed %" PRIuGRUB_SIZE ""),
|
||||
+ db.key_entries);
|
||||
+ else if (cert_num < db.key_entries)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("there is no certificate on the trusted list. so, not permitted"));
|
||||
|
||||
- certificate_release (cert);
|
||||
- grub_free (cert);
|
||||
- return GRUB_ERR_NONE;
|
||||
- }
|
||||
- i = 2;
|
||||
- prev = db.keys;
|
||||
- cert = db.keys->next;
|
||||
- while (cert)
|
||||
+ for (i = 1; i < db.key_entries; i++)
|
||||
{
|
||||
- if (i == cert_num)
|
||||
+ if (cert_num == 1)
|
||||
+ {
|
||||
+ previous_cert = current_cert->next;
|
||||
+ break;
|
||||
+ }
|
||||
+ else if (cert_num == i)
|
||||
{
|
||||
- prev->next = cert->next;
|
||||
- certificate_release (cert);
|
||||
- grub_free (cert);
|
||||
- return GRUB_ERR_NONE;
|
||||
+ previous_cert->next = current_cert->next;
|
||||
+ break;
|
||||
}
|
||||
- i++;
|
||||
- prev = cert;
|
||||
- cert = cert->next;
|
||||
+
|
||||
+ previous_cert = current_cert;
|
||||
+ current_cert = current_cert->next;
|
||||
}
|
||||
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
- N_("No certificate number %lu found - only %lu certificates in the store"),
|
||||
- cert_num, i - 1);
|
||||
+ certificate_release (current_cert);
|
||||
+ grub_free (current_cert);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_cmd_trust (grub_command_t cmd __attribute__ ((unused)), int argc, char **args)
|
||||
+grub_cmd_distrusted_hash (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
- grub_file_t certf;
|
||||
- struct x509_certificate *cert = NULL;
|
||||
- grub_err_t err;
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_file_t hash_file = NULL;
|
||||
+ grub_uint8_t *hash_data = NULL;
|
||||
+ grub_ssize_t hash_data_size = 0;
|
||||
|
||||
- if (argc != 1)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||
-
|
||||
- certf = grub_file_open (args[0], GRUB_FILE_TYPE_CERTIFICATE_TRUST | GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
- if (!certf)
|
||||
- return grub_errno;
|
||||
-
|
||||
- cert = grub_zalloc (sizeof (struct x509_certificate));
|
||||
- if (!cert)
|
||||
- return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("Could not allocate memory for certificate"));
|
||||
+ if (argc != 2)
|
||||
+ {
|
||||
+ grub_printf (N_("a distrusted certificate/binary hash file is expected\n"
|
||||
+ "Example:\n\tdistrusted_signature [option] <FILE>\n"
|
||||
+ "option:\n[-b|--binary-hash] FILE [BINARY HASH FILE]\n"
|
||||
+ "[-c|--cert-hash] FILE [CERTFICATE HASH FILE]\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
|
||||
- err = read_cert_from_file (certf, cert);
|
||||
- grub_file_close (certf);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
+ if (check_sigs == check_sigs_forced)
|
||||
{
|
||||
- grub_free (cert);
|
||||
- return err;
|
||||
+ grub_printf ("Warning: since secure boot is enabled, "
|
||||
+ "adding of distrusted certificate/binary hash is not permitted!\n");
|
||||
+ return grub_errno;
|
||||
}
|
||||
- grub_dprintf ("appendedsig", "Loaded certificate with CN: %s\n", cert->subject);
|
||||
|
||||
- cert->next = db.keys;
|
||||
- db.keys = cert;
|
||||
+ if (!ctxt->state[OPTION_BINARY_HASH].set && !ctxt->state[OPTION_CERT_HASH].set)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing options and use --help to konw"));
|
||||
|
||||
- return GRUB_ERR_NONE;
|
||||
-}
|
||||
+ if (grub_strlen (args[1]) == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_FILENAME,
|
||||
+ N_("missing distrusted certificate/binary hash file"));
|
||||
|
||||
-static grub_err_t
|
||||
-grub_cmd_list (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)),
|
||||
- char **args __attribute__ ((unused)))
|
||||
-{
|
||||
- struct x509_certificate *cert;
|
||||
- int cert_num = 1;
|
||||
- grub_size_t i;
|
||||
+ hash_file = grub_file_open (args[1], GRUB_FILE_TYPE_TO_HASH | GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
+ if (hash_file == NULL)
|
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
||||
+ N_("unable to open the distrusted certificate/binary hash file"));
|
||||
|
||||
- for (cert = db.keys; cert; cert = cert->next)
|
||||
+ rc = grub_read_file (hash_file, &hash_data, &hash_data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
- grub_printf (N_("Certificate %d:\n"), cert_num);
|
||||
+ grub_file_close (hash_file);
|
||||
+ return rc;
|
||||
+ }
|
||||
|
||||
- grub_printf (N_("\tSerial: "));
|
||||
- for (i = 0; i < cert->serial_len - 1; i++)
|
||||
- {
|
||||
- grub_printf ("%02x:", cert->serial[i]);
|
||||
- }
|
||||
- grub_printf ("%02x\n", cert->serial[cert->serial_len - 1]);
|
||||
+ grub_file_close (hash_file);
|
||||
|
||||
- grub_printf ("\tCN: %s\n\n", cert->subject);
|
||||
- cert_num++;
|
||||
+ grub_dprintf ("appendedsig", "adding a distrusted certificate/binary hash %s\n"
|
||||
+ " with size of %" PRIuGRUB_SIZE "\n", hash_data, hash_data_size);
|
||||
+
|
||||
+ if (ctxt->state[OPTION_BINARY_HASH].set)
|
||||
+ {
|
||||
+ /* only accept SHA256, SHA384 and SHA512 binary hash */
|
||||
+ if (hash_data_size != 32 && hash_data_size != 48 && hash_data_size != 64)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
+ N_("unacceptable distrusted binary hash type"));
|
||||
+ }
|
||||
+ else if (ctxt->state[OPTION_CERT_HASH].set)
|
||||
+ {
|
||||
+ /* only accept SHA256, SHA384 and SHA512 certificate hash */
|
||||
+ if (hash_data_size != 32 && hash_data_size != 48 && hash_data_size != 64)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
+ N_("unacceptable distrusted certificate hash type"));
|
||||
}
|
||||
|
||||
- return GRUB_ERR_NONE;
|
||||
+ rc = add_hash ((const grub_uint8_t **) &hash_data, hash_data_size, &dbx.signatures,
|
||||
+ &dbx.signature_size, &dbx.signature_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ free_trusted_list ();
|
||||
+ free_distrusted_list ();
|
||||
+ grub_error (rc, "adding of distrusted binary/certificate hash failed");
|
||||
+ }
|
||||
+
|
||||
+ grub_free (hash_data);
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -842,8 +1008,6 @@ pseudo_read (struct grub_file *file, char *buf, grub_size_t len)
|
||||
/* Filesystem descriptor. */
|
||||
static struct grub_fs pseudo_fs = { .name = "pseudo", .fs_read = pseudo_read };
|
||||
|
||||
-static grub_command_t cmd_verify, cmd_list, cmd_distrust, cmd_trust;
|
||||
-
|
||||
/*
|
||||
* Verify the trusted certificate against the certificate hashes from platform keystore buffer's
|
||||
* distrusted list.
|
||||
@@ -1135,6 +1299,10 @@ load_static_keys (const struct grub_module_header *header, const grub_bool_t is_
|
||||
return rc;
|
||||
}
|
||||
|
||||
+static grub_extcmd_t cmd_distrusted_hash;
|
||||
+static grub_command_t cmd_verify, cmd_trusted_list, cmd_trusted_cert, cmd_trusted_hash,
|
||||
+ cmd_distrusted_list, cmd_distrusted_cert;
|
||||
+
|
||||
GRUB_MOD_INIT (appendedsig)
|
||||
{
|
||||
int rc;
|
||||
@@ -1196,17 +1364,31 @@ GRUB_MOD_INIT (appendedsig)
|
||||
|
||||
grub_pks_free_keystore ();
|
||||
}
|
||||
-
|
||||
- cmd_trust = grub_register_command ("trust_certificate", grub_cmd_trust, N_("X509_CERTIFICATE"),
|
||||
- N_("Add X509_CERTIFICATE to trusted certificates."));
|
||||
- cmd_list = grub_register_command ("list_certificates", grub_cmd_list, 0,
|
||||
- N_("Show the list of trusted x509 certificates."));
|
||||
+ cmd_trusted_cert = grub_register_command ("trusted_certificate", grub_cmd_trusted_cert,
|
||||
+ N_("X509_CERTIFICATE"),
|
||||
+ N_("Add X509_CERTIFICATE to trusted list."));
|
||||
+ cmd_trusted_hash = grub_register_command ("trusted_signature", grub_cmd_trusted_hash,
|
||||
+ N_("BINARY HASH FILE"),
|
||||
+ N_("Add trusted BINARY HASH to trusted list."));
|
||||
+ cmd_distrusted_cert = grub_register_command ("distrusted_certificate", grub_cmd_distrusted_cert,
|
||||
+ N_("CERT_NUMBER"),
|
||||
+ N_("Remove CERT_NUMBER (as listed by list_trusted)"
|
||||
+ " from trusted list."));
|
||||
+ cmd_distrusted_hash = grub_register_extcmd ("distrusted_signature", grub_cmd_distrusted_hash, 0,
|
||||
+ N_("[-b|--binary-hash] FILE [BINARY HASH FILE]\n"
|
||||
+ "[-c|--cert-hash] FILE [CERTFICATE HASH FILE]"),
|
||||
+ N_("Add distrusted CERTFICATE/BINARY HASH "
|
||||
+ "to distrusted list."),
|
||||
+ options);
|
||||
+ cmd_trusted_list = grub_register_command ("trusted_list", grub_cmd_trusted_list, 0,
|
||||
+ N_("Show the list of trusted x509 certificates and"
|
||||
+ " trusted binary hashes."));
|
||||
+ cmd_distrusted_list = grub_register_command ("distrusted_list", grub_cmd_distrusted_list, 0,
|
||||
+ N_("Show the list of distrusted certificates and"
|
||||
+ " certificate/binary hashes"));
|
||||
cmd_verify = grub_register_command ("verify_appended", grub_cmd_verify_signature, N_("FILE"),
|
||||
- N_("Verify FILE against the trusted x509 certificates."));
|
||||
- cmd_distrust = grub_register_command ("distrust_certificate", grub_cmd_distrust,
|
||||
- N_("CERT_NUMBER"),
|
||||
- N_("Remove CERT_NUMBER (as listed by list_certificates)"
|
||||
- " from trusted certificates."));
|
||||
+ N_("Verify FILE against the trusted x509 certificates/"
|
||||
+ "trusted binary hashes."));
|
||||
|
||||
grub_verifier_register (&grub_appendedsig_verifier);
|
||||
grub_dl_set_persistent (mod);
|
||||
@@ -1218,10 +1400,12 @@ GRUB_MOD_FINI (appendedsig)
|
||||
* grub_dl_set_persistent should prevent this from actually running, but
|
||||
* it does still run under emu.
|
||||
*/
|
||||
-
|
||||
grub_verifier_unregister (&grub_appendedsig_verifier);
|
||||
grub_unregister_command (cmd_verify);
|
||||
- grub_unregister_command (cmd_list);
|
||||
- grub_unregister_command (cmd_trust);
|
||||
- grub_unregister_command (cmd_distrust);
|
||||
+ grub_unregister_command (cmd_trusted_list);
|
||||
+ grub_unregister_command (cmd_distrusted_list);
|
||||
+ grub_unregister_command (cmd_trusted_cert);
|
||||
+ grub_unregister_command (cmd_distrusted_cert);
|
||||
+ grub_unregister_command (cmd_trusted_hash);
|
||||
+ grub_unregister_extcmd (cmd_distrusted_hash);
|
||||
}
|
210
0475-appendedsig-documentation.patch
Normal file
210
0475-appendedsig-documentation.patch
Normal file
@ -0,0 +1,210 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Thu, 27 Mar 2025 01:02:42 +0530
|
||||
Subject: [PATCH] appendedsig: documentation
|
||||
|
||||
This explains how static and dynamic key appended signatures can be used to form part of
|
||||
a secure boot chain, and documents the commands and variables introduced.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
docs/grub.texi | 109 +++++++++++++++++++++++++++++++++++++++------------------
|
||||
1 file changed, 74 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 72cf517..a4ae8cd 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -4016,7 +4016,9 @@ you forget a command, you can run the command @command{help}
|
||||
* date:: Display or set current date and time
|
||||
* devicetree:: Load a device tree blob
|
||||
* distrust:: Remove a pubkey from trusted keys
|
||||
-* distrust_certificate:: Remove a certificate from the list of trusted certificates
|
||||
+* distrusted_certificate:: Remove a certificate from the trusted list
|
||||
+* distrusted_list:: List distrusted certificates and binary/certificate hashes
|
||||
+* distrusted_signature:: Add a binary hash to the distrusted list
|
||||
* drivemap:: Map a drive to another
|
||||
* echo:: Display a line of text
|
||||
* eval:: Evaluate agruments as GRUB commands
|
||||
@@ -4033,7 +4035,6 @@ you forget a command, you can run the command @command{help}
|
||||
* keystatus:: Check key modifier status
|
||||
* linux:: Load a Linux kernel
|
||||
* linux16:: Load a Linux kernel (16-bit mode)
|
||||
-* list_certificates:: List trusted certificates
|
||||
* list_env:: List variables in environment block
|
||||
* list_trusted:: List trusted public keys
|
||||
* load_env:: Load variables from environment block
|
||||
@@ -4072,7 +4073,9 @@ you forget a command, you can run the command @command{help}
|
||||
* test:: Check file types and compare values
|
||||
* true:: Do nothing, successfully
|
||||
* trust:: Add public key to list of trusted keys
|
||||
-* trust_certificate:: Add an x509 certificate to the list of trusted certificates
|
||||
+* trusted_certificate:: Add an x509 certificate to the trusted list
|
||||
+* trusted_list:: List trusted certificates and binary hashes
|
||||
+* trusted_signature:: Add a binary hash to the trusted list.
|
||||
* unset:: Unset an environment variable
|
||||
@comment * vbeinfo:: List available video modes
|
||||
* verify_appended:: Verify appended digital signature
|
||||
@@ -4416,16 +4419,15 @@ These keys are used to validate signatures when environment variable
|
||||
GPG-style digital signatures}, for more information.
|
||||
@end deffn
|
||||
|
||||
+@node distrusted_certificate
|
||||
+@subsection distrusted_certificate
|
||||
|
||||
-@node distrust_certificate
|
||||
-@subsection distrust_certificate
|
||||
-
|
||||
-@deffn Command distrust_certificate cert_number
|
||||
+@deffn Command distrusted_certificate cert_number
|
||||
Remove the x509 certificate numbered @var{cert_number} from GRUB's keyring of
|
||||
trusted x509 certificates for verifying appended signatures.
|
||||
|
||||
@var{cert_number} is the certificate number as listed by
|
||||
-@command{list_certificates} (@pxref{list_certificates}).
|
||||
+@command{trusted_list} (@pxref{trusted_list}).
|
||||
|
||||
These certificates are used to validate appended signatures when environment
|
||||
variable @code{check_appended_signatures} is set to @code{enforce} or
|
||||
@@ -4434,6 +4436,27 @@ variable @code{check_appended_signatures} is set to @code{enforce} or
|
||||
@xref{Using appended signatures} for more information.
|
||||
@end deffn
|
||||
|
||||
+@node distrusted_list
|
||||
+@subsection distrusted_list
|
||||
+
|
||||
+@deffn Command distrusted_list
|
||||
+List all the distrusted x509 certificates and binary/certificate hashes.
|
||||
+The output is a numbered list of certificates and binary/certificate hashes,
|
||||
+showing the certificate's serial number and Common Name.
|
||||
+@end deffn
|
||||
+
|
||||
+@node distrusted_signature
|
||||
+@subsection distrusted_signature
|
||||
+
|
||||
+@deffn Command distrusted_signature
|
||||
+Read a binary hash from the file @var{binary hash file}
|
||||
+and add it to GRUB's internal distrusted list. These hash are used to
|
||||
+restrict validation of linux image integrity using trusted list if appended
|
||||
+signatures validation failed when the environment variable
|
||||
+@code{check_appended_signatures} is set to @code{enforce}.
|
||||
+
|
||||
+See @xref{Using appended signatures} for more information.
|
||||
+@end deffn
|
||||
|
||||
@node drivemap
|
||||
@subsection drivemap
|
||||
@@ -4691,22 +4714,6 @@ for the sake of convenience.
|
||||
This command is only available on x86 systems.
|
||||
@end deffn
|
||||
|
||||
-
|
||||
-@node list_certificates
|
||||
-@subsection list_certificates
|
||||
-
|
||||
-@deffn Command list_certificates
|
||||
-List all x509 certificates trusted by GRUB for validating appended signatures.
|
||||
-The output is a numbered list of certificates, showing the certificate's serial
|
||||
-number and Common Name.
|
||||
-
|
||||
-The certificate number can be used as an argument to
|
||||
-@command{distrust_certificate} (@pxref{distrust_certificate}).
|
||||
-
|
||||
-See @xref{Using appended signatures} for more information.
|
||||
-@end deffn
|
||||
-
|
||||
-
|
||||
@node list_env
|
||||
@subsection list_env
|
||||
|
||||
@@ -5540,10 +5547,10 @@ information.
|
||||
@end deffn
|
||||
|
||||
|
||||
-@node trust_certificate
|
||||
-@subsection trust_certificate
|
||||
+@node trusted_certificate
|
||||
+@subsection trusted_certificate
|
||||
|
||||
-@deffn Command trust_certificate x509_certificate
|
||||
+@deffn Command trusted_certificate x509_certificate
|
||||
Read an DER-formatted x509 certificate from the file @var{x509_certificate}
|
||||
and add it to GRUB's internal list of trusted x509 certificates. These
|
||||
certificates are used to validate appended signatures when the environment
|
||||
@@ -5551,7 +5558,7 @@ variable @code{check_appended_signatures} is set to @code{enforce} or
|
||||
@code{forced}.
|
||||
|
||||
Note that if @code{check_appended_signatures} is set to @code{enforce} or
|
||||
-@code{forced} when @command{trust_certificate} is executed, then
|
||||
+@code{forced} when @command{trusted_certificate} is executed, then
|
||||
@var{x509_certificate} must itself bear an appended signature. (It is not
|
||||
sufficient that @var{x509_certificate} be signed by a trusted certificate
|
||||
according to the x509 rules: grub does not include support for validating
|
||||
@@ -5560,6 +5567,32 @@ signatures within x509 certificates themselves.)
|
||||
See @xref{Using appended signatures} for more information.
|
||||
@end deffn
|
||||
|
||||
+@node trusted_list
|
||||
+@subsection trusted_list
|
||||
+
|
||||
+@deffn Command trusted_list
|
||||
+List all x509 certificates and binary hases trusted by GRUB for validating
|
||||
+appended signatures. The output is a numbered list of certificates and binary
|
||||
+hashes, showing the certificate's serial number and Common Name.
|
||||
+
|
||||
+The certificate number can be used as an argument to
|
||||
+@command{distrusted_certificate} (@pxref{distrusted_certificate}).
|
||||
+
|
||||
+See @xref{Using appended signatures} for more information.
|
||||
+@end deffn
|
||||
+
|
||||
+@node trusted_signature
|
||||
+@subsection trusted_signature
|
||||
+
|
||||
+@deffn Command trust_signature
|
||||
+Read a binary hash from the file @var{binary hash file}
|
||||
+and add it to GRUB's internal trusted list. These binary hash are used to
|
||||
+validate linux image integrity if appended signatures validation failed
|
||||
+when the environment variable @code{check_appended_signatures} is set
|
||||
+to @code{enforce}.
|
||||
+
|
||||
+See @xref{Using appended signatures} for more information.
|
||||
+@end deffn
|
||||
|
||||
@node unset
|
||||
@subsection unset
|
||||
@@ -5584,9 +5617,8 @@ only on PC BIOS platforms.
|
||||
|
||||
@deffn Command verify_appended file
|
||||
Verifies an appended signature on @var{file} against the trusted certificates
|
||||
-known to GRUB (See @pxref{list_certificates}, @pxref{trust_certificate}, and
|
||||
-@pxref{distrust_certificate}).
|
||||
-
|
||||
+known to GRUB (See @pxref{trusted_list}, @pxref{trusted_certificate}, and
|
||||
+@pxref{distrusted_certificate}).
|
||||
Exit code @code{$?} is set to 0 if the signature validates
|
||||
successfully. If validation fails, it is set to a non-zero value.
|
||||
See @xref{Using appended signatures}, for more information.
|
||||
@@ -6183,10 +6215,17 @@ with an appended signature ends with the magic string:
|
||||
|
||||
where @code{\n} represents the line-feed character, @code{0x0a}.
|
||||
|
||||
-Certificates can be managed at boot time using the @pxref{trust_certificate},
|
||||
-@pxref{distrust_certificate} and @pxref{list_certificates} commands.
|
||||
-Certificates can also be built in to the core image using the @code{--x509}
|
||||
-parameter to @command{grub-install} or @command{grub-mkimage}.
|
||||
+For static key, Certificates will be built in to the core image using
|
||||
+the @code{--x509} parameter to @command{grub-install} or @command{grub-mkimage}.
|
||||
+it can allow to list the trusted certificates and binary hashes at boot time using
|
||||
+@pxref{trusted_list} and list distrusted certificates and binary/certificate hashes
|
||||
+at boot time using @pxref{distrusted_list} commands.
|
||||
+
|
||||
+For dynamic key, loads the signature database (DB) and forbidden
|
||||
+signature database (DBX) from platform keystore (PKS) and it can allow to list
|
||||
+the trusted certificates and binary hashes at boot time using @pxref{trusted_list}
|
||||
+and list distrusted certificates and binary/certificate hashes at boot time using
|
||||
+@pxref{distrusted_list} commands.
|
||||
|
||||
A file can be explictly verified using the @pxref{verify_appended} command.
|
||||
|
301
0476-efi-Add-efitextmode-command-for-getting-setting-the-.patch
Normal file
301
0476-efi-Add-efitextmode-command-for-getting-setting-the-.patch
Normal file
@ -0,0 +1,301 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
Date: Fri, 22 Jul 2022 02:16:33 -0500
|
||||
Subject: [PATCH] efi: Add efitextmode command for getting/setting the text
|
||||
mode resolution
|
||||
|
||||
This command is meant to behave similarly to the "mode" command of the EFI
|
||||
Shell application. In addition to allowing mode selection by giving the
|
||||
number of columns and rows as arguments, the command allows specifying the
|
||||
mode number to select the mode. Also supported are the arguments "min" and
|
||||
"max", which set the mode to the minimum and maximum mode respectively as
|
||||
calculated by the columns * rows of that mode.
|
||||
|
||||
Signed-off-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 42 ++++++++++
|
||||
grub-core/Makefile.core.def | 6 ++
|
||||
grub-core/commands/efi/efitextmode.c | 155 +++++++++++++++++++++++++++++++++++
|
||||
include/grub/efi/api.h | 6 ++
|
||||
include/grub/err.h | 1 +
|
||||
5 files changed, 210 insertions(+)
|
||||
create mode 100644 grub-core/commands/efi/efitextmode.c
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index a4ae8cd..2677059 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -4021,6 +4021,7 @@ you forget a command, you can run the command @command{help}
|
||||
* distrusted_signature:: Add a binary hash to the distrusted list
|
||||
* drivemap:: Map a drive to another
|
||||
* echo:: Display a line of text
|
||||
+* efitextmode:: Set/Get text output mode resolution
|
||||
* eval:: Evaluate agruments as GRUB commands
|
||||
* export:: Export an environment variable
|
||||
* false:: Do nothing, unsuccessfully
|
||||
@@ -4527,6 +4528,47 @@ character will print that character.
|
||||
@end deffn
|
||||
|
||||
|
||||
+@node efitextmode
|
||||
+@subsection efitextmode
|
||||
+
|
||||
+@deffn Command efitextmode [min | max | <mode_num> | <cols> <rows>]
|
||||
+When used with no arguments displays all available text output modes. The
|
||||
+set mode determines the columns and rows of the text display when in
|
||||
+text mode. An asterisk, @samp{*}, will be at the end of the line of the
|
||||
+currently set mode.
|
||||
+
|
||||
+If given a single parameter, it must be @samp{min}, @samp{max}, or a mode
|
||||
+number given by the listing when run with no arguments. These arguments set
|
||||
+the mode to the minimum, maximum, and particular mode respectively.
|
||||
+
|
||||
+Otherwise, the command must be given two numerical arguments specifying the
|
||||
+columns and rows of the desired mode. Specifying a columns and rows
|
||||
+combination that corresponds to no supported mode, will return error, but
|
||||
+otherwise have no effect.
|
||||
+
|
||||
+By default GRUB will start in whatever mode the EFI firmware defaults to.
|
||||
+There are firmwares known to set up the default mode such that output
|
||||
+behaves strangely, for example the cursor in the GRUB shell never reaches
|
||||
+the bottom of the screen or, when typing characters at the prompt,
|
||||
+characters from previous command output are overwritten. Setting the mode
|
||||
+may fix this.
|
||||
+
|
||||
+The EFI specification says that mode 0 must be available and have
|
||||
+columns and rows of 80 and 25 respectively. Mode 1 may be defined and if
|
||||
+so must have columns and rows of 80 and 50 respectively. Any other modes
|
||||
+may have columns and rows arbitrarily defined by the firmware. This means
|
||||
+that a mode with columns and rows of 100 and 31 on one firmware may be
|
||||
+a different mode number on a different firmware or not exist at all.
|
||||
+Likewise, mode number 2 on one firmware may have a different number of
|
||||
+columns and rows than mode 2 on a different firmware. So one should not
|
||||
+rely on a particular mode number or a mode of a certain number of columns
|
||||
+and rows existing on all firmwares, except for mode 0.
|
||||
+
|
||||
+Note: This command is only available on EFI platforms and is similar to
|
||||
+EFI shell "mode" command.
|
||||
+@end deffn
|
||||
+
|
||||
+
|
||||
@node eval
|
||||
@subsection eval
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 218068b..4588fa7 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -844,6 +844,12 @@ module = {
|
||||
enable = efi;
|
||||
};
|
||||
|
||||
+module = {
|
||||
+ name = efitextmode;
|
||||
+ efi = commands/efi/efitextmode.c;
|
||||
+ enable = efi;
|
||||
+};
|
||||
+
|
||||
module = {
|
||||
name = blocklist;
|
||||
common = commands/blocklist.c;
|
||||
diff --git a/grub-core/commands/efi/efitextmode.c b/grub-core/commands/efi/efitextmode.c
|
||||
new file mode 100644
|
||||
index 0000000..3679f6b
|
||||
--- /dev/null
|
||||
+++ b/grub-core/commands/efi/efitextmode.c
|
||||
@@ -0,0 +1,155 @@
|
||||
+/*
|
||||
+ * 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/>.
|
||||
+ *
|
||||
+ * Set/Get UEFI text output mode resolution.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/dl.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/command.h>
|
||||
+#include <grub/i18n.h>
|
||||
+#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/api.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_efi_set_mode (grub_efi_simple_text_output_interface_t *o,
|
||||
+ grub_efi_int32_t mode)
|
||||
+{
|
||||
+ grub_efi_status_t status;
|
||||
+
|
||||
+ if (mode != o->mode->mode)
|
||||
+ {
|
||||
+ status = efi_call_2 (o->set_mode, o, mode);
|
||||
+ if (status == GRUB_EFI_SUCCESS)
|
||||
+ ;
|
||||
+ else if (status == GRUB_EFI_DEVICE_ERROR)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("device error: could not set requested mode"));
|
||||
+ else if (status == GRUB_EFI_UNSUPPORTED)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("invalid mode: number not valid"));
|
||||
+ else
|
||||
+ return grub_error (GRUB_ERR_BAD_FIRMWARE,
|
||||
+ N_("unexpected EFI error number: `%u'"),
|
||||
+ (unsigned) status);
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_efitextmode (grub_command_t cmd __attribute__ ((unused)),
|
||||
+ int argc, char **args)
|
||||
+{
|
||||
+ grub_efi_simple_text_output_interface_t *o = grub_efi_system_table->con_out;
|
||||
+ unsigned long mode;
|
||||
+ const char *p = NULL;
|
||||
+ grub_err_t err;
|
||||
+ grub_efi_uintn_t columns, rows;
|
||||
+ grub_efi_int32_t i;
|
||||
+
|
||||
+ if (o == NULL)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE, N_("no UEFI output console interface"));
|
||||
+
|
||||
+ if (o->mode == NULL)
|
||||
+ return grub_error (GRUB_ERR_BUG, N_("no mode struct for UEFI output console"));
|
||||
+
|
||||
+ if (argc > 2)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("at most two arguments expected"));
|
||||
+
|
||||
+ if (argc == 0)
|
||||
+ {
|
||||
+ grub_printf_ (N_("Available modes for console output device.\n"));
|
||||
+
|
||||
+ for (i = 0; i < o->mode->max_mode; i++)
|
||||
+ if (GRUB_EFI_SUCCESS == efi_call_4 (o->query_mode, o, i,
|
||||
+ &columns, &rows))
|
||||
+ grub_printf_ (N_(" [%" PRIuGRUB_EFI_UINT32_T "] Col %5"
|
||||
+ PRIuGRUB_EFI_UINTN_T " Row %5" PRIuGRUB_EFI_UINTN_T
|
||||
+ " %c\n"),
|
||||
+ i, columns, rows, (i == o->mode->mode) ? '*' : ' ');
|
||||
+ }
|
||||
+ else if (argc == 1)
|
||||
+ {
|
||||
+ if (grub_strcmp (args[0], "min") == 0)
|
||||
+ mode = 0;
|
||||
+ else if (grub_strcmp (args[0], "max") == 0)
|
||||
+ mode = o->mode->max_mode - 1;
|
||||
+ else
|
||||
+ {
|
||||
+ mode = grub_strtoul (args[0], &p, 0);
|
||||
+
|
||||
+ if (*args[0] == '\0' || *p != '\0')
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("non-numeric or invalid mode `%s'"), args[0]);
|
||||
+ }
|
||||
+
|
||||
+ if (mode < (unsigned long) o->mode->max_mode)
|
||||
+ {
|
||||
+ err = grub_efi_set_mode (o, (grub_efi_int32_t) mode);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
+ }
|
||||
+ else
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("invalid mode: `%lu' is greater than maximum mode `%lu'"),
|
||||
+ mode, (unsigned long) o->mode->max_mode);
|
||||
+ }
|
||||
+ else if (argc == 2)
|
||||
+ {
|
||||
+ grub_efi_uintn_t u_columns, u_rows;
|
||||
+
|
||||
+ u_columns = (grub_efi_uintn_t) grub_strtoul (args[0], &p, 0);
|
||||
+
|
||||
+ if (*args[0] == '\0' || *p != '\0')
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("non-numeric or invalid columns number `%s'"), args[0]);
|
||||
+
|
||||
+ u_rows = (grub_efi_uintn_t) grub_strtoul (args[1], &p, 0);
|
||||
+
|
||||
+ if (*args[1] == '\0' || *p != '\0')
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("non-numeric or invalid rows number `%s'"), args[1]);
|
||||
+
|
||||
+ for (i = 0; i < o->mode->max_mode; i++)
|
||||
+ if (GRUB_EFI_SUCCESS == efi_call_4 (o->query_mode, o, i,
|
||||
+ &columns, &rows))
|
||||
+ if (u_columns == columns && u_rows == rows)
|
||||
+ return grub_efi_set_mode (o, (grub_efi_int32_t) i);
|
||||
+
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("no mode found with requested columns and rows"));
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_command_t cmd;
|
||||
+GRUB_MOD_INIT (efitextmode)
|
||||
+{
|
||||
+ cmd = grub_register_command ("efitextmode", grub_cmd_efitextmode,
|
||||
+ N_("[min | max | <mode_num> | <cols> <rows>]"),
|
||||
+ N_("Get or set EFI text mode."));
|
||||
+}
|
||||
+
|
||||
+GRUB_MOD_FINI (efitextmode)
|
||||
+{
|
||||
+ grub_unregister_command (cmd);
|
||||
+}
|
||||
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
|
||||
index 464842b..f224037 100644
|
||||
--- a/include/grub/efi/api.h
|
||||
+++ b/include/grub/efi/api.h
|
||||
@@ -545,9 +545,13 @@ typedef char grub_efi_boolean_t;
|
||||
#if GRUB_CPU_SIZEOF_VOID_P == 8
|
||||
typedef grub_int64_t grub_efi_intn_t;
|
||||
typedef grub_uint64_t grub_efi_uintn_t;
|
||||
+#define PRIxGRUB_EFI_UINTN_T PRIxGRUB_UINT64_T
|
||||
+#define PRIuGRUB_EFI_UINTN_T PRIuGRUB_UINT64_T
|
||||
#else
|
||||
typedef grub_int32_t grub_efi_intn_t;
|
||||
typedef grub_uint32_t grub_efi_uintn_t;
|
||||
+#define PRIxGRUB_EFI_UINTN_T PRIxGRUB_UINT32_T
|
||||
+#define PRIuGRUB_EFI_UINTN_T PRIuGRUB_UINT32_T
|
||||
#endif
|
||||
typedef grub_int8_t grub_efi_int8_t;
|
||||
typedef grub_uint8_t grub_efi_uint8_t;
|
||||
@@ -555,6 +559,8 @@ typedef grub_int16_t grub_efi_int16_t;
|
||||
typedef grub_uint16_t grub_efi_uint16_t;
|
||||
typedef grub_int32_t grub_efi_int32_t;
|
||||
typedef grub_uint32_t grub_efi_uint32_t;
|
||||
+#define PRIxGRUB_EFI_UINT32_T PRIxGRUB_UINT32_T
|
||||
+#define PRIuGRUB_EFI_UINT32_T PRIuGRUB_UINT32_T
|
||||
typedef grub_int64_t grub_efi_int64_t;
|
||||
typedef grub_uint64_t grub_efi_uint64_t;
|
||||
typedef grub_uint8_t grub_efi_char8_t;
|
||||
diff --git a/include/grub/err.h b/include/grub/err.h
|
||||
index 905a6df..7530f58 100644
|
||||
--- a/include/grub/err.h
|
||||
+++ b/include/grub/err.h
|
||||
@@ -73,6 +73,7 @@ typedef enum
|
||||
GRUB_ERR_NET_NO_DOMAIN,
|
||||
GRUB_ERR_EOF,
|
||||
GRUB_ERR_BAD_SIGNATURE,
|
||||
+ GRUB_ERR_BAD_FIRMWARE,
|
||||
GRUB_ERR_STILL_REFERENCED,
|
||||
GRUB_ERR_RECURSION_DEPTH
|
||||
}
|
10
grub.patches
10
grub.patches
@ -463,3 +463,13 @@ Patch0463: 0463-fs-xfs-Handle-non-continuous-data-blocks-in-director.patch
|
||||
Patch0464: 0464-fs-xfs-fix-large-extent-counters-incompat-feature-su.patch
|
||||
Patch0465: 0465-grub-mkimage-Create-new-ELF-note-for-SBAT.patch
|
||||
Patch0466: 0466-grub-mkimage-Add-SBAT-metadata-into-ELF-note-for-Pow.patch
|
||||
Patch0467: 0467-appended-sig-sync-d-with-upstream-code.patch
|
||||
Patch0468: 0468-ieee1275-Platform-Keystore-PKS-Support.patch
|
||||
Patch0469: 0469-ieee1275-Read-the-DB-and-DBX-secure-boot-variables.patch
|
||||
Patch0470: 0470-appendedsig-The-creation-of-trusted-and-distrusted-l.patch
|
||||
Patch0471: 0471-appendedsig-While-verifying-the-kernel-use-trusted-a.patch
|
||||
Patch0472: 0472-powerpc_ieee1275-set-use_static_keys-flag.patch
|
||||
Patch0473: 0473-appendedsig-Reads-the-default-DB-keys-from-ELF-Note.patch
|
||||
Patch0474: 0474-appendedsig-The-grub-command-s-trusted-and-distruste.patch
|
||||
Patch0475: 0475-appendedsig-documentation.patch
|
||||
Patch0476: 0476-efi-Add-efitextmode-command-for-getting-setting-the-.patch
|
||||
|
@ -16,7 +16,7 @@
|
||||
Name: grub2
|
||||
Epoch: 1
|
||||
Version: 2.06
|
||||
Release: 107%{?dist}
|
||||
Release: 108%{?dist}
|
||||
Summary: Bootloader with support for Linux, Multiboot and more
|
||||
License: GPLv3+
|
||||
URL: http://www.gnu.org/software/grub/
|
||||
@ -547,6 +547,10 @@ mv ${EFI_HOME}/grub.cfg.stb ${EFI_HOME}/grub.cfg
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed May 21 2025 Nicolas Frayer <nfrayer@redhat.com> - 2.06-108
|
||||
- ieee1275: Appended signature support
|
||||
- Resolves: #RHEL-24742
|
||||
|
||||
* Wed May 14 2025 Nicolas Frayer <nfrayer@redhat.com> - 2.06-107
|
||||
- Remove BLS fake config in case of kernel removal
|
||||
- Resolves: #RHEL-83915
|
||||
|
Loading…
Reference in New Issue
Block a user