From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: Heinrich Schuchardt <xypron.glpk@gmx.de>
Cc: ilias.apalodimas@linaro.org, sughosh.ganu@linaro.org,
masami.hiramatsu@linaro.org, u-boot@lists.denx.de,
agraf@csgraf.de, sjg@chromium.org
Subject: Re: [PATCH v6 03/12] tools: mkeficapsule: add firmwware image signing
Date: Mon, 8 Nov 2021 13:38:16 +0900 [thread overview]
Message-ID: <20211108043816.GC16401@laputa> (raw)
In-Reply-To: <a6085796-6810-8ba9-2205-3dc006a6bbb6@gmx.de>
On Sun, Nov 07, 2021 at 07:53:24AM +0100, Heinrich Schuchardt wrote:
> On 11/2/21 01:55, AKASHI Takahiro wrote:
> > With this enhancement, mkeficapsule will be able to sign a capsule
> > file when it is created. A signature added will be used later
> > in the verification at FMP's SetImage() call.
> >
> > To do that, We need specify additional command parameters:
> > -monotonic-cout <count> : monotonic count
> > -private-key <private key file> : private key file
> > -certificate <certificate file> : certificate file
> > Only when all of those parameters are given, a signature will be added
> > to a capsule file.
> >
> > Users are expected to maintain and increment the monotonic count at
> > every time of the update for each firmware image.
> >
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > Reviewed-by: Simon Glass <sjg@chromium.org>
>
> You licensed tools/mkeficapsule.c under GPL-2.0 which is imcompatible
> with OpenSSL (https://www.gnu.org/licenses/license-list.html#OpenSSL).
In fact, this is not a this-tool-specific issue, but other tools,
including mkimage, have it and that is why CONFIG_TOOLS_LIBCRYPTO was
introduced.
# I think that I have mentioned the issue in my past comment.
-Takahiro Akashi
> Either agree with all contributors of the tool to use a more liberal
> license or use another library.
>
> > ---
> > tools/Kconfig | 8 +
> > tools/Makefile | 8 +-
> > tools/mkeficapsule.c | 382 ++++++++++++++++++++++++++++++++++++++++---
> > 3 files changed, 376 insertions(+), 22 deletions(-)
> >
> > diff --git a/tools/Kconfig b/tools/Kconfig
> > index 91ce8ae3e516..117c921da3fe 100644
> > --- a/tools/Kconfig
> > +++ b/tools/Kconfig
> > @@ -90,4 +90,12 @@ config TOOLS_SHA512
> > help
> > Enable SHA512 support in the tools builds
> >
> > +config TOOLS_MKEFICAPSULE
> > + bool "Build efimkcapsule command"
> > + default y if EFI_CAPSULE_ON_DISK
> > + help
> > + This command allows users to create a UEFI capsule file and,
> > + optionally sign that file. If you want to enable UEFI capsule
> > + update feature on your target, you certainly need this.
> > +
> > endmenu
> > diff --git a/tools/Makefile b/tools/Makefile
> > index b45219e2c30c..5a73cc4b363d 100644
> > --- a/tools/Makefile
> > +++ b/tools/Makefile
> > @@ -238,8 +238,12 @@ hostprogs-$(CONFIG_MIPS) += mips-relocs
> > hostprogs-$(CONFIG_ASN1_COMPILER) += asn1_compiler
> > HOSTCFLAGS_asn1_compiler.o = -idirafter $(srctree)/include
> >
> > -mkeficapsule-objs := mkeficapsule.o $(LIBFDT_OBJS)
> > -hostprogs-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += mkeficapsule
> > +HOSTLDLIBS_mkeficapsule += -luuid
> > +ifeq ($(CONFIG_TOOLS_LIBCRYPTO),y)
> > +HOSTLDLIBS_mkeficapsule += \
> > + $(shell pkg-config --libs libssl libcrypto 2> /dev/null || echo "-lssl -lcrypto")
> > +endif
> > +hostprogs-$(CONFIG_TOOLS_MKEFICAPSULE) += mkeficapsule
> >
> > # We build some files with extra pedantic flags to try to minimize things
> > # that won't build on some weird host compiler -- though there are lots of
> > diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
> > index 8427fedd941c..086757ee8ad7 100644
> > --- a/tools/mkeficapsule.c
> > +++ b/tools/mkeficapsule.c
> > @@ -15,6 +15,16 @@
> > #include <sys/stat.h>
> > #include <sys/types.h>
> >
> > +#include <linux/kconfig.h>
> > +#ifdef CONFIG_TOOLS_LIBCRYPTO
> > +#include <openssl/asn1.h>
> > +#include <openssl/bio.h>
> > +#include <openssl/evp.h>
> > +#include <openssl/err.h>
> > +#include <openssl/pem.h>
> > +#include <openssl/pkcs7.h>
> > +#endif
> > +
> > typedef __u8 u8;
> > typedef __u16 u16;
> > typedef __u32 u32;
> > @@ -38,12 +48,25 @@ efi_guid_t efi_guid_image_type_uboot_fit =
> > EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID;
> > efi_guid_t efi_guid_image_type_uboot_raw =
> > EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID;
> > +efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
> > +
> > +#ifdef CONFIG_TOOLS_LIBCRYPTO
> > +static const char *opts_short = "f:r:i:I:v:p:c:m:dh";
> > +#else
> > +static const char *opts_short = "f:r:i:I:v:h";
> > +#endif
> >
> > static struct option options[] = {
> > {"fit", required_argument, NULL, 'f'},
> > {"raw", required_argument, NULL, 'r'},
> > {"index", required_argument, NULL, 'i'},
> > {"instance", required_argument, NULL, 'I'},
> > +#ifdef CONFIG_TOOLS_LIBCRYPTO
> > + {"private-key", required_argument, NULL, 'p'},
> > + {"certificate", required_argument, NULL, 'c'},
> > + {"monotonic-count", required_argument, NULL, 'm'},
> > + {"dump-sig", no_argument, NULL, 'd'},
> > +#endif
> > {"help", no_argument, NULL, 'h'},
> > {NULL, 0, NULL, 0},
> > };
> > @@ -57,10 +80,252 @@ static void print_usage(void)
> > "\t-r, --raw <raw image> new raw image file\n"
> > "\t-i, --index <index> update image index\n"
> > "\t-I, --instance <instance> update hardware instance\n"
> > +#ifdef CONFIG_TOOLS_LIBCRYPTO
> > + "\t-p, --private-key <privkey file> private key file\n"
> > + "\t-c, --certificate <cert file> signer's certificate file\n"
> > + "\t-m, --monotonic-count <count> monotonic count\n"
> > + "\t-d, --dump_sig dump signature (*.p7)\n"
> > +#endif
> > "\t-h, --help print a help message\n",
> > tool_name);
> > }
> >
> > +/**
> > + * auth_context - authentication context
> > + * @key_file: Path to a private key file
> > + * @cert_file: Path to a certificate file
> > + * @image_data: Pointer to firmware data
> > + * @image_size: Size of firmware data
> > + * @auth: Authentication header
> > + * @sig_data: Signature data
> > + * @sig_size: Size of signature data
> > + *
> > + * Data structure used in create_auth_data(). @key_file through
> > + * @image_size are input parameters. @auth, @sig_data and @sig_size
> > + * are filled in by create_auth_data().
> > + */
> > +struct auth_context {
> > + char *key_file;
> > + char *cert_file;
> > + u8 *image_data;
> > + size_t image_size;
> > + struct efi_firmware_image_authentication auth;
> > + u8 *sig_data;
> > + size_t sig_size;
> > +};
> > +
> > +static int dump_sig;
> > +
> > +#ifdef CONFIG_TOOLS_LIBCRYPTO
> > +/**
> > + * fileio-read_pkey - read out a private key
> > + * @filename: Path to a private key file
> > + *
> > + * Read out a private key file and parse it into "EVP_PKEY" structure.
> > + *
> > + * Return:
> > + * * Pointer to private key structure - on success
> > + * * NULL - on failure
> > + */
> > +static EVP_PKEY *fileio_read_pkey(const char *filename)
> > +{
> > + EVP_PKEY *key = NULL;
> > + BIO *bio;
> > +
> > + bio = BIO_new_file(filename, "r");
> > + if (!bio)
> > + goto out;
> > +
> > + key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
> > +
> > +out:
> > + BIO_free_all(bio);
> > + if (!key) {
> > + printf("Can't load key from file '%s'\n", filename);
> > + ERR_print_errors_fp(stderr);
> > + }
> > +
> > + return key;
> > +}
> > +
> > +/**
> > + * fileio-read_cert - read out a certificate
> > + * @filename: Path to a certificate file
> > + *
> > + * Read out a certificate file and parse it into "X509" structure.
> > + *
> > + * Return:
> > + * * Pointer to certificate structure - on success
> > + * * NULL - on failure
> > + */
> > +static X509 *fileio_read_cert(const char *filename)
> > +{
> > + X509 *cert = NULL;
> > + BIO *bio;
> > +
> > + bio = BIO_new_file(filename, "r");
> > + if (!bio)
> > + goto out;
> > +
> > + cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
> > +
> > +out:
> > + BIO_free_all(bio);
> > + if (!cert) {
> > + printf("Can't load certificate from file '%s'\n", filename);
> > + ERR_print_errors_fp(stderr);
> > + }
> > +
> > + return cert;
> > +}
> > +
> > +/**
> > + * create_auth_data - compose authentication data in capsule
> > + * @auth_context: Pointer to authentication context
> > + *
> > + * Fill up an authentication header (.auth) and signature data (.sig_data)
> > + * in @auth_context, using library functions from openssl.
> > + * All the parameters in @auth_context must be filled in by a caller.
> > + *
> > + * Return:
> > + * * 0 - on success
> > + * * -1 - on failure
> > + */
> > +static int create_auth_data(struct auth_context *ctx)
> > +{
> > + EVP_PKEY *key = NULL;
> > + X509 *cert = NULL;
> > + BIO *data_bio = NULL;
> > + const EVP_MD *md;
> > + PKCS7 *p7;
> > + int flags, ret = -1;
> > +
> > + OpenSSL_add_all_digests();
> > + OpenSSL_add_all_ciphers();
> > + ERR_load_crypto_strings();
> > +
> > + key = fileio_read_pkey(ctx->key_file);
> > + if (!key)
> > + goto err;
> > + cert = fileio_read_cert(ctx->cert_file);
> > + if (!cert)
> > + goto err;
> > +
> > + /*
> > + * create a BIO, containing:
> > + * * firmware image
> > + * * monotonic count
> > + * in this order!
> > + * See EDK2's FmpAuthenticatedHandlerRsa2048Sha256()
> > + */
> > + data_bio = BIO_new(BIO_s_mem());
> > + BIO_write(data_bio, ctx->image_data, ctx->image_size);
> > + BIO_write(data_bio, &ctx->auth.monotonic_count,
> > + sizeof(ctx->auth.monotonic_count));
> > +
> > + md = EVP_get_digestbyname("SHA256");
> > + if (!md)
> > + goto err;
> > +
> > + /* create signature */
> > + /* TODO: maybe add PKCS7_NOATTR and PKCS7_NOSMIMECAP */
> > + flags = PKCS7_BINARY | PKCS7_DETACHED;
> > + p7 = PKCS7_sign(NULL, NULL, NULL, data_bio, flags | PKCS7_PARTIAL);
> > + if (!p7)
> > + goto err;
> > + if (!PKCS7_sign_add_signer(p7, cert, key, md, flags))
> > + goto err;
> > + if (!PKCS7_final(p7, data_bio, flags))
> > + goto err;
> > +
> > + /* convert pkcs7 into DER */
> > + ctx->sig_data = NULL;
> > + ctx->sig_size = ASN1_item_i2d((ASN1_VALUE *)p7, &ctx->sig_data,
> > + ASN1_ITEM_rptr(PKCS7));
> > + if (!ctx->sig_size)
> > + goto err;
> > +
> > + /* fill auth_info */
> > + ctx->auth.auth_info.hdr.dwLength = sizeof(ctx->auth.auth_info)
> > + + ctx->sig_size;
> > + ctx->auth.auth_info.hdr.wRevision = WIN_CERT_REVISION_2_0;
> > + ctx->auth.auth_info.hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;
> > + memcpy(&ctx->auth.auth_info.cert_type, &efi_guid_cert_type_pkcs7,
> > + sizeof(efi_guid_cert_type_pkcs7));
> > +
> > + ret = 0;
> > +err:
> > + BIO_free_all(data_bio);
> > + EVP_PKEY_free(key);
> > + X509_free(cert);
> > +
> > + return ret;
> > +}
> > +
> > +/**
> > + * dump_signature - dump out a signature
> > + * @path: Path to a capsule file
> > + * @signature: Signature data
> > + * @sig_size: Size of signature data
> > + *
> > + * Signature data pointed to by @signature will be saved into
> > + * a file whose file name is @path with ".p7" suffix.
> > + *
> > + * Return:
> > + * * 0 - on success
> > + * * -1 - on failure
> > + */
> > +static int dump_signature(const char *path, u8 *signature, size_t sig_size)
> > +{
> > + char *sig_path;
> > + FILE *f;
> > + size_t size;
> > + int ret = -1;
> > +
> > + sig_path = malloc(strlen(path) + 3 + 1);
> > + if (!sig_path)
> > + return ret;
> > +
> > + sprintf(sig_path, "%s.p7", path);
> > + f = fopen(sig_path, "w");
> > + if (!f)
> > + goto err;
> > +
> > + size = fwrite(signature, 1, sig_size, f);
> > + if (size == sig_size)
> > + ret = 0;
> > +
> > + fclose(f);
> > +err:
> > + free(sig_path);
> > + return ret;
> > +}
> > +
> > +/**
> > + * free_sig_data - free out signature data
> > + * @ctx: Pointer to authentication context
> > + *
> > + * Free signature data allocated in create_auth_data().
> > + */
> > +static void free_sig_data(struct auth_context *ctx)
> > +{
> > + if (ctx->sig_size)
> > + OPENSSL_free(ctx->sig_data);
> > +}
> > +#else
> > +static int create_auth_data(struct auth_context *ctx)
> > +{
> > + return 0;
> > +}
> > +
> > +static int dump_signature(const char *path, u8 *signature, size_t sig_size)
> > +{
> > + return 0;
> > +}
> > +
> > +static void free_sig_data(struct auth_context *ctx) {}
> > +#endif
> > +
> > /**
> > * read_bin_file - read a firmware binary file
> > * @bin: Path to a firmware binary file
> > @@ -162,11 +427,13 @@ static int write_capsule_file(FILE *f, void *data, size_t size, const char *msg)
> > * * -1 - on failure
> > */
> > static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
> > - unsigned long index, unsigned long instance)
> > + unsigned long index, unsigned long instance,
> > + uint64_t mcount, char *privkey_file, char *cert_file)
> > {
> > struct efi_capsule_header header;
> > struct efi_firmware_management_capsule_header capsule;
> > struct efi_firmware_management_capsule_image_header image;
> > + struct auth_context auth_context;
> > FILE *f;
> > void *data;
> > off_t bin_size;
> > @@ -176,9 +443,9 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
> > #ifdef DEBUG
>
> scripts/checkpatch.pl gives the following warning for this file:
>
> Use 'if (IS_ENABLED(CONFIG...))' instead of '#if or #ifdef' where possible.
>
> Best regards
>
> Heinrich
>
> > printf("For output: %s\n", path);
> > printf("\tbin: %s\n\ttype: %pUl\n", bin, guid);
> > - printf("\tindex: %ld\n\tinstance: %ld\n", index, instance);
> > + printf("\tindex: %lu\n\tinstance: %lu\n", index, instance);
> > #endif
> > -
> > + auth_context.sig_size = 0;
> > f = NULL;
> > data = NULL;
> > ret = -1;
> > @@ -189,6 +456,27 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
> > if (read_bin_file(bin, &data, &bin_size))
> > goto err;
> >
> > + /* first, calculate signature to determine its size */
> > + if (privkey_file && cert_file) {
> > + auth_context.key_file = privkey_file;
> > + auth_context.cert_file = cert_file;
> > + auth_context.auth.monotonic_count = mcount;
> > + auth_context.image_data = data;
> > + auth_context.image_size = bin_size;
> > +
> > + if (create_auth_data(&auth_context)) {
> > + printf("Signing firmware image failed\n");
> > + goto err;
> > + }
> > +
> > + if (dump_sig &&
> > + dump_signature(path, auth_context.sig_data,
> > + auth_context.sig_size)) {
> > + printf("Creating signature file failed\n");
> > + goto err;
> > + }
> > + }
> > +
> > /*
> > * write a capsule file
> > */
> > @@ -209,6 +497,9 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
> > + sizeof(capsule) + sizeof(u64)
> > + sizeof(image)
> > + bin_size;
> > + if (auth_context.sig_size)
> > + header.capsule_image_size += sizeof(auth_context.auth)
> > + + auth_context.sig_size;
> > if (write_capsule_file(f, &header, sizeof(header),
> > "Capsule header"))
> > goto err;
> > @@ -239,13 +530,32 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
> > image.reserved[1] = 0;
> > image.reserved[2] = 0;
> > image.update_image_size = bin_size;
> > + if (auth_context.sig_size)
> > + image.update_image_size += sizeof(auth_context.auth)
> > + + auth_context.sig_size;
> > image.update_vendor_code_size = 0; /* none */
> > image.update_hardware_instance = instance;
> > image.image_capsule_support = 0;
> > + if (auth_context.sig_size)
> > + image.image_capsule_support |= CAPSULE_SUPPORT_AUTHENTICATION;
> > if (write_capsule_file(f, &image, sizeof(image),
> > "Firmware capsule image header"))
> > goto err;
> >
> > + /*
> > + * signature
> > + */
> > + if (auth_context.sig_size) {
> > + if (write_capsule_file(f, &auth_context.auth,
> > + sizeof(auth_context.auth),
> > + "Authentication header"))
> > + goto err;
> > +
> > + if (write_capsule_file(f, auth_context.sig_data,
> > + auth_context.sig_size, "Signature"))
> > + goto err;
> > + }
> > +
> > /*
> > * firmware binary
> > */
> > @@ -262,23 +572,37 @@ err:
> > return ret;
> > }
> >
> > -/*
> > - * Usage:
> > - * $ mkeficapsule -f <firmware binary> <output file>
> > +/**
> > + * main - main entry function of mkeficapsule
> > + * @argc: Number of arguments
> > + * @argv: Array of pointers to arguments
> > + *
> > + * Create an uefi capsule file, optionally signing it.
> > + * Parse all the arguments and pass them on to create_fwbin().
> > + *
> > + * Return:
> > + * * 0 - on success
> > + * * -1 - on failure
> > */
> > int main(int argc, char **argv)
> > {
> > char *file;
> > efi_guid_t *guid;
> > unsigned long index, instance;
> > + uint64_t mcount;
> > + char *privkey_file, *cert_file;
> > int c, idx;
> >
> > file = NULL;
> > guid = NULL;
> > index = 0;
> > instance = 0;
> > + mcount = 0;
> > + privkey_file = NULL;
> > + cert_file = NULL;
> > + dump_sig = 0;
> > for (;;) {
> > - c = getopt_long(argc, argv, "f:r:i:I:v:h", options, &idx);
> > + c = getopt_long(argc, argv, opts_short, options, &idx);
> > if (c == -1)
> > break;
> >
> > @@ -286,7 +610,7 @@ int main(int argc, char **argv)
> > case 'f':
> > if (file) {
> > printf("Image already specified\n");
> > - return -1;
> > + exit(EXIT_FAILURE);
> > }
> > file = optarg;
> > guid = &efi_guid_image_type_uboot_fit;
> > @@ -294,7 +618,7 @@ int main(int argc, char **argv)
> > case 'r':
> > if (file) {
> > printf("Image already specified\n");
> > - return -1;
> > + exit(EXIT_FAILURE);
> > }
> > file = optarg;
> > guid = &efi_guid_image_type_uboot_raw;
> > @@ -305,26 +629,44 @@ int main(int argc, char **argv)
> > case 'I':
> > instance = strtoul(optarg, NULL, 0);
> > break;
> > +#ifdef CONFIG_TOOLS_LIBCRYPTO
> > + case 'p':
> > + if (privkey_file) {
> > + printf("Private Key already specified\n");
> > + exit(EXIT_FAILURE);
> > + }
> > + privkey_file = optarg;
> > + break;
> > + case 'c':
> > + if (cert_file) {
> > + printf("Certificate file already specified\n");
> > + exit(EXIT_FAILURE);
> > + }
> > + cert_file = optarg;
> > + break;
> > + case 'm':
> > + mcount = strtoul(optarg, NULL, 0);
> > + break;
> > + case 'd':
> > + dump_sig = 1;
> > + break;
> > +#endif /* CONFIG_TOOLS_LIBCRYPTO */
> > case 'h':
> > print_usage();
> > - return 0;
> > + exit(EXIT_SUCCESS);
> > }
> > }
> >
> > - /* need an output file */
> > - if (argc != optind + 1) {
> > + /* check necessary parameters */
> > + if ((argc != optind + 1) || !file ||
> > + ((privkey_file && !cert_file) ||
> > + (!privkey_file && cert_file))) {
> > print_usage();
> > exit(EXIT_FAILURE);
> > }
> >
> > - /* need a fit image file or raw image file */
> > - if (!file) {
> > - print_usage();
> > - exit(EXIT_SUCCESS);
> > - }
> > -
> > - if (create_fwbin(argv[optind], file, guid, index, instance)
> > - < 0) {
> > + if (create_fwbin(argv[optind], file, guid, index, instance,
> > + mcount, privkey_file, cert_file) < 0) {
> > printf("Creating firmware capsule failed\n");
> > exit(EXIT_FAILURE);
> > }
> >
next prev parent reply other threads:[~2021-11-08 4:38 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-02 0:55 [PATCH v6 00/12] efi_loader: capsule: improve capsule authentication support AKASHI Takahiro
2021-11-02 0:55 ` [PATCH v6 01/12] efi_loader: capsule: drop __weak from efi_get_public_key_data() AKASHI Takahiro
2021-11-02 0:55 ` [PATCH v6 02/12] tools: mkeficapsule: rework the code a little bit AKASHI Takahiro
2021-11-02 14:57 ` Simon Glass
2021-11-07 6:35 ` Heinrich Schuchardt
2021-11-08 4:18 ` AKASHI Takahiro
2021-11-02 0:55 ` [PATCH v6 03/12] tools: mkeficapsule: add firmwware image signing AKASHI Takahiro
2021-11-07 6:53 ` Heinrich Schuchardt
2021-11-08 4:38 ` AKASHI Takahiro [this message]
2021-11-02 0:55 ` [PATCH v6 04/12] tools: mkeficapsule: add man page AKASHI Takahiro
2021-11-02 0:55 ` [PATCH v6 05/12] doc: update UEFI document for usage of mkeficapsule AKASHI Takahiro
2021-11-02 0:55 ` [PATCH v6 06/12] test/py: efi_capsule: add image authentication test AKASHI Takahiro
2021-11-02 14:58 ` Simon Glass
2021-11-02 16:15 ` Ilias Apalodimas
2021-11-02 0:55 ` [PATCH v6 07/12] tools: mkeficapsule: allow for specifying GUID explicitly AKASHI Takahiro
2021-11-02 14:58 ` Simon Glass
2021-11-04 2:12 ` AKASHI Takahiro
2021-11-04 2:49 ` Simon Glass
2021-11-02 0:55 ` [PATCH v6 08/12] test/py: efi_capsule: align with the syntax change of mkeficapsule AKASHI Takahiro
2021-11-02 14:58 ` Simon Glass
2021-11-02 0:55 ` [PATCH v6 09/12] test/py: efi_capsule: add a test for "--guid" option AKASHI Takahiro
2021-11-02 0:55 ` [PATCH v6 10/12] test/py: efi_capsule: check the results in case of CAPSULE_AUTHENTICATE AKASHI Takahiro
2021-11-02 14:58 ` Simon Glass
2021-11-02 0:55 ` [PATCH v6 11/12] (RFC) tools: add fdtsig.sh AKASHI Takahiro
2021-11-02 0:55 ` [PATCH v6 12/12] (RFC) efi_loader, dts: add public keys for capsules to device tree AKASHI Takahiro
2021-11-02 14:58 ` Simon Glass
2021-11-04 2:17 ` AKASHI Takahiro
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=20211108043816.GC16401@laputa \
--to=takahiro.akashi@linaro.org \
--cc=agraf@csgraf.de \
--cc=ilias.apalodimas@linaro.org \
--cc=masami.hiramatsu@linaro.org \
--cc=sjg@chromium.org \
--cc=sughosh.ganu@linaro.org \
--cc=u-boot@lists.denx.de \
--cc=xypron.glpk@gmx.de \
/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.