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

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