All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
To: grub-devel@gnu.org
Cc: dja@axtens.net, jan.setjeeilers@oracle.com,
	julian.klode@canonical.com, mate.kukri@canonical.com,
	pjones@redhat.com, msuchanek@suse.com, mlewando@redhat.com,
	stefanb@linux.ibm.com, avnish@linux.ibm.com, nayna@linux.ibm.com,
	ssrish@linux.ibm.com, Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Subject: [PATCH v6 12/20] appended signatures: Create db and dbx lists
Date: Tue, 29 Jul 2025 18:07:01 +0530	[thread overview]
Message-ID: <20250729123709.83349-13-sudhakar@linux.ibm.com> (raw)
In-Reply-To: <20250729123709.83349-1-sudhakar@linux.ibm.com>

If secure boot is enabled with static key management mode, the trusted
certificates will be extracted from the GRUB ELF Note and added to db list.
This is introduced by a subsequent patch.

If secure boot is enabled with dynamic key management mode, the trusted
certificates and certificate/binary hash will be extracted from the PKS
and added to db list. The distrusted certificates, certificate/binary hash
from the PKS and added to dbx list. Both dbx and db lists are introduced by
a subsequent patch.

Note:-

If the certificate or the certificate hash exists in the dbx list, then
do not add that certificate/certificate hash to the db list.

Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
---
 grub-core/commands/appendedsig/appendedsig.c | 530 +++++++++++++++++--
 include/grub/crypto.h                        |   1 +
 include/grub/efi/pks.h                       | 112 ++++
 include/grub/types.h                         |   4 +
 4 files changed, 606 insertions(+), 41 deletions(-)
 create mode 100644 include/grub/efi/pks.h

diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
index 48f1ec94e..1e5610ddf 100644
--- a/grub-core/commands/appendedsig/appendedsig.c
+++ b/grub-core/commands/appendedsig/appendedsig.c
@@ -33,7 +33,8 @@
 #include <libtasn1.h>
 #include <grub/env.h>
 #include <grub/ieee1275/ieee1275.h>
-
+#include <grub/efi/pks.h>
+#include <grub/powerpc/ieee1275/platform_keystore.h>
 #include "appendedsig.h"
 
 GRUB_MOD_LICENSE ("GPLv3+");
@@ -67,8 +68,30 @@ struct grub_appended_signature
   struct pkcs7_signedData pkcs7;        /* Parsed PKCS#7 data. */
 };
 
-/* Trusted certificates for verifying appended signatures. */
-struct x509_certificate *db;
+/* This represents a db/dbx list. */
+struct grub_database
+{
+  struct x509_certificate *certs; /* Certificates. */
+  grub_size_t cert_entries;       /* Number of certificates. */
+  grub_uint8_t **signatures;      /* Certificate/binary hashes. */
+  grub_size_t *signature_size;    /* Size of certificate/binary hashes. */
+  grub_size_t signature_entries;  /* Number of certificate/binary hashes. */
+};
+
+/* The db list */
+struct grub_database db = {.certs = NULL, .cert_entries = 0, .signatures = NULL,
+                           .signature_size = NULL, .signature_entries = 0};
+
+/* The dbx list */
+struct grub_database dbx = {.certs = NULL, .cert_entries = 0, .signatures = NULL,
+                            .signature_size = NULL, .signature_entries = 0};
+
+/* Free db list memory */
+static void
+free_db_list (void);
+/* Free dbx list memory */
+static void
+free_dbx_list (void);
 
 /* Appended signature size. */
 static grub_size_t append_sig_len = 0;
@@ -124,6 +147,94 @@ grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)), const cha
   return ret;
 }
 
+/*
+ * GUID can be used to determine the hashing function and
+ * generate the hash using determined hashing function.
+ */
+static grub_err_t
+get_hash (const grub_packed_guid_t *guid, const grub_uint8_t *data, const grub_size_t data_size,
+          grub_uint8_t *hash, grub_size_t *hash_size)
+{
+  gcry_md_spec_t *hash_func = NULL;
+
+  if (guid == NULL)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "GUID is not available");
+
+  if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_PACKED_GUID_SIZE) == 0 ||
+      grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA256_GUID, GRUB_PACKED_GUID_SIZE) == 0)
+    hash_func = &_gcry_digest_spec_sha256;
+  else if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_PACKED_GUID_SIZE) == 0 ||
+           grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA384_GUID, GRUB_PACKED_GUID_SIZE) == 0)
+    hash_func = &_gcry_digest_spec_sha384;
+  else if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_PACKED_GUID_SIZE) == 0 ||
+           grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA512_GUID, GRUB_PACKED_GUID_SIZE) == 0)
+    hash_func = &_gcry_digest_spec_sha512;
+  else
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "unsupported GUID hash");
+
+  grub_memset (hash, 0, GRUB_MAX_HASH_SIZE);
+  grub_crypto_hash (hash_func, hash, data, data_size);
+  *hash_size =  hash_func->mdlen;
+
+  return GRUB_ERR_NONE;
+}
+
+/* Add the certificate/binary hash into the db/dbx list. */
+static grub_err_t
+add_hash (const grub_uint8_t **data, const grub_size_t data_size,
+          grub_uint8_t ***signature_list, grub_size_t **signature_size_list,
+          grub_size_t *signature_list_entries)
+{
+  grub_uint8_t **signatures = *signature_list;
+  grub_size_t *signature_size = *signature_size_list;
+  grub_size_t signature_entries = *signature_list_entries;
+
+  if (*data == NULL || data_size == 0)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "certificate/binary-hash data or size is not available");
+
+  signatures = grub_realloc (signatures, sizeof (grub_uint8_t *) * (signature_entries + 1));
+  signature_size = grub_realloc (signature_size,
+                                 sizeof (grub_size_t) * (signature_entries + 1));
+
+  if (signatures == NULL || signature_size == NULL)
+    {
+      /*
+       * Allocated memory will be freed by
+       * free_db_list/free_dbx_list.
+       */
+      if (signatures != NULL)
+        {
+          *signature_list = signatures;
+          *signature_list_entries = signature_entries + 1;
+        }
+
+      if (signature_size != NULL)
+        *signature_size_list = signature_size;
+
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+    }
+
+  signatures[signature_entries] = (grub_uint8_t *) *data;
+  signature_size[signature_entries] = data_size;
+  signature_entries++;
+  *data = NULL;
+
+  *signature_list = signatures;
+  *signature_size_list = signature_size;
+  *signature_list_entries = signature_entries;
+
+  return GRUB_ERR_NONE;
+}
+
+static bool
+is_x509 (const grub_packed_guid_t *guid)
+{
+  if (grub_memcmp (guid, &GRUB_PKS_CERT_X509_GUID, GRUB_PACKED_GUID_SIZE) == 0)
+    return true;
+
+  return false;
+}
+
 static bool
 is_cert_match (const struct x509_certificate *distrusted_cert,
                const struct x509_certificate *db_cert)
@@ -138,6 +249,95 @@ is_cert_match (const struct x509_certificate *distrusted_cert,
   return false;
 }
 
+/* Check the certificate presence in the Platform Keystore dbx list. */
+static grub_err_t
+is_dbx_cert (const struct x509_certificate *db_cert)
+{
+  grub_err_t rc;
+  grub_size_t i;
+  struct x509_certificate *distrusted_cert;
+
+  for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
+    {
+      if (grub_pks_keystore.dbx[i].data == NULL)
+        continue;
+
+      if (is_x509 (&grub_pks_keystore.dbx[i].guid) == true)
+        {
+          distrusted_cert = grub_zalloc (sizeof (struct x509_certificate));
+          if (distrusted_cert == NULL)
+            return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+
+          rc = parse_x509_certificate (grub_pks_keystore.dbx[i].data,
+                                       grub_pks_keystore.dbx[i].data_size, distrusted_cert);
+          if (rc != GRUB_ERR_NONE)
+            {
+              grub_free (distrusted_cert);
+              continue;
+            }
+
+          if (is_cert_match (distrusted_cert, db_cert) == true)
+            {
+              grub_dprintf ("appendedsig", "a trusted certificate CN='%s' is ignored "
+                            "because it is on the dbx list\n", db_cert->subject);
+              return GRUB_ERR_ACCESS_DENIED;
+            }
+
+          certificate_release (distrusted_cert);
+          grub_free (distrusted_cert);
+        }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Add the certificate into the db/dbx list */
+static grub_err_t
+add_certificate (const grub_uint8_t *data, const grub_size_t data_size,
+                 struct grub_database *database, const bool is_db)
+{
+  struct x509_certificate *cert;
+  grub_err_t rc;
+  grub_size_t cert_entries = database->cert_entries;
+
+  if (data == NULL || data_size == 0)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "certificate data or size is not available");
+
+  cert = grub_zalloc (sizeof (struct x509_certificate));
+  if (cert == NULL)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+
+  rc = parse_x509_certificate (data, data_size, cert);
+  if (rc != GRUB_ERR_NONE)
+    {
+      grub_dprintf ("appendedsig", "skipped %s certificate (%d)\n",
+                    ((is_db == true) ? "trusted" : "distrusted"), (int) rc);
+      grub_free (cert);
+      return rc;
+    }
+
+  if (is_db == true)
+    {
+      rc = is_dbx_cert (cert);
+      if (rc != GRUB_ERR_NONE)
+        {
+          certificate_release (cert);
+          grub_free (cert);
+          return rc;
+        }
+    }
+
+  grub_dprintf ("appendedsig", "add a %s certificate CN='%s'\n",
+                ((is_db == true) ? "trusted" : "distrusted"), cert->subject);
+
+  cert_entries++;
+  cert->next = database->certs;
+  database->certs = cert;
+  database->cert_entries = cert_entries;
+
+  return rc;
+}
+
 static grub_err_t
 file_read_whole (grub_file_t file, grub_uint8_t **buf, grub_size_t *len)
 {
@@ -272,7 +472,7 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
   struct pkcs7_signerInfo *si;
   int i;
 
-  if (db == NULL)
+  if (!db.cert_entries)
     return grub_error (GRUB_ERR_BAD_SIGNATURE, "no trusted keys to verify against");
 
   err = extract_appended_signature (buf, bufsize, &sig);
@@ -303,7 +503,7 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
       grub_dprintf ("appendedsig", "data size %" PRIuGRUB_SIZE ", signer %d hash %02x%02x%02x%02x...\n",
                     datasize, i, hash[0], hash[1], hash[2], hash[3]);
 
-      for (pk = db; pk != NULL; pk = pk->next)
+      for (pk = db.certs; pk != NULL; pk = pk->next)
         {
           err = verify_signature (pk->mpis, si->sig_mpi, si->hash, hash);
           if (err == GRUB_ERR_NONE)
@@ -359,7 +559,7 @@ is_cert_present_in_db (const struct x509_certificate *cert_in)
 {
   struct x509_certificate *cert;
 
-  for (cert = db; cert; cert = cert->next)
+  for (cert = db.certs; cert; cert = cert->next)
     {
       if (is_cert_match (cert, cert_in) == true)
         return true;
@@ -374,12 +574,12 @@ is_cert_removed_from_db (const struct x509_certificate *cert)
   int i = 1;
   struct x509_certificate *curr_cert, *prev_cert;
 
-  for (curr_cert = prev_cert = db; curr_cert != NULL; curr_cert = curr_cert->next)
+  for (curr_cert = prev_cert = db.certs; curr_cert != NULL; curr_cert = curr_cert->next)
     {
       if (is_cert_match (curr_cert, cert) == true)
         {
           if (i == 1) /* Match with first certificate in the db list. */
-            db = curr_cert->next;
+            db.certs = curr_cert->next;
           else
             prev_cert->next = curr_cert->next;
 
@@ -468,8 +668,9 @@ grub_cmd_db_cert (grub_command_t cmd __attribute__ ((unused)), int argc, char **
 
   grub_dprintf ("appendedsig", "added certificate with CN: %s\n", cert->subject);
 
-  cert->next = db;
-  db = cert;
+  cert->next = db.certs;
+  db.certs = cert;
+  db.cert_entries++;
 
   return GRUB_ERR_NONE;
 }
@@ -517,7 +718,7 @@ grub_cmd_list_db (grub_command_t cmd __attribute__ ((unused)), int argc __attrib
   int cert_num = 1;
   grub_size_t i;
 
-  for (cert = db; cert != NULL; cert = cert->next)
+  for (cert = db.certs; cert != NULL; cert = cert->next)
     {
       grub_printf ("Certificate %d:\n", cert_num);
       grub_printf ("\tSerial: ");
@@ -609,6 +810,238 @@ static struct grub_fs pseudo_fs = {
 
 static grub_command_t cmd_verify, cmd_list_db, cmd_dbx_cert, cmd_db_cert;
 
+/* Check the certificate hash presence in the PKS dbx list. */
+static bool
+is_dbx_cert_hash (const grub_uint8_t *data, const grub_size_t data_size)
+{
+  grub_err_t rc;
+  grub_size_t i, cert_hash_size = 0;
+  grub_uint8_t cert_hash[GRUB_MAX_HASH_SIZE] = { 0 };
+
+  for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
+    {
+      if (grub_pks_keystore.dbx[i].data == NULL ||
+          grub_pks_keystore.dbx[i].data_size == 0)
+        continue;
+
+      rc = get_hash (&grub_pks_keystore.dbx[i].guid, data, data_size,
+                     cert_hash, &cert_hash_size);
+      if (rc != GRUB_ERR_NONE)
+        continue;
+
+      if (cert_hash_size == grub_pks_keystore.dbx[i].data_size &&
+          grub_memcmp (grub_pks_keystore.dbx[i].data, cert_hash, cert_hash_size) == 0)
+        {
+          grub_dprintf ("appendedsig", "a trusted certificate (%02x%02x%02x%02x) is ignored "
+                        "because this certificate hash is on the dbx list\n",
+                        cert_hash[0], cert_hash[1], cert_hash[2], cert_hash[3]);
+          return true;
+        }
+    }
+
+  return false;
+}
+
+/* Check the binary hash presence in the PKS dbx list. */
+static bool
+is_dbx_binary_hash (const grub_uint8_t *binary_hash, const grub_size_t binary_hash_size)
+{
+  grub_size_t i;
+
+  for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
+    {
+      if (grub_pks_keystore.dbx[i].data == NULL ||
+          grub_pks_keystore.dbx[i].data_size == 0)
+        continue;
+
+      if (binary_hash_size == grub_pks_keystore.dbx[i].data_size &&
+          grub_memcmp (grub_pks_keystore.dbx[i].data, binary_hash, binary_hash_size) == 0)
+        {
+          grub_dprintf ("appendedsig", "a trusted binary hash (%02x%02x%02x%02x) is ignored"
+                        " because it is on the dbx list\n", binary_hash[0], binary_hash[1],
+                        binary_hash[2], binary_hash[3]);
+          return true;
+        }
+    }
+
+  return false;
+}
+
+/* Add the binary hash to the db list if it does not exist in the PKS dbx list. */
+static grub_err_t
+add_db_binary_hash (const grub_uint8_t **data, const grub_size_t data_size)
+{
+  if (*data == NULL || data_size == 0)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "trusted binary hash data or size is not available");
+
+  if (is_dbx_binary_hash (*data, data_size) == false)
+    return add_hash (data, data_size, &db.signatures, &db.signature_size,
+                     &db.signature_entries);
+
+  return GRUB_ERR_BAD_SIGNATURE;
+}
+
+static bool
+is_hash (const grub_packed_guid_t *guid)
+{
+  /* GUID type of the binary hash. */
+  if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_PACKED_GUID_SIZE) == 0 ||
+      grub_memcmp (guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_PACKED_GUID_SIZE) == 0 ||
+      grub_memcmp (guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_PACKED_GUID_SIZE) == 0)
+    return true;
+
+  /* GUID type of the certificate hash. */
+  if (grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA256_GUID, GRUB_PACKED_GUID_SIZE) == 0 ||
+      grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA384_GUID, GRUB_PACKED_GUID_SIZE) == 0 ||
+      grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA512_GUID, GRUB_PACKED_GUID_SIZE) == 0)
+    return true;
+
+  return false;
+}
+
+/* Add the X.509 certificates/binary hash to the db list from PKS. */
+static grub_err_t
+create_db_list (void)
+{
+  grub_err_t rc;
+  grub_size_t i;
+
+  for (i = 0; i < grub_pks_keystore.db_entries; i++)
+    {
+      if (is_hash (&grub_pks_keystore.db[i].guid) == true)
+        {
+          rc = add_db_binary_hash ((const grub_uint8_t **) grub_pks_keystore.db[i].data,
+                                   grub_pks_keystore.db[i].data_size);
+          if (rc == GRUB_ERR_OUT_OF_MEMORY)
+            return rc;
+        }
+      else if (is_x509 (&grub_pks_keystore.db[i].guid) == true)
+        {
+          if (is_dbx_cert_hash (grub_pks_keystore.db[i].data,
+                                grub_pks_keystore.db[i].data_size) == true)
+            continue;
+
+          rc = add_certificate (grub_pks_keystore.db[i].data,
+                                grub_pks_keystore.db[i].data_size, &db, true);
+          if (rc == GRUB_ERR_OUT_OF_MEMORY)
+            return rc;
+        }
+      else
+        grub_dprintf ("appendedsig", "unsupported signature data type and "
+                      "skipped (%" PRIuGRUB_SIZE ")\n", i + 1);
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Add the certificates and certificate/binary hash to the dbx list from PKS. */
+static grub_err_t
+create_dbx_list (void)
+{
+  grub_err_t rc;
+  grub_size_t i;
+
+  for (i = 0; i < grub_pks_keystore.dbx_entries; i++)
+    {
+      if (is_x509 (&grub_pks_keystore.dbx[i].guid) == true)
+        {
+          rc = add_certificate (grub_pks_keystore.dbx[i].data,
+                                grub_pks_keystore.dbx[i].data_size, &dbx, false);
+          if (rc == GRUB_ERR_OUT_OF_MEMORY)
+            return rc;
+        }
+      else if (is_hash (&grub_pks_keystore.dbx[i].guid) == true)
+        {
+          rc = add_hash ((const grub_uint8_t **) grub_pks_keystore.dbx[i].data,
+                         grub_pks_keystore.dbx[i].data_size, &dbx.signatures,
+                         &dbx.signature_size, &dbx.signature_entries);
+          if (rc != GRUB_ERR_NONE)
+            return rc;
+        }
+      else
+        grub_dprintf ("appendedsig", "unsupported signature data type and "
+                      "skipped (%" PRIuGRUB_SIZE ")\n", i + 1);
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/*
+ * Extract the x509 certificates from the ELF Note header,
+ * parse it, and add it to the db list.
+ */
+static grub_err_t
+build_static_db_list (const struct grub_module_header *header)
+{
+  grub_err_t err;
+  struct grub_file pseudo_file;
+  grub_uint8_t *cert_data = NULL;
+  grub_size_t cert_data_size = 0;
+
+  grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
+  pseudo_file.fs = &pseudo_fs;
+  pseudo_file.size = header->size - sizeof (struct grub_module_header);
+  pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
+
+  grub_dprintf ("appendedsig", "found an x509 key, size=%" PRIuGRUB_UINT64_T "\n",
+                pseudo_file.size);
+
+  err = file_read_whole (&pseudo_file, &cert_data, &cert_data_size);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  err = add_certificate (cert_data, cert_data_size, &db, true);
+  grub_free (cert_data);
+
+  return err;
+}
+
+/* Free db list memory */
+static void
+free_db_list (void)
+{
+  struct x509_certificate *cert;
+  grub_size_t i = 0;
+
+  while (db.certs != NULL)
+    {
+      cert = db.certs;
+      db.certs = db.certs->next;
+      certificate_release (cert);
+      grub_free (cert);
+    }
+
+  for (i = 0; i < db.signature_entries; i++)
+    grub_free (db.signatures[i]);
+
+  grub_free (db.signatures);
+  grub_free (db.signature_size);
+  grub_memset (&db, 0, sizeof (db));
+}
+
+/* Free dbx list memory */
+static void
+free_dbx_list (void)
+{
+  struct x509_certificate *cert;
+  grub_size_t i = 0;
+
+  while (dbx.certs != NULL)
+    {
+      cert = dbx.certs;
+      dbx.certs = dbx.certs->next;
+      certificate_release (cert);
+      grub_free (cert);
+    }
+
+  for (i = 0; i < dbx.signature_entries; i++)
+    grub_free (dbx.signatures[i]);
+
+  grub_free (dbx.signatures);
+  grub_free (dbx.signature_size);
+  grub_memset (&dbx, 0, sizeof (dbx));
+}
+
 GRUB_MOD_INIT (appendedsig)
 {
   int rc;
@@ -621,7 +1054,6 @@ GRUB_MOD_INIT (appendedsig)
   if (grub_ieee1275_is_secure_boot () == GRUB_SB_ENFORCED)
     check_sigs = true;
 
-  db = NULL;
   grub_register_variable_hook ("check_appended_signatures", grub_env_read_sec, grub_env_write_sec);
   grub_env_export ("check_appended_signatures");
 
@@ -630,38 +1062,54 @@ GRUB_MOD_INIT (appendedsig)
     grub_fatal ("error initing ASN.1 data structures: %d: %s\n", rc, asn1_strerror (rc));
 
   /*
-   * If signature verification is enabled,
-   * extract trusted keys from ELF Note and store them in the db.
+   * If signature verification is enabled with static key management mode,
+   * extract trusted keys from ELF Note and store them in the db list.
    */
-  if (check_sigs == true)
+  if (grub_pks_use_keystore == false && check_sigs == true)
     {
       FOR_MODULES (header)
-      {
-        struct grub_file pseudo_file;
-        struct x509_certificate *pk = NULL;
-        grub_err_t err;
-
-        /* Not an X.509 certificate, skip. */
-        if (header->type != OBJ_TYPE_X509_PUBKEY)
-          continue;
-
-        grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
-        pseudo_file.fs = &pseudo_fs;
-        pseudo_file.size = header->size - sizeof (struct grub_module_header);
-        pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
-
-        grub_dprintf ("appendedsig", "found an x509 key, size=%" PRIuGRUB_UINT64_T "\n",
-                      pseudo_file.size);
-
-        err = read_cert_from_file (&pseudo_file, &pk);
-        if (err != GRUB_ERR_NONE)
-          grub_fatal ("error loading initial key: %s", grub_errmsg);
-
-        grub_dprintf ("appendedsig", "loaded certificate CN='%s'\n", pk->subject);
-
-        pk->next = db;
-        db = pk;
-      }
+        {
+          /* Not an ELF module, skip.  */
+          if (header->type != OBJ_TYPE_X509_PUBKEY)
+            continue;
+          rc = build_static_db_list (header);
+          if (rc != GRUB_ERR_NONE)
+            {
+              free_db_list ();
+              grub_error (rc, "static db list creation failed");
+            }
+          else
+            grub_dprintf ("appendedsig", "the db list now has %" PRIuGRUB_SIZE " static keys\n",
+                          db.cert_entries);
+        }
+    }
+  /*
+   * If signature verification is enabled with dynamic key management mode,
+   * extract trusted and distrusted keys from PKS and store them in the db and dbx list.
+   */
+  else if (grub_pks_use_keystore == true && check_sigs == true)
+    {
+      rc = create_db_list ();
+      if (rc != GRUB_ERR_NONE)
+        {
+          free_db_list ();
+          grub_error (rc, "db list creation failed");
+        }
+      else
+        {
+          rc = create_dbx_list ();
+          if (rc != GRUB_ERR_NONE)
+            {
+              free_db_list ();
+              free_dbx_list ();
+              grub_error (rc, "dbx list creation failed");
+            }
+          else
+            grub_dprintf ("appendedsig", "the db list now has %" PRIuGRUB_SIZE " keys\n"
+                          "the dbx list now has %" PRIuGRUB_SIZE " keys\n",
+                          db.signature_entries + db.cert_entries, dbx.signature_entries);
+        }
+      grub_pks_free_keystore ();
     }
 
   cmd_db_cert = grub_register_command ("append_add_db_cert", grub_cmd_db_cert, N_("X509_CERTIFICATE"),
diff --git a/include/grub/crypto.h b/include/grub/crypto.h
index b0d7add1d..00d074df8 100644
--- a/include/grub/crypto.h
+++ b/include/grub/crypto.h
@@ -510,6 +510,7 @@ grub_crypto_hmac_buffer (const struct gcry_md_spec *md,
 extern gcry_md_spec_t _gcry_digest_spec_md5;
 extern gcry_md_spec_t _gcry_digest_spec_sha1;
 extern gcry_md_spec_t _gcry_digest_spec_sha256;
+extern gcry_md_spec_t _gcry_digest_spec_sha384;
 extern gcry_md_spec_t _gcry_digest_spec_sha512;
 extern gcry_md_spec_t _gcry_digest_spec_crc32;
 extern gcry_cipher_spec_t _gcry_cipher_spec_aes;
diff --git a/include/grub/efi/pks.h b/include/grub/efi/pks.h
new file mode 100644
index 000000000..ff306f591
--- /dev/null
+++ b/include/grub/efi/pks.h
@@ -0,0 +1,112 @@
+/*
+ * 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 PKS_HEADER
+#define PKS_HEADER   1
+
+#include <grub/types.h>
+
+/*
+ * It is derived from EFI_CERT_X509_GUID.
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
+ */
+#define GRUB_PKS_CERT_X509_GUID \
+  (grub_guid_t) \
+  { 0xa159c0a5, 0xe494, 0xa74a, \
+    { 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 } \
+  }
+
+/*
+ * It is derived from EFI_CERT_SHA256_GUID.
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
+ */
+#define GRUB_PKS_CERT_SHA256_GUID \
+  (grub_guid_t) \
+  { 0x2616c4c1, 0x4c50, 0x9240, \
+    { 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 } \
+  }
+
+/*
+ * It is derived from EFI_CERT_SHA384_GUID.
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
+ */
+#define GRUB_PKS_CERT_SHA384_GUID \
+  (grub_guid_t) \
+  { 0x07533eff, 0xd09f, 0xc948, \
+    { 0x85, 0xf1, 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x1 } \
+  }
+
+/*
+ * It is derived from EFI_CERT_SHA512_GUID.
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
+ */
+#define GRUB_PKS_CERT_SHA512_GUID \
+  (grub_guid_t) \
+  { 0xae0f3e09, 0xc4a6, 0x504f, \
+    { 0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a } \
+  }
+
+/*
+ * It is derived from EFI_CERT_X509_SHA256_GUID.
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
+ */
+#define GRUB_PKS_CERT_X509_SHA256_GUID \
+  (grub_guid_t) \
+  { 0x92a4d23b, 0xc096, 0x7940, \
+    { 0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed } \
+  }
+
+/*
+ * It is derived from EFI_CERT_X509_SHA384_GUID.
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
+ */
+#define GRUB_PKS_CERT_X509_SHA384_GUID     \
+  (grub_guid_t) \
+  { 0x6e877670, 0xc280, 0xe64e, \
+    { 0xaa, 0xd2, 0x28, 0xb3, 0x49, 0xa6, 0x86, 0x5b } \
+  }
+
+/*
+ * It is derived from EFI_CERT_X509_SHA512_GUID.
+ * https://github.com/tianocore/edk2-staging/blob/master/MdePkg/Include/Guid/ImageAuthentication.h
+ */
+#define GRUB_PKS_CERT_X509_SHA512_GUID \
+  (grub_guid_t) \
+  { 0x63bf6d44, 0x0225, 0xda4c, \
+    { 0xbc, 0xfa, 0x24, 0x65, 0xd2, 0xb0, 0xfe, 0x9d } \
+  }
+
+#endif
diff --git a/include/grub/types.h b/include/grub/types.h
index 45079bf65..b3ba762fc 100644
--- a/include/grub/types.h
+++ b/include/grub/types.h
@@ -379,6 +379,8 @@ struct grub_guid
 } __attribute__ ((aligned(4)));
 typedef struct grub_guid grub_guid_t;
 
+#define GRUB_GUID_SIZE    (sizeof (grub_guid_t))
+
 struct grub_packed_guid
 {
   grub_uint32_t data1;
@@ -388,4 +390,6 @@ struct grub_packed_guid
 } GRUB_PACKED;
 typedef struct grub_packed_guid grub_packed_guid_t;
 
+#define GRUB_PACKED_GUID_SIZE    (sizeof (grub_packed_guid_t))
+
 #endif /* ! GRUB_TYPES_HEADER */
-- 
2.39.5 (Apple Git-154)


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

  parent reply	other threads:[~2025-07-29 12:40 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-29 12:36 [PATCH v6 00/20] Appended Signature Secure Boot Support for PowerPC Sudhakar Kuppusamy
2025-07-29 12:36 ` [PATCH v6 01/20] powerpc-ieee1275: Add support for signing GRUB with an appended signature Sudhakar Kuppusamy
2025-07-29 12:36 ` [PATCH v6 02/20] crypto: Move storage for grub_crypto_pk_* to crypto.c Sudhakar Kuppusamy
2025-07-29 12:36 ` [PATCH v6 03/20] pgp: Rename OBJ_TYPE_PUBKEY to OBJ_TYPE_GPG_PUBKEY Sudhakar Kuppusamy
2025-07-29 12:36 ` [PATCH v6 04/20] grub-install: Support embedding x509 certificates Sudhakar Kuppusamy
2025-07-29 12:36 ` [PATCH v6 05/20] appended signatures: Import GNUTLS's ASN.1 description files Sudhakar Kuppusamy
2025-07-29 12:36 ` [PATCH v6 06/20] appended signatures: Parse ASN1 node Sudhakar Kuppusamy
2025-07-29 12:36 ` [PATCH v6 07/20] appended signatures: Parse PKCS#7 signedData Sudhakar Kuppusamy
2025-07-29 12:36 ` [PATCH v6 08/20] appended signatures: Parse X.509 certificates Sudhakar Kuppusamy
2025-07-29 12:36 ` [PATCH v6 09/20] powerpc_ieee1275: Enter lockdown based on /ibm, secure-boot Sudhakar Kuppusamy
2025-07-29 12:36 ` [PATCH v6 10/20] appended signatures: Support verifying appended signatures Sudhakar Kuppusamy
2025-07-29 12:37 ` [PATCH v6 11/20] powerpc_ieee1275: Read the db and dbx secure boot variables Sudhakar Kuppusamy
2025-07-29 12:37 ` Sudhakar Kuppusamy [this message]
2025-07-29 12:37 ` [PATCH v6 13/20] appended signatures: Using db and dbx lists for signature verification Sudhakar Kuppusamy
2025-07-29 12:37 ` [PATCH v6 14/20] powerpc_ieee1275: Introduce use_static_keys flag Sudhakar Kuppusamy
2025-07-29 12:37 ` [PATCH v6 15/20] appended signatures: Read default db keys from the ELF Note Sudhakar Kuppusamy
2025-07-29 12:37 ` [PATCH v6 16/20] appended signatures: Introduce GRUB commands to access db and dbx Sudhakar Kuppusamy
2025-07-29 12:37 ` [PATCH v6 17/20] appended signatures: Verification tests Sudhakar Kuppusamy
2025-07-29 12:37 ` [PATCH v6 18/20] docs/grub: Document signing GRUB under UEFI Sudhakar Kuppusamy
2025-07-29 12:37 ` [PATCH v6 19/20] docs/grub: Document signing GRUB with an appended signature Sudhakar Kuppusamy
2025-07-29 12:37 ` [PATCH v6 20/20] docs/grub: Document " Sudhakar Kuppusamy
  -- strict thread matches above, loose matches on Subject: below --
2025-07-29 14:51 [PATCH v6 00/20] Appended Signature Secure Boot Support for PowerPC Sudhakar Kuppusamy
2025-07-29 14:51 ` [PATCH v6 12/20] appended signatures: Create db and dbx lists Sudhakar Kuppusamy
2025-08-11 17:21   ` Daniel Kiper
2025-08-11 17:34     ` Sudhakar Kuppusamy
2025-08-12 11:50       ` Daniel Kiper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250729123709.83349-13-sudhakar@linux.ibm.com \
    --to=sudhakar@linux.ibm.com \
    --cc=avnish@linux.ibm.com \
    --cc=dja@axtens.net \
    --cc=grub-devel@gnu.org \
    --cc=jan.setjeeilers@oracle.com \
    --cc=julian.klode@canonical.com \
    --cc=mate.kukri@canonical.com \
    --cc=mlewando@redhat.com \
    --cc=msuchanek@suse.com \
    --cc=nayna@linux.ibm.com \
    --cc=pjones@redhat.com \
    --cc=ssrish@linux.ibm.com \
    --cc=stefanb@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.