On Mon, Aug 25, 2025 at 04:38:34PM +0530, Sudhakar Kuppusamy wrote: > 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. > > If PKS is enabled, it will read secure boot variables such as db and dbx > from PKS and extract EFI Signature List (ESL) from it. The ESLs 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 management mode will be activated: > 1. When Secure Boot is enabled with static key management mode > 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: Key Management Mode > 1 - Enable dynamic key management mode. Read the db and dbx variables from > PKS, > and use them for signature verification. > 0 - Enable static key management mode. Read keys from the GRUB ELF Note and > use it for signature verification. > > Signed-off-by: Sudhakar Kuppusamy <sudha...@linux.ibm.com> > --- > grub-core/Makefile.am | 2 + > grub-core/Makefile.core.def | 2 + > grub-core/kern/ieee1275/ieee1275.c | 1 - > grub-core/kern/ieee1275/init.c | 7 + > grub-core/kern/powerpc/ieee1275/ieee1275.c | 139 ++++++++ > .../kern/powerpc/ieee1275/platform_keystore.c | 328 ++++++++++++++++++ > include/grub/ieee1275/ieee1275.h | 3 + > include/grub/powerpc/ieee1275/ieee1275.h | 20 ++ > .../grub/powerpc/ieee1275/platform_keystore.h | 139 ++++++++ > 9 files changed, 640 insertions(+), 1 deletion(-) > create mode 100644 grub-core/kern/powerpc/ieee1275/ieee1275.c > 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 e50db8106..8577462d5 100644 > --- a/grub-core/Makefile.am > +++ b/grub-core/Makefile.am > @@ -246,6 +246,8 @@ KERNEL_HEADER_FILES += > $(top_srcdir)/include/grub/ieee1275/alloc.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/ieee1275.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 d91694de0..16cdbadcb 100644 > --- a/grub-core/Makefile.core.def > +++ b/grub-core/Makefile.core.def > @@ -332,6 +332,8 @@ kernel = { > powerpc_ieee1275 = kern/powerpc/dl.c; > powerpc_ieee1275 = kern/powerpc/compiler-rt.S; > powerpc_ieee1275 = kern/lockdown.c; > + powerpc_ieee1275 = kern/powerpc/ieee1275/ieee1275.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/ieee1275.c > b/grub-core/kern/ieee1275/ieee1275.c > index 36ca2dbfc..afa37a9f0 100644 > --- a/grub-core/kern/ieee1275/ieee1275.c > +++ b/grub-core/kern/ieee1275/ieee1275.c > @@ -23,7 +23,6 @@ > > #define IEEE1275_PHANDLE_INVALID ((grub_ieee1275_cell_t) -1) > #define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_cell_t) 0) > -#define IEEE1275_CELL_INVALID ((grub_ieee1275_cell_t) -1) > > > > diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c > index 132d027c7..46bfaa9a8 100644 > --- a/grub-core/kern/ieee1275/init.c > +++ b/grub-core/kern/ieee1275/init.c > @@ -51,6 +51,8 @@ > #endif > #if defined(__powerpc__) > #include <grub/lockdown.h> > +#include <grub/powerpc/ieee1275/ieee1275.h> > +#include <grub/powerpc/ieee1275/platform_keystore.h> > #endif > > #ifdef __powerpc__ > @@ -1007,6 +1009,7 @@ grub_parse_cmdline (void) > static void > grub_ieee1275_get_secure_boot (void) > { > + grub_err_t err; > grub_ieee1275_phandle_t root; > grub_uint32_t sb_mode = GRUB_SB_DISABLED; > int rc; > @@ -1044,6 +1047,10 @@ grub_ieee1275_get_secure_boot (void) > } > else > grub_dprintf ("ieee1275", "Secure Boot Disabled\n"); > + > + err = grub_pks_keystore_init (); > + if (err != GRUB_ERR_NONE) > + grub_error (err, "initialization of the Platform KeyStore failed\n");
This should be a part of grub_pks_keystore_init(). > } > #endif /* __powerpc__ */ > Please drop this empty line. [...] > 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 000000000..eeb569fd1 > --- /dev/null > +++ b/grub-core/kern/powerpc/ieee1275/platform_keystore.c > @@ -0,0 +1,328 @@ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2024 Free Software Foundation, Inc. > + * Copyright (C) 2022, 2023, 2024, 2025 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/types.h> > +#include <grub/misc.h> > +#include <grub/lockdown.h> > +#include <grub/ieee1275/ieee1275.h> > +#include <grub/powerpc/ieee1275/ieee1275.h> > +#include <grub/powerpc/ieee1275/platform_keystore.h> > + > +#if __GNUC__ >= 9 > +#pragma GCC diagnostic ignored "-Waddress-of-packed-member" > +#endif Is it really needed? If yes it begs for a comment. > +/* PKS consumer type for firmware. */ > +#define PKS_CONSUMER_FW ((grub_uint8_t) 1) > + > +/* The maximum object size interface name for a PKS object. */ > +#define PKS_MAX_OBJ_SIZE ((grub_uint8_t *) "pks-max-object-size") > + > +/* PKS read object lable for secure boot version. */ > +#define SB_VERSION_KEY_NAME ((grub_uint8_t *) "SB_VERSION") > +#define SB_VERSION_KEY_LEN ((grub_size_t) 10) #define SB_VERSION_KEY_LEN (sizeof (SB_VERSION_KEY_NAME) - 1) > +/* PKS read secure boot variable request type for db and dbx. */ > +#define DB ((grub_uint8_t) 1) > +#define DBX ((grub_uint8_t) 2) > + > +static grub_size_t pks_max_object_size; > + > +/* > + * Platform KeyStore db and dbx, pks_supported flag to indicate the > availability > + * of PSK support and use_keystore flag to indicate the key management. s/key management/key management mode in the GRUB/ > + * pks_supported: > + * False: No PKS support. This is default. > + * True: PKS support available. The pks_supported member does not make a lot of sense for me. It makes code more complicated for nothing. In real we care about use_keystore only. > + * use_keystore: > + * False: Static key management (use built-in Keys). This is default. > + * True: Dynamic key management (use Platform KeySotre). > + */ > +grub_pks_t grub_pks_keystore = { .db = NULL, .dbx = NULL, .db_entries = 0, > .dbx_entries = 0, > + .use_keystore = false, .pks_supported = > false}; > + > +/* > + * Import the Globally Unique Identifier (GUID), EFI Signature Database > (ESD), > + * and its size into the PKS Signature Database (SD) (i.e pks_sd buffer) and > pks_sd entries > + * from the EFI Signature List (ESL). It should be made clear it is copied from the platform PKS into the pks_sd in the GRUB. Otherwise the comment and whole code in this patch is confusing. > + */ > +static grub_err_t > +_esl_to_esd (const grub_uint8_t *esl_data, grub_size_t esl_size, > + const grub_size_t signature_size, const grub_packed_guid_t > *guid, > + grub_pks_sd_t **pks_sd, grub_uint32_t *pks_sd_entries) > +{ > + grub_esd_t *esd; > + grub_pks_sd_t *signature = *pks_sd; > + grub_uint32_t entries = *pks_sd_entries; > + grub_size_t data_size, 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->signature_data, 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; > +} [...] > +/* > + * Test the availability of PKS support. If PKS support is avaialble and > + * objects present, it reads the secure boot version (SB_VERSION) from PKS. > + * > + * SB_VERSION: Key Management Mode > + * 1 - Enable dynamic key management mode. Read the db and dbx variables > from PKS, > + and use them for signature verification. > + * 0 - Enable static key management mode. Read keys from the GRUB ELF Note > and > + * use it for signature verification. > + */ > +static grub_err_t > +is_pks_present (void) This function should return bool. > +{ > + grub_err_t err; > + grub_int32_t rc; > + grub_ieee1275_cell_t missing = 0; > + grub_uint8_t *data = NULL; > + grub_uint32_t len = 0, policy = 0; > + > + rc = grub_ieee1275_test (PKS_MAX_OBJ_SIZE, &missing); > + if (rc < 0 || missing == IEEE1275_CELL_INVALID) > + return 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 < 0) > + return grub_error (GRUB_ERR_BAD_NUMBER, "PKS support is there but > it has zero objects\n"); > + } > + > + grub_pks_keystore.pks_supported = true; We do not care... > + err = read_sbversion_from_pks (&data, &len, &policy); > + if (err == GRUB_ERR_NONE && (len != 1 || (*data >= 2))) > + { > + grub_free (data); > + return grub_error (GRUB_ERR_BAD_NUMBER, "found unexpected SB version > (%d)\n", *data); > + } > + else if (*data) > + grub_pks_keystore.use_keystore = true; This should happen in the grub_pks_keystore_init(). > + grub_free (data); > + > + return err; > +} > + > +/* Free allocated memory. */ > +void > +grub_pks_free_keystore (void) > +{ > + grub_size_t i; > + > + 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 return void... > +grub_pks_keystore_init (void) > +{ > + grub_err_t rc; > + > + grub_dprintf ("ieee1275", "trying to load Platform KeyStore\n"); > + > + rc = is_pks_present (); if (is_pks_present () == false) { grub_dprintf ("ieee1275", "Platform PKS is not available\n"); return; } > + if (rc != GRUB_ERR_NONE) > + { > + grub_dprintf ("ieee1275", "switch to static key\n"); > + return rc; > + } > + > + if (grub_pks_keystore.pks_supported == true) > + { > + grub_memset (&grub_pks_keystore, 0, sizeof (grub_pks_t)); > + /* Read db from PKS. */ > + rc = read_sbvar_from_pks (0, DB, &grub_pks_keystore.db, > &grub_pks_keystore.db_entries); > + if (rc == GRUB_ERR_NONE) > + { > + /* Read dbx from PKS. */ > + rc = read_sbvar_from_pks (0, DBX, &grub_pks_keystore.dbx, > &grub_pks_keystore.dbx_entries); > + if (rc == GRUB_ERR_UNKNOWN_COMMAND) > + rc = GRUB_ERR_NONE; > + } > + > + if (rc != GRUB_ERR_NONE) > + grub_pks_free_keystore (); > + } grub_pks_keystore.use_keystore = true; > + 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 000000000..8b6ba2e5f > --- /dev/null > +++ b/include/grub/powerpc/ieee1275/platform_keystore.h > +#if defined(__powerpc__) > + > +/* > + * Platform KeyStore db and dbx, pks_supported flag to indicate the > availability > + * of PSK support and use_keystore flag to indicate the key management. > + * > + * pks_supported: > + * False: No PKS support. This is default. > + * True: PKS support available. > + * > + * use_keystore: > + * False: Static key management (use built-in Keys). This is default. > + * True: Dynamic key management (use Platform KeySotre). > + */ > +extern grub_pks_t EXPORT_VAR (grub_pks_keystore); > + > +/* Initialization of the Platform Keystore. */ > +extern grub_err_t > +grub_pks_keystore_init (void); > + > +/* Free allocated memory. */ > +extern void > +EXPORT_FUNC (grub_pks_free_keystore) (void); > + > +#else > + > +grub_pks_t grub_pks_keystore; This clearly shows it should not be a global variable. You should have a function which returns pointer to PKS or NULL. And even this makes use_keystore usage questionable... > +static inline void > +grub_pks_free_keystore (void) I am not convinced this function should be called of outside platform_keystore.c above. > +{ > + Please drop this empty line if this function is really needed. > +} Daniel _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel