From patchwork Thu Jul 14 18:39:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 590398 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5817:0:0:0:0 with SMTP id j23csp1851010max; Thu, 14 Jul 2022 11:42:12 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sasYuA139G38Uj2bpdt7VDWFZvHq2oJZhKT4KXWlUB0vI+H7dcZvjcorUpPNxFe2rhi8BT X-Received: by 2002:a5d:9d8e:0:b0:67b:8436:b1af with SMTP id ay14-20020a5d9d8e000000b0067b8436b1afmr4847049iob.58.1657824131977; Thu, 14 Jul 2022 11:42:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657824131; cv=none; d=google.com; s=arc-20160816; b=ERWltZac6D8RybUy7SdCnpBLXJJqi+3VBibzEOTEcpFgeGpLrA0n3K2zQuWILLC99g JvxFdNThUqy4KwPu44crnmUGEldgujIIPVfByAT1MerTl3lDaLZk433KOX8opEe0Ybmu Csaa2bx1vsRNa6ESezeelF9sgyZqDjd5AhcRaeeO4nar+mtPKv1NowgE56yWCZ59mqd8 yntwLJup8OigH4jZ69domJBgZKc+uY6ujoNVS1mYvZNo6L887/AVtUNmRNv4hXflujod 4s9/aSMhfRXpA7KNx6uNsZzWKdHSay3NuGY5h1M1aRXSTgn9ow7LLnTTPu5u9LMbF2lv JEZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from; bh=xLJ8UAr5IzUK8zrtzAiDHii92LgP2a1f8fFyBhkSKHU=; b=rchouWvECiTfbtqUVESEikxS2iOzBU9/DOWJHrfQv5ASbLiawqWilx8Ead7BniAwOC zcSF+DjmZQis53yWrF1udkoxeS51KHlHCJbWycTJq80f5HDzIdKTv+4zdHmxM3R8LTNr uqIHX5viH724NdTu7Z9WwjYeO8duHptRTTC+asXuutkw2i1nupV5TMT7tS+3bal4n3AT DsDrmE22M84dN6Dw3YlOC9MQJ3ecViX99aiIzDn6rd6+JSJQwzMvAA3t+KCcGx/CmllC 6Xxulrsa3O2GUM6EYx4pAdDftgT/J3h1bRwnA5Mp2OBQ8FSw0HdfZnbPygQF8RMpAA4a F9Tw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id b187-20020a0219c4000000b0033cc9bf53dcsi2305020jab.30.2022.07.14.11.42.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Jul 2022 11:42:11 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 69BFE84111; Thu, 14 Jul 2022 20:40:42 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 20EDF84137; Thu, 14 Jul 2022 20:40:32 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_SOFTFAIL,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id 3C61E840EE for ; Thu, 14 Jul 2022 20:40:27 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B0FEB1D13; Thu, 14 Jul 2022 11:40:26 -0700 (PDT) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.16.44]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BAEFA3F70D; Thu, 14 Jul 2022 11:40:22 -0700 (PDT) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Takahiro Akashi , Patrick Delaunay , Patrice Chotard , Simon Glass , Bin Meng , Tom Rini , Etienne Carriere , Michal Simek , Jassi Brar , Sughosh Ganu Subject: [PATCH v7 11/13] mkeficapsule: Add support for generating empty capsules Date: Fri, 15 Jul 2022 00:09:11 +0530 Message-Id: <20220714183913.118505-12-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220714183913.118505-1-sughosh.ganu@linaro.org> References: <20220714183913.118505-1-sughosh.ganu@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean The Dependable Boot specification[1] describes the structure of the firmware accept and revert capsules. These are empty capsules which are used for signalling the acceptance or rejection of the updated firmware by the OS. Add support for generating these empty capsules. [1] - https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf Signed-off-by: Sughosh Ganu --- Changes since V6: None doc/mkeficapsule.1 | 29 ++++++++++---- tools/eficapsule.h | 8 ++++ tools/mkeficapsule.c | 92 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 115 insertions(+), 14 deletions(-) diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1 index 09bdc24295..77ca061efd 100644 --- a/doc/mkeficapsule.1 +++ b/doc/mkeficapsule.1 @@ -8,7 +8,7 @@ mkeficapsule \- Generate EFI capsule file for U-Boot .SH SYNOPSIS .B mkeficapsule -.RI [ options "] " image-blob " " capsule-file +.RI [ options ] " " [ image-blob ] " " capsule-file .SH "DESCRIPTION" .B mkeficapsule @@ -23,8 +23,13 @@ Optionally, a capsule file can be signed with a given private key. In this case, the update will be authenticated by verifying the signature before applying. +Additionally, an empty capsule file can be generated for acceptance or +rejection of firmware images by a governing component like an Operating +System. The empty capsules do not require an image-blob input file. + + .B mkeficapsule -takes any type of image files, including: +takes any type of image files when generating non empty capsules, including: .TP .I raw image format is a single binary blob of any type of firmware. @@ -36,18 +41,16 @@ multiple binary blobs in a single capsule file. This type of image file can be generated by .BR mkimage . -.PP -If you want to use other types than above two, you should explicitly -specify a guid for the FMP driver. - .SH "OPTIONS" + .TP .BI "-g\fR,\fB --guid " guid-string Specify guid for image blob type. The format is: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx The first three elements are in little endian, while the rest -is in big endian. +is in big endian. The option must be specified for all non empty and +image acceptance capsules .TP .BI "-i\fR,\fB --index " index @@ -57,6 +60,18 @@ Specify an image index .BI "-I\fR,\fB --instance " instance Specify a hardware instance +.PP +For generation of firmware accept empty capsule +.BR --guid +is mandatory +.TP +.BI "-A\fR,\fB --fw-accept " +Generate a firmware acceptance empty capsule + +.TP +.BI "-R\fR,\fB --fw-revert " +Generate a firmware revert empty capsule + .TP .BR -h ", " --help Print a help message diff --git a/tools/eficapsule.h b/tools/eficapsule.h index d63b831443..072a4b5598 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -41,6 +41,14 @@ typedef struct { EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) +#define FW_ACCEPT_OS_GUID \ + EFI_GUID(0x0c996046, 0xbcc0, 0x4d04, 0x85, 0xec, \ + 0xe1, 0xfc, 0xed, 0xf1, 0xc6, 0xf8) + +#define FW_REVERT_OS_GUID \ + EFI_GUID(0xacd58b4b, 0xc0e8, 0x475f, 0x99, 0xb5, \ + 0x6b, 0x3f, 0x7e, 0x07, 0xaa, 0xf0) + /* flags */ #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000 diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index 5f74d23b9e..244c80e1f7 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -29,7 +29,13 @@ static const char *tool_name = "mkeficapsule"; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; -static const char *opts_short = "g:i:I:v:p:c:m:dh"; +static const char *opts_short = "g:i:I:v:p:c:m:dhAR"; + +enum { + CAPSULE_NORMAL_BLOB = 0, + CAPSULE_ACCEPT, + CAPSULE_REVERT, +} capsule_type; static struct option options[] = { {"guid", required_argument, NULL, 'g'}, @@ -39,6 +45,8 @@ static struct option options[] = { {"certificate", required_argument, NULL, 'c'}, {"monotonic-count", required_argument, NULL, 'm'}, {"dump-sig", no_argument, NULL, 'd'}, + {"fw-accept", no_argument, NULL, 'A'}, + {"fw-revert", no_argument, NULL, 'R'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0}, }; @@ -55,6 +63,8 @@ static void print_usage(void) "\t-c, --certificate signer's certificate file\n" "\t-m, --monotonic-count monotonic count\n" "\t-d, --dump_sig dump signature (*.p7)\n" + "\t-A, --fw-accept firmware accept capsule, requires GUID, no image blob\n" + "\t-R, --fw-revert firmware revert capsule, takes no GUID, no image blob\n" "\t-h, --help print a help message\n", tool_name); } @@ -564,6 +574,49 @@ void convert_uuid_to_guid(unsigned char *buf) buf[7] = c; } +static int create_empty_capsule(char *path, efi_guid_t *guid, bool fw_accept) +{ + struct efi_capsule_header header = { 0 }; + FILE *f = NULL; + int ret = -1; + efi_guid_t fw_accept_guid = FW_ACCEPT_OS_GUID; + efi_guid_t fw_revert_guid = FW_REVERT_OS_GUID; + efi_guid_t capsule_guid; + + f = fopen(path, "w"); + if (!f) { + fprintf(stderr, "cannot open %s\n", path); + goto err; + } + + capsule_guid = fw_accept ? fw_accept_guid : fw_revert_guid; + + memcpy(&header.capsule_guid, &capsule_guid, sizeof(efi_guid_t)); + header.header_size = sizeof(header); + header.flags = 0; + + header.capsule_image_size = fw_accept ? + sizeof(header) + sizeof(efi_guid_t) : sizeof(header); + + if (write_capsule_file(f, &header, sizeof(header), + "Capsule header")) + goto err; + + if (fw_accept) { + if (write_capsule_file(f, guid, sizeof(*guid), + "FW Accept Capsule Payload")) + goto err; + } + + ret = 0; + +err: + if (f) + fclose(f); + + return ret; +} + /** * main - main entry function of mkeficapsule * @argc: Number of arguments @@ -592,6 +645,7 @@ int main(int argc, char **argv) privkey_file = NULL; cert_file = NULL; dump_sig = 0; + capsule_type = CAPSULE_NORMAL_BLOB; for (;;) { c = getopt_long(argc, argv, opts_short, options, &idx); if (c == -1) @@ -639,22 +693,46 @@ int main(int argc, char **argv) case 'd': dump_sig = 1; break; - case 'h': + case 'A': + capsule_type |= CAPSULE_ACCEPT; + break; + case 'R': + capsule_type |= CAPSULE_REVERT; + break; + default: print_usage(); exit(EXIT_SUCCESS); } } + if (capsule_type == (CAPSULE_ACCEPT | CAPSULE_REVERT)) { + fprintf(stderr, + "Select either of Accept or Revert capsule generation\n"); + exit(EXIT_FAILURE); + } + /* check necessary parameters */ - if ((argc != optind + 2) || !guid || - ((privkey_file && !cert_file) || - (!privkey_file && cert_file))) { + if ((capsule_type == CAPSULE_NORMAL_BLOB && + ((argc != optind + 2) || !guid || + ((privkey_file && !cert_file) || + (!privkey_file && cert_file)))) || + (capsule_type != CAPSULE_NORMAL_BLOB && + ((argc != optind + 1) || + ((capsule_type == CAPSULE_ACCEPT) && !guid) || + ((capsule_type == CAPSULE_REVERT) && guid)))) { print_usage(); exit(EXIT_FAILURE); } - if (create_fwbin(argv[argc - 1], argv[argc - 2], guid, index, instance, - mcount, privkey_file, cert_file) < 0) { + if (capsule_type != CAPSULE_NORMAL_BLOB) { + if (create_empty_capsule(argv[argc - 1], guid, + capsule_type == CAPSULE_ACCEPT) < 0) { + fprintf(stderr, "Creating empty capsule failed\n"); + exit(EXIT_FAILURE); + } + } else if (create_fwbin(argv[argc - 1], argv[argc - 2], guid, + index, instance, mcount, privkey_file, + cert_file) < 0) { fprintf(stderr, "Creating firmware capsule failed\n"); exit(EXIT_FAILURE); }