On Tue, Sep 30, 2025 at 05:10:05PM +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 <[email protected]>
> ---
> grub-core/Makefile.am | 2 +
> grub-core/Makefile.core.def | 2 +
> grub-core/kern/ieee1275/ieee1275.c | 1 -
> grub-core/kern/ieee1275/init.c | 4 +
> grub-core/kern/powerpc/ieee1275/ieee1275.c | 137 +++++++
> .../kern/powerpc/ieee1275/platform_keystore.c | 344 ++++++++++++++++++
> include/grub/ieee1275/ieee1275.h | 3 +
> include/grub/powerpc/ieee1275/ieee1275.h | 18 +
> .../grub/powerpc/ieee1275/platform_keystore.h | 122 +++++++
> 9 files changed, 632 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 6824a0ee4..853d879a4 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -334,6 +334,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 a81a36f57..c46624f39 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__
> @@ -1043,6 +1045,8 @@ grub_ieee1275_get_secure_boot (void)
> }
> else
> grub_dprintf ("ieee1275", "Secure Boot Disabled\n");
> +
> + grub_pks_keystore_init ();
> }
> #endif /* __powerpc__ */
> grub_addr_t grub_modbase;
> diff --git a/grub-core/kern/powerpc/ieee1275/ieee1275.c
> b/grub-core/kern/powerpc/ieee1275/ieee1275.c
> new file mode 100644
> index 000000000..38cfe4d8d
> --- /dev/null
> +++ b/grub-core/kern/powerpc/ieee1275/ieee1275.c
> @@ -0,0 +1,137 @@
> +/* ieee1275.c - Access the Open Firmware client interface. */
> +/*
> + * GRUB -- GRand Unified Bootloader
> + * Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation,
> Inc.
> + * Copyright (C) 2020, 2021, 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/ieee1275/ieee1275.h>
> +#include <grub/powerpc/ieee1275/ieee1275.h>
> +#include <grub/misc.h>
> +
> +grub_int32_t
> +grub_ieee1275_test (const char *name)
> +{
> + struct test_args
> + {
> + struct grub_ieee1275_common_hdr common;/* The header information like
> interface name, number of inputs and outputs. */
> + grub_ieee1275_cell_t name; /* The interface 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;
> +
> + return 0;
> +}
> +
> +grub_int32_t
> +grub_ieee1275_pks_max_object_size (grub_uint32_t *result)
> +{
> + struct mos_args
> + {
> + struct grub_ieee1275_common_hdr common;/* The header information like
> interface name, number of inputs and outputs. */
> + grub_ieee1275_cell_t size; /* The maximum object size for a
> PKS object. */
> + } 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;
I can imagine the buggy firmware may return 0 here and later you will
call grub_malloc() with this value. And grub_malloc() may not return
NULL in such case... So, I think it would be good if you identify
a minimal value which should be returned by this function. Smaller values
should be treated as an error and the function should return -1.
> + return 0;
> +}
> +
> +grub_int32_t
> +grub_ieee1275_pks_read_object (const grub_uint32_t consumer, const char
> *label,
> + const grub_uint32_t label_len, const
> grub_uint32_t buffer_len,
> + grub_uint8_t *buffer, grub_uint32_t *data_len,
> + grub_uint32_t *policies)
> +{
> + struct pks_read_args
> + {
> + struct grub_ieee1275_common_hdr common; /* The header information like
> interface name, number of inputs and outputs. */
> + grub_ieee1275_cell_t consumer; /* The object belonging to
> consumer with the label. */
> + grub_ieee1275_cell_t label; /* Object label buffer logical
> real address. */
> + grub_ieee1275_cell_t label_len; /* The byte length of the object
> label. */
> + grub_ieee1275_cell_t buffer; /* Output buffer logical real
> address. */
> + grub_ieee1275_cell_t buffer_len; /* Length of the output buffer.
> */
> + grub_ieee1275_cell_t data_len; /* The number of bytes copied to
> the output buffer. */
> + grub_ieee1275_cell_t policies; /* The object policies. */
> + grub_int32_t rc; /* The return code. */
> + } args;
> +
> + INIT_IEEE1275_COMMON (&args.common, "pks-read-object", 5, 3);
> + args.consumer = consumer;
> + args.label_len = label_len;
> + args.buffer_len = buffer_len;
> + args.label = (grub_ieee1275_cell_t) label;
> + args.buffer = (grub_ieee1275_cell_t) buffer;
> +
> + 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 args.rc;
> +}
> +
> +grub_int32_t
> +grub_ieee1275_pks_read_sbvar (const grub_uint32_t sbvar_flags, const
> grub_uint32_t sbvar_type,
> + const grub_uint32_t buffer_len, grub_uint8_t
> *buffer,
> + grub_size_t *data_len)
> +{
> + struct pks_read_sbvar_args
> + {
> + struct grub_ieee1275_common_hdr common; /* The header information like
> interface name, number of inputs and outputs. */
> + grub_ieee1275_cell_t sbvar_flags; /* The sbvar operation flags. */
> + grub_ieee1275_cell_t sbvar_type; /* The sbvar being requested. */
> + grub_ieee1275_cell_t buffer; /* Output buffer logical real
> address. */
> + grub_ieee1275_cell_t buffer_len; /* Length of the Output buffer.
> */
> + grub_ieee1275_cell_t data_len; /* The number of bytes copied to
> the output buffer. */
> + grub_int32_t rc; /* The return code. */
> + } args;
> +
> + INIT_IEEE1275_COMMON (&args.common, "pks-read-sbvar", 4, 2);
> + args.sbvar_flags = sbvar_flags;
> + args.sbvar_type = sbvar_type;
> + args.buffer_len = buffer_len;
> + args.buffer = (grub_ieee1275_cell_t) buffer;
> +
> + if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
> + return -1;
> +
> + if (args.data_len == IEEE1275_CELL_INVALID)
> + return -1;
> +
> + *data_len = args.data_len;
> +
> + return args.rc;
> +}
> 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..715587cde
> --- /dev/null
> +++ b/grub-core/kern/powerpc/ieee1275/platform_keystore.c
> @@ -0,0 +1,344 @@
> +/*
> + * 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>
> +
> +/* PKS consumer type for firmware. */
> +#define PKS_CONSUMER_FW ((grub_uint32_t) 1)
> +
> +/* The maximum object size interface name for a PKS object. */
> +#define PKS_MAX_OBJ_SIZE "pks-max-object-size"
You define a constant here and you use it partially in this patch.
I think at least some of these constants above and below should
be moved to a header which declares functions using them.
> +/* PKS read object label for secure boot version. */
> +#define SB_VERSION_KEY_NAME "SB_VERSION"
> +#define SB_VERSION_KEY_LEN (sizeof (SB_VERSION_KEY_NAME) - 1)
> +
> +/* PKS read secure boot variable request type for db and dbx. */
> +#define PKS_SBVAR_DB ((grub_uint32_t) 1)
> +#define PKS_SBVAR_DBX ((grub_uint32_t) 2)
When you fix these two issues you can add my RB to this patch.
Additionally, as I can see many RBs left as is in many patches
regardless of significant amount of changes to them. So, I need
confirmation from all folks which gave RBs earlier before I will
push the patches as such...
Daniel
_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel