From patchwork Wed Dec 11 02:35:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 53915 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0A30E77184 for ; Wed, 11 Dec 2024 02:35:21 +0000 (UTC) Received: from TWMBX01.aspeed.com (TWMBX01.aspeed.com [211.20.114.72]) by mx.groups.io with SMTP id smtpd.web11.1956.1733884518864803607 for ; Tue, 10 Dec 2024 18:35:20 -0800 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: aspeedtech.com, ip: 211.20.114.72, mailfrom: jamin_lin@aspeedtech.com) Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 11 Dec 2024 10:35:15 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 11 Dec 2024 10:35:15 +0800 From: Jamin Lin To: CC: , Subject: [PATCH v5 1/3] uboot-sign: support to create TEE and ATF image tree source Date: Wed, 11 Dec 2024 10:35:13 +0800 Message-ID: <20241211023515.2108415-2-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241211023515.2108415-1-jamin_lin@aspeedtech.com> References: <20241211023515.2108415-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 11 Dec 2024 02:35:21 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/208569 Currently, uboot-sign.bbclass only supports to create Image Tree Source(ITS) for "u-boot" and "flat_dt". However, users may want to support multiple images such as ARM Trusted Firmware(ATF), Trusted Execution Environment(TEE) and users private images for specific application and purpose. To make this bbclass more flexible and support ATF and TEE, creates new functions which are "uboot_fitimage_atf" and "uboot_fitimage_tee" for ATF and TEE ITS file creation, respectively. Add a variable "UBOOT_FIT_ARM_TRUSTED_FIRMWARE" to enable ATF ITS generation and it is disable by default. Add a variable "UBOOT_FIT_TEE" to enable TEE ITS generation and it is disable by default. Signed-off-by: Jamin Lin --- meta/classes-recipe/uboot-sign.bbclass | 80 +++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/meta/classes-recipe/uboot-sign.bbclass b/meta/classes-recipe/uboot-sign.bbclass index a17be745ce..f1b3470127 100644 --- a/meta/classes-recipe/uboot-sign.bbclass +++ b/meta/classes-recipe/uboot-sign.bbclass @@ -88,6 +88,18 @@ UBOOT_FIT_ADDRESS_CELLS ?= "1" # This is only necessary for determining the signing configuration KERNEL_PN = "${PREFERRED_PROVIDER_virtual/kernel}" +# ARM Trusted Firmware(ATF) is a reference implementation of secure world +# software for Arm A-Profile architectures, (Armv8-A and Armv7-A), including +# an Exception Level 3 (EL3) Secure Monitor. +UBOOT_FIT_ARM_TRUSTED_FIRMWARE ?= "0" +UBOOT_FIT_ARM_TRUSTED_FIRMWARE_IMAGE ?= "bl31.bin" + +# A Trusted Execution Environment(TEE) is an environment for executing code, +# in which those executing the code can have high levels of trust in the asset +# management of that surrounding environment. +UBOOT_FIT_TEE ?= "0" +UBOOT_FIT_TEE_IMAGE ?= "tee-raw.bin" + UBOOT_FIT_UBOOT_LOADADDRESS ?= "${UBOOT_LOADADDRESS}" UBOOT_FIT_UBOOT_ENTRYPOINT ?= "${UBOOT_ENTRYPOINT}" @@ -234,9 +246,64 @@ do_uboot_generate_rsa_keys() { addtask uboot_generate_rsa_keys before do_uboot_assemble_fitimage after do_compile +# Create a ITS file for the atf +uboot_fitimage_atf() { + cat << EOF >> ${UBOOT_ITS} + atf { + description = "ARM Trusted Firmware"; + data = /incbin/("${UBOOT_FIT_ARM_TRUSTED_FIRMWARE_IMAGE}"); + type = "firmware"; + arch = "${UBOOT_ARCH}"; + os = "arm-trusted-firmware"; + load = <${UBOOT_FIT_ARM_TRUSTED_FIRMWARE_LOADADDRESS}>; + entry = <${UBOOT_FIT_ARM_TRUSTED_FIRMWARE_ENTRYPOINT}>; + compression = "none"; +EOF + if [ "${SPL_SIGN_ENABLE}" = "1" ] ; then + cat << EOF >> ${UBOOT_ITS} + signature { + algo = "${UBOOT_FIT_HASH_ALG},${UBOOT_FIT_SIGN_ALG}"; + key-name-hint = "${SPL_SIGN_KEYNAME}"; + }; +EOF + fi + + cat << EOF >> ${UBOOT_ITS} + }; +EOF +} + +# Create a ITS file for the tee +uboot_fitimage_tee() { + cat << EOF >> ${UBOOT_ITS} + tee { + description = "Trusted Execution Environment"; + data = /incbin/("${UBOOT_FIT_TEE_IMAGE}"); + type = "tee"; + arch = "${UBOOT_ARCH}"; + os = "tee"; + load = <${UBOOT_FIT_TEE_LOADADDRESS}>; + entry = <${UBOOT_FIT_TEE_ENTRYPOINT}>; + compression = "none"; +EOF + if [ "${SPL_SIGN_ENABLE}" = "1" ] ; then + cat << EOF >> ${UBOOT_ITS} + signature { + algo = "${UBOOT_FIT_HASH_ALG},${UBOOT_FIT_SIGN_ALG}"; + key-name-hint = "${SPL_SIGN_KEYNAME}"; + }; +EOF + fi + + cat << EOF >> ${UBOOT_ITS} + }; +EOF +} + # Create a ITS file for the U-boot FIT, for use when # we want to sign it so that the SPL can verify it uboot_fitimage_assemble() { + conf_loadables="\"uboot\"" rm -f ${UBOOT_ITS} ${UBOOT_FITIMAGE_BINARY} # First we create the ITS script @@ -289,13 +356,24 @@ EOF cat << EOF >> ${UBOOT_ITS} }; +EOF + if [ "${UBOOT_FIT_TEE}" = "1" ] ; then + conf_loadables="\"tee\", ${conf_loadables}" + uboot_fitimage_tee + fi + + if [ "${UBOOT_FIT_ARM_TRUSTED_FIRMWARE}" = "1" ] ; then + conf_loadables="\"atf\", ${conf_loadables}" + uboot_fitimage_atf + fi + cat << EOF >> ${UBOOT_ITS} }; configurations { default = "conf"; conf { description = "Boot with signed U-Boot FIT"; - loadables = "uboot"; + loadables = ${conf_loadables}; fdt = "fdt"; }; }; From patchwork Wed Dec 11 02:35:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 53916 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0400E77183 for ; Wed, 11 Dec 2024 02:35:21 +0000 (UTC) Received: from TWMBX01.aspeed.com (TWMBX01.aspeed.com [211.20.114.72]) by mx.groups.io with SMTP id smtpd.web11.1956.1733884518864803607 for ; Tue, 10 Dec 2024 18:35:20 -0800 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: aspeedtech.com, ip: 211.20.114.72, mailfrom: jamin_lin@aspeedtech.com) Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 11 Dec 2024 10:35:15 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 11 Dec 2024 10:35:15 +0800 From: Jamin Lin To: CC: , Subject: [PATCH v5 2/3] uboot-sign: support to add users specific image tree source Date: Wed, 11 Dec 2024 10:35:14 +0800 Message-ID: <20241211023515.2108415-3-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241211023515.2108415-1-jamin_lin@aspeedtech.com> References: <20241211023515.2108415-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 11 Dec 2024 02:35:21 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/208570 Currently, uboot-sign.bbclass only supports to create Image Tree Source(ITS) for "u-boot" and "flat_dt". However, users may want to add their private images into u-boot FIT image for specific application and purpose. To make this bbclass more flexible and support to add users specific snippet ITS, creates a new "UBOOT_FIT_USER_SETTINGS" variable. Users can add their specific snippet ITS into this variable. Example: ``` UBOOT_FIT_MY_ITS = '\ myfw {\n\ description = \"MY Firmware\";\n\ data = /incbin/(\"myfw.bin\");\n\ type = \"mytype\";\n\ arch = \"myarch\";\n\ os = \"myos\";\n\ load = <0xb2000000>;\n\ entry = <0xb2000000>;\n\ compression = \"none\";\n\ };\n\ ' UBOOT_FIT_USER_SETTINGS = "${UBOOT_FIT_MY_ITS}" ``` The generated ITS ``` myfw { description = "My Firmware"; data = /incbin/("myfw.bin"); type = "mytype"; arch = "myarch"; os = "myos"; load = <0xb2000000>; entry = <0xb2000000>; compression = "none"; }; ``` Add a variable "UBOOT_FIT_CONF_USER_LOADABLES" to load users specific images and it is an empty by default. Signed-off-by: Jamin Lin --- meta/classes-recipe/uboot-sign.bbclass | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/meta/classes-recipe/uboot-sign.bbclass b/meta/classes-recipe/uboot-sign.bbclass index f1b3470127..4a2dc99037 100644 --- a/meta/classes-recipe/uboot-sign.bbclass +++ b/meta/classes-recipe/uboot-sign.bbclass @@ -100,6 +100,13 @@ UBOOT_FIT_ARM_TRUSTED_FIRMWARE_IMAGE ?= "bl31.bin" UBOOT_FIT_TEE ?= "0" UBOOT_FIT_TEE_IMAGE ?= "tee-raw.bin" +# User specific settings +UBOOT_FIT_USER_SETTINGS ?= "" + +# Unit name containing a list of users additional binaries to be loaded. +# It is a comma-separated list of strings. +UBOOT_FIT_CONF_USER_LOADABLES ?= '' + UBOOT_FIT_UBOOT_LOADADDRESS ?= "${UBOOT_LOADADDRESS}" UBOOT_FIT_UBOOT_ENTRYPOINT ?= "${UBOOT_ENTRYPOINT}" @@ -366,6 +373,15 @@ EOF conf_loadables="\"atf\", ${conf_loadables}" uboot_fitimage_atf fi + + if [ -n "${UBOOT_FIT_USER_SETTINGS}" ] ; then + echo -e "${UBOOT_FIT_USER_SETTINGS}" >> ${UBOOT_ITS} + fi + + if [ -n "${UBOOT_FIT_CONF_USER_LOADABLES}" ] ; then + conf_loadables="${conf_loadables}${UBOOT_FIT_CONF_USER_LOADABLES}" + fi + cat << EOF >> ${UBOOT_ITS} }; From patchwork Wed Dec 11 02:35:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 53914 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE351E7717F for ; Wed, 11 Dec 2024 02:35:21 +0000 (UTC) Received: from TWMBX01.aspeed.com (TWMBX01.aspeed.com [211.20.114.72]) by mx.groups.io with SMTP id smtpd.web11.1956.1733884518864803607 for ; Tue, 10 Dec 2024 18:35:21 -0800 Authentication-Results: mx.groups.io; dkim=none (message not signed); spf=pass (domain: aspeedtech.com, ip: 211.20.114.72, mailfrom: jamin_lin@aspeedtech.com) Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 11 Dec 2024 10:35:15 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 11 Dec 2024 10:35:15 +0800 From: Jamin Lin To: CC: , Subject: [PATCH v5 3/3] oe-selftest: fitimage: add testcases to test ATF and TEE Date: Wed, 11 Dec 2024 10:35:15 +0800 Message-ID: <20241211023515.2108415-4-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241211023515.2108415-1-jamin_lin@aspeedtech.com> References: <20241211023515.2108415-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 11 Dec 2024 02:35:21 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/208571 Add "test_uboot_atf_tee_fit_image" test caste to check u-boot FIT image and Image Tree Source(ITS) are built and the ITS has the correct fields. Add "test_sign_standalone_uboot_atf_tee_fit_image" test case to check if u-boot FIT image and Image Tree Source (ITS) are created and signed correctly for the scenario where only the u-boot proper fitImage is being created and signed. Currently, ATF and TEE(optee-os) recipes are placed in meta-arm layer. OpenEmbedded-Core is a basic and core meta layer. To avoid OpenEmbedded-core depends meta-arm, both test cases are used dummy images for testing. Signed-off-by: Jamin Lin --- meta/lib/oeqa/selftest/cases/fitimage.py | 288 +++++++++++++++++++++++ 1 file changed, 288 insertions(+) diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py index 0b5f4602fb..fc9d224f50 100644 --- a/meta/lib/oeqa/selftest/cases/fitimage.py +++ b/meta/lib/oeqa/selftest/cases/fitimage.py @@ -852,3 +852,291 @@ FIT_HASH_ALG = "sha256" # Verify the signature uboot_tools_sysroot_native = self._setup_uboot_tools_native() self._verify_fit_image_signature(uboot_tools_sysroot_native, fitimage_path, os.path.join(bb_vars['DEPLOY_DIR_IMAGE'], 'am335x-bone.dtb')) + + + def test_uboot_atf_tee_fit_image(self): + """ + Summary: Check if U-boot FIT image and Image Tree Source + (its) are built and the Image Tree Source has the + correct fields. + Expected: 1. Create atf and tee dummy images + 2. Both u-boot-fitImage and u-boot-its can be built + 3. The os, load address, entrypoint address and + default values of U-boot, ATF and TEE images are + correct in the Image Tree Source. Not all the + fields are tested, only the key fields that wont + vary between different architectures. + Product: oe-core + Author: Jamin Lin + """ + config = """ +# We need at least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set +MACHINE = "qemuarm" +UBOOT_MACHINE = "am57xx_evm_defconfig" +SPL_BINARY = "MLO" + +# Enable creation of the U-Boot fitImage +UBOOT_FITIMAGE_ENABLE = "1" + +# (U-boot) fitImage properties +UBOOT_LOADADDRESS = "0x80080000" +UBOOT_ENTRYPOINT = "0x80080000" +UBOOT_FIT_DESC = "A model description" + +# Enable creation of the TEE fitImage +UBOOT_FIT_TEE = "1" + +# TEE fitImage properties +UBOOT_FIT_TEE_IMAGE = "${TOPDIR}/tee-dummy.bin" +UBOOT_FIT_TEE_LOADADDRESS = "0x80180000" +UBOOT_FIT_TEE_ENTRYPOINT = "0x80180000" + +# Enable creation of the ATF fitImage +UBOOT_FIT_ARM_TRUSTED_FIRMWARE = "1" + +# ATF fitImage properties +UBOOT_FIT_ARM_TRUSTED_FIRMWARE_IMAGE = "${TOPDIR}/atf-dummy.bin" +UBOOT_FIT_ARM_TRUSTED_FIRMWARE_LOADADDRESS = "0x80280000" +UBOOT_FIT_ARM_TRUSTED_FIRMWARE_ENTRYPOINT = "0x80280000" +""" + self.write_config(config) + + # Create an ATF dummy image + atf_dummy_image = os.path.join(self.builddir, "atf-dummy.bin") + cmd = 'dd if=/dev/random of=%s bs=1k count=64' % (atf_dummy_image) + result = runCmd(cmd) + self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output) + + # Create a TEE dummy image + tee_dummy_image = os.path.join(self.builddir, "tee-dummy.bin") + cmd = 'dd if=/dev/random of=%s bs=1k count=64' % (tee_dummy_image) + result = runCmd(cmd) + self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output) + + # The U-Boot fitImage is created as part of the U-Boot recipe + bitbake("virtual/bootloader") + + deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') + machine = get_bb_var('MACHINE') + fitimage_its_path = os.path.join(deploy_dir_image, + "u-boot-its-%s" % (machine,)) + fitimage_path = os.path.join(deploy_dir_image, + "u-boot-fitImage-%s" % (machine,)) + + self.assertExists(fitimage_its_path, "%s image tree source doesn't exist" % (fitimage_its_path)) + self.assertExists(fitimage_path, "%s FIT image doesn't exist" % (fitimage_path)) + + # Check that the os, load address, entrypoint address and default + # values for u-boot, ATF and TEE in Image Tree Source are as expected. + # The order of fields in the below array is important. Not all the + # fields are tested, only the key fields that wont vary between + # different architectures. + its_field_check = [ + 'description = "A model description";', + 'os = "u-boot";', + 'load = <0x80080000>;', + 'entry = <0x80080000>;', + 'description = "Trusted Execution Environment";', + 'os = "tee";', + 'load = <0x80180000>;', + 'entry = <0x80180000>;', + 'description = "ARM Trusted Firmware";', + 'os = "arm-trusted-firmware";', + 'load = <0x80280000>;', + 'entry = <0x80280000>;', + 'default = "conf";', + 'loadables = "atf", "tee", "uboot";', + 'fdt = "fdt";' + ] + + with open(fitimage_its_path) as its_file: + field_index = 0 + for line in its_file: + if field_index == len(its_field_check): + break + if its_field_check[field_index] in line: + field_index +=1 + + if field_index != len(its_field_check): # if its equal, the test passed + self.assertTrue(field_index == len(its_field_check), + "Fields in Image Tree Source File %s did not match, error in finding %s" + % (fitimage_its_path, its_field_check[field_index])) + + + def test_sign_standalone_uboot_atf_tee_fit_image(self): + """ + Summary: Check if U-Boot FIT image and Image Tree Source (its) are + created and signed correctly for the scenario where only + the U-Boot proper fitImage is being created and signed. + Expected: 1. Create atf and tee dummy images + 2. U-Boot its and FIT image are built successfully + 3. Scanning the its file indicates signing is enabled + as requested by SPL_SIGN_ENABLE (using keys generated + via UBOOT_FIT_GENERATE_KEYS) + 4. Dumping the FIT image indicates signature values + are present + 5. Examination of the do_uboot_assemble_fitimage + runfile/logfile indicate that UBOOT_MKIMAGE, UBOOT_MKIMAGE_SIGN + and SPL_MKIMAGE_SIGN_ARGS are working as expected. + Product: oe-core + Author: Jamin Lin + """ + a_comment = "a smart cascaded U-Boot ATF TEE comment" + config = """ +# There's no U-boot deconfig with CONFIG_FIT_SIGNATURE yet, so we need at +# least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set +MACHINE = "qemuarm" +UBOOT_MACHINE = "am57xx_evm_defconfig" +SPL_BINARY = "MLO" + +# The kernel-fitimage class is a dependency even if we're only +# creating/signing the U-Boot fitImage +KERNEL_CLASSES = " kernel-fitimage" + +# Enable creation and signing of the U-Boot fitImage +UBOOT_FITIMAGE_ENABLE = "1" +SPL_SIGN_ENABLE = "1" +SPL_SIGN_KEYNAME = "spl-oe-selftest" +SPL_SIGN_KEYDIR = "${TOPDIR}/signing-keys" +UBOOT_DTB_BINARY = "u-boot.dtb" +UBOOT_ARCH = "arm" +SPL_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000" +SPL_MKIMAGE_SIGN_ARGS = "-c '%s'" +UBOOT_EXTLINUX = "0" +UBOOT_FIT_GENERATE_KEYS = "1" +UBOOT_FIT_HASH_ALG = "sha256" + +# (U-boot) fitImage properties +UBOOT_LOADADDRESS = "0x80080000" +UBOOT_ENTRYPOINT = "0x80080000" +UBOOT_FIT_DESC = "A model description" + +# Enable creation of the TEE fitImage +UBOOT_FIT_TEE = "1" + +# TEE fitImage properties +UBOOT_FIT_TEE_IMAGE = "${TOPDIR}/tee-dummy.bin" +UBOOT_FIT_TEE_LOADADDRESS = "0x80180000" +UBOOT_FIT_TEE_ENTRYPOINT = "0x80180000" + +# Enable creation of the ATF fitImage +UBOOT_FIT_ARM_TRUSTED_FIRMWARE = "1" + +# ATF fitImage properties +UBOOT_FIT_ARM_TRUSTED_FIRMWARE_IMAGE = "${TOPDIR}/atf-dummy.bin" +UBOOT_FIT_ARM_TRUSTED_FIRMWARE_LOADADDRESS = "0x80280000" +UBOOT_FIT_ARM_TRUSTED_FIRMWARE_ENTRYPOINT = "0x80280000" +""" % a_comment + + self.write_config(config) + + # Create an ATF dummy image + atf_dummy_image = os.path.join(self.builddir, "atf-dummy.bin") + cmd = 'dd if=/dev/random of=%s bs=1k count=64' % (atf_dummy_image) + result = runCmd(cmd) + self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output) + + # Create a TEE dummy image + tee_dummy_image = os.path.join(self.builddir, "tee-dummy.bin") + cmd = 'dd if=/dev/random of=%s bs=1k count=64' % (tee_dummy_image) + result = runCmd(cmd) + self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output) + + # The U-Boot fitImage is created as part of the U-Boot recipe + bitbake("virtual/bootloader") + + deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') + machine = get_bb_var('MACHINE') + fitimage_its_path = os.path.join(deploy_dir_image, + "u-boot-its-%s" % (machine,)) + fitimage_path = os.path.join(deploy_dir_image, + "u-boot-fitImage-%s" % (machine,)) + + self.assertExists(fitimage_its_path, "%s image tree source doesn't exist" % (fitimage_its_path)) + self.assertExists(fitimage_path, "%s FIT image doesn't exist" % (fitimage_path)) + + req_itspaths = [ + ['/', 'images', 'uboot'], + ['/', 'images', 'uboot', 'signature'], + ['/', 'images', 'fdt'], + ['/', 'images', 'fdt', 'signature'], + ['/', 'images', 'tee'], + ['/', 'images', 'tee', 'signature'], + ['/', 'images', 'atf'], + ['/', 'images', 'atf', 'signature'], + ] + + itspath = [] + itspaths = [] + linect = 0 + sigs = {} + with open(fitimage_its_path) as its_file: + linect += 1 + for line in its_file: + line = line.strip() + if line.endswith('};'): + itspath.pop() + elif line.endswith('{'): + itspath.append(line[:-1].strip()) + itspaths.append(itspath[:]) + elif itspath and itspath[-1] == 'signature': + itsdotpath = '.'.join(itspath) + if not itsdotpath in sigs: + sigs[itsdotpath] = {} + if not '=' in line or not line.endswith(';'): + self.fail('Unexpected formatting in %s sigs section line %d:%s' % (fitimage_its_path, linect, line)) + key, value = line.split('=', 1) + sigs[itsdotpath][key.rstrip()] = value.lstrip().rstrip(';') + + for reqpath in req_itspaths: + if not reqpath in itspaths: + self.fail('Missing section in its file: %s' % reqpath) + + reqsigvalues_image = { + 'algo': '"sha256,rsa2048"', + 'key-name-hint': '"spl-oe-selftest"', + } + + for itspath, values in sigs.items(): + reqsigvalues = reqsigvalues_image + for reqkey, reqvalue in reqsigvalues.items(): + value = values.get(reqkey, None) + if value is None: + self.fail('Missing key "%s" in its file signature section %s' % (reqkey, itspath)) + self.assertEqual(value, reqvalue) + + # Dump the image to see if it really got signed + uboot_tools_sysroot_native = self._setup_uboot_tools_native() + dumpimage_path = os.path.join(uboot_tools_sysroot_native, 'usr', 'bin', 'dumpimage') + result = runCmd('%s -l %s' % (dumpimage_path, fitimage_path)) + in_signed = None + signed_sections = {} + for line in result.output.splitlines(): + if line.startswith((' Image')): + in_signed = re.search(r'\((.*)\)', line).groups()[0] + elif re.match(' \w', line): + in_signed = None + elif in_signed: + if not in_signed in signed_sections: + signed_sections[in_signed] = {} + key, value = line.split(':', 1) + signed_sections[in_signed][key.strip()] = value.strip() + self.assertIn('uboot', signed_sections) + self.assertIn('fdt', signed_sections) + self.assertIn('tee', signed_sections) + self.assertIn('atf', signed_sections) + for signed_section, values in signed_sections.items(): + value = values.get('Sign algo', None) + self.assertEqual(value, 'sha256,rsa2048:spl-oe-selftest', 'Signature algorithm for %s not expected value' % signed_section) + value = values.get('Sign value', None) + self.assertEqual(len(value), 512, 'Signature value for section %s not expected length' % signed_section) + + # Check for SPL_MKIMAGE_SIGN_ARGS + # Looks like mkimage supports to add a comment but does not support to read it back. + found_comments = FitImageTests._find_string_in_bin_file(fitimage_path, a_comment) + self.assertEqual(found_comments, 4, "Expected 4 signed and commented section in the fitImage.") + + # Verify the signature + self._verify_fit_image_signature(uboot_tools_sysroot_native, fitimage_path, + os.path.join(deploy_dir_image, 'u-boot-spl.dtb')) +