diff options
Diffstat (limited to 'tools/binman')
| -rw-r--r-- | tools/binman/btool/p11_kit.py | 11 | ||||
| -rw-r--r-- | tools/binman/btool/pkcs11_tool.py | 11 | ||||
| -rw-r--r-- | tools/binman/btool/softhsm2_util.py | 12 | ||||
| -rw-r--r-- | tools/binman/etype/atf_fip.py | 2 | ||||
| -rw-r--r-- | tools/binman/etype/collection.py | 9 | ||||
| -rw-r--r-- | tools/binman/etype/nxp_imx8mimage.py | 14 | ||||
| -rw-r--r-- | tools/binman/etype/pre_load.py | 9 | ||||
| -rw-r--r-- | tools/binman/etype/section.py | 5 | ||||
| -rw-r--r-- | tools/binman/ftest.py | 81 | ||||
| -rw-r--r-- | tools/binman/missing-blob-help | 6 | ||||
| -rw-r--r-- | tools/binman/pyproject.toml | 2 | ||||
| -rw-r--r-- | tools/binman/test/security/pre_load_fit_encrypted.dts | 63 | ||||
| -rw-r--r-- | tools/binman/test/vendor/nxp_imx8m_fspi.dts | 18 | ||||
| -rw-r--r-- | tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts | 18 | ||||
| -rw-r--r-- | tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts | 18 |
15 files changed, 237 insertions, 42 deletions
diff --git a/tools/binman/btool/p11_kit.py b/tools/binman/btool/p11_kit.py index 9d8d5d848b4..1bbece5bb2b 100644 --- a/tools/binman/btool/p11_kit.py +++ b/tools/binman/btool/p11_kit.py @@ -7,7 +7,16 @@ from binman import bintool class Bintoolp11_kit(bintool.Bintool): - """p11-kit -- support tool for pkcs#11 libraries""" + """p11-kit -- support tool for pkcs#11 libraries + + This bintool wraps the `p11-kit` command, a support tool for PKCS#11 + modules. Binman uses this wrapper only to check that p11-kit is installed + (and to fetch it if missing); any actual PKCS#11 module discovery for + signing FIT images or capsules is done outside binman, by mkimage and the + OpenSSL PKCS#11 engine. + + See https://p11-glue.github.io/p11-glue/p11-kit.html for more details. + """ def __init__(self, name): super().__init__('p11-kit', 'Pkcs11 library modules tool', diff --git a/tools/binman/btool/pkcs11_tool.py b/tools/binman/btool/pkcs11_tool.py index 673c0ea0ac3..ca80943f98c 100644 --- a/tools/binman/btool/pkcs11_tool.py +++ b/tools/binman/btool/pkcs11_tool.py @@ -7,7 +7,16 @@ from binman import bintool class Bintoolpkcs11_tool(bintool.Bintool): - """pkcs11-tool -- support tool for managing pkcs#11 tokens""" + """pkcs11-tool -- support tool for managing pkcs#11 tokens + + This bintool wraps the `pkcs11-tool` command from the OpenSC project for + managing objects stored in PKCS#11 tokens. Binman uses this wrapper only + to check that pkcs11-tool is installed (and to fetch it if missing); any + actual key or token management for signing FIT images or capsules is done + outside binman. + + See https://github.com/OpenSC/OpenSC/wiki for more details. + """ def __init__(self, name): super().__init__('pkcs11-tool', 'PKCS #11 tokens managing tool', diff --git a/tools/binman/btool/softhsm2_util.py b/tools/binman/btool/softhsm2_util.py index 869221d841d..fd2ff2d6473 100644 --- a/tools/binman/btool/softhsm2_util.py +++ b/tools/binman/btool/softhsm2_util.py @@ -7,7 +7,17 @@ from binman import bintool class Bintoolsofthsm2_util(bintool.Bintool): - """SoftHSMv2 -- support tool for libsofthsm2""" + """SoftHSMv2 -- support tool for libsofthsm2 + + This bintool wraps the `softhsm2-util` command shipped with SoftHSMv2 (a + software implementation of a PKCS#11 token). Binman uses this wrapper only + to check that softhsm2-util is installed (and to fetch it if missing); any + actual token initialisation or key import for signing FIT images or + capsules is done outside binman, typically via mkimage and the OpenSSL + PKCS#11 engine. + + See https://www.opendnssec.org/softhsm/ for more details. + """ def __init__(self, name): super().__init__('softhsm2-util', 'SoftHSMv2 support tool for libsofthsm2', diff --git a/tools/binman/etype/atf_fip.py b/tools/binman/etype/atf_fip.py index 636e073afc8..681b7900682 100644 --- a/tools/binman/etype/atf_fip.py +++ b/tools/binman/etype/atf_fip.py @@ -163,7 +163,7 @@ class Entry_atf_fip(Entry_section): .. _FIP: https://trustedfirmware-a.readthedocs.io/en/latest/design/firmware-design.html#firmware-image-package-fip .. _`TF-A source tree`: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git - .. _`send a patch`: https://docs.u-boot.org/en/latest/develop/sending_patches.html + .. _`send a patch`: https://docs.u-boot-project.org/en/latest/develop/sending_patches.html """ def __init__(self, section, etype, node): # Put this here to allow entry-docs and help to work without libfdt diff --git a/tools/binman/etype/collection.py b/tools/binman/etype/collection.py index c532aafe3e7..866ea8dcc1e 100644 --- a/tools/binman/etype/collection.py +++ b/tools/binman/etype/collection.py @@ -45,12 +45,17 @@ class Entry_collection(Entry): self.Info('Getting contents, required=%s' % required) data = bytearray() for entry_phandle in self.content: - entry_data = self.section.GetContentsByPhandle(entry_phandle, self, - required) + entry, entry_data = self.section.GetContentsByPhandle( + entry_phandle, self, required) if not required and entry_data is None: self.Info('Contents not available yet') # Data not available yet return None + + # Mark referenced entries as build_done to avoid rebuilding + if required: + entry.mark_build_done() + data += entry_data self.Info('Returning contents size %x' % len(data)) diff --git a/tools/binman/etype/nxp_imx8mimage.py b/tools/binman/etype/nxp_imx8mimage.py index 8ad177b3b65..25c43438a87 100644 --- a/tools/binman/etype/nxp_imx8mimage.py +++ b/tools/binman/etype/nxp_imx8mimage.py @@ -7,6 +7,8 @@ # configuration file and input data. # +import os + from collections import OrderedDict from binman.entry import Entry @@ -23,6 +25,8 @@ class Entry_nxp_imx8mimage(Entry_mkimage): - nxp,boot-from - device to boot from (e.g. 'sd') - nxp,loader-address - loader address (SPL text base) - nxp,rom-version - BootROM version ('2' for i.MX8M Nano and Plus) + - nxp,fspi-header-filename - FSPI header file name (CONFIG_FSPI_CONF_FILE). + Used only if 'nxp,boot-from == "fspi"' . """ def __init__(self, section, etype, node): @@ -33,6 +37,7 @@ class Entry_nxp_imx8mimage(Entry_mkimage): def ReadNode(self): super().ReadNode() self.boot_from = fdt_util.GetString(self._node, 'nxp,boot-from') + self.fspi_header = fdt_util.GetString(self._node, 'nxp,fspi-header-filename', 'fspi_header.bin') self.loader_address = fdt_util.GetInt(self._node, 'nxp,loader-address') self.rom_version = fdt_util.GetInt(self._node, 'nxp,rom-version') self.ReadEntries() @@ -52,7 +57,14 @@ class Entry_nxp_imx8mimage(Entry_mkimage): args = ['-d', input_fname, '-n', cfg_fname, '-T', 'imx8mimage', output_fname] if self.mkimage.run_cmd(*args) is not None: - return tools.read_file(output_fname) + outdata = tools.read_file(output_fname) + if self.boot_from == 'fspi': + spidata = tools.read_file(os.path.join(tools.get_output_dir(), self.fspi_header)) + if len(spidata) != 448: + raise ValueError("FSPI header is not 448 Bytes long") + spidata += tools.get_bytes(0, 0x1000 - len(spidata)) + outdata = spidata + outdata + return outdata else: # Bintool is missing; just use the input data as the output self.record_missing_bintool(self.mkimage) diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py index 00f1a896767..0d953cb258e 100644 --- a/tools/binman/etype/pre_load.py +++ b/tools/binman/etype/pre_load.py @@ -152,14 +152,11 @@ class Entry_pre_load(Entry_collection): return data + pad def ObtainContents(self): - """Obtain a placeholder for the header contents""" - # wait that the image is available - self.image = self.GetContents(False) - if self.image is None: - return False - self.SetContents(self._CreateHeader()) + """Create a placeholder for the header""" + self.SetContents(tools.get_bytes(0, self.header_size)) return True def ProcessContents(self): + self.image = self.GetContents(True) data = self._CreateHeader() return self.ProcessContentsUpdate(data) diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index 6a26d687056..8530b7ee17f 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -557,7 +557,8 @@ class Entry_section(Entry): return None Returns: - data from associated entry (as a string), or None if not found + tuple: (entry, data) where entry is the Entry object and data is + from that entry (as a string), or (entry, None) if data not found """ node = self._node.GetFdt().LookupPhandle(phandle) if not node: @@ -565,7 +566,7 @@ class Entry_section(Entry): entry = self.FindEntryByNode(node) if not entry: source_entry.Raise("Cannot find entry for node '%s'" % node.name) - return entry.GetData(required) + return entry, entry.GetData(required) def LookupEntry(self, entries, sym_name, msg): """Look up the entry for a binman symbol diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index ca5149ee654..bf98b268ac1 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -5895,6 +5895,27 @@ fdt fdtmap Extract the devicetree blob from the fdtmap data = self._DoReadFileDtb('security/pre_load_invalid_key.dts', entry_args=entry_args) + def testPreLoadEncryptedFit(self): + """Test an encrypted FIT image with a pre-load header""" + entry_args = { + 'pre-load-key-path': os.path.join(self._binman_dir, 'test'), + } + data = tools.read_file(self.TestFile("fit/aes256.bin")) + self._MakeInputFile("keys/aes256.bin", data) + + keys_subdir = os.path.join(self._indir, "keys") + data = self._DoReadFileDtb( + 'security/pre_load_fit_encrypted.dts', entry_args=entry_args, + extra_indirs=[keys_subdir])[0] + + image_fname = tools.get_output_filename('image.bin') + is_signed = self._CheckPreload(image_fname, self.TestFile("dev.key")) + + self.assertEqual(PRE_LOAD_MAGIC, data[:len(PRE_LOAD_MAGIC)]) + self.assertEqual(PRE_LOAD_VERSION, data[4:4 + len(PRE_LOAD_VERSION)]) + self.assertEqual(PRE_LOAD_HDR_SIZE, data[8:8 + len(PRE_LOAD_HDR_SIZE)]) + self.assertEqual(is_signed, True) + def _CheckSafeUniqueNames(self, *images): """Check all entries of given images for unsafe unique names""" for image in images: @@ -7560,7 +7581,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap self._CheckBintool(p11_kit) p11_kit_config = configparser.ConfigParser() - out = tools.run('p11-kit', 'print-config') + out = p11_kit.run_cmd('print-config') p11_kit_config.read_string(out) softhsm2_lib = p11_kit_config.get('softhsm2', 'module', fallback=None) @@ -7569,16 +7590,16 @@ fdt fdtmap Extract the devicetree blob from the fdtmap with unittest.mock.patch.dict('os.environ', {'SOFTHSM2_CONF': softhsm2_conf, 'PKCS11_MODULE_PATH': softhsm2_lib}): - tools.run('softhsm2-util', '--init-token', '--free', '--label', - 'U-Boot token', '--pin', '1111', '--so-pin', - '222222') - tools.run('pkcs11-tool', '--module', softhsm2_lib, - '--write-object', cert_file, '--pin', '1111', - '--type', 'cert', '--id', '999999', '--label', - 'test_cert', '--login') - tools.run('softhsm2-util', '--import', private_key, '--token', - 'U-Boot token', '--label', 'test_key', '--id', '999999', - '--pin', '1111') + softhsm2_util.run_cmd('--init-token', '--free', '--label', + 'U-Boot token', '--pin', '1111', + '--so-pin', '222222') + pkcs11_tool.run_cmd('--module', softhsm2_lib, + '--write-object', cert_file, '--pin', '1111', + '--type', 'cert', '--id', '999999', '--label', + 'test_cert', '--login') + softhsm2_util.run_cmd('--import', private_key, '--token', + 'U-Boot token', '--label', 'test_key', + '--id', '999999', '--pin', '1111') data = self._DoReadFile('capsule/signed_pkcs11.dts') self._CheckCapsule(data, signed_capsule=True) @@ -8078,6 +8099,20 @@ fdt fdtmap Extract the devicetree blob from the fdtmap result = cst.fetch(bintool.FETCH_BUILD) self.assertEqual(('cst', None), result) + def testNxpImx8MFSPI(self): + """Test that binman can produce an iMX8m FSPI image""" + testdir = tempfile.mkdtemp(prefix='binman.') + + tools.write_file(os.path.join(testdir, 'fspi_header.bin'), tools.get_bytes(0, 448)) + with terminal.capture(): + self._DoTestFile('vendor/nxp_imx8m_fspi.dts', output_dir=testdir) + self._DoTestFile('vendor/nxp_imx8m_fspi_pass.dts', output_dir=testdir) + + tools.write_file(os.path.join(testdir, 'fspi_header_fail.bin'), tools.get_bytes(0, 4097)) + with terminal.capture(): + with self.assertRaises(ValueError) as e: + self._DoTestFile('vendor/nxp_imx8m_fspi_fail.dts', output_dir=testdir) + def testNxpHeaderDdrfw(self): """Test that binman can add a header to DDR PHY firmware images""" data = self._DoReadFile('vendor/nxp_ddrfw_imx95.dts') @@ -8230,12 +8265,12 @@ fdt fdtmap Extract the devicetree blob from the fdtmap with unittest.mock.patch.dict('os.environ', {'SOFTHSM2_CONF': softhsm2_conf}): - tools.run('softhsm2-util', '--init-token', '--free', '--label', - 'U-Boot token', '--pin', '1111', '--so-pin', - '222222') - tools.run('softhsm2-util', '--import', private_key, '--token', - 'U-Boot token', '--label', 'test_key', '--id', '999999', - '--pin', '1111') + softhsm2_util.run_cmd('--init-token', '--free', '--label', + 'U-Boot token', '--pin', '1111', + '--so-pin', '222222') + softhsm2_util.run_cmd('--import', private_key, '--token', + 'U-Boot token', '--label', 'test_key', + '--id', '999999', '--pin', '1111') # Make sure the private key can only be accessed through the engine os.remove(private_key) @@ -8305,12 +8340,12 @@ fdt fdtmap Extract the devicetree blob from the fdtmap with unittest.mock.patch.dict('os.environ', {'SOFTHSM2_CONF': softhsm2_conf}): - tools.run('softhsm2-util', '--init-token', '--free', '--label', - 'U-Boot prod token', '--pin', '1234', '--so-pin', - '222222') - tools.run('softhsm2-util', '--import', private_key, '--token', - 'U-Boot prod token', '--label', 'prod', '--id', '999999', - '--pin', '1234') + softhsm2_util.run_cmd('--init-token', '--free', '--label', + 'U-Boot prod token', '--pin', '1234', + '--so-pin', '222222') + softhsm2_util.run_cmd('--import', private_key, '--token', + 'U-Boot prod token', '--label', 'prod', + '--id', '999999', '--pin', '1234') # Make sure the private key can only be accessed through the engine os.remove(private_key) diff --git a/tools/binman/missing-blob-help b/tools/binman/missing-blob-help index d2ed35bef4d..27dc620bd35 100644 --- a/tools/binman/missing-blob-help +++ b/tools/binman/missing-blob-help @@ -55,7 +55,7 @@ HS-FS and HS-SE parts will not boot without this certificate. Have a look at your board's documentation to find and include the latest TIFS certificate blobs and how to include them in the build. - https://docs.u-boot.org/en/latest/board/ti/k3.html + https://docs.u-boot-project.org/en/latest/board/ti/k3.html tee-os: See the documentation for your board. You may need to build Open Portable @@ -69,7 +69,7 @@ will not boot without this firmware. Have a look at your board's documentation to find the latest version of the DM firmware binary and how to include it in the build. - https://docs.u-boot.org/en/latest/board/ti/k3.html + https://docs.u-boot-project.org/en/latest/board/ti/k3.html ti-fs-enc.bin: You are missing TI's Foundational Security (TIFS) firmware which is @@ -80,4 +80,4 @@ this firmware. Have a look at your board's documentation to find the latest version of the TIFS firmware binary and how to include them in the build. - https://docs.u-boot.org/en/latest/board/ti/k3.html + https://docs.u-boot-project.org/en/latest/board/ti/k3.html diff --git a/tools/binman/pyproject.toml b/tools/binman/pyproject.toml index 7c9ab0f2a27..2f17588e9df 100644 --- a/tools/binman/pyproject.toml +++ b/tools/binman/pyproject.toml @@ -19,7 +19,7 @@ classifiers = [ ] [project.urls] -"Homepage" = "https://docs.u-boot.org/en/latest/develop/package/index.html" +"Homepage" = "https://docs.u-boot-project.org/en/latest/develop/package/index.html" "Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues" [project.scripts] diff --git a/tools/binman/test/security/pre_load_fit_encrypted.dts b/tools/binman/test/security/pre_load_fit_encrypted.dts new file mode 100644 index 00000000000..f5e9bf9426c --- /dev/null +++ b/tools/binman/test/security/pre_load_fit_encrypted.dts @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + pre-load { + content = <&image>; + algo-name = "sha256,rsa2048"; + key-name = "dev.key"; + header-size = <4096>; + version = <0x11223344>; + }; + + image: fit { + fit,encrypt; + description = "Test a FIT with encrypted data and signed with a preload"; + #address-cells = <1>; + + images { + u-boot { + description = "U-Boot"; + type = "firmware"; + arch = "arm64"; + os = "U-Boot"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + cipher { + algo = "aes256"; + key-name-hint = "aes256"; + }; + u-boot-nodtb { + }; + }; + fdt-1 { + description = "Flattened Device Tree blob"; + type = "flat_dt"; + arch = "arm64"; + compression = "none"; + cipher { + algo = "aes256"; + key-name-hint = "aes256"; + }; + u-boot-dtb { + }; + }; + }; + + configurations { + default = "conf-1"; + conf-1 { + description = "Boot U-Boot with FDT blob"; + firmware = "u-boot"; + fdt = "fdt-1"; + }; + }; + }; + }; +}; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi.dts b/tools/binman/test/vendor/nxp_imx8m_fspi.dts new file mode 100644 index 00000000000..ae6cc5981e6 --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8m_fspi.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mimage { + args; /* TODO: Needed by mkimage etype superclass */ + nxp,boot-from = "fspi"; + nxp,fspi-header-filename = "fspi_header.bin"; + nxp,rom-version = <1>; + nxp,loader-address = <0x10>; + }; + }; +}; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts new file mode 100644 index 00000000000..5a0d758e5a3 --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mimage { + args; /* TODO: Needed by mkimage etype superclass */ + nxp,boot-from = "fspi"; + nxp,fspi-header-filename = "fspi_header_fail.bin"; + nxp,rom-version = <2>; + nxp,loader-address = <0x10>; + }; + }; +}; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts new file mode 100644 index 00000000000..448d93d277a --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mimage { + args; /* TODO: Needed by mkimage etype superclass */ + nxp,boot-from = "fspi"; + /* Default nxp,fspi-header-filename = "fspi_header.bin"; */ + nxp,rom-version = <2>; + nxp,loader-address = <0x10>; + }; + }; +}; |
