Blame SOURCES/0191-grub-install-support-embedding-x509-certificates.patch

5593c8
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
5593c8
From: Alastair D'Silva <alastair@d-silva.org>
5593c8
Date: Mon, 6 Jul 2020 13:33:04 +1000
5593c8
Subject: [PATCH] grub-install: support embedding x509 certificates
5593c8
5593c8
To support verification of appended signatures, we need a way to
5593c8
embed the necessary public keys. Existing appended signature schemes
5593c8
in the Linux kernel use X.509 certificates, so allow certificates to
5593c8
be embedded in the grub core image in the same way as PGP keys.
5593c8
5593c8
Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
5593c8
Signed-off-by: Daniel Axtens <dja@axtens.net>
5593c8
---
5593c8
 grub-core/commands/pgp.c    |  2 +-
5593c8
 util/grub-install-common.c  | 22 +++++++++++++++++++++-
5593c8
 util/grub-mkimage.c         | 15 +++++++++++++--
5593c8
 util/mkimage.c              | 38 ++++++++++++++++++++++++++++++++++++--
5593c8
 include/grub/kernel.h       |  4 +++-
5593c8
 include/grub/util/install.h |  7 +++++--
5593c8
 6 files changed, 79 insertions(+), 9 deletions(-)
5593c8
5593c8
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
5593c8
index 355a43844ac..b81ac0ae46c 100644
5593c8
--- a/grub-core/commands/pgp.c
5593c8
+++ b/grub-core/commands/pgp.c
5593c8
@@ -944,7 +944,7 @@ GRUB_MOD_INIT(pgp)
5593c8
     grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
5593c8
 
5593c8
     /* Not an ELF module, skip.  */
5593c8
-    if (header->type != OBJ_TYPE_PUBKEY)
5593c8
+    if (header->type != OBJ_TYPE_GPG_PUBKEY)
5593c8
       continue;
5593c8
 
5593c8
     pseudo_file.fs = &pseudo_fs;
5593c8
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
5593c8
index aab2a941f85..422f82362c7 100644
5593c8
--- a/util/grub-install-common.c
5593c8
+++ b/util/grub-install-common.c
5593c8
@@ -460,6 +460,8 @@ static char **pubkeys;
5593c8
 static size_t npubkeys;
5593c8
 static char *sbat;
5593c8
 static int disable_shim_lock;
5593c8
+static char **x509keys;
5593c8
+static size_t nx509keys;
5593c8
 static grub_compression_t compression;
5593c8
 static size_t appsig_size;
5593c8
 
5593c8
@@ -500,6 +502,11 @@ grub_install_parse (int key, char *arg)
5593c8
       return 1;
5593c8
     case GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK:
5593c8
       disable_shim_lock = 1;
5593c8
+    case 'x':
5593c8
+      x509keys = xrealloc (x509keys,
5593c8
+			  sizeof (x509keys[0])
5593c8
+			  * (nx509keys + 1));
5593c8
+      x509keys[nx509keys++] = xstrdup (arg);
5593c8
       return 1;
5593c8
 
5593c8
     case GRUB_INSTALL_OPTIONS_VERBOSITY:
5593c8
@@ -627,6 +634,9 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
5593c8
   for (pk = pubkeys; pk < pubkeys + npubkeys; pk++)
5593c8
     slen += 20 + grub_strlen (*pk);
5593c8
 
5593c8
+  for (pk = x509keys; pk < x509keys + nx509keys; pk++)
5593c8
+    slen += 10 + grub_strlen (*pk);
5593c8
+
5593c8
   for (md = modules.entries; *md; md++)
5593c8
     {
5593c8
       slen += 10 + grub_strlen (*md);
5593c8
@@ -655,6 +665,14 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
5593c8
       *p++ = ' ';
5593c8
     }
5593c8
 
5593c8
+  for (pk = x509keys; pk < x509keys + nx509keys; pk++)
5593c8
+    {
5593c8
+      p = grub_stpcpy (p, "--x509 '");
5593c8
+      p = grub_stpcpy (p, *pk);
5593c8
+      *p++ = '\'';
5593c8
+      *p++ = ' ';
5593c8
+    }
5593c8
+
5593c8
   for (md = modules.entries; *md; md++)
5593c8
     {
5593c8
       *p++ = '\'';
5593c8
@@ -688,7 +706,9 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
5593c8
 
5593c8
   grub_install_generate_image (dir, prefix, fp, outname,
5593c8
 			       modules.entries, memdisk_path,
5593c8
-			       pubkeys, npubkeys, config_path, tgt,
5593c8
+			       pubkeys, npubkeys,
5593c8
+			       x509keys, nx509keys,
5593c8
+			       config_path, tgt,
5593c8
 			       note, appsig_size, compression, dtb, sbat,
5593c8
 			       disable_shim_lock);
5593c8
   while (dc--)
5593c8
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
5593c8
index 8a53310548b..e1f1112784a 100644
5593c8
--- a/util/grub-mkimage.c
5593c8
+++ b/util/grub-mkimage.c
5593c8
@@ -75,7 +75,8 @@ static struct argp_option options[] = {
5593c8
    /* TRANSLATORS: "embed" is a verb (command description).  "*/
5593c8
   {"config",   'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0},
5593c8
    /* TRANSLATORS: "embed" is a verb (command description).  "*/
5593c8
-  {"pubkey",   'k', N_("FILE"), 0, N_("embed FILE as public key for signature checking"), 0},
5593c8
+  {"pubkey",   'k', N_("FILE"), 0, N_("embed FILE as public key for PGP signature checking"), 0},
5593c8
+  {"x509",     'x', N_("FILE"), 0, N_("embed FILE as an x509 certificate for appended signature checking"), 0},
5593c8
   /* TRANSLATORS: NOTE is a name of segment.  */
5593c8
   {"note",   'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0},
5593c8
   {"output",  'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
5593c8
@@ -124,6 +125,8 @@ struct arguments
5593c8
   char *dtb;
5593c8
   char **pubkeys;
5593c8
   size_t npubkeys;
5593c8
+  char **x509keys;
5593c8
+  size_t nx509keys;
5593c8
   char *font;
5593c8
   char *config;
5593c8
   char *sbat;
5593c8
@@ -206,6 +209,13 @@ argp_parser (int key, char *arg, struct argp_state *state)
5593c8
       arguments->pubkeys[arguments->npubkeys++] = xstrdup (arg);
5593c8
       break;
5593c8
 
5593c8
+    case 'x':
5593c8
+      arguments->x509keys = xrealloc (arguments->x509keys,
5593c8
+				      sizeof (arguments->x509keys[0])
5593c8
+				      * (arguments->nx509keys + 1));
5593c8
+      arguments->x509keys[arguments->nx509keys++] = xstrdup (arg);
5593c8
+      break;
5593c8
+
5593c8
     case 'c':
5593c8
       if (arguments->config)
5593c8
 	free (arguments->config);
5593c8
@@ -332,7 +342,8 @@ main (int argc, char *argv[])
5593c8
   grub_install_generate_image (arguments.dir, arguments.prefix, fp,
5593c8
 			       arguments.output, arguments.modules,
5593c8
 			       arguments.memdisk, arguments.pubkeys,
5593c8
-			       arguments.npubkeys, arguments.config,
5593c8
+			       arguments.npubkeys, arguments.x509keys,
5593c8
+			       arguments.nx509keys, arguments.config,
5593c8
 			       arguments.image_target, arguments.note,
5593c8
 			       arguments.appsig_size, arguments.comp,
5593c8
 			       arguments.dtb, arguments.sbat,
5593c8
diff --git a/util/mkimage.c b/util/mkimage.c
5593c8
index bab12276010..8319e8dfbde 100644
5593c8
--- a/util/mkimage.c
5593c8
+++ b/util/mkimage.c
5593c8
@@ -867,7 +867,8 @@ void
5593c8
 grub_install_generate_image (const char *dir, const char *prefix,
5593c8
 			     FILE *out, const char *outname, char *mods[],
5593c8
 			     char *memdisk_path, char **pubkey_paths,
5593c8
-			     size_t npubkeys, char *config_path,
5593c8
+			     size_t npubkeys, char **x509key_paths,
5593c8
+			     size_t nx509keys, char *config_path,
5593c8
 			     const struct grub_install_image_target_desc *image_target,
5593c8
 			     int note, size_t appsig_size, grub_compression_t comp,
5593c8
 			     const char *dtb_path, const char *sbat_path,
5593c8
@@ -913,6 +914,19 @@ grub_install_generate_image (const char *dir, const char *prefix,
5593c8
       }
5593c8
   }
5593c8
 
5593c8
+  {
5593c8
+    size_t i;
5593c8
+    for (i = 0; i < nx509keys; i++)
5593c8
+      {
5593c8
+	size_t curs;
5593c8
+	curs = ALIGN_ADDR (grub_util_get_image_size (x509key_paths[i]));
5593c8
+	grub_util_info ("the size of x509 public key %u is 0x%"
5593c8
+			GRUB_HOST_PRIxLONG_LONG,
5593c8
+			(unsigned) i, (unsigned long long) curs);
5593c8
+	total_module_size += curs + sizeof (struct grub_module_header);
5593c8
+      }
5593c8
+  }
5593c8
+
5593c8
   if (memdisk_path)
5593c8
     {
5593c8
       memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
5593c8
@@ -1034,7 +1048,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
5593c8
 	curs = grub_util_get_image_size (pubkey_paths[i]);
5593c8
 
5593c8
 	header = (struct grub_module_header *) (kernel_img + offset);
5593c8
-	header->type = grub_host_to_target32 (OBJ_TYPE_PUBKEY);
5593c8
+	header->type = grub_host_to_target32 (OBJ_TYPE_GPG_PUBKEY);
5593c8
 	header->size = grub_host_to_target32 (curs + sizeof (*header));
5593c8
 	offset += sizeof (*header);
5593c8
 
5593c8
@@ -1043,6 +1057,26 @@ grub_install_generate_image (const char *dir, const char *prefix,
5593c8
       }
5593c8
   }
5593c8
 
5593c8
+  {
5593c8
+    size_t i;
5593c8
+    for (i = 0; i < nx509keys; i++)
5593c8
+      {
5593c8
+	size_t curs;
5593c8
+	struct grub_module_header *header;
5593c8
+
5593c8
+	curs = grub_util_get_image_size (x509key_paths[i]);
5593c8
+
5593c8
+	header = (struct grub_module_header *) (kernel_img + offset);
5593c8
+	header->type = grub_host_to_target32 (OBJ_TYPE_X509_PUBKEY);
5593c8
+	header->size = grub_host_to_target32 (curs + sizeof (*header));
5593c8
+	offset += sizeof (*header);
5593c8
+
5593c8
+	grub_util_load_image (x509key_paths[i], kernel_img + offset);
5593c8
+	offset += ALIGN_ADDR (curs);
5593c8
+      }
5593c8
+  }
5593c8
+
5593c8
+
5593c8
   if (memdisk_path)
5593c8
     {
5593c8
       struct grub_module_header *header;
5593c8
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
5593c8
index 55849777eaa..98edc0863f6 100644
5593c8
--- a/include/grub/kernel.h
5593c8
+++ b/include/grub/kernel.h
5593c8
@@ -30,7 +30,9 @@ enum
5593c8
   OBJ_TYPE_PREFIX,
5593c8
   OBJ_TYPE_PUBKEY,
5593c8
   OBJ_TYPE_DTB,
5593c8
-  OBJ_TYPE_DISABLE_SHIM_LOCK
5593c8
+  OBJ_TYPE_DISABLE_SHIM_LOCK,
5593c8
+  OBJ_TYPE_GPG_PUBKEY,
5593c8
+  OBJ_TYPE_X509_PUBKEY,
5593c8
 };
5593c8
 
5593c8
 /* The module header.  */
5593c8
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
5593c8
index cf4531e02b6..51f3b13ac13 100644
5593c8
--- a/include/grub/util/install.h
5593c8
+++ b/include/grub/util/install.h
5593c8
@@ -67,6 +67,8 @@
5593c8
       N_("SBAT metadata"), 0 },						\
5593c8
   { "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0,	\
5593c8
       N_("disable shim_lock verifier"), 0 },				\
5593c8
+  { "x509key",   'x', N_("FILE"), 0,					\
5593c8
+      N_("embed FILE as an x509 certificate for signature checking"), 0}, \
5593c8
   { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\
5593c8
     "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \
5593c8
     1},                                                                 \
5593c8
@@ -188,8 +190,9 @@ void
5593c8
 grub_install_generate_image (const char *dir, const char *prefix,
5593c8
 			     FILE *out,
5593c8
 			     const char *outname, char *mods[],
5593c8
-			     char *memdisk_path, char **pubkey_paths,
5593c8
-			     size_t npubkeys,
5593c8
+			     char *memdisk_path,
5593c8
+			     char **pubkey_paths, size_t npubkeys,
5593c8
+			     char **x509key_paths, size_t nx509keys,
5593c8
 			     char *config_path,
5593c8
 			     const struct grub_install_image_target_desc *image_target,
5593c8
 			     int note, size_t appsig_size,