From patchwork Tue Jul 25 08:57:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 706131 Delivered-To: patch@linaro.org Received: by 2002:a5d:464f:0:b0:317:2194:b2bc with SMTP id j15csp70425wrs; Tue, 25 Jul 2023 02:08:01 -0700 (PDT) X-Google-Smtp-Source: APBJJlGRrFaWob33np+LIYRoGVZE7LHQW0O6YRDm/6/KKIuP0y8u59GE4kW2IEjo8UWmX02AHpKQ X-Received: by 2002:a05:600c:450:b0:3f8:c70e:7ed1 with SMTP id s16-20020a05600c045000b003f8c70e7ed1mr10421860wmb.20.1690276081357; Tue, 25 Jul 2023 02:08:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690276081; cv=none; d=google.com; s=arc-20160816; b=y+Xdsbt8+xd+osx815oLgzvZiiOSNgbjBI9zFwnGAFKNaRZ8DPfEXNyVrgqzYPStaP ule47N6y6P4RDEITVV3EJthkdT4agZrm6gepnPIoGwptacnyCFzrci+7IhU/zbjj3tSW 2RZ2joZKwMVFyKsqmpjSHyNbGbaZ8+693shBL4r+jZuj/7PiInSWDmYdatt60Ft5jwqS W/cjpHyXETprrgZVmfgEAihQg/kc/BtguUHbTOGfMKGDFWdcp15jiOGQNV5kvkaAPuzE J4Kbgv3y8M46ukm/JonOyjbnEHhgZqjKPev2lTYZz2hdUyBAnMBox0MuYeT3bSCV9xCH oXVA== 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=p1YmK/TyZkjOwLhJjC54Je1dI8q3jZtqiV57GQpDQmI=; fh=pvWoYJ8DnC9IyTD46q2s71hlWpPSBdE/YYp0/eyIYcc=; b=JMAwMPQpbANGRdBgTGSUdiQufGhYUFUqHA4QhW3/faouhXFpFRzeIR1TpFuk0MQcgm cBIRYHSBrBnWQ+wuiPUnHZRtqAYpX/GxpxM0Gu1Nba30IZk17kYdpsTeNPejA6mpbB2w 1tDBIONJQkU2EfP7P9TYUDdGTsyJKeLgJ88fS0u8bTUh6+vd732SQjhuh2FgVQ1YDokK mF+EXiFDOBf2dIfPvhGPSiGru2RLvESMJ5DLrzzjDtHtAN2vDvhhxuLRDg2Mu/N3cMZ8 hKdUTiBScmY0fv13i8PbhrUIBKngzB6rxzV2Xhm7Ne/0SkGFWE4n0sZmilriEqRRj0EJ HMOA== 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 24-20020a05600c021800b003facc8c7722si8117859wmi.27.2023.07.25.02.08.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 Jul 2023 02:08:01 -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 1199A86892; Tue, 25 Jul 2023 11:07:40 +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 37DF786828; Tue, 25 Jul 2023 11:01:00 +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.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, T_SCC_BODY_TEXT_LINE autolearn=ham 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 BE1548679A for ; Tue, 25 Jul 2023 10:58:17 +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 6985115BF; Tue, 25 Jul 2023 01:59:00 -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 3B9AC3F6C4; Tue, 25 Jul 2023 01:58:14 -0700 (PDT) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Malte Schmidt , Michal Simek , Tom Rini , Sughosh Ganu Subject: [PATCH v5 07/12] binman: capsule: Add support for generating capsules Date: Tue, 25 Jul 2023 14:27:20 +0530 Message-Id: <20230725085725.350917-8-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230725085725.350917-1-sughosh.ganu@linaro.org> References: <20230725085725.350917-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. Also add test cases in binman for capsule generation, and enable this testing on the sandbox_spl variant. Signed-off-by: Sughosh Ganu --- Changes since V4: * Rebase on top of current HEAD. * Remove blank lines after function comments. * Fix a couple of typos. * Use single quotes for strings. * Put the GUIDs in variables with relevant names. * Declare certain values in local variables instead of member values. * Add comments for explaning the payload offsets in the capsule file. * Drop the test case for generating the capsule from the config file. * Define payload data for the capsule tests. * Add logic to find input and output files in capsule generation in the indir and outdir directories when absolute path is not passed. configs/sandbox_spl_defconfig | 1 + tools/binman/btool/mkeficapsule.py | 153 ++++++++++++++++++ tools/binman/entries.rst | 42 +++++ tools/binman/etype/capsule.py | 132 +++++++++++++++ tools/binman/ftest.py | 115 +++++++++++++ tools/binman/test/307_capsule.dts | 19 +++ tools/binman/test/308_capsule_signed.dts | 21 +++ tools/binman/test/309_capsule_version.dts | 20 +++ tools/binman/test/310_capsule_missing_key.dts | 20 +++ .../binman/test/311_capsule_missing_index.dts | 18 +++ .../binman/test/312_capsule_missing_guid.dts | 17 ++ .../test/313_capsule_missing_payload.dts | 18 +++ tools/binman/test/314_capsule_missing.dts | 18 +++ tools/binman/test/files/capsule_cfg.txt | 6 + 14 files changed, 600 insertions(+) create mode 100644 tools/binman/btool/mkeficapsule.py create mode 100644 tools/binman/etype/capsule.py create mode 100644 tools/binman/test/307_capsule.dts create mode 100644 tools/binman/test/308_capsule_signed.dts create mode 100644 tools/binman/test/309_capsule_version.dts create mode 100644 tools/binman/test/310_capsule_missing_key.dts create mode 100644 tools/binman/test/311_capsule_missing_index.dts create mode 100644 tools/binman/test/312_capsule_missing_guid.dts create mode 100644 tools/binman/test/313_capsule_missing_payload.dts create mode 100644 tools/binman/test/314_capsule_missing.dts create mode 100644 tools/binman/test/files/capsule_cfg.txt diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index 8d50162b27..65223475ab 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -249,3 +249,4 @@ CONFIG_UNIT_TEST=y CONFIG_SPL_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_TOOLS_MKEFICAPSULE=y diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py new file mode 100644 index 0000000000..bfd6552b9a --- /dev/null +++ b/tools/binman/btool/mkeficapsule.py @@ -0,0 +1,153 @@ +# 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 + -v, --fw-version firmware version + -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): + """Generate a capsule reading parameters from config file + + Args: + cfg_file (str): Path to the config file + + Returns: + str: Tool output + """ + args = [ + f'--cfg-file={cfg_file}' + ] + return self.run_cmd(*args) + + def cmdline_capsule(self, image_index, image_guid, hardware_instance, + payload, output_fname, version=0): + """Generate a capsule through commandline provided parameters + + Args: + image_index (int): Unique number for identifying payload image + image_guid (str): GUID used for identifying the image + hardware_instance (int): Optional unique hardware instance of + a device in the system. 0 if not being used + payload (str): Path to the input payload image + output_fname (str): Path to the output capsule file + version (int): Image version (Optional) + + Returns: + str: Tool output + """ + if version: + args = [ + f'--index={image_index}', + f'--fw-version={version}', + f'--guid={image_guid}', + f'--instance={hardware_instance}', + payload, + output_fname + ] + else: + args = [ + f'--index={image_index}', + f'--guid={image_guid}', + f'--instance={hardware_instance}', + payload, + output_fname + ] + + return self.run_cmd(*args) + + def cmdline_auth_capsule(self, image_index, image_guid, hardware_instance, + monotonic_count, priv_key, pub_key, + payload, output_fname, version=0): + """Generate a signed capsule through commandline provided parameters + + Args: + image_index (int): Unique number for identifying payload image + image_guid (str): GUID used for identifying the image + hardware_instance (int): Optional unique hardware instance of + a device in the system. 0 if not being used + monotonic_count (int): Count used when signing an image + priv_key (str): Path to the private key + pub_key(str): Path to the public key + payload (str): Path to the input payload image + output_fname (str): Path to the output capsule file + version (int): Image version (Optional) + + Returns: + str: Tool output + """ + if version: + 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}', + f'--fw-version={version}', + payload, + output_fname + ] + else: + 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 + ] + + return 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 + + cmd = ['tools-only_defconfig', 'tools'] + result = self.build_from_git( + 'https://source.denx.de/u-boot/u-boot.git', + cmd, + 'tools/mkeficapsule') + return result diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst index f2376932be..d0efe95374 100644 --- a/tools/binman/entries.rst +++ b/tools/binman/entries.rst @@ -283,6 +283,48 @@ 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. These are parameters needed for generating the + capsules. The parameters can be listed by running the + './tools/mkeficapsule -h' command. + - image-index: Unique number for identifying corresponding + payload image. Number between 1 and descriptor count, i.e. + the total number of firmware images that can be updated. + - image-type-id: Image GUID which will be used for identifying the + updatable image on the board. + - hardware-instance: Optional number for identifying unique + hardware instance of a device in the system. Default value of 0 + for images where value is not to be used. + - fw-version: Optional value of image version that can be put on + the capsule through the Firmware Management Protocol(FMP) header. + - monotonic-count: Count used when signing an image. + - private-key: Path to PEM formatted .key private key file. + - pub-key-cert: Path to PEM formatted .crt public key certificate + file. + - filename: Path to the input(payload) file. File can be any + format, a binary or an elf, platform specific. + - capsule: Path to the output capsule file. A capsule is a + continuous set of data as defined by the EFI specification. Refer + to the specification for more details. + +For more details on the description of the capsule format, and the capsule +update functionality, refer Section 8.5 and Chapter 23 in the UEFI +specification. +https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf + + + .. _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..53fb668c00 --- /dev/null +++ b/tools/binman/etype/capsule.py @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2023 Linaro Limited +# +# Entry-type module for producing a capsule +# + +import os + +from binman.entry import Entry +from dtoc import fdt_util +from u_boot_pylib import tools + +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. These are parameters needed for generating the + capsules. The parameters can be listed by running the + './tools/mkeficapsule -h' command. + - image-index: Unique number for identifying corresponding + payload image. Number between 1 and descriptor count, i.e. + the total number of firmware images that can be updated. + - image-type-id: Image GUID which will be used for identifying the + updatable image on the board. + - hardware-instance: Optional number for identifying unique + hardware instance of a device in the system. Default value of 0 + for images where value is not to be used. + - fw-version: Optional value of image version that can be put on + the capsule through the Firmware Management Protocol(FMP) header. + - monotonic-count: Count used when signing an image. + - private-key: Path to PEM formatted .key private key file. + - pub-key-cert: Path to PEM formatted .crt public key certificate + file. + - filename: Path to the input(payload) file. File can be any + format, a binary or an elf, platform specific. + - capsule: Path to the output capsule file. A capsule is a + continuous set of data as defined by the EFI specification. Refer + to the specification for more details. + + For more details on the description of the capsule format, and the capsule + update functionality, refer Section 8.5 and Chapter 23 in the UEFI + specification. + https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf + """ + 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.fw_version = 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 self.cfg_file: + if not os.path.isabs(self.cfg_file): + self.cfg_file = tools.get_input_filename(self.cfg_file) + else: + 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.fw_version = fdt_util.GetInt(self._node, 'fw-version') + 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)') + if not os.path.isabs(self.payload): + self.payload = tools.get_input_filename(self.payload) + + self.capsule_fname = fdt_util.GetString(self._node, 'capsule') + if not self.capsule_fname: + self.Raise('Specify the output capsule file') + if not os.path.isabs(self.capsule_fname): + self.capsule_fname = tools.get_output_filename(self.capsule_fname) + + def _GenCapsule(self): + if self.cfg_file: + return self.mkeficapsule.capsule_cfg_file(self.cfg_file) + elif self.auth: + return 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, + self.fw_version) + else: + return self.mkeficapsule.cmdline_capsule(self.image_index, + self.image_guid, + self.hardware_instance, + self.payload, + self.capsule_fname, + self.fw_version) + + def ObtainContents(self): + self.SetContents(tools.to_bytes(self._GenCapsule())) + return True + + def AddBintools(self, btools): + self.mkeficapsule = self.AddBintool(btools, 'mkeficapsule') diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 1cfa349d38..13059d93d5 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -48,6 +48,7 @@ U_BOOT_VPL_DATA = b'vpl76543210fedcbazywxyz_' BLOB_DATA = b'89' ME_DATA = b'0abcd' VGA_DATA = b'vga' +EFI_DATA = b'efi' U_BOOT_DTB_DATA = b'udtb' U_BOOT_SPL_DTB_DATA = b'spldtb' U_BOOT_TPL_DTB_DATA = b'tpldtb' @@ -119,6 +120,11 @@ COMP_BINTOOLS = ['bzip2', 'gzip', 'lz4', 'lzma_alone', 'lzop', 'xz', 'zstd'] TEE_ADDR = 0x5678 +# Firmware Management Protocol(FMP) GUID +FW_MGMT_GUID = 'edd5cb6d2de8444cbda17194199ad92a' +# Image GUID specified in the DTS +CAPSULE_IMAGE_GUID = '52cfd7092007104791d108469b7fe9c8' + class TestFunctional(unittest.TestCase): """Functional tests for binman @@ -7087,5 +7093,114 @@ fdt fdtmap Extract the devicetree blob from the fdtmap self.assertEqual(fdt_util.GetString(key_node, "key-name-hint"), "key") + def _CheckCapsule(self, signed_capsule=False, version_check=False): + fmp_signature = "4d535331" # 'M', 'S', 'S', '1' + fmp_size = "10" + fmp_fw_version = "02" + + self.capsule_data = tools.read_file(self.capsule_fname) + + # Firmware Management Protocol(FMP) GUID - offset(0 - 32) + self.assertEqual(FW_MGMT_GUID, self.capsule_data.hex()[:32]) + # Image GUID - offset(96 - 128) + self.assertEqual(CAPSULE_IMAGE_GUID, self.capsule_data.hex()[96:128]) + + if version_check: + # FMP header signature - offset(184 - 192) + self.assertEqual(fmp_signature, self.capsule_data.hex()[184:192]) + # FMP header size - offset(192 - 194) + self.assertEqual(fmp_size, self.capsule_data.hex()[192:194]) + # firmware version - offset(200 - 202) + self.assertEqual(fmp_fw_version, self.capsule_data.hex()[200:202]) + + if signed_capsule: + # payload offset signed capsule(4770 - 4776) + self.assertEqual(self.payload_data.hex(), self.capsule_data.hex()[4770:4776]) + elif version_check: + # payload offset for non-signed capsule with version header(216 - 222) + self.assertEqual(self.payload_data.hex(), self.capsule_data.hex()[216:222]) + else: + # payload offset for non-signed capsule with no version header(184 - 190) + self.assertEqual(self.payload_data.hex(), self.capsule_data.hex()[184:190]) + + def testCapsuleGen(self): + """Test generation of EFI capsule""" + self.payload_data = EFI_DATA + + TestFunctional._MakeInputFile('payload.txt', self.payload_data) + + self._DoReadFile('307_capsule.dts') + + self.capsule_fname = tools.get_output_filename('test.capsule') + self.assertTrue(os.path.exists(self.capsule_fname)) + + self._CheckCapsule() + + def testSignedCapsuleGen(self): + """Test generation of EFI capsule""" + self.payload_data = EFI_DATA + + TestFunctional._MakeInputFile('payload.txt', self.payload_data) + + self._DoReadFile('308_capsule_signed.dts') + + self.capsule_fname = tools.get_output_filename('test.capsule') + self.assertTrue(os.path.exists(self.capsule_fname)) + + self._CheckCapsule(signed_capsule=True) + + def testCapsuleGenVersionSupport(self): + """Test generation of EFI capsule with version support""" + self.payload_data = EFI_DATA + + TestFunctional._MakeInputFile('payload.txt', self.payload_data) + + self._DoReadFile('309_capsule_version.dts') + + self.capsule_fname = tools.get_output_filename('test.capsule') + self.assertTrue(os.path.exists(self.capsule_fname)) + + self._CheckCapsule(version_check=True) + + def testCapsuleGenKeyMissing(self): + """Test that binman errors out on missing key""" + with self.assertRaises(ValueError) as e: + self._DoReadFile('310_capsule_missing_key.dts') + + self.assertIn("Both private key and public key certificate need to be provided", + str(e.exception)) + + def testCapsuleGenIndexMissing(self): + """Test that binman errors out on missing image index""" + with self.assertRaises(ValueError) as e: + self._DoReadFile('311_capsule_missing_index.dts') + + self.assertIn("mkeficapsule must be provided an Image Index", + str(e.exception)) + + def testCapsuleGenGuidMissing(self): + """Test that binman errors out on missing image GUID""" + with self.assertRaises(ValueError) as e: + self._DoReadFile('312_capsule_missing_guid.dts') + + self.assertIn("mkeficapsule must be provided an Image GUID", + str(e.exception)) + + def testCapsuleGenPayloadMissing(self): + """Test that binman errors out on missing input(payload)image""" + with self.assertRaises(ValueError) as e: + self._DoReadFile('313_capsule_missing_payload.dts') + + self.assertIn("mkeficapsule must be provided an input filename(payload)", + str(e.exception)) + + def testCapsuleGenCapsuleFileMissing(self): + """Test that binman errors out on missing output capsule file""" + with self.assertRaises(ValueError) as e: + self._DoReadFile('314_capsule_missing.dts') + + self.assertIn("Specify the output capsule file", + str(e.exception)) + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/307_capsule.dts b/tools/binman/test/307_capsule.dts new file mode 100644 index 0000000000..afc2478698 --- /dev/null +++ b/tools/binman/test/307_capsule.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + capsule { + image-index = <0x1>; + /* Image GUID for testing capsule update */ + image-type-id = "09D7CF52-0720-4710-91D1-08469B7FE9C8"; + hardware-instance = <0x0>; + filename = "payload.txt"; + capsule = "test.capsule"; + }; + }; +}; diff --git a/tools/binman/test/308_capsule_signed.dts b/tools/binman/test/308_capsule_signed.dts new file mode 100644 index 0000000000..2de0f198f4 --- /dev/null +++ b/tools/binman/test/308_capsule_signed.dts @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + capsule { + image-index = <0x1>; + /* Image GUID for testing capsule update */ + image-type-id = "09D7CF52-0720-4710-91D1-08469B7FE9C8"; + hardware-instance = <0x0>; + private-key = "tools/binman/test/key.key"; + pub-key-cert = "tools/binman/test/key.pem"; + filename = "payload.txt"; + capsule = "test.capsule"; + }; + }; +}; diff --git a/tools/binman/test/309_capsule_version.dts b/tools/binman/test/309_capsule_version.dts new file mode 100644 index 0000000000..d449d22e6a --- /dev/null +++ b/tools/binman/test/309_capsule_version.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + capsule { + image-index = <0x1>; + fw-version = <0x2>; + /* Image GUID for testing capsule update */ + image-type-id = "09D7CF52-0720-4710-91D1-08469B7FE9C8"; + hardware-instance = <0x0>; + filename = "payload.txt"; + capsule = "test.capsule"; + }; + }; +}; diff --git a/tools/binman/test/310_capsule_missing_key.dts b/tools/binman/test/310_capsule_missing_key.dts new file mode 100644 index 0000000000..69e800df91 --- /dev/null +++ b/tools/binman/test/310_capsule_missing_key.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + capsule { + image-index = <0x1>; + /* Image GUID for testing capsule update */ + image-type-id = "09D7CF52-0720-4710-91D1-08469B7FE9C8"; + hardware-instance = <0x0>; + private-key = "tools/binman/test/key.key"; + filename = "payload.txt"; + capsule = "test.capsule"; + }; + }; +}; diff --git a/tools/binman/test/311_capsule_missing_index.dts b/tools/binman/test/311_capsule_missing_index.dts new file mode 100644 index 0000000000..a84cee7905 --- /dev/null +++ b/tools/binman/test/311_capsule_missing_index.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + capsule { + /* Image GUID for testing capsule update */ + image-type-id = "09D7CF52-0720-4710-91D1-08469B7FE9C8"; + hardware-instance = <0x0>; + filename = "payload.txt"; + capsule = "test.capsule"; + }; + }; +}; diff --git a/tools/binman/test/312_capsule_missing_guid.dts b/tools/binman/test/312_capsule_missing_guid.dts new file mode 100644 index 0000000000..b81aa3ecd2 --- /dev/null +++ b/tools/binman/test/312_capsule_missing_guid.dts @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + capsule { + image-index = <0x1>; + hardware-instance = <0x0>; + filename = "payload.txt"; + capsule = "test.capsule"; + }; + }; +}; diff --git a/tools/binman/test/313_capsule_missing_payload.dts b/tools/binman/test/313_capsule_missing_payload.dts new file mode 100644 index 0000000000..6dd0a77702 --- /dev/null +++ b/tools/binman/test/313_capsule_missing_payload.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + capsule { + image-index = <0x1>; + /* Image GUID for testing capsule update */ + image-type-id = "09D7CF52-0720-4710-91D1-08469B7FE9C8"; + hardware-instance = <0x0>; + capsule = "test.capsule"; + }; + }; +}; diff --git a/tools/binman/test/314_capsule_missing.dts b/tools/binman/test/314_capsule_missing.dts new file mode 100644 index 0000000000..df12f23e6c --- /dev/null +++ b/tools/binman/test/314_capsule_missing.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + capsule { + image-index = <0x1>; + /* Image GUID for testing capsule update */ + image-type-id = "09D7CF52-0720-4710-91D1-08469B7FE9C8"; + hardware-instance = <0x0>; + filename = "payload.txt"; + }; + }; +}; diff --git a/tools/binman/test/files/capsule_cfg.txt b/tools/binman/test/files/capsule_cfg.txt new file mode 100644 index 0000000000..bf44a431b9 --- /dev/null +++ b/tools/binman/test/files/capsule_cfg.txt @@ -0,0 +1,6 @@ +{ + image-index: 1 + image-guid: 09D7CF52-0720-4710-91D1-08469B7FE9C8 + payload: /tmp/capsules/payload.txt + capsule: /tmp/capsules/test.capsule +}