[Buildroot] [git commit] package/uboot-tools: fix host FIT signature support
Julien Olivain via buildroot <[email protected]> Wed, 29 Jul 2026 20:38:07 +0200
| Newsgroups | net.busybox.buildroot |
|---|---|
| Message-ID | <[email protected]> |
commit: https://gitlab.com/buildroot.org/buildroot/-/commit/928cc5dc5cb82e6f2cb43f853488309eb806ef89 branch: https://gitlab.com/buildroot.org/buildroot/-/tree/master U-Boot host tools use the tools configuration namespace when code calls CONFIG_IS_ENABLED(). With USE_HOSTCC, CONFIG_IS_ENABLED(FIT_SIGNATURE) resolves to CONFIG_TOOLS_FIT_SIGNATURE, while CONFIG_VAL(FIT_SIGNATURE_MAX_SIZE) resolves to CONFIG_TOOLS_FIT_SIGNATURE_MAX_SIZE. The host-uboot-tools package only generates the old CONFIG_FIT_SIGNATURE define. This makes tools/Makefile include fit_check_sign, but the host code sees FIT signature support as disabled and the OpenSSL-backed signing and verification objects are omitted. As a result, mkimage accepts a signature node without writing its value or injecting a required public key. fit_check_sign then has no required key and reports success without checking the configuration signature. A FIT-support-only configuration never exercises this path, which is why the existing hash-only runtime test still passes. Generate the tools FIT signature options needed by the host code and pass CONFIG_TOOLS_LIBCRYPTO=y so the OpenSSL-backed signing, verification and cipher objects are selected. Keep CONFIG_FIT_SIGNATURE=y in the make options because U-Boot tools/Makefile still uses it to build fit_check_sign. Extend TestHostUbootTools to create an RSA-signed FIT, require a 256-byte configuration signature and a required public key, verify the FIT, corrupt the signature, and require verification to fail. Signed-off-by: James Hilliard <[email protected]> [Julien: add comments in runtime test] Signed-off-by: Julien Olivain <[email protected]> --- package/uboot-tools/uboot-tools.mk | 7 ++- support/testing/tests/package/test_uboot_tools.py | 71 ++++++++++++++++++++++ .../testing/tests/package/test_uboot_tools/key.dts | 7 +++ .../tests/package/test_uboot_tools/signed.its | 38 ++++++++++++ 4 files changed, 121 insertions(+), 2 deletions(-) diff --git a/package/uboot-tools/uboot-tools.mk b/package/uboot-tools/uboot-tools.mk index 6b5554da9b..ef8bcabbd9 100644 --- a/package/uboot-tools/uboot-tools.mk +++ b/package/uboot-tools/uboot-tools.mk @@ -126,7 +126,10 @@ define HOST_UBOOT_TOOLS_CONFIGURE_CMDS mkdir -p $(@D)/include/generated $(if $(BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT),$(UBOOT_TOOLS_ENABLE_HASH_ALGOS)) $(if $(BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT),echo '#define CONFIG_TOOLS_FIT_PRINT 1' >> $(@D)/include/generated/autoconf.h) - echo $(if $(BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT),'#define CONFIG_FIT_SIGNATURE 1') >> $(@D)/include/generated/autoconf.h + $(if $(BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT),echo '#define CONFIG_TOOLS_IMAGE_PRE_LOAD 1' >> $(@D)/include/generated/autoconf.h) + $(if $(BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT),echo '#define CONFIG_TOOLS_RSASSA_PSS 1' >> $(@D)/include/generated/autoconf.h) + $(if $(BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT),echo '#define CONFIG_TOOLS_FIT_SIGNATURE 1' >> $(@D)/include/generated/autoconf.h) + $(if $(BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT),echo '#define CONFIG_TOOLS_FIT_SIGNATURE_MAX_SIZE 0x10000000' >> $(@D)/include/generated/autoconf.h) mkdir -p $(@D)/include/asm touch $(@D)/include/asm/linkage.h endef @@ -142,7 +145,7 @@ HOST_UBOOT_TOOLS_DEPENDENCIES += host-dtc endif ifeq ($(BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT),y) -HOST_UBOOT_TOOLS_MAKE_OPTS += CONFIG_FIT_SIGNATURE=y CONFIG_FIT_SIGNATURE_MAX_SIZE=0x10000000 +HOST_UBOOT_TOOLS_MAKE_OPTS += CONFIG_TOOLS_LIBCRYPTO=y CONFIG_FIT_SIGNATURE=y HOST_UBOOT_TOOLS_DEPENDENCIES += host-openssl define HOST_UBOOT_TOOLS_INSTALL_FIT_CHECK_SIGN $(INSTALL) -m 0755 -D $(@D)/tools/fit_check_sign $(HOST_DIR)/bin/fit_check_sign diff --git a/support/testing/tests/package/test_uboot_tools.py b/support/testing/tests/package/test_uboot_tools.py index 5e5b44af30..8cff6fda21 100644 --- a/support/testing/tests/package/test_uboot_tools.py +++ b/support/testing/tests/package/test_uboot_tools.py @@ -1,11 +1,14 @@ import hashlib import re +import subprocess import zlib from pathlib import Path import infra.basetest EXAMPLE_ITS = Path(__file__).parent / "test_uboot_tools/example.its" +KEY_DTS = Path(__file__).parent / "test_uboot_tools/key.dts" +SIGNED_ITS = Path(__file__).parent / "test_uboot_tools/signed.its" def get_hashes(output: str) -> dict[str, str]: @@ -72,6 +75,7 @@ class TestHostUbootTools(infra.basetest.BRHostPkgTest): """ BR2_PACKAGE_HOST_UBOOT_TOOLS=y BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y + BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y """ def test_run(self): @@ -86,3 +90,70 @@ class TestHostUbootTools(infra.basetest.BRHostPkgTest): self.assertEqual(expected[h], reported[h]) # Python does not have built-in CRC16 support, just check it is present self.assertIn("crc16-ccitt", reported) + + # See U-Boot FIT Signature Verification documentation: + # https://source.denx.de/u-boot/u-boot/-/blob/v2026.07/doc/usage/fit/signature.rst + keydir = Path(self.builddir) / "keys" + keydir.mkdir(exist_ok=True) + + # We generate a prublic/private key pair to sign the image. + cmd = [ + "host/bin/openssl", "req", "-batch", "-new", "-x509", "-nodes", + "-newkey", "rsa:2048", "-keyout", str(keydir / "dev.key"), + "-out", str(keydir / "dev.crt"), "-subj", "/CN=Buildroot FIT test", + ] + infra.run_cmd_on_host(self.builddir, cmd) + + # We compile the empty dtb that will be used to store the + # public key. + cmd = [ + "host/bin/dtc", "-I", "dts", "-O", "dtb", "-p", "0x1000", + "-o", "test-key.dtb", str(KEY_DTS), + ] + infra.run_cmd_on_host(self.builddir, cmd) + + # We sign the image and write the public key in our key + # storage dtb. + cmd = [ + "host/bin/mkimage", "-f", str(SIGNED_ITS), "-k", str(keydir), + "-K", "test-key.dtb", "-r", "signed.fit", + ] + infra.run_cmd_on_host(self.builddir, cmd) + + # We check there is a signature present in the FIT image. + cmd = [ + "host/bin/fdtget", "-t", "bx", "signed.fit", + "/configurations/config-1/signature-1", "value", + ] + signature = infra.run_cmd_on_host(self.builddir, cmd).split() + self.assertEqual(len(signature), 256) + + # We check the key is marked as required for the configuration. + cmd = [ + "host/bin/fdtget", "-t", "s", "test-key.dtb", + "/signature/key-dev", "required", + ] + required = infra.run_cmd_on_host(self.builddir, cmd).strip() + self.assertEqual(required, "conf") + + # We actually check the signature is valid. + cmd = [ + "host/bin/fit_check_sign", "-f", "signed.fit", + "-k", "test-key.dtb", + ] + infra.run_cmd_on_host(self.builddir, cmd) + + # We "corrupt" the signature, by setting it to zero. + cmd = [ + "host/bin/fdtput", "-t", "bx", "signed.fit", + "/configurations/config-1/signature-1", "value", "00", + ] + infra.run_cmd_on_host(self.builddir, cmd) + + # We check again the siganute, and expect a failure. + cmd = [ + "host/bin/fit_check_sign", "-f", "signed.fit", + "-k", "test-key.dtb", + ] + with self.assertRaises(subprocess.CalledProcessError): + infra.run_cmd_on_host(self.builddir, cmd) diff --git a/support/testing/tests/package/test_uboot_tools/key.dts b/support/testing/tests/package/test_uboot_tools/key.dts new file mode 100644 index 0000000000..c7a686c720 --- /dev/null +++ b/support/testing/tests/package/test_uboot_tools/key.dts @@ -0,0 +1,7 @@ +/dts-v1/; + +/* This empty dts will be used for storing the public key. + * The dtb is populated later by the "mkimage -K" command. */ + +/ { +}; diff --git a/support/testing/tests/package/test_uboot_tools/signed.its b/support/testing/tests/package/test_uboot_tools/signed.its new file mode 100644 index 0000000000..25128cbbda --- /dev/null +++ b/support/testing/tests/package/test_uboot_tools/signed.its @@ -0,0 +1,38 @@ +/dts-v1/; + +/ { + description = "Signed test FIT"; + #address-cells = <1>; + + images { + kernel { + description = "This file, pretending to be a kernel"; + data = /incbin/("example.its"); + type = "kernel"; + arch = "arm64"; + os = "linux"; + compression = "none"; + load = <0x40400000>; + entry = <0x40400000>; + + hash-1 { + algo = "sha256"; + }; + }; + }; + + configurations { + default = "config-1"; + + config-1 { + description = "Signed test entry"; + kernel = "kernel"; + + signature-1 { + algo = "sha256,rsa2048"; + key-name-hint = "dev"; + sign-images = "kernel"; + }; + }; + }; +}; _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot