#include <grub/env.h>
#include <grub/lockdown.h>
#include <grub/powerpc/ieee1275/platform_keystore.h>
+#include <grub/efi/pks.h>
#include "appendedsig.h"
#define SIG_MAGIC "~Module signature appended~\n"
#define SIG_MAGIC_SIZE ((sizeof(SIG_MAGIC) - 1))
+/* SHA256, SHA384 and SHA512 hash sizes. */
+#define SHA256_HASH_SIZE 32
+#define SHA384_HASH_SIZE 48
+#define SHA512_HASH_SIZE 64
+
/*
* This structure is extracted from scripts/sign-file.c in the linux kernel
* source. It was licensed as LGPLv2.1+, which is GPLv3+ compatible.
{
grub_x509_cert_t *certs; /* Certificates. */
grub_uint32_t cert_entries; /* Number of certificates. */
+ grub_uint8_t **hashes; /* Certificate/binary hashes. */
+ grub_size_t *hash_sizes; /* Sizes of certificate/binary hashes. */
+ grub_uint32_t hash_entries; /* Number of certificate/binary hashes. */
+ bool is_db; /* Flag to indicate the db/dbx list. */
};
typedef struct sb_database sb_database_t;
/* The db list is used to validate appended signatures. */
-static sb_database_t db = {.certs = NULL, .cert_entries = 0};
+static sb_database_t db = {.certs = NULL, .cert_entries = 0, .hashes = NULL,
+ .hash_sizes = NULL, .hash_entries = 0, .is_db = true};
+/*
+ * The dbx list is used to ensure that the distrusted certificates or GRUB
+ * modules/kernel binaries are rejected during appended signatures/hashes
+ * validation.
+ */
+static sb_database_t dbx = {.certs = NULL, .cert_entries = 0, .hashes = NULL,
+ .hash_sizes = NULL, .hash_entries = 0, .is_db = false};
/*
* Signature verification flag (check_sigs).
.fs_read = pseudo_read
};
+/*
+ * 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_crypto_hash (hash_func, hash, data, data_size);
+ *hash_size = hash_func->mdlen;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+generate_cert_hash (const grub_size_t cert_hash_size, const grub_uint8_t *data,
+ const grub_size_t data_size, grub_uint8_t *hash, grub_size_t *hash_size)
+{
+ grub_packed_guid_t guid = { 0 };
+
+ /* support SHA256, SHA384 and SHA512 for certificate hash */
+ if (cert_hash_size == SHA256_HASH_SIZE)
+ grub_memcpy (&guid, &GRUB_PKS_CERT_X509_SHA256_GUID, GRUB_PACKED_GUID_SIZE);
+ else if (cert_hash_size == SHA384_HASH_SIZE)
+ grub_memcpy (&guid, &GRUB_PKS_CERT_X509_SHA384_GUID, GRUB_PACKED_GUID_SIZE);
+ else if (cert_hash_size == SHA512_HASH_SIZE)
+ grub_memcpy (&guid, &GRUB_PKS_CERT_X509_SHA512_GUID, GRUB_PACKED_GUID_SIZE);
+ else
+ {
+ grub_dprintf ("appendedsig", "unsupported hash type (%" PRIuGRUB_SIZE ") and "
+ "skipped\n", cert_hash_size);
+ return GRUB_ERR_UNKNOWN_COMMAND;
+ }
+
+ return get_hash (&guid, data, data_size, hash, hash_size);
+}
+
+/* Check the hash presence in the db/dbx list. */
+static bool
+check_hash_presence (grub_uint8_t *const hash, const grub_size_t hash_size,
+ const sb_database_t *sb_database)
+{
+ grub_uint32_t i;
+
+ for (i = 0; i < sb_database->hash_entries; i++)
+ {
+ if (sb_database->hashes[i] == NULL)
+ continue;
+
+ if (hash_size == sb_database->hash_sizes[i] &&
+ grub_memcmp (sb_database->hashes[i], hash, hash_size) == 0)
+ return true;
+ }
+
+ return false;
+}
+
+/* Add the certificate/binary hash into the db/dbx list. */
+static grub_err_t
+add_hash (grub_uint8_t *const data, const grub_size_t data_size, sb_database_t *sb_database)
+{
+ grub_uint8_t **hashes;
+ grub_size_t *hash_sizes;
+
+ if (data == NULL || data_size == 0)
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "certificate/binary-hash data or size is not available");
+
+ if (sb_database->is_db == true)
+ {
+ if (check_hash_presence (data, data_size, &dbx) == true)
+ {
+ grub_dprintf ("appendedsig",
+ "cannot add a hash (%02x%02x%02x%02x), as it is present in the dbx list\n",
+ data[0], data[1], data[2], data[3]);
+ return GRUB_ERR_ACCESS_DENIED;
+ }
+ }
+
+ if (check_hash_presence (data, data_size, sb_database) == true)
+ {
+ grub_dprintf ("appendedsig",
+ "cannot add a hash (%02x%02x%02x%02x), as it is present in the %s list\n",
+ data[0], data[1], data[2], data[3], ((sb_database->is_db == true) ? "db" : "dbx"));
+ return GRUB_ERR_EXISTS;
+ }
+
+ hashes = grub_realloc (sb_database->hashes, sizeof (grub_uint8_t *) * (sb_database->hash_entries + 1));
+ if (hashes == NULL)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+
+ hash_sizes = grub_realloc (sb_database->hash_sizes, sizeof (grub_size_t) * (sb_database->hash_entries + 1));
+ if (hash_sizes == NULL)
+ {
+ /* Allocated memory will be freed by free_db_list()/free_dbx_list(). */
+ hashes[sb_database->hash_entries] = NULL;
+ sb_database->hashes = hashes;
+ sb_database->hash_entries++;
+
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+ }
+
+ hashes[sb_database->hash_entries] = grub_malloc (data_size);
+ if (hashes[sb_database->hash_entries] == NULL)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+
+ grub_dprintf ("appendedsig",
+ "added the hash %02x%02x%02x%02x... with size of %" PRIuGRUB_SIZE " to the %s list\n",
+ data[0], data[1], data[2], data[3], data_size,
+ ((sb_database->is_db == true) ? "db" : "dbx"));
+
+ grub_memcpy (hashes[sb_database->hash_entries], data, data_size);
+ hash_sizes[sb_database->hash_entries] = data_size;
+ sb_database->hash_sizes = hash_sizes;
+ sb_database->hashes = hashes;
+ sb_database->hash_entries++;
+
+ return GRUB_ERR_NONE;
+}
+
+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;
+}
+
+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 grub_x509_cert_t *cert1, const grub_x509_cert_t *cert2)
{
return false;
}
-/* Check the certificate presence in the db list. */
+/* Check the certificate hash presence in the dbx list. */
+static bool
+is_cert_hash_present_in_dbx (const grub_uint8_t *data, const grub_size_t data_size)
+{
+ grub_err_t rc;
+ grub_uint32_t i;
+ grub_size_t cert_hash_size = 0;
+ grub_uint8_t cert_hash[GRUB_MAX_HASH_LEN] = { 0 };
+
+ for (i = 0; i < dbx.hash_entries; i++)
+ {
+ if (dbx.hashes[i] == NULL)
+ continue;
+
+ rc = generate_cert_hash (dbx.hash_sizes[i], data, data_size, cert_hash, &cert_hash_size);
+ if (rc != GRUB_ERR_NONE)
+ continue;
+
+ if (cert_hash_size == dbx.hash_sizes[i] &&
+ grub_memcmp (dbx.hashes[i], cert_hash, cert_hash_size) == 0)
+ return true;
+ }
+
+ return false;
+}
+
+/* Check the certificate presence in the db/dbx list. */
static bool
check_cert_presence (const grub_x509_cert_t *cert_in, const sb_database_t *sb_database)
{
return false;
}
-/* Add the certificate into the db list */
+/*
+ * Add the certificate into the db list if it is not present in the dbx and db
+ * list when is_db is true. Add the certificate into the dbx list when is_db is
+ * false.
+ */
static grub_err_t
add_certificate (const grub_uint8_t *data, const grub_size_t data_size,
sb_database_t *sb_database)
rc = grub_x509_cert_parse (data, data_size, cert);
if (rc != GRUB_ERR_NONE)
{
- grub_dprintf ("appendedsig", "cannot add a certificate CN='%s' to the db list\n",
- cert->subject);
+ grub_dprintf ("appendedsig", "cannot add a certificate CN='%s' to the %s list\n",
+ cert->subject, (sb_database->is_db == true) ? "db" : "dbx");
grub_free (cert);
return rc;
}
+ /*
+ * Only checks the certificate against dbx if is_db is true when dynamic key
+ * management is enabled.
+ */
+ if (append_key_mgmt == true)
+ {
+ if (sb_database->is_db == true)
+ {
+ if (is_cert_hash_present_in_dbx (data, data_size) == true ||
+ check_cert_presence (cert, &dbx) == true)
+ {
+ grub_dprintf ("appendedsig",
+ "cannot add a certificate CN='%s', as it is present in the dbx list",
+ cert->subject);
+ rc = GRUB_ERR_ACCESS_DENIED;
+ goto fail;
+ }
+ }
+ }
+
if (check_cert_presence (cert, sb_database) == true)
{
grub_dprintf ("appendedsig",
- "cannot add a certificate CN='%s', as it is present in the db list",
- cert->subject);
- grub_x509_cert_release (cert);
- grub_free (cert);
-
- return GRUB_ERR_EXISTS;
+ "cannot add a certificate CN='%s', as it is present in the %s list",
+ cert->subject, ((sb_database->is_db == true) ? "db" : "dbx"));
+ rc = GRUB_ERR_EXISTS;
+ goto fail;
}
- grub_dprintf ("appendedsig", "added a certificate CN='%s' to the db list\n",
- cert->subject);
+ grub_dprintf ("appendedsig", "added a certificate CN='%s' to the %s list\n",
+ cert->subject, ((sb_database->is_db == true) ? "db" : "dbx"));
cert->next = sb_database->certs;
sb_database->certs = cert;
sb_database->cert_entries++;
+ return rc;
+
+ fail:
+ grub_x509_cert_release (cert);
+ grub_free (cert);
+
return rc;
}
return err;
}
+/* Add the X.509 certificates/binary hash to the db list from PKS. */
+static grub_err_t
+load_pks2db (void)
+{
+ grub_err_t rc;
+ grub_uint32_t i;
+
+ for (i = 0; i < pks_keystore->db_entries; i++)
+ {
+ if (is_hash (&pks_keystore->db[i].guid) == true)
+ {
+ rc = add_hash (pks_keystore->db[i].data,
+ pks_keystore->db[i].data_size, &db);
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
+ return rc;
+ }
+ else if (is_x509 (&pks_keystore->db[i].guid) == true)
+ {
+ rc = add_certificate (pks_keystore->db[i].data,
+ pks_keystore->db[i].data_size, &db);
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
+ return rc;
+ }
+ else
+ grub_dprintf ("appendedsig", "unsupported signature data type and "
+ "skipped (%u)\n", i + 1);
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+/* Add the certificates and certificate/binary hash to the dbx list from PKS. */
+static grub_err_t
+load_pks2dbx (void)
+{
+ grub_err_t rc;
+ grub_uint32_t i;
+
+ for (i = 0; i < pks_keystore->dbx_entries; i++)
+ {
+ if (is_x509 (&pks_keystore->dbx[i].guid) == true)
+ {
+ rc = add_certificate (pks_keystore->dbx[i].data,
+ pks_keystore->dbx[i].data_size, &dbx);
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
+ return rc;
+ }
+ else if (is_hash (&pks_keystore->dbx[i].guid) == true)
+ {
+ rc = add_hash (pks_keystore->dbx[i].data,
+ pks_keystore->dbx[i].data_size, &dbx);
+ if (rc != GRUB_ERR_NONE)
+ return rc;
+ }
+ else
+ grub_dprintf ("appendedsig", "unsupported signature data type and "
+ "skipped (%u)\n", i + 1);
+ }
+
+ return GRUB_ERR_NONE;
+}
+
/*
* Extract the X.509 certificates from the ELF Note header, parse it, and add
* it to the db list.
}
}
+/*
+ * Extract trusted and distrusted keys from PKS and store them in the db and
+ * dbx list.
+ */
+static void
+create_dbs_from_pks (void)
+{
+ grub_err_t err;
+
+ err = load_pks2dbx ();
+ if (err != GRUB_ERR_NONE)
+ grub_printf ("warning: dbx list might not be fully populated\n");
+
+ /*
+ * If db does not exist in the PKS storage, then read the static keys as a db
+ * default keys from the GRUB ELF Note and add them into the db list.
+ */
+ if (pks_keystore->db_exists == false)
+ load_elf2db ();
+ else
+ {
+ err = load_pks2db ();
+ if (err != GRUB_ERR_NONE)
+ grub_printf ("warning: db list might not be fully populated\n");
+ }
+
+ grub_pks_free_data ();
+ grub_dprintf ("appendedsig", "the db list now has %u keys\n"
+ "the dbx list now has %u keys\n",
+ db.hash_entries + db.cert_entries,
+ dbx.hash_entries + dbx.cert_entries);
+}
+
/* Free db list memory */
static void
free_db_list (void)
{
grub_x509_cert_t *cert;
+ grub_uint32_t i;
while (db.certs != NULL)
{
grub_free (cert);
}
+ for (i = 0; i < db.hash_entries; i++)
+ grub_free (db.hashes[i]);
+
+ grub_free (db.hashes);
+ grub_free (db.hash_sizes);
grub_memset (&db, 0, sizeof (sb_database_t));
}
+/* Free dbx list memory */
+static void
+free_dbx_list (void)
+{
+ grub_x509_cert_t *cert;
+ grub_uint32_t i;
+
+ while (dbx.certs != NULL)
+ {
+ cert = dbx.certs;
+ dbx.certs = dbx.certs->next;
+ grub_x509_cert_release (cert);
+ grub_free (cert);
+ }
+
+ for (i = 0; i < dbx.hash_entries; i++)
+ grub_free (dbx.hashes[i]);
+
+ grub_free (dbx.hashes);
+ grub_free (dbx.hash_sizes);
+ grub_memset (&dbx, 0, sizeof (sb_database_t));
+}
+
static const char *
grub_env_read_sec (struct grub_env_var *var __attribute__ ((unused)),
const char *val __attribute__ ((unused)))
if (rc != ASN1_SUCCESS)
grub_fatal ("error initing ASN.1 data structures: %d: %s\n", rc, asn1_strerror (rc));
- /* Extract trusted keys from ELF Note and store them in the db. */
- load_elf2db ();
- grub_dprintf ("appendedsig", "the db list now has %u static keys\n",
- db.cert_entries);
+ /*
+ * If signature verification is enabled with the dynamic key management,
+ * extract trusted and distrusted keys from PKS and store them in the db
+ * and dbx list.
+ */
+ if (append_key_mgmt == true)
+ create_dbs_from_pks ();
+ /*
+ * If signature verification is enabled with the static key management,
+ * extract trusted keys from ELF Note and store them in the db list.
+ */
+ else
+ {
+ load_elf2db ();
+ grub_dprintf ("appendedsig", "the db list now has %u static keys\n",
+ db.cert_entries);
+ }
grub_verifier_register (&grub_appendedsig_verifier);
grub_dl_set_persistent (mod);
*/
free_db_list ();
+ free_dbx_list ();
grub_register_variable_hook ("check_appended_signatures", NULL, NULL);
grub_env_unset ("check_appended_signatures");
grub_register_variable_hook ("appendedsig_key_mgmt", NULL, NULL);
--- /dev/null
+/*
+ * 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