All of lore.kernel.org
 help / color / mirror / Atom feed
From: Avnish Chouhan <avnish@linux.ibm.com>
To: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Cc: grub-devel@gnu.org, dja@axtens.net, jan.setjeeilers@oracle.com,
	julian.klode@canonical.com, mate.kukri@canonical.com,
	pjones@redhat.com, stefanb@linux.ibm.com, nayna@linux.ibm.com,
	ssrish@linux.ibm.com, daniel.kiper@oracle.com
Subject: Re: [PATCH v1 16/21] appendedsig: The creation of trusted and distrusted lists
Date: Fri, 07 Feb 2025 12:09:51 +0530	[thread overview]
Message-ID: <789bb685eb016602cb7348aa1ca60d31@linux.ibm.com> (raw)
In-Reply-To: <20241218145647.1390837-17-sudhakar@linux.ibm.com>


Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>

On 2024-12-18 20:26, Sudhakar Kuppusamy wrote:
> The trusted certificates and binary hashes, distrusted certificates and
> binary/certificate hashes will be extracted from the platform keystore 
> buffer
> if Secure Boot is enabled with PKS.
> In order to verify the integerity of the kernel, the extracted data
> would be stored in the buffer db and dbx.
> 
> The trusted certificates will be extracted from the grub ELFNOTE if
> Secure Boot is
> enabled with static key. In order to verify the integerity of the 
> kernel,
> the extracted data would be stored in the buffer db.
> 
> Note:-
> 
> if the trusted certificate nor binary hash exists in the distrusted 
> list (DBX),
> rejected it while extracting it from the platform keystore buffer.
> 
> Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
> ---
>  grub-core/commands/appendedsig/appendedsig.c | 636 +++++++++++++++++--
>  1 file changed, 592 insertions(+), 44 deletions(-)
> 
> diff --git a/grub-core/commands/appendedsig/appendedsig.c
> b/grub-core/commands/appendedsig/appendedsig.c
> index 5c82b96a4..31649e800 100644
> --- a/grub-core/commands/appendedsig/appendedsig.c
> +++ b/grub-core/commands/appendedsig/appendedsig.c
> @@ -34,7 +34,7 @@
>  #include <libtasn1.h>
>  #include <grub/env.h>
>  #include <grub/lockdown.h>
> -
> +#include <grub/platform_keystore.h>
>  #include "appendedsig.h"
> 
>  GRUB_MOD_LICENSE ("GPLv3+");
> @@ -64,9 +64,23 @@ struct grub_appended_signature
>    struct pkcs7_signedData pkcs7;        /* Parsed PKCS#7 data */
>  };
> 
> -/* Trusted certificates for verifying appended signatures */
> -struct x509_certificate *grub_trusted_key;
> +/* This represents a trusted/distrusted list*/
> +struct grub_database
> +{
> +  struct x509_certificate *keys; /* Certificates */
> +  grub_size_t key_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 */
> +};
> +
> +/* Trusted list */
> +struct grub_database grub_db = {.keys = NULL, .key_entries = 0,
> .signatures = NULL,
> +                                .signature_size = NULL,
> .signature_entries = 0};
> 
> +/* Distrusted list */
> +struct grub_database grub_dbx = {.signatures = NULL, .signature_size = 
> NULL,
> +                                 .signature_entries = 0};
>  /*
>   * Force gcry_rsa to be a module dependency.
>   *
> @@ -87,6 +101,13 @@ struct x509_certificate *grub_trusted_key;
>   * also resolves our concerns about loading from the filesystem.
>   */
>  extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
> +extern gcry_md_spec_t _gcry_digest_spec_sha224;
> +extern gcry_md_spec_t _gcry_digest_spec_sha384;
> +
> +/* releasing trusted list memory */
> +static void grub_release_trusted_list (void);
> +/* releasing distrusted list memory */
> +static void grub_release_distrusted_list (void);
> 
>  static enum
>  {
> @@ -95,6 +116,248 @@ static enum
>    check_sigs_forced = 2
>  } check_sigs = check_sigs_no;
> 
> +/*
> + * GUID can be used to determine the hashing function and
> + * generate the hash using determined hashing function.
> + */
> +static grub_err_t
> +grub_get_hash (const grub_uuid_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 null");
> +
> +  if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE) 
> == 0 ||
> +           grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA256_GUID,
> GRUB_UUID_SIZE) == 0)
> +    hash_func = &_gcry_digest_spec_sha256;
> +  else if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA384_GUID,
> GRUB_UUID_SIZE) == 0 ||
> +           grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA384_GUID,
> GRUB_UUID_SIZE) == 0)
> +    hash_func = &_gcry_digest_spec_sha384;
> +  else if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA512_GUID,
> GRUB_UUID_SIZE) == 0 ||
> +           grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA512_GUID,
> GRUB_UUID_SIZE) == 0)
> +    hash_func = &_gcry_digest_spec_sha512;
> +  else
> +    return GRUB_ERR_UNKNOWN_COMMAND;
> +
> +  grub_memset (hash, 0x00, GRUB_MAX_HASH_SIZE);
> +  grub_crypto_hash (hash_func, hash, data, data_size);
> +  *hash_size =  hash_func->mdlen;
> +
> +  return GRUB_ERR_NONE;
> +}
> +
> +/* adding the certificate/binary hash into the trusted/distrusted list 
> */
> +static grub_err_t
> +grub_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/size is null");
> +
> +  if (signatures == NULL && signature_size == NULL)
> +    {
> +      signatures = grub_zalloc (sizeof (grub_uint8_t *));
> +      signature_size = grub_zalloc (sizeof (grub_size_t));
> +    }
> +  else
> +    {
> +      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
> +       * grub_release_trusted_list/grub_release_distrusted_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 grub_err_t
> +grub_is_x509 (const grub_uuid_t *guid)
> +{
> +  if (grub_memcmp (guid, &GRUB_PKS_CERT_X509_GUID, GRUB_UUID_SIZE) == 
> 0)
> +    return GRUB_ERR_NONE;
> +
> +  return GRUB_ERR_UNKNOWN_COMMAND;
> +}
> +
> +static grub_err_t
> +grub_is_cert_match (const struct x509_certificate *distrusted_cert,
> +                    const struct x509_certificate *db_cert)
> +{
> +
> +  if (grub_memcmp (distrusted_cert->subject, db_cert->subject,
> db_cert->subject_len) == 0
> +      && grub_memcmp (distrusted_cert->serial, db_cert->serial,
> db_cert->serial_len) == 0
> +      && grub_memcmp (distrusted_cert->mpis[0], db_cert->mpis[0],
> sizeof (db_cert->mpis[0])) == 0
> +      && grub_memcmp (distrusted_cert->mpis[1], db_cert->mpis[1],
> sizeof (db_cert->mpis[1])) == 0)
> +    return GRUB_ERR_NONE;
> +
> +  return GRUB_ERR_UNKNOWN_COMMAND;
> +}
> +
> +/*
> + * verify the certificate against the certificate from platform
> keystore buffer's
> + * distrusted list, if it is present, return a bad signature.
> + * else, no errors.
> + */
> +static grub_err_t
> +grub_is_distrusted_cert (const struct x509_certificate *db_cert)
> +{
> +  grub_err_t rc = GRUB_ERR_NONE;
> +  grub_size_t i = 0;
> +  struct x509_certificate *distrusted_cert = NULL;
> +
> +  for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
> +    {
> +      if (grub_platform_keystore.dbx[i].data == NULL &&
> +          grub_platform_keystore.dbx[i].data_size == 0)
> +        continue;
> +
> +      if (grub_is_x509 (&grub_platform_keystore.dbx[i].guid) == 
> GRUB_ERR_NONE)
> +        {
> +          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_platform_keystore.dbx[i].data,
> +
> grub_platform_keystore.dbx[i].data_size, distrusted_cert);
> +          if (rc != GRUB_ERR_NONE)
> +            {
> +              grub_free (distrusted_cert);
> +              continue;
> +            }
> +
> +          if (grub_is_cert_match (distrusted_cert, db_cert) == 
> GRUB_ERR_NONE)
> +            {
> +              grub_printf ("Warning: a trusted certificate CN='%s' is 
> ignored "
> +                           "because it is on the distrusted list
> (dbx).\n", db_cert->subject);
> +              grub_free (grub_platform_keystore.dbx[i].data);
> +              grub_memset (&grub_platform_keystore.dbx[i], 0x00,
> sizeof (grub_pks_sd_t));
> +              certificate_release (distrusted_cert);
> +              grub_free (distrusted_cert);
> +              return GRUB_ERR_BAD_SIGNATURE;
> +            }
> +
> +          certificate_release (distrusted_cert);
> +          grub_free (distrusted_cert);
> +        }
> +    }
> +
> +  return GRUB_ERR_NONE;
> +}
> +
> +/* adding the certificate into the trusted/distrusted list */
> +static grub_err_t
> +grub_add_certificate (const grub_uint8_t *data, const grub_size_t 
> data_size,
> +                      struct grub_database *database, const 
> grub_size_t is_db)
> +{
> +  grub_err_t rc = GRUB_ERR_NONE;
> +  grub_size_t key_entries = database->key_entries;
> +  struct x509_certificate *cert = NULL;
> +
> +  if (data == NULL || data_size == 0)
> +    return grub_error (GRUB_ERR_OUT_OF_RANGE, "certificate data/size 
> is null");
> +
> +  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_printf ("Warning: skipping %s certificate (%d)\n",
> +                   (is_db ? "trusted":"distrused"), rc);
> +      grub_free (cert);
> +      return rc;
> +    }
> +
> +  if (is_db)
> +    {
> +      rc = grub_is_distrusted_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 ? "trusted":"distrused"), cert->subject);
> +
> +  key_entries++;
> +  cert->next = database->keys;
> +  database->keys = cert;
> +  database->key_entries = key_entries;
> +
> +  return rc;
> +}
> +
> +static grub_err_t
> +grub_read_file (const grub_file_t file, grub_uint8_t **data,
> grub_ssize_t *data_size)
> +{
> +  grub_uint8_t *buffer = NULL;
> +  grub_ssize_t read_size = 0;
> +  grub_off_t total_read_size = 0;
> +  grub_off_t file_size = grub_file_size (file);
> +
> +  if (file_size == GRUB_FILE_SIZE_UNKNOWN)
> +    return grub_error (GRUB_ERR_BAD_ARGUMENT,
> +                       N_("could not parse the unknown size of the 
> file."));
> +
> +  buffer = grub_zalloc (file_size);
> +  if (buffer == NULL)
> +    return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
> +
> +  while (total_read_size < file_size)
> +    {
> +      read_size = grub_file_read (file, &buffer[total_read_size],
> file_size - total_read_size);
> +      if (read_size < 0)
> +        {
> +          grub_free (buffer);
> +          return grub_error (GRUB_ERR_READ_ERROR, N_("unable to read
> the file"));
> +        }
> +
> +      total_read_size += read_size;
> +    }
> +
> +  *data = buffer;
> +  *data_size = total_read_size;
> +
> +  return GRUB_ERR_NONE;
> +}
> +
>  static const char *
>  grub_env_read_sec (struct grub_env_var *var __attribute__ ((unused)),
>                     const char *val __attribute__ ((unused)))
> @@ -248,7 +511,7 @@ grub_verify_appended_signature (const grub_uint8_t
> *buf, grub_size_t bufsize)
>    struct pkcs7_signerInfo *si;
>    int i;
> 
> -  if (!grub_trusted_key)
> +  if (!grub_db.key_entries)
>      return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("No trusted keys to
> verify against"));
> 
>    err = extract_appended_signature (buf, bufsize, &sig);
> @@ -279,7 +542,7 @@ grub_verify_appended_signature (const grub_uint8_t
> *buf, grub_size_t bufsize)
>                      datasize, i, hash[0], hash[1], hash[2], hash[3]);
> 
>        err = GRUB_ERR_BAD_SIGNATURE;
> -      for (pk = grub_trusted_key; pk; pk = pk->next)
> +      for (pk = grub_db.keys; pk; pk = pk->next)
>          {
>            rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, 
> pk->mpis[0]);
>            if (rc)
> @@ -376,16 +639,16 @@ grub_cmd_distrust (grub_command_t cmd
> __attribute__ ((unused)), int argc, char *
> 
>    if (cert_num == 1)
>      {
> -      cert = grub_trusted_key;
> -      grub_trusted_key = cert->next;
> +      cert = grub_db.keys;
> +      grub_db.keys = cert->next;
> 
>        certificate_release (cert);
>        grub_free (cert);
>        return GRUB_ERR_NONE;
>      }
>    i = 2;
> -  prev = grub_trusted_key;
> -  cert = grub_trusted_key->next;
> +  prev = grub_db.keys;
> +  cert = grub_db.keys->next;
>    while (cert)
>      {
>        if (i == cert_num)
> @@ -432,8 +695,8 @@ grub_cmd_trust (grub_command_t cmd __attribute__
> ((unused)), int argc, char **ar
>      }
>    grub_dprintf ("appendedsig", "Loaded certificate with CN: %s\n",
> cert->subject);
> 
> -  cert->next = grub_trusted_key;
> -  grub_trusted_key = cert;
> +  cert->next = grub_db.keys;
> +  grub_db.keys = cert;
> 
>    return GRUB_ERR_NONE;
>  }
> @@ -446,7 +709,7 @@ grub_cmd_list (grub_command_t cmd __attribute__
> ((unused)), int argc __attribute
>    int cert_num = 1;
>    grub_size_t i;
> 
> -  for (cert = grub_trusted_key; cert; cert = cert->next)
> +  for (cert = grub_db.keys; cert; cert = cert->next)
>      {
>        grub_printf (N_("Certificate %d:\n"), cert_num);
> 
> @@ -539,6 +802,280 @@ static struct grub_fs pseudo_fs = { .name =
> "pseudo", .fs_read = pseudo_read };
> 
>  static grub_command_t cmd_verify, cmd_list, cmd_distrust, cmd_trust;
> 
> +/*
> + * verify the trusted certificate against the certificate hashes from
> platform keystore buffer's
> + * distrusted list, if it is present, return a bad signature.
> + * else, no errors.
> + */
> +static grub_err_t
> +grub_is_distrusted_cert_hash (const grub_uint8_t *data, const
> grub_size_t data_size)
> +{
> +  grub_err_t rc = GRUB_ERR_NONE;
> +  grub_size_t i = 0, cert_hash_size = 0;
> +  grub_uint8_t cert_hash[GRUB_MAX_HASH_SIZE] = { 0 };
> +
> +  if (data == NULL || data_size == 0)
> +    return grub_error (GRUB_ERR_OUT_OF_RANGE, "trusted certificate
> data/size is null");
> +
> +  for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
> +    {
> +      if (grub_platform_keystore.dbx[i].data == NULL &&
> +          grub_platform_keystore.dbx[i].data_size == 0)
> +        continue;
> +
> +      rc = grub_get_hash (&grub_platform_keystore.dbx[i].guid, data, 
> data_size,
> +                          cert_hash, &cert_hash_size);
> +      if (rc != GRUB_ERR_NONE)
> +        continue;
> +
> +      if (cert_hash_size == grub_platform_keystore.dbx[i].data_size &&
> +          grub_memcmp (grub_platform_keystore.dbx[i].data, cert_hash,
> cert_hash_size) == 0)
> +        {
> +          grub_printf ("Warning: a trusted certificate
> (%02x%02x%02x%02x) is ignored "
> +                       "because this certificate hash is on the
> distrusted list (dbx).\n",
> +                       cert_hash[0], cert_hash[1], cert_hash[2], 
> cert_hash[3]);
> +          grub_free (grub_platform_keystore.dbx[i].data);
> +          grub_memset (&grub_platform_keystore.dbx[i], 0x00, sizeof
> (grub_pks_sd_t));
> +          return GRUB_ERR_BAD_SIGNATURE;
> +        }
> +    }
> +
> +  return GRUB_ERR_NONE;
> +}
> +
> +/*
> + * verify the trusted binary hash against the platform keystore 
> buffer's
> + * distrusted list, if it is present, return a bad signature.
> + * else, no errors.
> + */
> +static grub_err_t
> +grub_is_distrusted_binary_hash (const grub_uint8_t *binary_hash,
> +                                const grub_size_t binary_hash_size)
> +{
> +  grub_size_t i = 0;
> +
> +  for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
> +    {
> +      if (grub_platform_keystore.dbx[i].data == NULL &&
> +          grub_platform_keystore.dbx[i].data_size == 0)
> +        continue;
> +
> +      if (binary_hash_size == grub_platform_keystore.dbx[i].data_size 
> &&
> +          grub_memcmp (grub_platform_keystore.dbx[i].data,
> binary_hash, binary_hash_size) == 0)
> +        {
> +          grub_printf ("Warning: a trusted binary hash
> (%02x%02x%02x%02x) is ignored"
> +                       " because it is on the distrusted list 
> (dbx).\n",
> +                       binary_hash[0], binary_hash[1],
> binary_hash[2], binary_hash[3]);
> +          grub_free (grub_platform_keystore.dbx[i].data);
> +          grub_memset (&grub_platform_keystore.dbx[i], 0x00, sizeof
> (grub_pks_sd_t));
> +          return GRUB_ERR_BAD_SIGNATURE;
> +        }
> +    }
> +
> +  return GRUB_ERR_NONE;
> +}
> +
> +/*
> + * extracts the binary hashes from the platform keystore buffer,
> + * and adds it to the trusted list if not exists in distrusted list.
> + */
> +static grub_err_t
> +grub_add_trusted_binary_hash (const grub_uint8_t **data, const
> grub_size_t data_size)
> +{
> +  grub_err_t rc = GRUB_ERR_NONE;
> +
> +  if (*data == NULL || data_size == 0)
> +    return grub_error (GRUB_ERR_OUT_OF_RANGE, "trusted binary hash
> data/size is null");
> +
> +  rc = grub_is_distrusted_binary_hash (*data, data_size);
> +  if (rc != GRUB_ERR_NONE)
> +    return rc;
> +
> +  rc = grub_add_hash (data, data_size, &grub_db.signatures,
> &grub_db.signature_size,
> +                      &grub_db.signature_entries);
> +  return rc;
> +}
> +
> +static grub_err_t
> +grub_is_hash (const grub_uuid_t *guid)
> +{
> +  /* GUID type of the binary hash */
> +  if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE) 
> == 0 ||
> +      grub_memcmp (guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_UUID_SIZE) 
> == 0 ||
> +      grub_memcmp (guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_UUID_SIZE) 
> == 0)
> +    return GRUB_ERR_NONE;
> +
> +  /* GUID type of the certificate hash */
> +  if (grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA256_GUID,
> GRUB_UUID_SIZE) == 0 ||
> +      grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA384_GUID,
> GRUB_UUID_SIZE) == 0 ||
> +      grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA512_GUID, 
> GRUB_UUID_SIZE) == 0)
> +    return GRUB_ERR_NONE;
> +
> +  return GRUB_ERR_UNKNOWN_COMMAND;
> +}
> +
> +/*
> + * extracts the x509 certificates/binary hashes from the platform
> keystore buffer,
> + * parses it, and adds it to the trusted list.
> + */
> +static grub_err_t
> +grub_create_trusted_list (void)
> +{
> +  grub_err_t rc = GRUB_ERR_NONE;
> +  grub_size_t i = 0;
> +
> +  for (i = 0; i < grub_platform_keystore.db_entries; i++)
> +    {
> +      if (grub_is_hash (&grub_platform_keystore.db[i].guid) == 
> GRUB_ERR_NONE)
> +        {
> +          rc = grub_add_trusted_binary_hash ((const grub_uint8_t **)
> +
> &grub_platform_keystore.db[i].data,
> +
> grub_platform_keystore.db[i].data_size);
> +          if (rc == GRUB_ERR_OUT_OF_MEMORY)
> +            return rc;
> +
> +          continue;
> +        }
> +      else if (grub_is_x509 (&grub_platform_keystore.db[i].guid) ==
> GRUB_ERR_NONE)
> +        {
> +
> +          rc = grub_is_distrusted_cert_hash 
> (grub_platform_keystore.db[i].data,
> +
> grub_platform_keystore.db[i].data_size);
> +          if (rc != GRUB_ERR_NONE)
> +            continue;
> +
> +          rc = grub_add_certificate 
> (grub_platform_keystore.db[i].data,
> +
> grub_platform_keystore.db[i].data_size, &grub_db, 1);
> +          if (rc == GRUB_ERR_OUT_OF_MEMORY)
> +            return rc;
> +          else if (rc != GRUB_ERR_NONE)
> +            continue;
> +        }
> +      else
> +        grub_printf ("Warning: unsupported signature data type and "
> +                     "skipping trusted data (%" PRIuGRUB_SIZE ")\n", i 
> + 1);
> +    }
> +
> +  return GRUB_ERR_NONE;
> +}
> +
> +/*
> + * extracts the certificates, certificate/binary hashes out of the
> platform keystore buffer,
> + * and adds it to the distrusted list.
> + */
> +static grub_err_t
> +grub_create_distrusted_list (void)
> +{
> +  grub_err_t rc = GRUB_ERR_NONE;
> +  grub_size_t i = 0;
> +
> +  for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
> +    {
> +      if (grub_platform_keystore.dbx[i].data != NULL &&
> +          grub_platform_keystore.dbx[i].data_size > 0)
> +        {
> +          if (grub_is_x509 (&grub_platform_keystore.dbx[i].guid) ==
> GRUB_ERR_NONE)
> +            {
> +              rc = grub_add_certificate 
> (grub_platform_keystore.dbx[i].data,
> +
> grub_platform_keystore.dbx[i].data_size, &grub_dbx, 0);
> +              if (rc == GRUB_ERR_OUT_OF_MEMORY)
> +                return rc;
> +            }
> +          else if (grub_is_hash (&grub_platform_keystore.dbx[i].guid)
> == GRUB_ERR_NONE)
> +            {
> +              rc = grub_add_hash ((const grub_uint8_t **)
> &grub_platform_keystore.dbx[i].data,
> +                                  
> grub_platform_keystore.dbx[i].data_size,
> +                                  &grub_dbx.signatures,
> &grub_dbx.signature_size,
> +                                  &grub_dbx.signature_entries);
> +              if (rc != GRUB_ERR_NONE)
> +                return rc;
> +            }
> +          else
> +            grub_printf ("Warning: unsupported signature data type and 
> "
> +                         "skipping distrusted data (%" PRIuGRUB_SIZE
> ")\n", i + 1);
> +        }
> +    }
> +
> +  return rc;
> +}
> +
> +/*
> + * extracts the x509 certificates from the ELF note header,
> + * parses it, and adds it to the trusted list.
> + */
> +static grub_err_t
> +grub_build_static_trusted_list (const struct grub_module_header 
> *header)
> +{
> +  grub_err_t err = GRUB_ERR_NONE;
> +  struct grub_file pseudo_file;
> +  grub_uint8_t *cert_data = NULL;
> +  grub_ssize_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 = grub_read_file (&pseudo_file, &cert_data, &cert_data_size);
> +  if (err != GRUB_ERR_NONE)
> +    return err;
> +
> +  err = grub_add_certificate (cert_data, cert_data_size, &grub_db, 1);
> +  if (cert_data != NULL)
> +    grub_free (cert_data);
> +
> +  return err;
> +}
> +
> +/* releasing memory */
> +static void
> +grub_release_trusted_list (void)
> +{
> +  struct x509_certificate *cert;
> +  grub_size_t i = 0;
> +
> +  while (grub_db.keys != NULL)
> +    {
> +      cert = grub_db.keys;
> +      grub_db.keys = grub_db.keys->next;
> +      certificate_release (cert);
> +      grub_free (cert);
> +    }
> +
> +  for (i = 0; i < grub_db.signature_entries; i++)
> +    grub_free (grub_db.signatures[i]);
> +
> +  grub_free (grub_db.signatures);
> +  grub_free (grub_db.signature_size);
> +  grub_memset (&grub_db, 0x00, sizeof (grub_db));
> +}
> +
> +/* releasing memory */
> +static void
> +grub_release_distrusted_list (void)
> +{
> +  struct x509_certificate *cert;
> +  grub_size_t i = 0;
> +
> +  while (grub_dbx.keys != NULL)
> +    {
> +      cert = grub_dbx.keys;
> +      grub_dbx.keys = grub_dbx.keys->next;
> +      certificate_release (cert);
> +      grub_free (cert);
> +    }
> +
> +  for (i = 0; i < grub_dbx.signature_entries; i++)
> +    grub_free (grub_dbx.signatures[i]);
> +
> +  grub_free (grub_dbx.signatures);
> +  grub_free (grub_dbx.signature_size);
> +  grub_memset (&grub_dbx, 0x00, sizeof (grub_dbx));
> +}
> +
>  GRUB_MOD_INIT (appendedsig)
>  {
>    int rc;
> @@ -548,7 +1085,6 @@ GRUB_MOD_INIT (appendedsig)
>    if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
>      check_sigs = check_sigs_forced;
> 
> -  grub_trusted_key = NULL;
>    grub_register_variable_hook ("check_appended_signatures",
> grub_env_read_sec, grub_env_write_sec);
>    grub_env_export ("check_appended_signatures");
> 
> @@ -556,39 +1092,51 @@ GRUB_MOD_INIT (appendedsig)
>    if (rc)
>      grub_fatal ("Error initing ASN.1 data structures: %d: %s\n", rc,
> asn1_strerror (rc));
> 
> -  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);
> -
> -    pk = grub_zalloc (sizeof (struct x509_certificate));
> -    if (!pk)
> -      {
> -        grub_fatal ("Out of memory loading initial certificates");
> -      }
> -
> -    err = read_cert_from_file (&pseudo_file, pk);
> -    if (err != GRUB_ERR_NONE)
> -      grub_fatal ("Error loading initial key: %s", grub_errmsg);
> +  if (!grub_use_platform_keystore && check_sigs == check_sigs_forced)
> +    {
> +      FOR_MODULES (header)
> +        {
> +          /* Not an ELF module, skip.  */
> +          if (header->type != OBJ_TYPE_X509_PUBKEY)
> +            continue;
> 
> -    grub_dprintf ("appendedsig", "loaded certificate CN='%s'\n", 
> pk->subject);
> +          rc = grub_build_static_trusted_list (header);
> +          if (rc != GRUB_ERR_NONE)
> +            {
> +              grub_release_trusted_list ();
> +              grub_error (rc, "static trusted list creation failed");
> +            }
> +          else
> +            grub_printf ("appendedsig: the trusted list now has %"
> PRIuGRUB_SIZE " static keys\n",
> +                         grub_db.key_entries);
> +        }
> +    }
> +  else if (grub_use_platform_keystore && check_sigs == 
> check_sigs_forced)
> +    {
> +      rc = grub_create_trusted_list ();
> +      if (rc != GRUB_ERR_NONE)
> +        {
> +          grub_release_trusted_list ();
> +          grub_error (rc, "trusted list creation failed");
> +        }
> +      else
> +        {
> +          rc = grub_create_distrusted_list ();
> +          if (rc != GRUB_ERR_NONE)
> +            {
> +              grub_release_trusted_list ();
> +              grub_release_distrusted_list ();
> +              grub_error (rc, "distrusted list creation failed");
> +            }
> +          else
> +            grub_printf ("appendedsig: the trusted list now has %"
> PRIuGRUB_SIZE " keys.\n"
> +                         "appendedsig: the distrusted list now has %"
> PRIuGRUB_SIZE " keys.\n",
> +                         grub_db.signature_entries + 
> grub_db.key_entries,
> +                         grub_dbx.signature_entries);
> +        }
> 
> -    pk->next = grub_trusted_key;
> -    grub_trusted_key = pk;
> -  }
> +      grub_release_platform_keystore ();
> +    }
> 
>    cmd_trust = grub_register_command ("trust_certificate",
> grub_cmd_trust, N_("X509_CERTIFICATE"),
>                                       N_("Add X509_CERTIFICATE to
> trusted certificates."));

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

  parent reply	other threads:[~2025-02-07  6:40 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-18 14:56 [PATCH v1 00/21] Appended Signature Secure Boot Support for PowerPC Sudhakar Kuppusamy
2024-12-18 14:56 ` [PATCH v1 01/21] powerpc-ieee1275: Add support for signing grub with an appended signature Sudhakar Kuppusamy
2024-12-27 14:58   ` Stefan Berger
2025-02-26  4:24     ` sudhakar
2025-01-04 18:30   ` Vladimir 'phcoder' Serbinenko
2025-01-06  6:25   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 02/21] docs/grub: Document signing grub under UEFI Sudhakar Kuppusamy
2024-12-27 15:00   ` Stefan Berger
2024-12-18 14:56 ` [PATCH v1 03/21] docs/grub: Document signing grub with an appended signature Sudhakar Kuppusamy
2024-12-27 15:04   ` Stefan Berger
2025-01-04 18:32   ` Vladimir 'phcoder' Serbinenko
2025-01-24  9:44   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 04/21] dl: provide a fake grub_dl_set_persistent for the emu target Sudhakar Kuppusamy
2024-12-27 15:06   ` Stefan Berger
2025-01-04 18:36   ` Vladimir 'phcoder' Serbinenko
2025-01-24  9:47   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 05/21] pgp: factor out rsa_pad Sudhakar Kuppusamy
2024-12-27 15:11   ` Stefan Berger
2025-01-04 18:40   ` Vladimir 'phcoder' Serbinenko
2025-02-27 15:26     ` sudhakar
2025-01-24 10:40   ` Avnish Chouhan
2025-02-27 15:28     ` sudhakar
2024-12-18 14:56 ` [PATCH v1 06/21] crypto: move storage for grub_crypto_pk_* to crypto.c Sudhakar Kuppusamy
2024-12-27 15:13   ` Stefan Berger
2025-01-04 18:41   ` Vladimir 'phcoder' Serbinenko
2025-01-24 10:42   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 07/21] grub-install: support embedding x509 certificates Sudhakar Kuppusamy
2024-12-27 16:08   ` Stefan Berger
2025-01-24 10:45   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 08/21] appended signatures: import GNUTLS's ASN.1 description files Sudhakar Kuppusamy
2024-12-28 19:02   ` Stefan Berger
2025-01-24 10:47   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 09/21] appended signatures: parse PKCS#7 signedData and X.509 certificates Sudhakar Kuppusamy
2024-12-28 19:46   ` Stefan Berger
2025-02-26  4:26     ` sudhakar
2025-01-24 11:10   ` Avnish Chouhan
2025-02-27 15:31     ` sudhakar
2025-01-24 11:23   ` Michal Suchánek
2024-12-18 14:56 ` [PATCH v1 10/21] appended signatures: support verifying appended signatures Sudhakar Kuppusamy
2024-12-29 16:37   ` Stefan Berger
2025-02-06  6:10   ` Avnish Chouhan
2025-02-27 15:33     ` sudhakar
2024-12-18 14:56 ` [PATCH v1 11/21] appended signatures: verification tests Sudhakar Kuppusamy
2024-12-30 15:39   ` Stefan Berger
2025-02-14 10:27   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 12/21] appended signatures: documentation Sudhakar Kuppusamy
2024-12-30 15:50   ` Stefan Berger
2025-02-26  4:28     ` sudhakar
2025-02-14 10:39   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 13/21] ieee1275: enter lockdown based on /ibm,secure-boot Sudhakar Kuppusamy
2024-12-30 22:02   ` Stefan Berger
2025-02-06  6:23   ` Avnish Chouhan
2025-02-27 15:34     ` sudhakar
2024-12-18 14:56 ` [PATCH v1 14/21] ieee1275: Platform Keystore (PKS) Support Sudhakar Kuppusamy
2024-12-30 22:14   ` Stefan Berger
2025-02-26  4:33     ` sudhakar
2025-02-06  9:09   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 15/21] ieee1275: Read the DB and DBX secure boot variables Sudhakar Kuppusamy
2024-12-30 23:01   ` Stefan Berger
2025-02-26  4:43     ` sudhakar
2024-12-30 23:04   ` Stefan Berger
2025-02-26  4:44     ` sudhakar
2025-02-07  5:57   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 16/21] appendedsig: The creation of trusted and distrusted lists Sudhakar Kuppusamy
2024-12-31 17:21   ` Stefan Berger
2025-02-27 15:21     ` sudhakar
2025-02-07  6:39   ` Avnish Chouhan [this message]
2024-12-18 14:56 ` [PATCH v1 17/21] appendedsig: While verifying the kernel, use " Sudhakar Kuppusamy
2024-12-31 17:37   ` Stefan Berger
2025-02-27 15:22     ` sudhakar
2025-02-07  6:44   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 18/21] ieee1275: set use_static_keys flag Sudhakar Kuppusamy
2025-01-02 13:22   ` Stefan Berger
2025-02-27 15:24     ` sudhakar
2025-02-07  6:46   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 19/21] appendedsig: Reads the default DB keys from ELF Note Sudhakar Kuppusamy
2025-01-02 13:19   ` Stefan Berger
2025-02-27 15:23     ` sudhakar
2025-02-07  6:54   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 20/21] appendedsig: The grub command's trusted and distrusted support Sudhakar Kuppusamy
2025-02-07 10:16   ` Avnish Chouhan
2024-12-18 14:56 ` [PATCH v1 21/21] appendedsig: documentation Sudhakar Kuppusamy
2025-02-07 10:00   ` Avnish Chouhan

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=789bb685eb016602cb7348aa1ca60d31@linux.ibm.com \
    --to=avnish@linux.ibm.com \
    --cc=daniel.kiper@oracle.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=nayna@linux.ibm.com \
    --cc=pjones@redhat.com \
    --cc=ssrish@linux.ibm.com \
    --cc=stefanb@linux.ibm.com \
    --cc=sudhakar@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.