[Buildroot] [PATCH v2 1/1] package/uboot-tools: fix host FIT signature support
James Hilliard <[email protected]> Tue, 28 Jul 2026 13:45:41 -0600
| Newsgroups | net.busybox.buildroot |
|---|---|
| Message-ID | <[email protected]> |
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]> --- Changes v1 -> v2: - Clarify that the old configuration silently omits FIT signatures - Add FIT signing, required-key and tamper-rejection runtime coverage --- package/uboot-tools/uboot-tools.mk | 7 ++- .../testing/tests/package/test_uboot_tools.py | 57 +++++++++++++++++++ .../tests/package/test_uboot_tools/key.dts | 4 ++ .../tests/package/test_uboot_tools/signed.its | 38 +++++++++++++ 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 support/testing/tests/package/test_uboot_tools/key.dts create mode 100644 support/testing/tests/package/test_uboot_tools/signed.its 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..b5ab586192 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,56 @@ 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) + + keydir = Path(self.builddir) / "keys" + keydir.mkdir(exist_ok=True) + 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) + + 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) + + 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) + + 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) + + 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") + + cmd = [ + "host/bin/fit_check_sign", "-f", "signed.fit", + "-k", "test-key.dtb", + ] + infra.run_cmd_on_host(self.builddir, cmd) + + cmd = [ + "host/bin/fdtput", "-t", "bx", "signed.fit", + "/configurations/config-1/signature-1", "value", "00", + ] + infra.run_cmd_on_host(self.builddir, cmd) + 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..e160dad6a6 --- /dev/null +++ b/support/testing/tests/package/test_uboot_tools/key.dts @@ -0,0 +1,4 @@ +/dts-v1/; + +/ { +}; 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"; + }; + }; + }; +}; -- 2.53.0 _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot