From patchwork Sun Oct 25 18:23:54 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 101922 Received: from mta-65-226.siemens.flowmailer.net (mta-65-226.siemens.flowmailer.net [185.136.65.226]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.27595.1792952682143348416 for ; Sun, 25 Oct 2026 11:24:43 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=OYq5gBbB; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.226, mailfrom: fm-1329275-202610251824390e36e88b07000207a9-6diw_r@rts-flowmailer.siemens.com) Received: by mta-65-226.siemens.flowmailer.net with ESMTPSA id 202610251824390e36e88b07000207a9 for ; Sun, 25 Oct 2026 19:24:39 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=vQVcmgjYxUEbY6/QPfm51RMw8b4UCoFe6Or/ajs/9qs=; b=OYq5gBbBHxUqfgPnBk1YS2OseKO4A5Y1biGBvBog96DdDZZWlOWpyYjGLkd+VJCNdHArfY lhxtckPqQSnh+7yMEqROoOgA7VManLY3BA161cRXpKsgK8zfT1o2Ezd3s0sUOZSODUCqrvNJ gWhgb11rgy/WpZZR2r0AMFyZpkNhx3T0WIYxrlPJCsdZLRzHCUdDfw65GZnwsnJmEKtlEDJP /DG1aOzzv8bHqgv3XjW/XOwKGx86fKE/cYmyNYRTGvnk6Ea3xmgxQAuYcnHK1CKxubjoq4Py C2dT5NXiXW7hwWwaarWKBqloYTJuXaLzq9TEI7efoR+0L6JsYFKFX5Nw==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Marta Rybczynska , Adrian Freihofer Subject: [PATCH v5 1/6] uboot-sign: add the option to sign SPL FIT configurations Date: Sun, 25 Oct 2026 19:23:54 +0100 Message-ID: <20261025182436.788918-2-adrian.freihofer@siemens.com> In-Reply-To: <20261025182436.788918-1-adrian.freihofer@siemens.com> References: <20261025182436.788918-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Sun, 25 Oct 2026 18:24:51 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248623 From: Marta Rybczynska The SPL FIT signing path was signing individual images, but not the configuration. Introduce signing of configuration with images under a separate option SPL_SIGN_CONF. For now it is disabled. Enabling this option implies changes in the DTB content. The old behaviour is possible with SPL_SIGN_INDIVIDUAL, but should be removed in a subsequent patch. Signed-off-by: Marta Rybczynska Reviewed-by: Adrian Freihofer --- meta/classes-recipe/uboot-sign.bbclass | 86 ++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/meta/classes-recipe/uboot-sign.bbclass b/meta/classes-recipe/uboot-sign.bbclass index 5d9e48e103..9a79aeb366 100644 --- a/meta/classes-recipe/uboot-sign.bbclass +++ b/meta/classes-recipe/uboot-sign.bbclass @@ -33,6 +33,16 @@ UBOOT_FITIMAGE_ENABLE ?= "0" # Signature activation - this requires UBOOT_FITIMAGE_ENABLE = "1" SPL_SIGN_ENABLE ?= "0" +# Sign the FIT configuration in the SPL signing flow. Configuration +# signatures bind the selected images and boot metadata together. +SPL_SIGN_CONF ?= "0" + +# Legacy compatibility knob for per-image signatures in the SPL FIT path. +# Individual image signatures do not protect the configuration metadata +# which selects and parameterizes the boot images. +# INSECURE, use at your own risk +SPL_SIGN_INDIVIDUAL ?= "1" + # Default value for deployment filenames. UBOOT_DTB_IMAGE ?= "u-boot-${MACHINE}-${PV}-${PR}.dtb" UBOOT_DTB_BINARY ?= "u-boot.dtb" @@ -350,7 +360,15 @@ uboot_fitimage_atf() { entry = <${UBOOT_FIT_ARM_TRUSTED_FIRMWARE_ENTRYPOINT}>; compression = "none"; EOF - if [ "${SPL_SIGN_ENABLE}" = "1" ] ; then + if [ "${SPL_SIGN_ENABLE}" = "1" ] && [ "${SPL_SIGN_CONF}" = "1" ] ; then + cat << EOF >> ${UBOOT_ITS} + hash-1 { + algo = "${UBOOT_FIT_HASH_ALG}"; + }; +EOF + fi + + if [ "${SPL_SIGN_ENABLE}" = "1" ] && [ "${SPL_SIGN_INDIVIDUAL}" = "1" ] ; then cat << EOF >> ${UBOOT_ITS} signature { algo = "${UBOOT_FIT_HASH_ALG},${UBOOT_FIT_SIGN_ALG}"; @@ -377,7 +395,15 @@ uboot_fitimage_tee() { entry = <${UBOOT_FIT_TEE_ENTRYPOINT}>; compression = "none"; EOF - if [ "${SPL_SIGN_ENABLE}" = "1" ] ; then + if [ "${SPL_SIGN_ENABLE}" = "1" ] && [ "${SPL_SIGN_CONF}" = "1" ] ; then + cat << EOF >> ${UBOOT_ITS} + hash-1 { + algo = "${UBOOT_FIT_HASH_ALG}"; + }; +EOF + fi + + if [ "${SPL_SIGN_ENABLE}" = "1" ] && [ "${SPL_SIGN_INDIVIDUAL}" = "1" ] ; then cat << EOF >> ${UBOOT_ITS} signature { algo = "${UBOOT_FIT_HASH_ALG},${UBOOT_FIT_SIGN_ALG}"; @@ -418,7 +444,15 @@ uboot_fitimage_assemble() { entry = <${UBOOT_FIT_UBOOT_ENTRYPOINT}>; EOF - if [ "${SPL_SIGN_ENABLE}" = "1" ] ; then + if [ "${SPL_SIGN_ENABLE}" = "1" ] && [ "${SPL_SIGN_CONF}" = "1" ] ; then + cat << EOF >> ${UBOOT_ITS} + hash-1 { + algo = "${UBOOT_FIT_HASH_ALG}"; + }; +EOF + fi + + if [ "${SPL_SIGN_ENABLE}" = "1" ] && [ "${SPL_SIGN_INDIVIDUAL}" = "1" ] ; then cat << EOF >> ${UBOOT_ITS} signature { algo = "${UBOOT_FIT_HASH_ALG},${UBOOT_FIT_SIGN_ALG}"; @@ -437,7 +471,15 @@ EOF compression = "none"; EOF - if [ "${SPL_SIGN_ENABLE}" = "1" ] ; then + if [ "${SPL_SIGN_ENABLE}" = "1" ] && [ "${SPL_SIGN_CONF}" = "1" ] ; then + cat << EOF >> ${UBOOT_ITS} + hash-1 { + algo = "${UBOOT_FIT_HASH_ALG}"; + }; +EOF + fi + + if [ "${SPL_SIGN_ENABLE}" = "1" ] && [ "${SPL_SIGN_INDIVIDUAL}" = "1" ] ; then cat << EOF >> ${UBOOT_ITS} signature { algo = "${UBOOT_FIT_HASH_ALG},${UBOOT_FIT_SIGN_ALG}"; @@ -470,10 +512,21 @@ EOF conf_loadables="${conf_loadables}${UBOOT_FIT_CONF_USER_LOADABLES}" fi + conf_sign_images="" + conf_sign_images_sep="" + if [ -n "${UBOOT_FIT_CONF_FIRMWARE}" ] ; then conf_firmware="firmware = \"${UBOOT_FIT_CONF_FIRMWARE}\";" + conf_sign_images="${conf_sign_images}${conf_sign_images_sep}\"firmware\"" + conf_sign_images_sep=", " fi + if [ -n "${conf_loadables}" ] ; then + conf_sign_images="${conf_sign_images}${conf_sign_images_sep}\"loadables\"" + conf_sign_images_sep=", " + fi + conf_sign_images="${conf_sign_images}${conf_sign_images_sep}\"fdt\"" + cat << EOF >> ${UBOOT_ITS} }; @@ -484,6 +537,19 @@ EOF ${conf_firmware} loadables = ${conf_loadables}; fdt = "fdt"; +EOF + + if [ "${SPL_SIGN_ENABLE}" = "1" ] && [ "${SPL_SIGN_CONF}" = "1" ] ; then + cat << EOF >> ${UBOOT_ITS} + signature { + algo = "${UBOOT_FIT_HASH_ALG},${UBOOT_FIT_SIGN_ALG}"; + key-name-hint = "${SPL_SIGN_KEYNAME}"; + sign-images = ${conf_sign_images}; + }; +EOF + fi + + cat << EOF >> ${UBOOT_ITS} }; }; }; @@ -498,6 +564,18 @@ EOF ${UBOOT_FITIMAGE_BINARY} if [ "${SPL_SIGN_ENABLE}" = "1" ] ; then + if [ "${SPL_SIGN_CONF}" != "1" ] && [ "${SPL_SIGN_INDIVIDUAL}" != "1" ] ; then + bbfatal "SPL_SIGN_ENABLE=1 requires SPL_SIGN_CONF=1 or SPL_SIGN_INDIVIDUAL=1" + fi + + if [ "${SPL_SIGN_CONF}" != "1" ] ; then + bbwarn "SPL_SIGN_CONF is disabled. FIT configuration signing is recommended for SPL verified boot." + fi + + if [ "${SPL_SIGN_INDIVIDUAL}" = "1" ] ; then + bbwarn "SPL_SIGN_INDIVIDUAL=1 is enabled for compatibility only. It is INSECURE. Individual image signatures do not replace configuration signing." + fi + if [ -n "${SPL_DTB_BINARY}" ] ; then # # Sign the U-boot FIT image and add public key to SPL dtb. From patchwork Sun Oct 25 18:23:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 101919 Received: from mta-64-227.siemens.flowmailer.net (mta-64-227.siemens.flowmailer.net [185.136.64.227]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.27594.1792952682142977798 for ; Sun, 25 Oct 2026 11:24:43 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=Sz4qWWmG; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.227, mailfrom: fm-1329275-20261025182439bc35fe0ca3000207c8-ukktnn@rts-flowmailer.siemens.com) Received: by mta-64-227.siemens.flowmailer.net with ESMTPSA id 20261025182439bc35fe0ca3000207c8 for ; Sun, 25 Oct 2026 19:24:39 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=DaGQDg75imm3H+HGbJ06QdvLnyeI0svdx2macBzQBXo=; b=Sz4qWWmGNrLlLJdOrysd4o5ddIEFx40KnUIrR5JLGV5Tycz3cu9H/jN8v91r3UvJ8T8aVR wdz/KfxrcmhQTZ4QNOJjiKWnrI6PV8dMf4NlMasY+x/XHdSzhDSsNgtxjsjrEGxW/CzkANqj 6ZErenGZEb+UcN33B04UHtygq/l9xMcOp93Tk2n5wTGHVgyh69sKRPbVnostkqH6AR1jDz4y EfFyn1yjuTeRBZ6bvaaxBcFs9BPuVvekB0F++itFUKwAwU/fT2uE2eyDDUJ/bIbtwu3FUNJb g7QZVFQFGJlrifEqm7YdBFxM1bw/g4yhjZyepErWBkRdqTU7IkfY+erQ==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Marta Rybczynska , Adrian Freihofer Subject: [PATCH v5 2/6] oe-selftest: fitimage: support new schema for uboot configuration signing Date: Sun, 25 Oct 2026 19:23:55 +0100 Message-ID: <20261025182436.788918-3-adrian.freihofer@siemens.com> In-Reply-To: <20261025182436.788918-1-adrian.freihofer@siemens.com> References: <20261025182436.788918-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Sun, 25 Oct 2026 18:24:51 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248624 From: Marta Rybczynska Modify testcases after adding signing of a configuration of uboot instead of various sections separately. This change includes an additional parameter to _check_signing that allows more flexible configuration and avoids assumptions on what section has, and which section does not have a signature - now they are defined in a data structure. [Adrian: dropped the check of the undefined req_values variable in KernelFitImageBase._check_signing which caused a NameError] Signed-off-by: Marta Rybczynska Reviewed-by: Adrian Freihofer --- meta/lib/oeqa/selftest/cases/fitimage.py | 51 +++++++++++++++--------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py index 5d77e6da09..50ac3f94ea 100644 --- a/meta/lib/oeqa/selftest/cases/fitimage.py +++ b/meta/lib/oeqa/selftest/cases/fitimage.py @@ -614,7 +614,7 @@ class FitImageTestCase(OESelftestTestCase): self._is_req_dict_in_dict(sections, req_sections) # Call the signing related checks if the function is provided by a inherited class - self._check_signing(bb_vars, sections, num_signatures, uboot_tools_bindir, fitimage_path) + self._check_signing(bb_vars, sections, req_sections, num_signatures, uboot_tools_bindir, fitimage_path) def _get_req_its_paths(self, bb_vars): self.logger.error("This function needs to be implemented") @@ -636,7 +636,7 @@ class FitImageTestCase(OESelftestTestCase): self.logger.error("This function needs to be implemented") return ({}, 0) - def _check_signing(self, bb_vars, sections, num_signatures, uboot_tools_bindir, fitimage_path): + def _check_signing(self, bb_vars, sections, req_sections, num_signatures, uboot_tools_bindir, fitimage_path): """Verify the signatures in the FIT image.""" self.fail("Function needs to be implemented by inheriting classes") @@ -1076,7 +1076,7 @@ class KernelFitImageBase(FitImageTestCase): req_sections[section]['Hash algo'] = fit_hash_alg return (req_sections, num_signatures) - def _check_signing(self, bb_vars, sections, num_signatures, uboot_tools_bindir, fitimage_path): + def _check_signing(self, bb_vars, sections, req_sections, num_signatures, uboot_tools_bindir, fitimage_path): """Verify the signature nodes in the FIT image""" if bb_vars['UBOOT_SIGN_ENABLE'] == "1": self.logger.debug("Verifying signatures in the FIT image") @@ -1688,6 +1688,8 @@ class UBootFitImageTests(FitImageTestCase): 'SPL_MKIMAGE_SIGN_ARGS', 'SPL_SIGN_ENABLE', 'SPL_SIGN_KEYNAME', + 'SPL_SIGN_INDIVIDUAL', + 'SPL_SIGN_CONF', 'TOPDIR', 'UBOOT_ARCH', 'UBOOT_DTB_BINARY', @@ -1763,10 +1765,14 @@ class UBootFitImageTests(FitImageTestCase): req_its_paths = [] for image in images: req_its_paths.append(['/', 'images', image]) - if bb_vars['SPL_SIGN_ENABLE'] == "1": + if bb_vars['SPL_SIGN_ENABLE'] == "1" and bb_vars['SPL_SIGN_INDIVIDUAL'] == "1": req_its_paths.append(['/', 'images', image, 'signature']) + elif bb_vars['SPL_SIGN_ENABLE'] == "1" and bb_vars['SPL_SIGN_CONF'] == "1": + req_its_paths.append(['/', 'images', image, 'hash-1']) for configuration in configurations: req_its_paths.append(['/', 'configurations', configuration]) + if bb_vars['SPL_SIGN_ENABLE'] == "1" and bb_vars['SPL_SIGN_CONF'] == "1": + req_its_paths.append(['/', 'configurations', 'conf', 'signature']) return (req_its_paths, []) def _get_req_its_fields(self, bb_vars): @@ -1874,16 +1880,26 @@ class UBootFitImageTests(FitImageTestCase): uboot_fit_sign_alg = bb_vars['UBOOT_FIT_SIGN_ALG'] spl_sign_enable = bb_vars['SPL_SIGN_ENABLE'] spl_sign_keyname = bb_vars['SPL_SIGN_KEYNAME'] + spl_sign_conf = bb_vars['SPL_SIGN_CONF'] + spl_sign_individual = bb_vars['SPL_SIGN_INDIVIDUAL'] num_signatures = 0 if spl_sign_enable == "1": for section in req_sections: - if not section.startswith('conf'): - req_sections[section]['Sign algo'] = "%s,%s:%s" % \ - (uboot_fit_hash_alg, uboot_fit_sign_alg, spl_sign_keyname) - num_signatures += 1 + if section.startswith('conf'): + if spl_sign_conf == "1": + req_sections[section]['Sign algo'] = "%s,%s:%s" % \ + (uboot_fit_hash_alg, uboot_fit_sign_alg, spl_sign_keyname) + num_signatures += 1 + else: + if spl_sign_conf == "1": + req_sections[section]['Hash algo'] = uboot_fit_hash_alg + elif spl_sign_individual == "1": + req_sections[section]['Sign algo'] = "%s,%s:%s" % \ + (uboot_fit_hash_alg, uboot_fit_sign_alg, spl_sign_keyname) + num_signatures += 1 return (req_sections, num_signatures) - def _check_signing(self, bb_vars, sections, num_signatures, uboot_tools_bindir, fitimage_path): + def _check_signing(self, bb_vars, sections, req_sections, num_signatures, uboot_tools_bindir, fitimage_path): if bb_vars['UBOOT_FITIMAGE_ENABLE'] == '1' and bb_vars['SPL_SIGN_ENABLE'] == "1": self.logger.debug("Verifying signatures in the FIT image") else: @@ -1896,16 +1912,13 @@ class UBootFitImageTests(FitImageTestCase): fit_sign_alg_len = FitImageTestCase.MKIMAGE_SIGNATURE_LENGTHS[uboot_fit_sign_alg] for section, values in sections.items(): # Configuration nodes are always signed with UBOOT_SIGN_KEYNAME (if UBOOT_SIGN_ENABLE = "1") - if section.startswith("conf"): - # uboot-sign does not sign configuration nodes - pass - else: - # uboot-sign does not add hash nodes, only image signatures - sign_algo = values.get('Sign algo', None) - req_sign_algo = "%s,%s:%s" % (uboot_fit_hash_alg, uboot_fit_sign_alg, spl_sign_keyname) - self.assertEqual(sign_algo, req_sign_algo, 'Signature algorithm for %s not expected value' % section) - sign_value = values.get('Sign value', None) - self.assertEqual(len(sign_value), fit_sign_alg_len, 'Signature value for section %s not expected length' % section) + if 'Sign algo' not in req_sections[section]: + continue + sign_algo = values.get('Sign algo', None) + req_sign_algo = "%s,%s:%s" % (uboot_fit_hash_alg, uboot_fit_sign_alg, spl_sign_keyname) + self.assertEqual(sign_algo, req_sign_algo, 'Signature algorithm for %s not expected value' % section) + sign_value = values.get('Sign value', None) + self.assertEqual(len(sign_value), fit_sign_alg_len, 'Signature value for section %s not expected length' % section) # Search for the string passed to mkimage in each signed section of the FIT image. # Looks like mkimage supports to add a comment but does not support to read it back. From patchwork Sun Oct 25 18:23:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 101921 Received: from mta-65-225.siemens.flowmailer.net (mta-65-225.siemens.flowmailer.net [185.136.65.225]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.27808.1792952682142185802 for ; Sun, 25 Oct 2026 11:24:42 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=b9ltNjSh; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.225, mailfrom: fm-1329275-2026102518243994b8c7ffb50002070f-zlyfjx@rts-flowmailer.siemens.com) Received: by mta-65-225.siemens.flowmailer.net with ESMTPSA id 2026102518243994b8c7ffb50002070f for ; Sun, 25 Oct 2026 19:24:40 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=RJRLZHHqqGvWSg/436fj7Oj6nr9z2myF2Xo21r1MRB4=; b=b9ltNjShl9E8jTJa3Vk8M9SNrvRez/DJXM6cyb5QIaCge7sv6rWDsf4Yy/UJsb63m0XX9u TdcNz0+dLaH1jup13ThNMnHYvX5evqsyqTXWXk+cu4ns4MGRQ3hDyIsZmo23my9wY/WDnPks nBOWuU8w5WlYwTjY/Jdj4aWJ5bFu9WZ/jA/fXavCIX1d51EDFQF5dLCc6Me9El1IbU+kLwOB AT2zliUfpp3wXGtmFLfpmEmCvqhTpNYSCUfFYyhDXK5mp7zB0VoiCmcUails88HZ497t/d3y 4/htPZeY+s9mBAvRMClR9otBfmy0bFJk+zcvkpGltX3kYhmXUFrekskw==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH v5 3/6] oe-selftest: fitimage: check image vs. configuration signing Date: Sun, 25 Oct 2026 19:23:56 +0100 Message-ID: <20261025182436.788918-4-adrian.freihofer@siemens.com> In-Reply-To: <20261025182436.788918-1-adrian.freihofer@siemens.com> References: <20261025182436.788918-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Sun, 25 Oct 2026 18:24:51 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248622 From: Adrian Freihofer Extend the UBootFitImageTests checks to tell individual image signing (SPL_SIGN_INDIVIDUAL) and configuration signing (SPL_SIGN_CONF) apart: - The its file must not contain the image signature, image hash or configuration signature nodes of the mode which is not enabled. - The configuration signature node is looked up per configuration instead of a hardcoded "conf" node. - The configuration signature must list the signed images in sign-images. - The public key in the deployed SPL DTB must be required for "conf" respectively "image". Signed-off-by: Adrian Freihofer --- meta/lib/oeqa/selftest/cases/fitimage.py | 45 ++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py index 50ac3f94ea..c5c446dabf 100644 --- a/meta/lib/oeqa/selftest/cases/fitimage.py +++ b/meta/lib/oeqa/selftest/cases/fitimage.py @@ -1685,6 +1685,8 @@ class UBootFitImageTests(FitImageTestCase): 'FIT_SIGN_INDIVIDUAL', 'FIT_SIGN_NUMBITS', 'MACHINE', + 'SPL_DTB_BINARY', + 'SPL_DTB_IMAGE', 'SPL_MKIMAGE_SIGN_ARGS', 'SPL_SIGN_ENABLE', 'SPL_SIGN_KEYNAME', @@ -1699,6 +1701,7 @@ class UBootFitImageTests(FitImageTestCase): 'UBOOT_FIT_ARM_TRUSTED_FIRMWARE_LOADADDRESS', 'UBOOT_FIT_ARM_TRUSTED_FIRMWARE', 'UBOOT_FIT_CONF_DESC', + 'UBOOT_FIT_CONF_FIRMWARE', 'UBOOT_FIT_CONF_USER_LOADABLES', 'UBOOT_FIT_DESC', 'UBOOT_FIT_HASH_ALG', @@ -1761,19 +1764,30 @@ class UBootFitImageTests(FitImageTestCase): # configuration nodes configurations = [ 'conf'] + spl_sign_enable = bb_vars['SPL_SIGN_ENABLE'] == "1" + spl_sign_individual = spl_sign_enable and bb_vars['SPL_SIGN_INDIVIDUAL'] == "1" + spl_sign_conf = spl_sign_enable and bb_vars['SPL_SIGN_CONF'] == "1" + # Create a list of paths for all image and configuration nodes req_its_paths = [] + not_req_its_paths = [] for image in images: req_its_paths.append(['/', 'images', image]) - if bb_vars['SPL_SIGN_ENABLE'] == "1" and bb_vars['SPL_SIGN_INDIVIDUAL'] == "1": + if spl_sign_individual: req_its_paths.append(['/', 'images', image, 'signature']) - elif bb_vars['SPL_SIGN_ENABLE'] == "1" and bb_vars['SPL_SIGN_CONF'] == "1": + else: + not_req_its_paths.append(['/', 'images', image, 'signature']) + if spl_sign_conf: req_its_paths.append(['/', 'images', image, 'hash-1']) + else: + not_req_its_paths.append(['/', 'images', image, 'hash-1']) for configuration in configurations: req_its_paths.append(['/', 'configurations', configuration]) - if bb_vars['SPL_SIGN_ENABLE'] == "1" and bb_vars['SPL_SIGN_CONF'] == "1": - req_its_paths.append(['/', 'configurations', 'conf', 'signature']) - return (req_its_paths, []) + if spl_sign_conf: + req_its_paths.append(['/', 'configurations', configuration, 'signature']) + else: + not_req_its_paths.append(['/', 'configurations', configuration, 'signature']) + return (req_its_paths, not_req_its_paths) def _get_req_its_fields(self, bb_vars): loadables = ["uboot"] @@ -1823,10 +1837,17 @@ class UBootFitImageTests(FitImageTestCase): 'loadables = "%s";' % '", "'.join(loadables), 'fdt = "fdt";', ] + if bb_vars['SPL_SIGN_ENABLE'] == "1" and bb_vars['SPL_SIGN_CONF'] == "1": + sign_images = [] + if bb_vars.get('UBOOT_FIT_CONF_FIRMWARE'): + sign_images.append("firmware") + sign_images += ["loadables", "fdt"] + its_field_check.append('sign-images = "%s";' % '", "'.join(sign_images)) return its_field_check def _get_req_sigvalues_config(self, bb_vars): - # COnfigurations are not signed by uboot-sign + # The "conf" node does not match FIT_CONF_PREFIX, so a configuration + # signature (SPL_SIGN_CONF) is checked against _get_req_sigvalues_image return {} def _get_req_sigvalues_image(self, bb_vars): @@ -1920,6 +1941,18 @@ class UBootFitImageTests(FitImageTestCase): sign_value = values.get('Sign value', None) self.assertEqual(len(sign_value), fit_sign_alg_len, 'Signature value for section %s not expected length' % section) + # The public key added to the SPL DTB tells SPL what has to be signed: + # "conf" for configuration signatures, "image" for individual image signatures. + if bb_vars['SPL_DTB_BINARY']: + dtc_bindir = FitImageTestCase._setup_native('dtc-native') + spl_dtb_path = os.path.join(bb_vars['DEPLOY_DIR_IMAGE'], bb_vars['SPL_DTB_IMAGE']) + key_dtb_path = "/signature/key-" + spl_sign_keyname + req_required = "conf" if bb_vars['SPL_SIGN_CONF'] == "1" else "image" + self._verify_dtb_property(dtc_bindir, spl_dtb_path, key_dtb_path, "required", req_required) + self._verify_dtb_property(dtc_bindir, spl_dtb_path, key_dtb_path, "algo", + "%s,%s" % (uboot_fit_hash_alg, uboot_fit_sign_alg)) + self._verify_dtb_property(dtc_bindir, spl_dtb_path, key_dtb_path, "key-name-hint", spl_sign_keyname) + # Search for the string passed to mkimage in each signed section of the FIT image. # Looks like mkimage supports to add a comment but does not support to read it back. a_comment = FitImageTestCase._get_uboot_mkimage_sign_args(bb_vars['SPL_MKIMAGE_SIGN_ARGS']) From patchwork Sun Oct 25 18:23:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 101918 Received: from mta-65-226.siemens.flowmailer.net (mta-65-226.siemens.flowmailer.net [185.136.65.226]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.27593.1792952682142798443 for ; Sun, 25 Oct 2026 11:24:43 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=POyG9uq6; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.226, mailfrom: fm-1329275-20261025182439570d229b370002075b-ijgtw0@rts-flowmailer.siemens.com) Received: by mta-65-226.siemens.flowmailer.net with ESMTPSA id 20261025182439570d229b370002075b for ; Sun, 25 Oct 2026 19:24:40 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=rEnecPHorCjefT8uKHO5eI1ojqJyQrJqRcdb843U9RU=; b=POyG9uq6oNK7B8yJZ71WAIdOmTHMS5Hs09x0jYoRFLQOg+PtNz/FRASnThwj24yrb2Io57 kWgY3gAbLEpKgbwvtDaZRZ9rD3tROtfF9eibKWiguef64Nr99ZHe5BxsOrCTxXXfKoW0mbkG iFvIuniZ8iIBZ3xVi7/WkH15WN5Bvxh5Via7nCv87E89w7mUPsknUNUUYY2Ylf2FUIlLT28N Gah8tTxd3nt0sfITvfJXkB9FGutGBYX6Mxz2W/OegA+/21pCf4UJD7TTvGq3TH1FjaOpoJ1S Z5rdhFj9yBdrtOScVzwbDJjCUi9P3g7hbN2iUBmgh6ckurOJtAL57Q0w==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH v5 4/6] oe-selftest: fitimage: test SPL FIT configuration signing Date: Sun, 25 Oct 2026 19:23:57 +0100 Message-ID: <20261025182436.788918-5-adrian.freihofer@siemens.com> In-Reply-To: <20261025182436.788918-1-adrian.freihofer@siemens.com> References: <20261025182436.788918-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Sun, 25 Oct 2026 18:24:51 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248625 From: Adrian Freihofer The existing SPL signing tests use the default settings of uboot-sign.bbclass which sign the individual images. Add test_sign_standalone_uboot_fit_image_conf which covers the non-default case: SPL_SIGN_CONF = "1" and SPL_SIGN_INDIVIDUAL = "0". It verifies that the configuration is signed instead of the individual images and that the public key in the SPL DTB is required for "conf". Signed-off-by: Adrian Freihofer --- meta/lib/oeqa/selftest/cases/fitimage.py | 43 ++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py index c5c446dabf..6fe41b769f 100644 --- a/meta/lib/oeqa/selftest/cases/fitimage.py +++ b/meta/lib/oeqa/selftest/cases/fitimage.py @@ -2087,6 +2087,49 @@ UBOOT_FIT_HASH_ALG = "sha256" self._test_fitimage(bb_vars) + def test_sign_standalone_uboot_fit_image_conf(self): + """ + Summary: Check if U-Boot FIT image and Image Tree Source (its) are + created and signed correctly when the FIT configuration + is signed (SPL_SIGN_CONF = "1") instead of the individual + images (SPL_SIGN_INDIVIDUAL = "0"). + Expected: 1) U-Boot its and FIT image are built successfully + 2) The its file has a hash node in each image node, no + image signature nodes, and a signature node in the + configuration which covers the loadables and the fdt + 3) Dumping the FIT image shows hashes for the images and + a signature for the configuration only + 4) The public key in the SPL DTB is required for "conf" + 5) SPL_MKIMAGE_SIGN_ARGS is passed to mkimage + Product: oe-core + """ + machine = self._get_machine_or_skip() + config = """ +# There's no U-boot defconfig with CONFIG_FIT_SIGNATURE yet, so we need at +# least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set +# Enable creation and signing of the U-Boot fitImage configuration +UBOOT_FITIMAGE_ENABLE = "1" +SPL_SIGN_ENABLE = "1" +SPL_SIGN_CONF = "1" +SPL_SIGN_INDIVIDUAL = "0" +SPL_SIGN_KEYNAME = "spl-conf-oe-selftest" +SPL_SIGN_KEYDIR = "${TOPDIR}/signing-keys" +UBOOT_ENTRYPOINT = "0x80000000" +UBOOT_LOADADDRESS = "0x80000000" +UBOOT_DTB_LOADADDRESS = "0x82000000" +SPL_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000" +SPL_MKIMAGE_SIGN_ARGS = "-c 'a smart U-Boot conf comment'" +UBOOT_EXTLINUX = "0" +UBOOT_FIT_GENERATE_KEYS = "1" +UBOOT_FIT_HASH_ALG = "sha256" +""" + config = FitImageTestCase._config_add_machine_settings(config, machine, keys=["UBOOT_MACHINE", "SPL_BINARY", "UBOOT_DTB_BINARY", "UBOOT_ARCH"]) + config = self._require_machine_capability(config, machine, '_cap_spl_dtb') + self.write_config(config) + bb_vars = self._fit_get_bb_vars() + self._test_fitimage(bb_vars) + + def test_sign_cascaded_uboot_fit_image(self): """ Summary: Check if U-Boot FIT image and Image Tree Source (its) are From patchwork Sun Oct 25 18:23:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 101917 Received: from mta-65-228.siemens.flowmailer.net (mta-65-228.siemens.flowmailer.net [185.136.65.228]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.27811.1792952682466489243 for ; Sun, 25 Oct 2026 11:24:42 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=AKRb6Gvs; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.228, mailfrom: fm-1329275-20261025182440ca9d008a45000207f8-2cwb4m@rts-flowmailer.siemens.com) Received: by mta-65-228.siemens.flowmailer.net with ESMTPSA id 20261025182440ca9d008a45000207f8 for ; Sun, 25 Oct 2026 19:24:40 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=KliNyqr0Wqn/aB3iL41k9zBwspJCPeE7oG4QDWd2Sw8=; b=AKRb6GvsBoW5QX9P+/SlR8eR1hSF/uZrD9cS775YKAOV//EKBLlfYtAfzaBmJcNNhXdS0l Zt3HBKFY8ivZbDUFMeCBwm+yhCQ16c7bpS1xFgoR/uogDHsqYYGY44HNMoumKVsJeaukFtk0 4BUL49bep/NPpRMNaL8EwUZFWQaNzF2tLaTFavh20Dq37Tlviqwz97G5vUjIUBEygCFaEQ3Q 5zUY2B3TwbwSYplXNT9y5NWJHd4uGOYzV43YzWew6u5YL5kHUeXSNoVWX7geiSAPCDs282Kj yBsBX7c6i5aQPytWVBAzd2G1q0A6o+Nvemxkb1/kVEm9gLt1jUvEXokA==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Marta Rybczynska , Adrian Freihofer Subject: [PATCH v5 5/6] uboot-sign: enable signing SPL FIT configuration Date: Sun, 25 Oct 2026 19:23:58 +0100 Message-ID: <20261025182436.788918-6-adrian.freihofer@siemens.com> In-Reply-To: <20261025182436.788918-1-adrian.freihofer@siemens.com> References: <20261025182436.788918-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Sun, 25 Oct 2026 18:24:50 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248620 From: Marta Rybczynska This commit enables signing SPL FIT configuration instead of specific elements. This introduces an incompatibility with the previous behavior, but is the correct way to do it. Signed-off-by: Marta Rybczynska Reviewed-by: Adrian Freihofer --- meta/classes-recipe/uboot-sign.bbclass | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meta/classes-recipe/uboot-sign.bbclass b/meta/classes-recipe/uboot-sign.bbclass index 9a79aeb366..409f6376b1 100644 --- a/meta/classes-recipe/uboot-sign.bbclass +++ b/meta/classes-recipe/uboot-sign.bbclass @@ -35,13 +35,13 @@ SPL_SIGN_ENABLE ?= "0" # Sign the FIT configuration in the SPL signing flow. Configuration # signatures bind the selected images and boot metadata together. -SPL_SIGN_CONF ?= "0" +SPL_SIGN_CONF ?= "1" # Legacy compatibility knob for per-image signatures in the SPL FIT path. # Individual image signatures do not protect the configuration metadata # which selects and parameterizes the boot images. # INSECURE, use at your own risk -SPL_SIGN_INDIVIDUAL ?= "1" +SPL_SIGN_INDIVIDUAL ?= "0" # Default value for deployment filenames. UBOOT_DTB_IMAGE ?= "u-boot-${MACHINE}-${PV}-${PR}.dtb" From patchwork Sun Oct 25 18:23:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AdrianF X-Patchwork-Id: 101920 Received: from mta-64-228.siemens.flowmailer.net (mta-64-228.siemens.flowmailer.net [185.136.64.228]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.27810.1792952682142521287 for ; Sun, 25 Oct 2026 11:24:42 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=adrian.freihofer@siemens.com header.s=fm2 header.b=ZY2UTj5E; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.228, mailfrom: fm-1329275-20261025182440f1005c9ed0000207fd-ou7m02@rts-flowmailer.siemens.com) Received: by mta-64-228.siemens.flowmailer.net with ESMTPSA id 20261025182440f1005c9ed0000207fd for ; Sun, 25 Oct 2026 19:24:40 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=adrian.freihofer@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=ly2SURVytWuK60uzPUwYFo01OaG0D485Ax+p97WBf5w=; b=ZY2UTj5EYfzLgAJy4pvmr28w2mShTElE2VEpekqwOGBM9B8KvBdezcv5PU8L3jc7mz5pcJ SaENCYnmN95JdoebQ6SL2qQxkCTwxJNjxGWVkQIQDVE15H7Pbbb1+qADFUO3tV2hUKL4NRre hcqZ8AdKdGdZj/A5m1t/FLHcaxxbQGhEkL0vp29YLJFDL5rFYUXSlz0zy5Zd5dky8/JgaITV 3q2i1Qy8SPPd+r93gXWBsuatifdx1LJrgUYSsMM/CcAxOwEuE+n/6Z7C/OBz51jL5y9+2gmt T7awGnRT+H41OxhgNjiuS6d+rLk91HQrhTmDkMok4UOUrNv2Fq+tZAWA==; From: AdrianF To: openembedded-core@lists.openembedded.org Cc: Adrian Freihofer Subject: [PATCH v5 6/6] oe-selftest: fitimage: test SPL FIT individual image signing Date: Sun, 25 Oct 2026 19:23:59 +0100 Message-ID: <20261025182436.788918-7-adrian.freihofer@siemens.com> In-Reply-To: <20261025182436.788918-1-adrian.freihofer@siemens.com> References: <20261025182436.788918-1-adrian.freihofer@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1329275:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by lin-tor-korg-lkml-alma10-1 with HTTPS for ; Sun, 25 Oct 2026 18:24:51 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/248621 From: Adrian Freihofer Since uboot-sign signs the SPL FIT configuration by default, the SPL signing tests using the default settings cover configuration signing. Invert the test for the non-default case accordingly: replace test_sign_standalone_uboot_fit_image_conf by test_sign_standalone_uboot_fit_image_individual which verifies the legacy signing of the individual images (SPL_SIGN_CONF = "0" and SPL_SIGN_INDIVIDUAL = "1"). Signed-off-by: Adrian Freihofer --- meta/lib/oeqa/selftest/cases/fitimage.py | 29 ++++++++++++------------ 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py index 6fe41b769f..81d2be5013 100644 --- a/meta/lib/oeqa/selftest/cases/fitimage.py +++ b/meta/lib/oeqa/selftest/cases/fitimage.py @@ -2087,19 +2087,18 @@ UBOOT_FIT_HASH_ALG = "sha256" self._test_fitimage(bb_vars) - def test_sign_standalone_uboot_fit_image_conf(self): + def test_sign_standalone_uboot_fit_image_individual(self): """ Summary: Check if U-Boot FIT image and Image Tree Source (its) are - created and signed correctly when the FIT configuration - is signed (SPL_SIGN_CONF = "1") instead of the individual - images (SPL_SIGN_INDIVIDUAL = "0"). + created and signed correctly when the individual images + are signed (SPL_SIGN_INDIVIDUAL = "1") instead of the FIT + configuration (SPL_SIGN_CONF = "0"). Expected: 1) U-Boot its and FIT image are built successfully - 2) The its file has a hash node in each image node, no - image signature nodes, and a signature node in the - configuration which covers the loadables and the fdt - 3) Dumping the FIT image shows hashes for the images and - a signature for the configuration only - 4) The public key in the SPL DTB is required for "conf" + 2) The its file has a signature node in each image node, + no image hash nodes and no configuration signature node + 3) Dumping the FIT image shows signatures for the images + and no signature for the configuration + 4) The public key in the SPL DTB is required for "image" 5) SPL_MKIMAGE_SIGN_ARGS is passed to mkimage Product: oe-core """ @@ -2107,18 +2106,18 @@ UBOOT_FIT_HASH_ALG = "sha256" config = """ # There's no U-boot defconfig with CONFIG_FIT_SIGNATURE yet, so we need at # least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set -# Enable creation and signing of the U-Boot fitImage configuration +# Enable creation and signing of the individual U-Boot fitImage images UBOOT_FITIMAGE_ENABLE = "1" SPL_SIGN_ENABLE = "1" -SPL_SIGN_CONF = "1" -SPL_SIGN_INDIVIDUAL = "0" -SPL_SIGN_KEYNAME = "spl-conf-oe-selftest" +SPL_SIGN_CONF = "0" +SPL_SIGN_INDIVIDUAL = "1" +SPL_SIGN_KEYNAME = "spl-individual-oe-selftest" SPL_SIGN_KEYDIR = "${TOPDIR}/signing-keys" UBOOT_ENTRYPOINT = "0x80000000" UBOOT_LOADADDRESS = "0x80000000" UBOOT_DTB_LOADADDRESS = "0x82000000" SPL_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000" -SPL_MKIMAGE_SIGN_ARGS = "-c 'a smart U-Boot conf comment'" +SPL_MKIMAGE_SIGN_ARGS = "-c 'a smart U-Boot individual comment'" UBOOT_EXTLINUX = "0" UBOOT_FIT_GENERATE_KEYS = "1" UBOOT_FIT_HASH_ALG = "sha256"