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                |  14 +-
 grub-core/kern/powerpc/ieee1275/ieee1275.c    | 139 +++++++
 .../kern/powerpc/ieee1275/platform_keystore.c | 341 ++++++++++++++++++
 include/grub/ieee1275/ieee1275.h              |   3 +
 include/grub/powerpc/ieee1275/ieee1275.h      |  20 +
 .../grub/powerpc/ieee1275/platform_keystore.h | 142 ++++++++
 9 files changed, 662 insertions(+), 2 deletions(-)
 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..cd6bb7c32 100644
--- a/grub-core/Makefile.am
+++ b/grub-core/Makefile.am
@@ -241,11 +241,13 @@ KERNEL_HEADER_FILES += 
$(top_builddir)/include/grub/machine/kernel.h
 endif
 
 if COND_powerpc_ieee1275
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/powerpc/ieee1275/ieee1275.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
 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/platform_keystore.h
 endif
 
 if COND_sparc64_ieee1275
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index d91694de0..05ccbf264 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -328,10 +328,12 @@ 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;
   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/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 89303f33e..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;
@@ -1038,7 +1041,16 @@ grub_ieee1275_get_secure_boot (void)
    * Now, only support disabled and enforced.
    */
   if (sb_mode == GRUB_SB_ENFORCED)
-    grub_lockdown ();
+    {
+      grub_dprintf ("ieee1275", "Secure Boot Enabled\n");
+      grub_lockdown ();
+    }
+  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");
 }
 #endif /* __powerpc__ */
 
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..aaf90500f
--- /dev/null
+++ b/grub-core/kern/powerpc/ieee1275/platform_keystore.c
@@ -0,0 +1,341 @@
+/*
+ *  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
+
+/* 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)
+
+/* 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;
+/*
+ * Flag to indicate the key management.
+ * True: Dynamic key management (use Platform KeySotre).
+ * False: Static key management (use built-in Keys).
+ */
+bool grub_pks_use_keystore = false;
+/*
+ * Flag to indicate the availability of PSK support.
+ * True: PKS support available.
+ * False: No PKS support.
+ */
+bool grub_pks_is_support_pks = false;
+
+/* Platform KeyStore db and dbx. */
+grub_pks_t grub_pks_keystore = { .db = NULL, .dbx = NULL, .db_entries = 0, 
.dbx_entries = 0 };
+
+/*
+ * 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).
+ */
+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_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 esd_from_esl (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.
+ * 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)
+{
+  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_sbvar (sbvarflags, sbvartype, 
pks_max_object_size, *out, outlen);
+  if (rc == IEEE1275_CELL_NOT_FOUND)
+    return grub_error (GRUB_ERR_UNKNOWN_COMMAND, "secure boot variable %s not 
found (%d)",
+                       (sbvartype == DB ? "db" : "dbx"), rc);
+  else if (rc < 0)
+    return grub_error (GRUB_ERR_READ_ERROR, "secure boot variable %s reading 
(%d)",
+                       (sbvartype == DB ? "db" : "dbx"), rc);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Test the availability of PKS support. */
+static grub_err_t
+is_support_pks (void)
+{
+  grub_int32_t rc;
+  grub_ieee1275_cell_t missing = 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");
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/*
+ * 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_uint32_t 
*pks_sd_entries)
+{
+  grub_err_t rc;
+  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);
+  if (rc == GRUB_ERR_NONE && 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 - 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 void
+get_secure_boot_version (void)
+{
+  grub_err_t rc;
+  grub_uint8_t *data = NULL;
+  grub_uint32_t len = 0, policy = 0;
+
+  rc = read_sbversion_from_pks (&data, &len, &policy);
+  if (rc == GRUB_ERR_NONE && (len != 1 || (*data >= 2)))
+    grub_error (GRUB_ERR_BAD_NUMBER, "found unexpected SB version (%d)\n", 
*data);
+
+  if (rc != GRUB_ERR_NONE)
+    grub_dprintf ("ieee1275", "switch to static key\n");
+  else if (*data)
+    grub_pks_use_keystore = true;
+
+  grub_free (data);
+}
+
+/* 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
+grub_pks_keystore_init (void)
+{
+  grub_err_t rc;
+
+  grub_dprintf ("ieee1275", "trying to load Platform KeyStore\n");
+
+  rc = is_support_pks ();
+  if (rc != GRUB_ERR_NONE)
+    {
+      grub_dprintf ("ieee1275", "switch to static key\n");
+      return rc;
+    }
+  else
+   grub_pks_is_support_pks = true;
+
+  /* Read SB_VERSION from PKS. */
+  get_secure_boot_version ();
+
+  if (grub_pks_is_support_pks == true)
+    {
+      grub_memset (&grub_pks_keystore, 0, sizeof (grub_pks_t));
+      /* Read db from PKS. */
+      rc = read_secure_boot_variables (0, DB, &grub_pks_keystore.db, 
&grub_pks_keystore.db_entries);
+      if (rc == GRUB_ERR_NONE)
+        {
+          /* Read dbx from PKS. */
+          rc = read_secure_boot_variables (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 ();
+    }
+
+  return rc;
+}
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..19a4772bf 100644
--- a/include/grub/powerpc/ieee1275/ieee1275.h
+++ b/include/grub/powerpc/ieee1275/ieee1275.h
@@ -28,4 +28,24 @@ 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
+
 #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..4b34a3198
--- /dev/null
+++ b/include/grub/powerpc/ieee1275/platform_keystore.h
@@ -0,0 +1,142 @@
+/*
+ * 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>
+
+#define GRUB_MAX_HASH_SIZE 64
+
+/*
+ * 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__)
+
+/*
+ * Flag to indicate the availability of PSK support.
+ * True: PKS support available.
+ * False: No PKS support.
+ */
+extern bool EXPORT_VAR (grub_pks_is_support_pks);
+/*
+ * Flag to indicate the key management.
+ * True: Dynamic key management (use Platform KeySotre).
+ * False: Static key management (use built-in Keys).
+ */
+extern bool EXPORT_VAR (grub_pks_use_keystore);
+/* Platform KeyStore db and dbx. */
+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
+
+bool grub_pks_is_support_pks;
+bool grub_pks_use_keystore;
+grub_pks_t grub_pks_keystore;
+
+static inline void
+grub_pks_free_keystore (void)
+{
+
+}
+
+#endif
+
+#endif
-- 
2.39.5 (Apple Git-154)


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to