672 lines
21 KiB
Diff
672 lines
21 KiB
Diff
|
From 8ef821ea18ed35f5969b98f2df6a76fefb71b175 Mon Sep 17 00:00:00 2001
|
||
|
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||
|
Date: Wed, 28 Dec 2022 17:49:24 +0530
|
||
|
Subject: [PATCH 2/8] 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 certificates from ESL.
|
||
|
It would be saved in the platform keystore buffer, and
|
||
|
the appendedsig (module) would read it later to extract
|
||
|
the certificate's details.
|
||
|
|
||
|
In the following scenarios, static key mode will be activated:
|
||
|
1. When secure boot is enabled with static
|
||
|
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>
|
||
|
Tested-by: Nageswara Sastry <rnsastry@linux.ibm.com>
|
||
|
---
|
||
|
grub-core/Makefile.am | 1 +
|
||
|
grub-core/Makefile.core.def | 1 +
|
||
|
grub-core/kern/ieee1275/init.c | 12 +-
|
||
|
grub-core/kern/ieee1275/platform_keystore.c | 377 ++++++++++++++++++++
|
||
|
include/grub/platform_keystore.h | 190 ++++++++++
|
||
|
5 files changed, 580 insertions(+), 1 deletion(-)
|
||
|
create mode 100644 grub-core/kern/ieee1275/platform_keystore.c
|
||
|
create mode 100644 include/grub/platform_keystore.h
|
||
|
|
||
|
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||
|
index 9d3d5f519..4630e2ba3 100644
|
||
|
--- a/grub-core/Makefile.am
|
||
|
+++ b/grub-core/Makefile.am
|
||
|
@@ -79,6 +79,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/file.h
|
||
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h
|
||
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h
|
||
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h
|
||
|
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/platform_keystore.h
|
||
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h
|
||
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lockdown.h
|
||
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h
|
||
|
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||
|
index dc639dd24..4ff35afb7 100644
|
||
|
--- a/grub-core/Makefile.core.def
|
||
|
+++ b/grub-core/Makefile.core.def
|
||
|
@@ -170,6 +170,7 @@ kernel = {
|
||
|
ieee1275 = kern/ieee1275/openfw.c;
|
||
|
ieee1275 = term/ieee1275/console.c;
|
||
|
ieee1275 = kern/ieee1275/init.c;
|
||
|
+ ieee1275 = kern/ieee1275/platform_keystore.c;
|
||
|
|
||
|
uboot = disk/uboot/ubootdisk.c;
|
||
|
uboot = kern/uboot/uboot.c;
|
||
|
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||
|
index 38f1f1f6e..bb800b275 100644
|
||
|
--- a/grub-core/kern/ieee1275/init.c
|
||
|
+++ b/grub-core/kern/ieee1275/init.c
|
||
|
@@ -50,6 +50,7 @@
|
||
|
#include <grub/ieee1275/alloc.h>
|
||
|
#endif
|
||
|
#include <grub/lockdown.h>
|
||
|
+#include <grub/platform_keystore.h>
|
||
|
|
||
|
/* The maximum heap size we're going to claim at boot. Not used by sparc. */
|
||
|
#ifdef __i386__
|
||
|
@@ -915,7 +916,16 @@ grub_get_ieee1275_secure_boot (void)
|
||
|
* We only support enforce.
|
||
|
*/
|
||
|
if (rc >= 0 && is_sb >= 2)
|
||
|
- grub_lockdown ();
|
||
|
+ {
|
||
|
+ grub_printf ("secure boot enabled\n");
|
||
|
+ rc = grub_platform_keystore_init ();
|
||
|
+ if (rc != GRUB_ERR_NONE)
|
||
|
+ grub_printf ("Warning: initialization of the platform keystore failed!\n");
|
||
|
+
|
||
|
+ grub_lockdown ();
|
||
|
+ }
|
||
|
+ else
|
||
|
+ grub_printf ("secure boot disabled\n");
|
||
|
}
|
||
|
|
||
|
grub_addr_t grub_modbase;
|
||
|
diff --git a/grub-core/kern/ieee1275/platform_keystore.c b/grub-core/kern/ieee1275/platform_keystore.c
|
||
|
new file mode 100644
|
||
|
index 000000000..976e4e9b5
|
||
|
--- /dev/null
|
||
|
+++ b/grub-core/kern/ieee1275/platform_keystore.c
|
||
|
@@ -0,0 +1,377 @@
|
||
|
+#include <grub/mm.h>
|
||
|
+#include <grub/ieee1275/ieee1275.h>
|
||
|
+#include <grub/types.h>
|
||
|
+#include <grub/misc.h>
|
||
|
+#include <grub/lockdown.h>
|
||
|
+#include <grub/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 -7
|
||
|
+#define PKS_UNPACK_ERROR 0x200
|
||
|
+#define PKS_UNPACK_VERSION_ERROR 0x201
|
||
|
+
|
||
|
+struct pks_timestamp
|
||
|
+{
|
||
|
+ grub_uint16_t year;
|
||
|
+ grub_uint8_t month;
|
||
|
+ grub_uint8_t day;
|
||
|
+ grub_uint8_t hour;
|
||
|
+ grub_uint8_t minute;
|
||
|
+ grub_uint8_t second;
|
||
|
+} GRUB_PACKED;
|
||
|
+
|
||
|
+struct pks_signed_var
|
||
|
+{
|
||
|
+ grub_uint8_t version;
|
||
|
+ struct pks_timestamp time;
|
||
|
+} GRUB_PACKED;
|
||
|
+
|
||
|
+/* Platform Keystore */
|
||
|
+static grub_size_t pks_max_object_size;
|
||
|
+grub_uint8_t grub_use_platform_keystore = 0;
|
||
|
+grub_pks_t grub_platform_keystore = { .use_static_keys = 0, .db = NULL, .dbx = NULL, .db_entries = 0, .dbx_entries = 0 };
|
||
|
+
|
||
|
+/* converts the esl data into the ESL */
|
||
|
+static grub_esl_t *
|
||
|
+grub_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;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * imports the GUID, esd, and its size into the pks sd buffer and
|
||
|
+ * pks sd entries from the EFI signature list.
|
||
|
+ */
|
||
|
+static grub_err_t
|
||
|
+grub_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);
|
||
|
+
|
||
|
+ if (signature != NULL)
|
||
|
+ signature = grub_realloc (signature, (entries + 1) * sizeof (grub_pks_sd_t));
|
||
|
+ else
|
||
|
+ signature = grub_malloc (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_release_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;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * extracts the esd after removing the esl header from esl.
|
||
|
+ */
|
||
|
+static grub_err_t
|
||
|
+grub_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 = grub_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 grub_esd_from_esl (esl_data + offset, esl_size, signature_size, &guid,
|
||
|
+ pks_sd, pks_sd_entries);
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * imports 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
|
||
|
+grub_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 = grub_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;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * unpacking the signed secure boot variable
|
||
|
+ * return error if size too small or version mismatch
|
||
|
+ * discards timestamp, only needed in verifying updates
|
||
|
+ */
|
||
|
+static grub_err_t
|
||
|
+grub_unpack_signed_variable (grub_uint8_t *indata, grub_size_t insize,
|
||
|
+ grub_uint8_t **data, grub_size_t *size)
|
||
|
+{
|
||
|
+ struct pks_signed_var *psv = NULL;
|
||
|
+
|
||
|
+ /* do not permit negative or size 0 data */
|
||
|
+ if (insize <= sizeof (struct pks_signed_var))
|
||
|
+ return PKS_UNPACK_ERROR;
|
||
|
+
|
||
|
+ psv = (struct pks_signed_var *) indata;
|
||
|
+ if (psv->version != 0)
|
||
|
+ return PKS_UNPACK_VERSION_ERROR;
|
||
|
+
|
||
|
+ *data = indata + sizeof (struct pks_signed_var);
|
||
|
+ *size = insize - sizeof (struct pks_signed_var);
|
||
|
+
|
||
|
+ return GRUB_ERR_NONE;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * reads the secure boot version from PKS as an object.
|
||
|
+ * caller must free result
|
||
|
+ */
|
||
|
+static grub_err_t
|
||
|
+grub_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
|
||
|
+grub_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
|
||
|
+grub_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)
|
||
|
+ grub_printf ("Warning: doesn't have PKS support!\n");
|
||
|
+ else
|
||
|
+ {
|
||
|
+ rc = grub_ieee1275_pks_max_object_size (&pks_max_object_size);
|
||
|
+ if (rc != GRUB_ERR_NONE)
|
||
|
+ grub_printf ("Warning: PKS support is there but it has zero objects!\n");
|
||
|
+ }
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * retrieves the secure boot variable from PKS, unpacks it, reads the esd
|
||
|
+ * from ESL, and stores the information in the pks sd buffer.
|
||
|
+ */
|
||
|
+static grub_err_t
|
||
|
+grub_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 *data = NULL, *esl_data = NULL;
|
||
|
+ grub_size_t data_len = 0, esl_data_size = 0;
|
||
|
+
|
||
|
+ rc = grub_sbvar_from_pks (sbvarflags, sbvartype, &data, &data_len);
|
||
|
+ /*
|
||
|
+ * 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
|
||
|
+ {
|
||
|
+ rc = grub_unpack_signed_variable (data, data_len, &esl_data, &esl_data_size);
|
||
|
+ if (rc != GRUB_ERR_NONE)
|
||
|
+ rc = grub_error (rc, "unpacking of signed variable %s structure (%d)",
|
||
|
+ (sbvartype == DB ? "db" : "dbx"), rc);
|
||
|
+ else
|
||
|
+ rc = grub_pks_sd_from_esl ((const grub_uint8_t *) esl_data, esl_data_size,
|
||
|
+ pks_sd, pks_sd_entries);
|
||
|
+ }
|
||
|
+
|
||
|
+ grub_free (data);
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+/* reads secure boot version (SB_VERSION) */
|
||
|
+static grub_err_t
|
||
|
+grub_secure_boot_version (void)
|
||
|
+{
|
||
|
+ grub_err_t rc = GRUB_ERR_NONE;
|
||
|
+ grub_uint8_t *data = NULL;
|
||
|
+ grub_size_t len = 0, policy = 0;
|
||
|
+
|
||
|
+ rc = grub_sbversion_from_pks (&data, &len, &policy);
|
||
|
+ if (rc != GRUB_ERR_NONE)
|
||
|
+ grub_printf ("Warning: SB version read failed! (%d)\n", rc);
|
||
|
+ else if (len != 1 || (*data != 1 && *data != 0))
|
||
|
+ {
|
||
|
+ grub_printf ("Warning: found unexpected SB version! (%d)\n", *data);
|
||
|
+ rc = GRUB_ERR_INVALID_COMMAND;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (rc != GRUB_ERR_NONE)
|
||
|
+ {
|
||
|
+ grub_printf ("Warning: switch to static key!\n");
|
||
|
+ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
|
||
|
+ grub_fatal ("Secure Boot locked down");
|
||
|
+ }
|
||
|
+ else
|
||
|
+ grub_use_platform_keystore = *data;
|
||
|
+
|
||
|
+ grub_free (data);
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
+
|
||
|
+/* releasing allocated memory */
|
||
|
+void
|
||
|
+grub_release_platform_keystore (void)
|
||
|
+{
|
||
|
+ grub_size_t i = 0;
|
||
|
+
|
||
|
+ for (i = 0; i < grub_platform_keystore.db_entries; i++)
|
||
|
+ grub_free (grub_platform_keystore.db[i].data);
|
||
|
+
|
||
|
+ for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
|
||
|
+ grub_free (grub_platform_keystore.dbx[i].data);
|
||
|
+
|
||
|
+ grub_free (grub_platform_keystore.db);
|
||
|
+ grub_free (grub_platform_keystore.dbx);
|
||
|
+ grub_memset (&grub_platform_keystore, 0x00, sizeof (grub_pks_t));
|
||
|
+}
|
||
|
+
|
||
|
+/* initialization of the Platform Keystore */
|
||
|
+grub_err_t
|
||
|
+grub_platform_keystore_init (void)
|
||
|
+{
|
||
|
+ grub_err_t rc = GRUB_ERR_NONE;
|
||
|
+
|
||
|
+ grub_printf ("trying to load Platform Keystore\n");
|
||
|
+
|
||
|
+ rc = grub_is_support_pks ();
|
||
|
+ if (rc != GRUB_ERR_NONE)
|
||
|
+ {
|
||
|
+ grub_printf ("Warning: switch to static key!\n");
|
||
|
+ return rc;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* SB_VERSION */
|
||
|
+ rc = grub_secure_boot_version ();
|
||
|
+ if (rc != GRUB_ERR_NONE)
|
||
|
+ return rc;
|
||
|
+
|
||
|
+ if (grub_use_platform_keystore)
|
||
|
+ {
|
||
|
+ grub_memset (&grub_platform_keystore, 0x00, sizeof (grub_pks_t));
|
||
|
+ /* DB */
|
||
|
+ rc = grub_secure_boot_variables (0, DB, &grub_platform_keystore.db,
|
||
|
+ &grub_platform_keystore.db_entries);
|
||
|
+ if ((int)rc == PKS_OBJECT_NOT_FOUND)
|
||
|
+ {
|
||
|
+ rc = GRUB_ERR_NONE;
|
||
|
+ /* DB variable won't be available by default in PKS, So, it will loads the Default Keys from ELF Note */
|
||
|
+ grub_platform_keystore.use_static_keys = 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (rc == GRUB_ERR_NONE)
|
||
|
+ {
|
||
|
+ /* DBX */
|
||
|
+ rc = grub_secure_boot_variables (0, DBX, &grub_platform_keystore.dbx,
|
||
|
+ &grub_platform_keystore.dbx_entries);
|
||
|
+ if ((int)rc == PKS_OBJECT_NOT_FOUND)
|
||
|
+ {
|
||
|
+ grub_printf ("Warning: dbx is not found!\n");
|
||
|
+ rc = GRUB_ERR_NONE;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ }
|
||
|
+
|
||
|
+ if (rc != GRUB_ERR_NONE)
|
||
|
+ grub_release_platform_keystore ();
|
||
|
+
|
||
|
+ return rc;
|
||
|
+}
|
||
|
diff --git a/include/grub/platform_keystore.h b/include/grub/platform_keystore.h
|
||
|
new file mode 100644
|
||
|
index 000000000..8cc4266c9
|
||
|
--- /dev/null
|
||
|
+++ b/include/grub/platform_keystore.h
|
||
|
@@ -0,0 +1,190 @@
|
||
|
+#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_UUID_SIZE 16
|
||
|
+#define GRUB_MAX_HASH_SIZE 64
|
||
|
+
|
||
|
+typedef struct grub_uuid grub_uuid_t;
|
||
|
+typedef struct grub_esd grub_esd_t;
|
||
|
+typedef struct grub_esl grub_esl_t;
|
||
|
+
|
||
|
+/* The structure of a UUID.*/
|
||
|
+struct grub_uuid
|
||
|
+{
|
||
|
+ grub_uint8_t b[GRUB_UUID_SIZE];
|
||
|
+};
|
||
|
+
|
||
|
+/* 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;
|
||
|
+
|
||
|
+/* 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;
|
||
|
+
|
||
|
+/*
|
||
|
+ * The GRUB_PKS_CERT_* is derived from the following files referred from edk2-staging[1] repo
|
||
|
+ * of tianocore
|
||
|
+ *
|
||
|
+ * MdePkg/Include/Guid/ImageAuthentication.h
|
||
|
+ *
|
||
|
+ * [1] https://github.com/tianocore/edk2-staging
|
||
|
+ */
|
||
|
+
|
||
|
+#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 \
|
||
|
+ } \
|
||
|
+ }
|
||
|
+
|
||
|
+#define GRUB_PKS_CERT_SHA1_GUID \
|
||
|
+ (grub_uuid_t) \
|
||
|
+ { \
|
||
|
+ { \
|
||
|
+ 0x12, 0xa5, 0x6c, 0x82, 0x10, 0xcf, \
|
||
|
+ 0xc9, 0x4a, 0xb1, 0x87, 0xbe, 0x1, \
|
||
|
+ 0x49, 0x66, 0x31, 0xbd \
|
||
|
+ } \
|
||
|
+ }
|
||
|
+
|
||
|
+#define GRUB_PKS_CERT_SHA224_GUID \
|
||
|
+ (grub_uuid_t) \
|
||
|
+ { \
|
||
|
+ { \
|
||
|
+ 0x33, 0x52, 0x6e, 0xb, 0x5c, 0xa6, \
|
||
|
+ 0xc9, 0x44, 0x94, 0x7, 0xd9, 0xab, \
|
||
|
+ 0x83, 0xbf, 0xc8, 0xbd \
|
||
|
+ } \
|
||
|
+ }
|
||
|
+
|
||
|
+#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 \
|
||
|
+ } \
|
||
|
+ }
|
||
|
+
|
||
|
+#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 \
|
||
|
+ } \
|
||
|
+ }
|
||
|
+
|
||
|
+#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 \
|
||
|
+ } \
|
||
|
+ }
|
||
|
+
|
||
|
+#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 \
|
||
|
+ } \
|
||
|
+ }
|
||
|
+
|
||
|
+#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 \
|
||
|
+ } \
|
||
|
+ }
|
||
|
+
|
||
|
+#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_uint8_t use_static_keys;
|
||
|
+ 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_platform_keystore_init (void);
|
||
|
+/* releasing allocated memory */
|
||
|
+void EXPORT_FUNC(grub_release_platform_keystore) (void);
|
||
|
+extern grub_uint8_t EXPORT_VAR(grub_use_platform_keystore);
|
||
|
+extern grub_pks_t EXPORT_VAR(grub_platform_keystore);
|
||
|
+
|
||
|
+#else
|
||
|
+
|
||
|
+#define grub_use_platform_keystore 0
|
||
|
+grub_pks_t grub_platform_keystore = {0, NULL, NULL, 0, 0};
|
||
|
+void grub_release_platform_keystore (void);
|
||
|
+
|
||
|
+#endif
|
||
|
+
|
||
|
+#endif
|
||
|
--
|
||
|
2.47.0
|
||
|
|