| Message ID | 20260603105453.25881-2-marta.rybczynska@ygreky.com |
|---|---|
| State | Changes Requested |
| Headers | show |
| Series | [v3,1/2] uboot-sign: sign SPL FIT configurations instead of images | expand |
On Wed Jun 3, 2026 at 12:54 PM CEST, Marta Rybczynska via lists.openembedded.org wrote: > From: Marta Rybczynska <rybczynska@gmail.com> > > 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. > > Signed-off-by: Marta Rybczynska <rybczynska@gmail.com> > --- Hi Marta, Thanks for the new version. It looks like we still have some failing selftests: 2026-06-04 10:59:24,072 - oe-selftest - INFO - fitimage.UBootFitImageTests.test_sign_standalone_uboot_atf_tee_fit_image (subunit.RemotedTestCase) 2026-06-04 10:59:24,073 - oe-selftest - INFO - ... FAIL ... ERROR: u-boot-1_2026.04-r0 do_uboot_assemble_fitimage: Execution of '/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/build-st-3150517/tmp/work/qemuarm-poky-linux-gnueabi/u-boot/2026.04/temp/run.do_uboot_assemble_fitimage.4036817' failed with exit code 1 ... | sha256,rsa2048:spl-oe-selftest- | error! | Verification failed for '(null)' hash node in 'conf' config node | Failed to verify required signature 'key-spl-cascaded-oe-selftest' | Signature check bad (error 1) | WARNING: exit code 1 from a shell command. NOTE: recipe u-boot-1_2026.04-r0: task do_uboot_assemble_fitimage: Failed ... 2026-06-04 11:00:25,624 - oe-selftest - INFO - fitimage.UBootFitImageTests.test_sign_standalone_uboot_fit_image (subunit.RemotedTestCase) 2026-06-04 11:00:25,625 - oe-selftest - INFO - ... FAIL ... ERROR: u-boot-1_2026.04-r0 do_uboot_assemble_fitimage: Execution of '/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/build-st-3150517/tmp/work/qemuarm-poky-linux-gnueabi/u-boot/2026.04/temp/run.do_uboot_assemble_fitimage.4134657' failed with exit code 1 ... | Signature check bad (error 1) | Verifying Hash Integrity for node 'conf'... sha256,rsa2048:spl-oe-selftest+ | sha256,rsa2048:spl-oe-selftest- | error! | Verification failed for '(null)' hash node in 'conf' config node | Failed to verify required signature 'key-spl-cascaded-oe-selftest' | WARNING: exit code 1 from a shell command. NOTE: recipe u-boot-1_2026.04-r0: task do_uboot_assemble_fitimage: Failed https://autobuilder.yoctoproject.org/valkyrie/#/builders/23/builds/4050 https://autobuilder.yoctoproject.org/valkyrie/#/builders/35/builds/3964 https://autobuilder.yoctoproject.org/valkyrie/#/builders/48/builds/3820 Can you have a look at the issue? Thanks, Mathieu
On Fri, 2026-06-05 at 08:47 +0200, Mathieu Dubois-Briand via lists.openembedded.org wrote: > On Wed Jun 3, 2026 at 12:54 PM CEST, Marta Rybczynska via > lists.openembedded.org wrote: > > From: Marta Rybczynska <rybczynska@gmail.com> > > > > 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. > > > > Signed-off-by: Marta Rybczynska <rybczynska@gmail.com> > > --- > > Hi Marta, > > Thanks for the new version. > > It looks like we still have some failing selftests: > > 2026-06-04 10:59:24,072 - oe-selftest - INFO - > fitimage.UBootFitImageTests.test_sign_standalone_uboot_atf_tee_fit_im > age (subunit.RemotedTestCase) > 2026-06-04 10:59:24,073 - oe-selftest - INFO - ... FAIL > ... > ERROR: u-boot-1_2026.04-r0 do_uboot_assemble_fitimage: Execution of > '/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/build-st- > 3150517/tmp/work/qemuarm-poky-linux-gnueabi/u- > boot/2026.04/temp/run.do_uboot_assemble_fitimage.4036817' failed with > exit code 1 > ... > > sha256,rsa2048:spl-oe-selftest- > > error! > > Verification failed for '(null)' hash node in 'conf' config node > > Failed to verify required signature 'key-spl-cascaded-oe-selftest' > > Signature check bad (error 1) > > WARNING: exit code 1 from a shell command. > NOTE: recipe u-boot-1_2026.04-r0: task do_uboot_assemble_fitimage: > Failed > ... > 2026-06-04 11:00:25,624 - oe-selftest - INFO - > fitimage.UBootFitImageTests.test_sign_standalone_uboot_fit_image > (subunit.RemotedTestCase) > 2026-06-04 11:00:25,625 - oe-selftest - INFO - ... FAIL > ... > ERROR: u-boot-1_2026.04-r0 do_uboot_assemble_fitimage: Execution of > '/srv/pokybuild/yocto-worker/oe-selftest-armhost/build/build-st- > 3150517/tmp/work/qemuarm-poky-linux-gnueabi/u- > boot/2026.04/temp/run.do_uboot_assemble_fitimage.4134657' failed with > exit code 1 > ... > > Signature check bad (error 1) > > Verifying Hash Integrity for node 'conf'... sha256,rsa2048:spl-oe- > > selftest+ > > sha256,rsa2048:spl-oe-selftest- > > error! > > Verification failed for '(null)' hash node in 'conf' config node > > Failed to verify required signature 'key-spl-cascaded-oe-selftest' > > WARNING: exit code 1 from a shell command. > NOTE: recipe u-boot-1_2026.04-r0: task do_uboot_assemble_fitimage: > Failed > > https://autobuilder.yoctoproject.org/valkyrie/#/builders/23/builds/4050 > https://autobuilder.yoctoproject.org/valkyrie/#/builders/35/builds/3964 > https://autobuilder.yoctoproject.org/valkyrie/#/builders/48/builds/3820 > > Can you have a look at the issue? > Hi Marta I hope this one https://lists.openembedded.org/g/openembedded-core/message/238219 will fix this issue. Regards, Adrian > Thanks, > Mathieu > > > -=-=-=-=-=-=-=-=-=-=-=- > Links: You receive all messages sent to this group. > View/Reply Online (#238142): > https://lists.openembedded.org/g/openembedded-core/message/238142 > Mute This Topic: https://lists.openembedded.org/mt/119626514/4454582 > Group Owner: openembedded-core+owner@lists.openembedded.org > Unsubscribe: > https://lists.openembedded.org/g/openembedded-core/unsub [ > adrian.freihofer@gmail.com] > -=-=-=-=-=-=-=-=-=-=-=-
On Wed, 2026-06-03 at 12:54 +0200, Marta Rybczynska via lists.openembedded.org wrote: > From: Marta Rybczynska <rybczynska@gmail.com> > > Modify testcases after adding signing of a configuration of uboot We should not modify the tests to cover only the new behavior. There are probably many users who use the image signing and will stick to that. Changing such things in real products is not always easy. We should add one more tests for the old behavior. I have that ready, here: https://git.openembedded.org/openembedded-core-contrib/commit/?h=adrianf/fit-improvements&id=b01b352ffd8c91eb000df3821ee8f5d3f488f2f1 Feel free to send your own version, or I can send mine after your patches got merged. > 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. > > Signed-off-by: Marta Rybczynska <rybczynska@gmail.com> > --- > meta/lib/oeqa/selftest/cases/fitimage.py | 53 +++++++++++++++------- > -- > 1 file changed, 34 insertions(+), 19 deletions(-) > > diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py > b/meta/lib/oeqa/selftest/cases/fitimage.py > index 3541c07520..ad523e93c1 100644 > --- a/meta/lib/oeqa/selftest/cases/fitimage.py > +++ b/meta/lib/oeqa/selftest/cases/fitimage.py > @@ -365,7 +365,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") > @@ -387,7 +387,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") > > @@ -789,7 +789,7 @@ class KernelFitImageBase(FitImageTestCase): > 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): > """Verify the signature nodes in the FIT image""" > if bb_vars['UBOOT_SIGN_ENABLE'] == "1": > self.logger.debug("Verifying signatures in the FIT > image") > @@ -809,6 +809,8 @@ class KernelFitImageBase(FitImageTestCase): > for section, values in sections.items(): > # Configuration nodes are always signed with > UBOOT_SIGN_KEYNAME (if UBOOT_SIGN_ENABLE = "1") > if section.startswith(bb_vars['FIT_CONF_PREFIX']): > + if 'Sign algo' not in req_values[section]: Should this be: if 'Sign algo' not in req_sections[section]: Regards, Adrian > + continue > sign_algo = values.get('Sign algo', None) > req_sign_algo = "%s,%s:%s" % (fit_hash_alg, > fit_sign_alg, uboot_sign_keyname) > self.assertEqual(sign_algo, req_sign_algo, > 'Signature algorithm for %s not expected value' % section) > @@ -1329,6 +1331,8 @@ class UBootFitImageTests(FitImageTestCase): > 'SPL_MKIMAGE_SIGN_ARGS', > 'SPL_SIGN_ENABLE', > 'SPL_SIGN_KEYNAME', > + 'SPL_SIGN_INDIVIDUAL', > + 'SPL_SIGN_CONF', > 'UBOOT_ARCH', > 'UBOOT_DTB_BINARY', > 'UBOOT_DTB_IMAGE', > @@ -1382,10 +1386,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): > @@ -1493,16 +1501,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: > @@ -1515,16 +1533,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. > > -=-=-=-=-=-=-=-=-=-=-=- > Links: You receive all messages sent to this group. > View/Reply Online (#238092): > https://lists.openembedded.org/g/openembedded-core/message/238092 > Mute This Topic: https://lists.openembedded.org/mt/119626514/4454582 > Group Owner: openembedded-core+owner@lists.openembedded.org > Unsubscribe: > https://lists.openembedded.org/g/openembedded-core/unsub [ > adrian.freihofer@gmail.com] > -=-=-=-=-=-=-=-=-=-=-=-
diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py index 3541c07520..ad523e93c1 100644 --- a/meta/lib/oeqa/selftest/cases/fitimage.py +++ b/meta/lib/oeqa/selftest/cases/fitimage.py @@ -365,7 +365,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") @@ -387,7 +387,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") @@ -789,7 +789,7 @@ class KernelFitImageBase(FitImageTestCase): 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): """Verify the signature nodes in the FIT image""" if bb_vars['UBOOT_SIGN_ENABLE'] == "1": self.logger.debug("Verifying signatures in the FIT image") @@ -809,6 +809,8 @@ class KernelFitImageBase(FitImageTestCase): for section, values in sections.items(): # Configuration nodes are always signed with UBOOT_SIGN_KEYNAME (if UBOOT_SIGN_ENABLE = "1") if section.startswith(bb_vars['FIT_CONF_PREFIX']): + if 'Sign algo' not in req_values[section]: + continue sign_algo = values.get('Sign algo', None) req_sign_algo = "%s,%s:%s" % (fit_hash_alg, fit_sign_alg, uboot_sign_keyname) self.assertEqual(sign_algo, req_sign_algo, 'Signature algorithm for %s not expected value' % section) @@ -1329,6 +1331,8 @@ class UBootFitImageTests(FitImageTestCase): 'SPL_MKIMAGE_SIGN_ARGS', 'SPL_SIGN_ENABLE', 'SPL_SIGN_KEYNAME', + 'SPL_SIGN_INDIVIDUAL', + 'SPL_SIGN_CONF', 'UBOOT_ARCH', 'UBOOT_DTB_BINARY', 'UBOOT_DTB_IMAGE', @@ -1382,10 +1386,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): @@ -1493,16 +1501,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: @@ -1515,16 +1533,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.