Thank you Srish, will fix it on v11.

Thanks,
Sudhakar

> On 11 Sep 2025, at 1:24 PM, Srish Srinivasan <[email protected]> wrote:
> 
> 
> On 9/9/25 5:15 PM, 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    | 139 +++++++
>>  .../kern/powerpc/ieee1275/platform_keystore.c | 346 ++++++++++++++++++
>>  include/grub/ieee1275/ieee1275.h              |   3 +
>>  include/grub/powerpc/ieee1275/ieee1275.h      |  18 +
>>  .../grub/powerpc/ieee1275/platform_keystore.h | 126 +++++++
>>  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 d5edc6b03..b63f6decf 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..5ddad4ab4
>> --- /dev/null
>> +++ b/grub-core/kern/powerpc/ieee1275/ieee1275.c
>> @@ -0,0 +1,139 @@
>> +/* 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 grub_uint8_t *name, grub_ieee1275_cell_t *missing)
>> +{
>> +  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;
>> +
>> +  *missing = args.missing;
>> +
>> +  return 0;
>> +}
>> +
>> +grub_int32_t
>> +grub_ieee1275_pks_max_object_size (grub_ieee1275_cell_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;
>> +
>> +  return 0;
>> +}
>> +
>> +grub_int32_t
>> +grub_ieee1275_pks_read_object (const grub_uint8_t consumer, const 
>> grub_uint8_t *label,
>> +                               const grub_size_t label_len, const 
>> grub_size_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 = (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 args.rc;
>> +}
>> +
>> +grub_int32_t
>> +grub_ieee1275_pks_read_sbvar (const grub_uint8_t sbvar_flags, const 
>> grub_uint8_t sbvar_type,
>> +                              const grub_size_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 = (grub_ieee1275_cell_t) sbvar_flags;
>> +  args.sbvar_type = (grub_ieee1275_cell_t) sbvar_type;
>> +  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 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..71a3d261e
>> --- /dev/null
>> +++ b/grub-core/kern/powerpc/ieee1275/platform_keystore.c
>> @@ -0,0 +1,346 @@
>> +/*
>> + *  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>
>> +
>> +/*
>> + * The grub_esl_t, grub_esd_t and grub_pks_* has "packed" members,
>> + * and GCC >= 9 gives a unaligned pointer error with the
>> + * "-Waddress-of-packed-member" flag. So, we are ignoring this flag here.
>> + */
>> +#if __GNUC__ >= 9
>> +#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
>> +#endif
>> +
>> +/* 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")
> It should be
> #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 DB                   ((grub_uint8_t) 1)
>> +#define DBX                  ((grub_uint8_t) 2)
>> +
>> +static grub_size_t pks_max_object_size;
>> +
>> +/* Platform KeyStore db and dbx. */
>> +static grub_pks_t pks_keystore = { .db = NULL, .dbx = NULL, .db_entries = 0,
>> +                                   .dbx_entries = 0};
>> +/*
>> + * pks_use_keystore: Key Management Modes
>> + * False: Static key management (use built-in Keys). This is default.
>> + * True: Dynamic key management (use Platform KeySotre).
>> + */
>> +static bool pks_use_keystore = false;
>> +
>> +/*
>> + * Reads the Globally Unique Identifier (GUID), EFI Signature Database 
>> (ESD),
>> + * and its size from the Platform KeyStore EFI Signature List (ESL), then
>> + * stores them into the PKS Signature Database (SD) (i.e., pks_sd buffer
>> + * and pks_sd entries) in the GRUB.
>> + */
>> +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;
>> +}
>> +
>> +/* 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_uint32_t *pks_sd_entries)
>> +{
>> +  grub_packed_guid_t guid;
>> +  grub_esl_t *esl;
>> +  grub_size_t offset, esl_size, signature_size, signature_header_size;
>> +
>> +  /* Convert the ESL data into the ESL. */
>> +  esl = (grub_esl_t *) esl_data;
>> +  if (*next_esl < sizeof (grub_esl_t) || esl == NULL)
>> +    return grub_error (GRUB_ERR_BUG, "invalid ESL");
>> +
>> +  esl_size = grub_le_to_cpu32 (esl->signature_list_size);
>> +  signature_header_size = grub_le_to_cpu32 (esl->signature_header_size);
>> +  signature_size = grub_le_to_cpu32 (esl->signature_size);
>> +  grub_memcpy (&guid, &esl->signature_type, sizeof (grub_packed_guid_t));
>> +
>> +  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 _esl_to_esd (esl_data + offset, esl_size, signature_size, &guid,
>> +                      pks_sd, pks_sd_entries);
>> +}
>> +
>> +/*
>> + * Import the EFI Signature Database (ESD) 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_uint32_t *pks_sd_entries)
>> +{
>> +  grub_err_t rc;
>> +  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_uint32_t *outlen, 
>> grub_uint32_t *policy)
>> +{
>> +  grub_int32_t rc;
>> +
>> +  *out = grub_malloc (pks_max_object_size);
>> +  if (*out == NULL)
>> +    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
>> +
>> +  rc = grub_ieee1275_pks_read_object (PKS_CONSUMER_FW, SB_VERSION_KEY_NAME,
>> +                                      SB_VERSION_KEY_LEN, 
>> pks_max_object_size, *out,
>> +                                      outlen, policy);
>> +  if (rc < 0)
>> +    return grub_error (GRUB_ERR_READ_ERROR, "SB version read failed 
>> (%d)\n", rc);
>> +
>> +  return GRUB_ERR_NONE;
>> +}
>> +
>> +/*
>> + * Reads 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_sbvar_from_pks (const grub_uint8_t sbvarflags, const grub_uint8_t 
>> sbvartype,
>> +                     grub_pks_sd_t **pks_sd, grub_uint32_t *pks_sd_entries)
>> +{
>> +  grub_int32_t rc;
>> +  grub_err_t err = GRUB_ERR_NONE;
>> +  grub_uint8_t *esl_data = NULL;
>> +  grub_size_t esl_data_size = 0;
>> +
>> +  esl_data = grub_malloc (pks_max_object_size);
>> +  if (esl_data == NULL)
>> +    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
>> +
>> +  rc = grub_ieee1275_pks_read_sbvar (sbvarflags, sbvartype, 
>> pks_max_object_size,
>> +                                     esl_data, &esl_data_size);
>> +  if (rc == IEEE1275_CELL_NOT_FOUND)
>> +    {
>> +      err =  grub_error (GRUB_ERR_UNKNOWN_COMMAND, "secure boot variable %s 
>> not found (%d)",
>> +                         ((sbvartype == DB) ? "db" : "dbx"), rc);
>> +      goto fail;
>> +    }
>> +  else if (rc < 0)
>> +    {
>> +      err = grub_error (GRUB_ERR_READ_ERROR, "secure boot variable %s 
>> reading (%d)",
>> +                        ((sbvartype == DB) ? "db" : "dbx"), rc);
>> +      goto fail;
>> +    }
>> +
>> +  if (esl_data_size > 0)
>> +    err = pks_sd_from_esl (esl_data, esl_data_size, pks_sd, pks_sd_entries);
>> +  else
>> +    err = GRUB_ERR_UNKNOWN_COMMAND;
>> +
>> + fail:
>> +  grub_free (esl_data);
>> +
>> +  return err;
>> +}
>> +
>> +/*
>> + * 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 bool
>> +is_pks_present (void)
>> +{
>> +  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;
>> +  bool ret = false;
>> +
>> +  rc = grub_ieee1275_test (PKS_MAX_OBJ_SIZE, &missing);
>> +  if (rc < 0 || missing == IEEE1275_CELL_INVALID)
> "missing == IEEE1275_CELL_INVALID" is already done grub_ieee1275_test
>> +    {
>> +      grub_error (GRUB_ERR_BAD_FIRMWARE, "firmware doesn't have PKS 
>> support\n");
>> +      return ret;
>> +    }
>> +  else
>> +    {
>> +      rc = grub_ieee1275_pks_max_object_size (&pks_max_object_size);
>> +      if (rc < 0)
>> +        {
>> +          grub_error (GRUB_ERR_BAD_NUMBER, "PKS support is there but it has 
>> zero objects\n");
>> +          return ret;
>> +        }
>> +    }
>> +
>> +  err = read_sbversion_from_pks (&data, &len, &policy);
>> +  if (err == GRUB_ERR_NONE && (len != 1 || (*data >= 2)))
>> +    {
>> +      grub_free (data);
>> +      grub_error (GRUB_ERR_BAD_NUMBER, "found unexpected SB version 
>> (%d)\n", *data);
>> +      return ret;
>> +    }
> This check should be handled in read_sbversion_from_pks
> Here, you can check as follows:
> 
> if (err != GRUB_ERR_NONE)
> {
>      grub_free (data);
>      return ret;
> }
> 
> 
> Thanks,
> Srish
>> +
>> +  /*
>> +   * If *data == 1, use dynamic key management and read the keys from the 
>> PKS.
>> +   * Else, use static key management and read the keys from the GRUB ELF 
>> Note.
>> +   */
>> +  ret = ((*data == 1) ? true : false);
>> +
>> +  grub_free (data);
>> +
>> +  return ret;
>> +}
>> +
>> +/* Free allocated memory. */
>> +void
>> +grub_pks_tmp_free (void)
>> +{
>> +  grub_size_t i;
>> +
>> +  for (i = 0; i < pks_keystore.db_entries; i++)
>> +    grub_free (pks_keystore.db[i].data);
>> +
>> +  for (i = 0; i < pks_keystore.dbx_entries; i++)
>> +    grub_free (pks_keystore.dbx[i].data);
>> +
>> +  grub_free (pks_keystore.db);
>> +  grub_free (pks_keystore.dbx);
>> +  grub_memset (&pks_keystore, 0, sizeof (grub_pks_t));
>> +}
>> +
>> +grub_pks_t *
>> +grub_pks_get_keystore (void)
>> +{
>> +  /* If dynamic key management mode is enabled, use PKS keystore. */
>> +  if (pks_use_keystore == true)
>> +    return &pks_keystore;
>> +
>> +  return NULL;
>> +}
>> +
>> +/* Initialization of the Platform KeyStore. */
>> +void
>> +grub_pks_keystore_init (void)
>> +{
>> +  grub_err_t rc;
>> +
>> +  grub_dprintf ("ieee1275", "trying to load Platform KeyStore\n");
>> +
>> +  if (is_pks_present () == false)
>> +    {
>> +      grub_dprintf ("ieee1275", "Platform PKS is not available\n");
>> +      return;
>> +    }
>> +
>> +  /* Read db from PKS. */
>> +  rc = read_sbvar_from_pks (0, DB, &pks_keystore.db, 
>> &pks_keystore.db_entries);
>> +  if (rc == GRUB_ERR_NONE)
>> +    {
>> +      /* Read dbx from PKS. */
>> +      rc = read_sbvar_from_pks (0, DBX, &pks_keystore.dbx, 
>> &pks_keystore.dbx_entries);
>> +      if (rc == GRUB_ERR_UNKNOWN_COMMAND)
>> +        rc = GRUB_ERR_NONE;
>> +    }
>> +
>> +  if (rc != GRUB_ERR_NONE)
>> +    grub_pks_tmp_free ();
>> +
>> +  pks_use_keystore = true;
>> +}
>> diff --git a/include/grub/ieee1275/ieee1275.h 
>> b/include/grub/ieee1275/ieee1275.h
>> index c445d0499..157ed57be 100644
>> --- a/include/grub/ieee1275/ieee1275.h
>> +++ b/include/grub/ieee1275/ieee1275.h
>> @@ -24,6 +24,9 @@
>>  #include <grub/types.h>
>>  #include <grub/machine/ieee1275.h>
>>  +#define IEEE1275_CELL_INVALID          ((grub_ieee1275_cell_t) -1)
>> +#define IEEE1275_CELL_NOT_FOUND        ((grub_int32_t) -7)
>> +
>>  #define GRUB_IEEE1275_CELL_FALSE       ((grub_ieee1275_cell_t) 0)
>>  #define GRUB_IEEE1275_CELL_TRUE        ((grub_ieee1275_cell_t) -1)
>>  diff --git a/include/grub/powerpc/ieee1275/ieee1275.h 
>> b/include/grub/powerpc/ieee1275/ieee1275.h
>> index 4eb207018..00e5399bc 100644
>> --- a/include/grub/powerpc/ieee1275/ieee1275.h
>> +++ b/include/grub/powerpc/ieee1275/ieee1275.h
>> @@ -28,4 +28,22 @@ typedef grub_uint32_t grub_ieee1275_cell_t;
>>  #define PRIxGRUB_IEEE1275_CELL_T PRIxGRUB_UINT32_T
>>  #define PRIuGRUB_IEEE1275_CELL_T PRIuGRUB_UINT32_T
>>  +#ifdef __powerpc__
>> +extern grub_int32_t
>> +grub_ieee1275_test (const grub_uint8_t *name, grub_ieee1275_cell_t 
>> *missing);
>> +
>> +extern grub_int32_t
>> +grub_ieee1275_pks_max_object_size (grub_ieee1275_cell_t *result);
>> +
>> +extern grub_int32_t
>> +grub_ieee1275_pks_read_object (const grub_uint8_t consumer, const 
>> grub_uint8_t *label,
>> +                               const grub_size_t label_len, const 
>> grub_size_t buffer_len,
>> +                               grub_uint8_t *buffer, grub_uint32_t 
>> *data_len,
>> +                               grub_uint32_t *policies);
>> +
>> +extern grub_int32_t
>> +grub_ieee1275_pks_read_sbvar (const grub_uint8_t sbvar_flags, const 
>> grub_uint8_t sbvar_type,
>> +                              const grub_uint32_t buffer_len, grub_uint8_t 
>> *buffer,
>> +                              grub_size_t *data_len);
>> +#endif /* __powerpc__ */
>>  #endif /* ! GRUB_IEEE1275_MACHINE_HEADER */
>> diff --git a/include/grub/powerpc/ieee1275/platform_keystore.h 
>> b/include/grub/powerpc/ieee1275/platform_keystore.h
>> new file mode 100644
>> index 000000000..b18bd4688
>> --- /dev/null
>> +++ b/include/grub/powerpc/ieee1275/platform_keystore.h
>> @@ -0,0 +1,126 @@
>> +/*
>> + * 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 2022, 2023, 2024, 2025 IBM Corp.
>> + */
>> +
>> +#ifndef PLATFORM_KEYSTORE_HEADER
>> +#define PLATFORM_KEYSTORE_HEADER    1
>> +
>> +#include <grub/symbol.h>
>> +#include <grub/mm.h>
>> +#include <grub/types.h>
>> +
>> +/*
>> + * 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_packed_guid_t signature_owner;
>> +  /* The format of the signature is defined by the SignatureType. */
>> +  grub_uint8_t signature_data[];
>> +} GRUB_PACKED;
>> +typedef struct grub_esd grub_esd_t;
>> +
>> +/*
>> + * 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_packed_guid_t signature_type;
>> +  /* Total size of the signature list, including this header. */
>> +  grub_uint32_t signature_list_size;
>> +  /*
>> +   * Size of the signature header which precedes
>> +   * the array of signatures.
>> +   */
>> +  grub_uint32_t signature_header_size;
>> +  /* Size of each signature.*/
>> +  grub_uint32_t signature_size;
>> +} GRUB_PACKED;
>> +typedef struct grub_esl grub_esl_t;
>> +
>> +/* The structure of a PKS Signature Database (SD). */
>> +struct grub_pks_sd
>> +{
>> +  grub_packed_guid_t guid; /* Signature type. */
>> +  grub_uint8_t *data;      /* Signature data. */
>> +  grub_size_t data_size;   /* Size of signature data. */
>> +} GRUB_PACKED;
>> +typedef struct grub_pks_sd grub_pks_sd_t;
>> +
>> +/* The structure of a Platform KeyStore (PKS). */
>> +struct grub_pks
>> +{
>> +  grub_pks_sd_t *db;        /* Signature database. */
>> +  grub_pks_sd_t *dbx;       /* Forbidden signature database. */
>> +  grub_uint32_t db_entries; /* Size of signature database. */
>> +  grub_uint32_t dbx_entries;/* Size of forbidden signature database. */
>> +} GRUB_PACKED;
>> +typedef struct grub_pks grub_pks_t;
>> +
>> +#if defined(__powerpc__)
>> +/* Initialization of the Platform Keystore. */
>> +extern void
>> +grub_pks_keystore_init (void);
>> +
>> +/* Platform KeyStore db and dbx. */
>> +extern grub_pks_t *
>> +EXPORT_FUNC (grub_pks_get_keystore) (void);
>> +
>> +/* Free allocated memory. */
>> +extern void
>> +EXPORT_FUNC (grub_pks_tmp_free) (void);
>> +#else
>> +static inline grub_pks_t *
>> +grub_pks_get_keystore (void)
>> +{
>> +  return NULL;
>> +}
>> +
>> +static inline void
>> +grub_pks_tmp_free (void)
>> +{
>> +  return;
>> +}
>> +#endif /* __powerpc__ */
>> +#endif



_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to