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 <sudha...@linux.ibm.com>
Reviewed-by: Stefan Berger <stef...@linux.ibm.com>
Reviewed-by: Avnish Chouhan <avn...@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

Reply via email to