From patchwork Sun Jul 9 13:33:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 700807 Delivered-To: patch@linaro.org Received: by 2002:adf:fcc5:0:0:0:0:0 with SMTP id f5csp4732631wrs; Sun, 9 Jul 2023 06:34:50 -0700 (PDT) X-Google-Smtp-Source: APBJJlG45QlKp8pP99YoApppweWYQn9J02O8TWeL57IgqFzADnOpj4JY9hj0DMxkgX9Ybzd0SDm4 X-Received: by 2002:a92:c8c8:0:b0:345:a629:83ff with SMTP id c8-20020a92c8c8000000b00345a62983ffmr9301872ilq.17.1688909690482; Sun, 09 Jul 2023 06:34:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688909690; cv=none; d=google.com; s=arc-20160816; b=hpMSvRcsxLOZhozdfHi4VYW+icNRRpJbq7+QKgeU6HW/azcfndzrVm5EFvB+c5ZrkD 6jhfinlgdFXd55HHyQrSM7XvFu+U83iLItX22yki1++PFgeeYqd8fDyKAy/H2WMCX5NY 2t70zyNN6+BJiSC2Un/RK4wAu+LxgOzgzU70GG1gefLY8Ne9Rh/8bLT2D98NZOJz3Bls tFU+rEc3IoxOAXb0o93J9xqVgqtf7ebh+5t9hc0ZSr5Ooprs7tHahvmyX4jc6sMPXa5R 0s/PGD8m63GcMEIdjQKylCCKU25G60gxddFv5+jmOirxBBipRf1EzlWuP8R7fo/3827Z 9E6w== 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=HFJDp+hxAyl4xteyuV//RzEQx8hC1H7O9IYzzFizcyY=; fh=5yufCDEpV5fWA8r3jJ0mHshq3zHArlCzbvaufLK2jtI=; b=RPEVgYnfgifjJuqq6b6MtkJjM/cJLcM0t3meFkZ/cWsrVWQ29dC1PExdkNExZ2jREa u1qg8nyr6zZXOFVUs6Am3vjnp+90fxJl+3df5ytcyTc0ayavwfCjtTB5eFuMlUyhkLbw 7Y+1ZgLZHJtxZS7qHNtTuM5uWoQQcghLQ5CTS5/SCIQHNDLoEYJcVCToIu7uEPs3CV89 R0ijK+If7mKRGVmrdM/DwxHoeIgfgqYCOs6dJ82zfbUGLHbj1p+H27KbSc/o2XFbfMad BHfZTBeTokHYMg61ASKeiESPvjU4A/pklxlXefBOUX8YLoUPj+a4n8gUIDzkcdVpqerV 8U7w== 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 u5-20020a056638134500b00424b4005790si3664385jad.146.2023.07.09.06.34.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Jul 2023 06:34:50 -0700 (PDT) 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 DB908865D4; Sun, 9 Jul 2023 15:34:06 +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 2BFF1865D1; Sun, 9 Jul 2023 15:34:06 +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 8A3DE85DEA for ; Sun, 9 Jul 2023 15:34:01 +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 2A1A31FB; Sun, 9 Jul 2023 06:34:43 -0700 (PDT) Received: from a076522.blr.arm.com (a076522.blr.arm.com [10.162.46.7]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id ACFDE3F762; Sun, 9 Jul 2023 06:33:58 -0700 (PDT) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Malte Schmidt , Tom Rini , Sughosh Ganu Subject: [PATCH v3 06/11] binman: capsule: Add support for generating capsules Date: Sun, 9 Jul 2023 19:03:21 +0530 Message-Id: <20230709133326.1015483-7-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230709133326.1015483-1-sughosh.ganu@linaro.org> References: <20230709133326.1015483-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.8 at phobos.denx.de X-Virus-Status: Clean Add support in binman for generating capsules. The capsule parameters can be specified either through a config file or through the capsule binman entry. Signed-off-by: Sughosh Ganu --- Changes since V2: * New patch which generates capsules through binman replacing the earlier make target. tools/binman/btool/mkeficapsule.py | 91 +++++++++++++++++++++++++ tools/binman/entries.rst | 27 ++++++++ tools/binman/etype/capsule.py | 102 +++++++++++++++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 tools/binman/btool/mkeficapsule.py create mode 100644 tools/binman/etype/capsule.py diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py new file mode 100644 index 0000000000..9f656c12cf --- /dev/null +++ b/tools/binman/btool/mkeficapsule.py @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2023 Linaro Limited +# +"""Bintool implementation for mkeficapsule tool + +mkeficapsule is a tool used for generating EFI capsules. + +The following are the command-line options to be provided +to the tool +Usage: mkeficapsule [options] +Options: + -g, --guid guid for image blob type + -i, --index update image index + -I, --instance update hardware instance + -p, --private-key private key file + -c, --certificate signer's certificate file + -m, --monotonic-count monotonic count + -d, --dump_sig dump signature (*.p7) + -A, --fw-accept firmware accept capsule, requires GUID, no image blob + -R, --fw-revert firmware revert capsule, takes no GUID, no image blob + -o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff + -f, --cfg-file config file with capsule parameters + -h, --help print a help message + +""" + +from binman import bintool + +class Bintoolmkeficapsule(bintool.Bintool): + """Handles the 'mkeficapsule' tool + + This bintool is used for generating the EFI capsules. The + capsule generation parameters can either be specified through + command-line, or through a config file. + + """ + def __init__(self, name): + super().__init__(name, 'mkeficapsule tool for generating capsules') + + def capsule_cfg_file(self, cfg_file): + + args = [ + f'--cfg-file={cfg_file}' + ] + self.run_cmd(*args) + + def cmdline_capsule(self, image_index, image_guid, hardware_instance, + payload, output_fname): + + args = [ + f'--index={image_index}', + f'--guid={image_guid}', + f'--instance={hardware_instance}', + payload, + output_fname + ] + self.run_cmd(*args) + + def cmdline_auth_capsule(self, image_index, image_guid, hardware_instance, + monotonic_count, priv_key, pub_key, + payload, output_fname): + + args = [ + f'--index={image_index}', + f'--guid={image_guid}', + f'--instance={hardware_instance}', + f'--monotonic-count={monotonic_count}', + f'--private-key={priv_key}', + f'--certificate={pub_key}', + payload, + output_fname + ] + self.run_cmd(*args) + + def fetch(self, method): + """Fetch handler for mkeficapsule + + This builds the tool from source + + Returns: + tuple: + str: Filename of fetched file to copy to a suitable directory + str: Name of temp directory to remove, or None + """ + if method != bintool.FETCH_BUILD: + return None + result = self.build_from_git( + 'https://source.denx.de/u-boot/u-boot.git', + 'tools', + 'tools/mkeficapsule') + return result diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst index b71af801fd..9a263e8691 100644 --- a/tools/binman/entries.rst +++ b/tools/binman/entries.rst @@ -283,6 +283,33 @@ entry; similarly for SPL. +.. _etype_capsule: + +Entry: capsule: Entry for generating EFI Capsule files +------------------------------------------------------ + +This is an entry for generating EFI capsules. + +The parameters needed for generation of the capsules can either be +provided separately, or through a config file. + +Properties / Entry arguments: + - cfg-file: Config file for providing capsule + parameters. + - image-index: Unique number for identifying + corresponding payload image. + - image-type-id: Image GUID which will be used + for identifying the image. + - hardware-instance: Optional number for identifying + unique hardware instance of a device in the system. + - monotomic-count: Count used when signing an image. + - private-key: Path to private key file. + - pub-key-cert: Path to public key certificate file. + - filename: Path to the input(payload) file. + - capsule: Path to the output capsule file. + + + .. _etype_cbfs: Entry: cbfs: Coreboot Filesystem (CBFS) diff --git a/tools/binman/etype/capsule.py b/tools/binman/etype/capsule.py new file mode 100644 index 0000000000..a5ada885a6 --- /dev/null +++ b/tools/binman/etype/capsule.py @@ -0,0 +1,102 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2023 Linaro Limited +# +# Entry-type module for producing a capsule +# + +import os +from u_boot_pylib import tools +from dtoc import fdt_util +from binman.entry import Entry + +class Entry_capsule(Entry): + """Entry for generating EFI capsules + + This is an entry for generating EFI capsules. + + The parameters needed for generation of the capsules can + either be provided separately, or through a config file. + + Properties / Entry arguments: + - cfg-file: Config file for providing capsule + parameters. + - image-index: Unique number for identifying + corresponding payload image. + - image-type-id: Image GUID which will be used + for identifying the image. + - hardware-instance: Optional number for identifying + unique hardware instance of a device in the system. + - monotomic-count: Count used when signing an image. + - private-key: Path to private key file. + - pub-key-cert: Path to public key certificate file. + - filename: Path to the input(payload) file. + - capsule: Path to the output capsule file. + + """ + def __init__(self, section, etype, node): + super().__init__(section, etype, node) + self.image_index = 0 + self.image_guid = "" + self.hardware_instance = 0 + self.monotonic_count = 0 + self.private_key = "" + self.pub_key_cert = "" + self.auth = 0 + self.payload = "" + self.capsule_fname = "" + + def ReadNode(self): + super().ReadNode() + + self.cfg_file = fdt_util.GetString(self._node, 'cfg-file') + if not self.cfg_file: + self.image_index = fdt_util.GetInt(self._node, 'image-index') + if not self.image_index: + self.Raise('mkeficapsule must be provided an Image Index') + + self.image_guid = fdt_util.GetString(self._node, 'image-type-id') + if not self.image_guid: + self.Raise('mkeficapsule must be provided an Image GUID') + + self.hardware_instance = fdt_util.GetInt(self._node, 'hardware-instance') + self.monotonic_count = fdt_util.GetInt(self._node, 'monotonic-count') + + self.private_key = fdt_util.GetString(self._node, 'private-key') + self.pub_key_cert = fdt_util.GetString(self._node, 'pub-key-cert') + + if ((self.private_key and not self.pub_key_cert) or (self.pub_key_cert and not self.private_key)): + self.Raise('Both private-key and public key Certificate need to be provided') + elif not (self.private_key and self.pub_key_cert): + self.auth = 0 + else: + self.auth = 1 + + self.payload = fdt_util.GetString(self._node, 'filename') + if not self.payload: + self.Raise('mkeficapsule must be provided an input filename(payload)') + + self.capsule_fname = fdt_util.GetString(self._node, 'capsule') + if not self.capsule_fname: + self.capsule_fname = os.path.splitext(self.payload)[0] + '.capsule' + + def ObtainContents(self): + if self.cfg_file: + self.mkeficapsule.capsule_cfg_file(self.cfg_file) + elif self.auth: + self.mkeficapsule.cmdline_auth_capsule(self.image_index, + self.image_guid, + self.hardware_instance, + self.monotonic_count, + self.private_key, + self.pub_key_cert, + self.payload, + self.capsule_fname) + else: + self.mkeficapsule.cmdline_capsule(self.image_index, + self.image_guid, + self.hardware_instance, + self.payload, + self.capsule_fname) + + def AddBintools(self, btools): + self.mkeficapsule = self.AddBintool(btools, 'mkeficapsule')