From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1kXajV-0001HI-0f for mharc-grub-devel@gnu.org; Tue, 27 Oct 2020 21:58:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:46646) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kXajT-0001Gj-WE for grub-devel@gnu.org; Tue, 27 Oct 2020 21:58:36 -0400 Received: from mail-pf1-x443.google.com ([2607:f8b0:4864:20::443]:38336) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kXajR-0007re-82 for grub-devel@gnu.org; Tue, 27 Oct 2020 21:58:35 -0400 Received: by mail-pf1-x443.google.com with SMTP id 10so2012640pfp.5 for ; Tue, 27 Oct 2020 18:58:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axtens.net; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/uUCQUPPRefMDZp97RklhXUt9IczEOaaMNCSuhwnibQ=; b=lsJB1Bo97tY26MrMHv/w/btWp4KwNTmvMejK030FZezB1BUHdZuh4TGrQDJl1wZtvG FpW7UhVuEq6Us7G5ncL/0fAWhiyXuHJDYx3TkCeVJisDUS4FptyT5rT6CFFbr1rWIA3B bw+sCWY+857PzMcMCxCnMlB8TFvqAGRYV6Z98= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/uUCQUPPRefMDZp97RklhXUt9IczEOaaMNCSuhwnibQ=; b=ia6rw9tECGPAADiC9DeIApfnHVcKEVk9/nnkwLBOoXhTz7RxWlgkIOomDE+oRsDAHU qljCMxpNU8nDtfKaopi4GjAlnBUK4jgzKaegJ6fZJTMktth7Cjnm0/FsMwrJtbWB0m0E CNqaefSmn5f4wAjXrZii7/3yn8p2JsRqfWLdEfDg9lhuSt6v6CcgpZNlgUbicuBXcHs+ y+dCQRlCqpUwdGDMufZQuIxgRXjT3V8O2/z2+KDNrCA8J9LnpSIql5y4/tUh7jj+WPbq lR09o6pS1SkWtKuGFvya5FqRB95Yn5aC6vzp9NJN6WXdbMnxhGFRPW7i/zvH8QVHbfqH 3Chg== X-Gm-Message-State: AOAM533cXXNbGiHjJ5AKr+F+d3MvSnh6oL01W6pGvZEs/7gGEVd9hR8t +T03wispuKG6rXFM9u1PTXsdejwyxTE+Qg== X-Google-Smtp-Source: ABdhPJxwMXo2kGVf1p72LNiZfAW6Xmg5zEdgfN5IE7ssqOtdXStR21T1DEuwrxPuKSm5nbsW7dNrow== X-Received: by 2002:a63:1810:: with SMTP id y16mr4243925pgl.309.1603850311130; Tue, 27 Oct 2020 18:58:31 -0700 (PDT) Received: from localhost (2001-44b8-1113-6700-b4f7-e8d4-abaa-2197.static.ipv6.internode.on.net. [2001:44b8:1113:6700:b4f7:e8d4:abaa:2197]) by smtp.gmail.com with ESMTPSA id w135sm3582533pfc.103.2020.10.27.18.58.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Oct 2020 18:58:30 -0700 (PDT) From: Daniel Axtens To: grub-devel@gnu.org Cc: rashmica.g@gmail.com, alastair@d-silva.org, Daniel Axtens Subject: [PATCH v2 13/18] grub-install: support embedding x509 certificates Date: Wed, 28 Oct 2020 12:57:30 +1100 Message-Id: <20201028015735.1131291-14-dja@axtens.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201028015735.1131291-1-dja@axtens.net> References: <20201028015735.1131291-1-dja@axtens.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=2607:f8b0:4864:20::443; envelope-from=dja@axtens.net; helo=mail-pf1-x443.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Oct 2020 01:58:36 -0000 From: Alastair D'Silva To support verification of appended signatures, we need a way to embed the necessary public keys. Existing appended signature schemes in the Linux kernel use X.509 certificates, so allow certificates to be embedded in the grub core image in the same way as PGP keys. Signed-off-by: Alastair D'Silva Signed-off-by: Daniel Axtens --- grub-core/commands/pgp.c | 2 +- include/grub/kernel.h | 3 ++- include/grub/util/install.h | 7 +++++-- util/grub-install-common.c | 23 ++++++++++++++++++++- util/grub-mkimage.c | 15 ++++++++++++-- util/mkimage.c | 41 ++++++++++++++++++++++++++++++++++--- 6 files changed, 81 insertions(+), 10 deletions(-) diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c index 4e0667c1cd0f..3cd31f50b5b4 100644 --- a/grub-core/commands/pgp.c +++ b/grub-core/commands/pgp.c @@ -944,7 +944,7 @@ GRUB_MOD_INIT(pgp) grub_memset (&pseudo_file, 0, sizeof (pseudo_file)); /* Not an ELF module, skip. */ - if (header->type != OBJ_TYPE_PUBKEY) + if (header->type != OBJ_TYPE_GPG_PUBKEY) continue; pseudo_file.fs = &pseudo_fs; diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 133a37c8d035..53aba82cad12 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -28,7 +28,8 @@ enum OBJ_TYPE_MEMDISK, OBJ_TYPE_CONFIG, OBJ_TYPE_PREFIX, - OBJ_TYPE_PUBKEY, + OBJ_TYPE_GPG_PUBKEY, + OBJ_TYPE_X509_PUBKEY, OBJ_TYPE_DTB }; diff --git a/include/grub/util/install.h b/include/grub/util/install.h index eb1b83b6d946..8353bafb00ad 100644 --- a/include/grub/util/install.h +++ b/include/grub/util/install.h @@ -63,6 +63,8 @@ /* TRANSLATORS: "embed" is a verb (command description). "*/ \ { "pubkey", 'k', N_("FILE"), 0, \ N_("embed FILE as public key for signature checking"), 0}, \ + { "x509key", 'x', N_("FILE"), 0, \ + N_("embed FILE as an x509 certificate for signature checking"), 0}, \ { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\ "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \ 1}, \ @@ -182,8 +184,9 @@ void grub_install_generate_image (const char *dir, const char *prefix, FILE *out, const char *outname, char *mods[], - char *memdisk_path, char **pubkey_paths, - size_t npubkeys, + char *memdisk_path, + char **pubkey_paths, size_t npubkeys, + char **x509key_paths, size_t nx509keys, char *config_path, const struct grub_install_image_target_desc *image_target, int note, size_t appsig_size, diff --git a/util/grub-install-common.c b/util/grub-install-common.c index 133dc85452dd..3c81d42bb189 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -307,6 +307,8 @@ handle_install_list (struct install_list *il, const char *val, static char **pubkeys; static size_t npubkeys; +static char **x509keys; +static size_t nx509keys; static grub_compression_t compression; static size_t appsig_size; @@ -339,6 +341,12 @@ grub_install_parse (int key, char *arg) * (npubkeys + 1)); pubkeys[npubkeys++] = xstrdup (arg); return 1; + case 'x': + x509keys = xrealloc (x509keys, + sizeof (x509keys[0]) + * (nx509keys + 1)); + x509keys[nx509keys++] = xstrdup (arg); + return 1; case GRUB_INSTALL_OPTIONS_VERBOSITY: verbosity++; @@ -465,6 +473,9 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) slen += 20 + grub_strlen (*pk); + for (pk = x509keys; pk < x509keys + nx509keys; pk++) + slen += 10 + grub_strlen (*pk); + for (md = modules.entries; *md; md++) { slen += 10 + grub_strlen (*md); @@ -493,6 +504,14 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, *p++ = ' '; } + for (pk = x509keys; pk < x509keys + nx509keys; pk++) + { + p = grub_stpcpy (p, "--x509 '"); + p = grub_stpcpy (p, *pk); + *p++ = '\''; + *p++ = ' '; + } + for (md = modules.entries; *md; md++) { *p++ = '\''; @@ -520,7 +539,9 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, grub_install_generate_image (dir, prefix, fp, outname, modules.entries, memdisk_path, - pubkeys, npubkeys, config_path, tgt, + pubkeys, npubkeys, + x509keys, nx509keys, + config_path, tgt, note, appsig_size, compression, dtb); while (dc--) grub_install_pop_module (); diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index c1e07c70dc7e..6034c51ece42 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -75,7 +75,8 @@ static struct argp_option options[] = { /* TRANSLATORS: "embed" is a verb (command description). "*/ {"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0}, /* TRANSLATORS: "embed" is a verb (command description). "*/ - {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for signature checking"), 0}, + {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for PGP signature checking"), 0}, + {"x509", 'x', N_("FILE"), 0, N_("embed FILE as an x509 certificate for appended signature checking"), 0}, /* TRANSLATORS: NOTE is a name of segment. */ {"note", 'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0}, {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0}, @@ -122,6 +123,8 @@ struct arguments char *dtb; char **pubkeys; size_t npubkeys; + char **x509keys; + size_t nx509keys; char *font; char *config; int note; @@ -202,6 +205,13 @@ argp_parser (int key, char *arg, struct argp_state *state) arguments->pubkeys[arguments->npubkeys++] = xstrdup (arg); break; + case 'x': + arguments->x509keys = xrealloc (arguments->x509keys, + sizeof (arguments->x509keys[0]) + * (arguments->nx509keys + 1)); + arguments->x509keys[arguments->nx509keys++] = xstrdup (arg); + break; + case 'c': if (arguments->config) free (arguments->config); @@ -317,7 +327,8 @@ main (int argc, char *argv[]) grub_install_generate_image (arguments.dir, arguments.prefix, fp, arguments.output, arguments.modules, arguments.memdisk, arguments.pubkeys, - arguments.npubkeys, arguments.config, + arguments.npubkeys, arguments.x509keys, + arguments.nx509keys, arguments.config, arguments.image_target, arguments.note, arguments.appsig_size, arguments.comp, arguments.dtb); diff --git a/util/mkimage.c b/util/mkimage.c index bd06968deccb..5702a00d06fa 100644 --- a/util/mkimage.c +++ b/util/mkimage.c @@ -819,8 +819,10 @@ grub_install_get_image_targets_string (void) void grub_install_generate_image (const char *dir, const char *prefix, FILE *out, const char *outname, char *mods[], - char *memdisk_path, char **pubkey_paths, - size_t npubkeys, char *config_path, + char *memdisk_path, + char **pubkey_paths, size_t npubkeys, + char **x509key_paths, size_t nx509keys, + char *config_path, const struct grub_install_image_target_desc *image_target, int note, size_t appsig_size, grub_compression_t comp, const char *dtb_path) { @@ -864,6 +866,19 @@ grub_install_generate_image (const char *dir, const char *prefix, } } + { + size_t i; + for (i = 0; i < nx509keys; i++) + { + size_t curs; + curs = ALIGN_ADDR (grub_util_get_image_size (x509key_paths[i])); + grub_util_info ("the size of x509 public key %u is 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned) i, (unsigned long long) curs); + total_module_size += curs + sizeof (struct grub_module_header); + } + } + if (memdisk_path) { memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); @@ -979,7 +994,7 @@ grub_install_generate_image (const char *dir, const char *prefix, curs = grub_util_get_image_size (pubkey_paths[i]); header = (struct grub_module_header *) (kernel_img + offset); - header->type = grub_host_to_target32 (OBJ_TYPE_PUBKEY); + header->type = grub_host_to_target32 (OBJ_TYPE_GPG_PUBKEY); header->size = grub_host_to_target32 (curs + sizeof (*header)); offset += sizeof (*header); @@ -988,6 +1003,26 @@ grub_install_generate_image (const char *dir, const char *prefix, } } + { + size_t i; + for (i = 0; i < nx509keys; i++) + { + size_t curs; + struct grub_module_header *header; + + curs = grub_util_get_image_size (x509key_paths[i]); + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_X509_PUBKEY); + header->size = grub_host_to_target32 (curs + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (x509key_paths[i], kernel_img + offset); + offset += ALIGN_ADDR (curs); + } + } + + if (memdisk_path) { struct grub_module_header *header; -- 2.25.1