From patchwork Wed Jan 19 18:55:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 533280 Delivered-To: patch@linaro.org Received: by 2002:ac0:f7d2:0:0:0:0:0 with SMTP id i18csp1131337imr; Wed, 19 Jan 2022 10:58:10 -0800 (PST) X-Google-Smtp-Source: ABdhPJzbvJv/w4w7rTmdP1F849YQ/rm9DtRI0xZXoXZ9KWxToEFv40gDzB8+cOgHmlaDpgUS1y3e X-Received: by 2002:a05:6402:1d54:: with SMTP id dz20mr31874664edb.395.1642618690159; Wed, 19 Jan 2022 10:58:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642618690; cv=none; d=google.com; s=arc-20160816; b=ckTaj4qun9lrttam1Y+SK+13qXCZHWMzRrW5048DP0vXM65YShrDPcORCepeNNuLK/ 5P3xv+LbIDqBqzhgIksPiFiX7fl4zAoKdzf+4VNSVde8aiutgDukDZRtlUUFrm7iM6NH jwnK/OFNqIJSOt/GkYFvz9lHNDGBUvstcfbNdsdNlVUn6CsQHCEJUoO0s2tpe4y8Y5kU +7vCxLAPzpQ9zuqqUR4+kb6O06jEiWiZar5ZT166iW5bOCXtpLu6w+HM0WoWAALklGii LHReNEeUhbSOXLCiTv46vA8nVCUWW4HpbVahEKRRUNmQXevLlF5+UsVnda3j+vOpaC9s ifuA== 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:references:in-reply-to :message-id:date:subject:cc:to:from; bh=t+8iHypcaZPC93Tffk6MLq1+z71wkKnlzrcNbILF4es=; b=XAmzKiHtpdN3UGjqJCsIzZRMm2CrjgkNjR3m03kgIUm7EY3KT1+/BEqhGDQt7J7HsO 2cr/Rqco5uc4LemIQcIwV9/Oo6bis46lIYNh1u89cu6S8tSfK888SV7G1hAiMxZEYXka /WDerXtlT477IeRutRM8AXIsrGr8Of6d8KLUwdopnkaXL0tYCHoIwVh/s8c94SIRuS2P GUzGGudHe081JMVKTmABKxhAdD63tr3Wkgl9yIPieu6OIoa9lTnqZO5iLsD9rDfa0ptX UZjhJoF3m/4pa+nTeyD2yoPNLzwQUXJJAM7lYRagQUPqu320YEd+sWWI3DJXqiGTJJ2N xwlg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id bl4si329903ejb.462.2022.01.19.10.58.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Jan 2022 10:58:10 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 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 19C958383D; Wed, 19 Jan 2022 19:57:32 +0100 (CET) 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 D7B5A8384B; Wed, 19 Jan 2022 19:57:29 +0100 (CET) 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 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 0726D8388D for ; Wed, 19 Jan 2022 19:57:26 +0100 (CET) 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 69D611FB; Wed, 19 Jan 2022 10:57:25 -0800 (PST) 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 3DB113F73D; Wed, 19 Jan 2022 10:57:19 -0800 (PST) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Masami Hiramatsu , Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , AKASHI Takahiro , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Tom Rini , Etienne Carriere , Sughosh Ganu Subject: [RFC PATCH v3 9/9] mkeficapsule: Add support for generating empty capsules Date: Thu, 20 Jan 2022 00:25:48 +0530 Message-Id: <20220119185548.16730-10-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220119185548.16730-1-sughosh.ganu@linaro.org> References: <20220119185548.16730-1-sughosh.ganu@linaro.org> 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.2 at phobos.denx.de X-Virus-Status: Clean The Dependable Boot specification 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. Signed-off-by: Sughosh Ganu --- Changes since V2: * New patch for generating empty capsules tools/eficapsule.h | 8 ++++ tools/mkeficapsule.c | 102 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 100 insertions(+), 10 deletions(-) diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 8c1560bb06..6001952bdc 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -50,6 +50,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 161affdd15..643da3849d 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -29,6 +29,7 @@ #include "eficapsule.h" static const char *tool_name = "mkeficapsule"; +static unsigned char empty_capsule; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; efi_guid_t efi_guid_image_type_uboot_fit = @@ -38,9 +39,9 @@ efi_guid_t efi_guid_image_type_uboot_raw = efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; #ifdef CONFIG_TOOLS_LIBCRYPTO -static const char *opts_short = "frg:i:I:v:p:c:m:dh"; +static const char *opts_short = "frg:i:I:v:p:c:m:dhAR"; #else -static const char *opts_short = "frg:i:I:v:h"; +static const char *opts_short = "frg:i:I:v:hAR"; #endif static struct option options[] = { @@ -55,15 +56,23 @@ static struct option options[] = { {"monotonic-count", required_argument, NULL, 'm'}, {"dump-sig", no_argument, NULL, 'd'}, #endif + {"fw-accept", no_argument, NULL, 'A'}, + {"fw-revert", no_argument, NULL, 'R'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0}, }; static void print_usage(void) { - fprintf(stderr, "Usage: %s [options] \n" - "Options:\n" + if (empty_capsule) { + fprintf(stderr, "Usage: %s [options] \n", + tool_name); + } else { + fprintf(stderr, "Usage: %s [options] \n", + tool_name); + } + fprintf(stderr, "Options:\n" "\t-f, --fit FIT image type\n" "\t-r, --raw raw image type\n" "\t-g, --guid guid for image blob type\n" @@ -75,8 +84,9 @@ static void print_usage(void) "\t-m, --monotonic-count monotonic count\n" "\t-d, --dump_sig dump signature (*.p7)\n" #endif - "\t-h, --help print a help message\n", - tool_name); + "\t-A, --fw-accept firmware accept capsule\n" + "\t-R, --fw-revert firmware revert capsule\n" + "\t-h, --help print a help message\n"); } /** @@ -598,6 +608,59 @@ 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; + FILE *f; + int ret; + efi_guid_t fw_accept_guid = FW_ACCEPT_OS_GUID; + efi_guid_t fw_revert_guid = FW_REVERT_OS_GUID; + efi_guid_t payload, capsule_guid; + + f = NULL; + ret = -1; + + f = fopen(path, "w"); + if (!f) { + printf("cannot open %s\n", path); + goto err; + } + + if (fw_accept) + capsule_guid = fw_accept_guid; + else + capsule_guid = fw_revert_guid; + + memcpy(&header.capsule_guid, &capsule_guid, sizeof(efi_guid_t)); + header.header_size = sizeof(header); + header.flags = 0; + + if (fw_accept) { + header.capsule_image_size = sizeof(header) + sizeof(efi_guid_t); + } else { + header.capsule_image_size = sizeof(header); + } + + if (write_capsule_file(f, &header, sizeof(header), + "Capsule header")) + goto err; + + if (fw_accept) { + memcpy(&payload, guid, sizeof(efi_guid_t)); + if (write_capsule_file(f, &payload, sizeof(payload), + "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 @@ -616,6 +679,7 @@ int main(int argc, char **argv) unsigned char uuid_buf[16]; unsigned long index, instance; uint64_t mcount; + unsigned char accept_fw_capsule, revert_fw_capsule; char *privkey_file, *cert_file; int c, idx; @@ -625,6 +689,8 @@ int main(int argc, char **argv) mcount = 0; privkey_file = NULL; cert_file = NULL; + accept_fw_capsule = 0; + revert_fw_capsule = 0; dump_sig = 0; for (;;) { c = getopt_long(argc, argv, opts_short, options, &idx); @@ -691,22 +757,38 @@ int main(int argc, char **argv) dump_sig = 1; break; #endif /* CONFIG_TOOLS_LIBCRYPTO */ + case 'A': + accept_fw_capsule = 1; + break; + case 'R': + revert_fw_capsule = 1; + break; case 'h': print_usage(); exit(EXIT_SUCCESS); } } + empty_capsule = (accept_fw_capsule || revert_fw_capsule); + /* check necessary parameters */ - if ((argc != optind + 2) || !guid || - ((privkey_file && !cert_file) || + if ((!empty_capsule && argc != optind + 2) || + (empty_capsule && argc != optind + 1) || + (!revert_fw_capsule && !guid) || ((privkey_file && !cert_file) || (!privkey_file && cert_file))) { print_usage(); exit(EXIT_FAILURE); } - if (create_fwbin(argv[argc - 1], argv[argc - 2], guid, index, instance, - mcount, privkey_file, cert_file) < 0) { + if (empty_capsule) { + if (create_empty_capsule(argv[argc - 1], guid, + accept_fw_capsule ? 1 : 0) < 0) { + printf("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); }