diff options
Diffstat (limited to 'tools/binman')
-rw-r--r-- | tools/binman/bintool.py | 17 | ||||
-rw-r--r-- | tools/binman/bintool_test.py | 1 | ||||
-rw-r--r-- | tools/binman/bintools.rst | 8 | ||||
-rw-r--r-- | tools/binman/btool/cst.py | 37 | ||||
-rw-r--r-- | tools/binman/control.py | 6 | ||||
-rw-r--r-- | tools/binman/etype/fdtmap.py | 5 | ||||
-rw-r--r-- | tools/binman/etype/image_header.py | 1 | ||||
-rw-r--r-- | tools/binman/etype/pre_load.py | 2 | ||||
-rw-r--r-- | tools/binman/etype/ti_board_config.py | 2 | ||||
-rw-r--r-- | tools/binman/etype/x509_cert.py | 1 | ||||
-rw-r--r-- | tools/binman/ftest.py | 42 | ||||
-rw-r--r-- | tools/binman/requirements.txt | 5 | ||||
-rw-r--r-- | tools/binman/setup.py | 2 | ||||
-rw-r--r-- | tools/binman/state.py | 3 | ||||
-rw-r--r-- | tools/binman/test/346_remove_template.dts | 49 |
15 files changed, 149 insertions, 32 deletions
diff --git a/tools/binman/bintool.py b/tools/binman/bintool.py index 3c4ad1adbb9..81872db377f 100644 --- a/tools/binman/bintool.py +++ b/tools/binman/bintool.py @@ -328,7 +328,8 @@ class Bintool: return result.stdout @classmethod - def build_from_git(cls, git_repo, make_targets, bintool_path, flags=None): + def build_from_git(cls, git_repo, make_targets, bintool_path, + flags=None, git_branch=None, make_path=None): """Build a bintool from a git repo This clones the repo in a temporary directory, builds it with 'make', @@ -341,6 +342,9 @@ class Bintool: bintool_path (str): Relative path of the tool in the repo, after build is complete flags (list of str): Flags or variables to pass to make, or None + git_branch (str): Branch of git repo, or None to use the default + make_path (str): Relative path inside git repo containing the + Makefile, or None Returns: tuple: @@ -350,10 +354,17 @@ class Bintool: """ tmpdir = tempfile.mkdtemp(prefix='binmanf.') print(f"- clone git repo '{git_repo}' to '{tmpdir}'") - tools.run('git', 'clone', '--depth', '1', git_repo, tmpdir) + if git_branch: + tools.run('git', 'clone', '--depth', '1', '--branch', git_branch, + git_repo, tmpdir) + else: + tools.run('git', 'clone', '--depth', '1', git_repo, tmpdir) for target in make_targets: print(f"- build target '{target}'") - cmd = ['make', '-C', tmpdir, '-j', f'{multiprocessing.cpu_count()}', + makedir = tmpdir + if make_path: + makedir = os.path.join(tmpdir, make_path) + cmd = ['make', '-C', makedir, '-j', f'{multiprocessing.cpu_count()}', target] if flags: cmd += flags diff --git a/tools/binman/bintool_test.py b/tools/binman/bintool_test.py index f9b16d4c73b..949d6f4c8a9 100644 --- a/tools/binman/bintool_test.py +++ b/tools/binman/bintool_test.py @@ -303,6 +303,7 @@ class TestBintool(unittest.TestCase): # See Bintool.build_from_git() tmpdir = cmd[2] self.fname = os.path.join(tmpdir, 'pathname') + os.makedirs(os.path.dirname(tmpdir), exist_ok=True) tools.write_file(self.fname, b'hello') expected = b'this is a test' diff --git a/tools/binman/bintools.rst b/tools/binman/bintools.rst index cd05ad8cb26..9f6cab544a5 100644 --- a/tools/binman/bintools.rst +++ b/tools/binman/bintools.rst @@ -52,6 +52,14 @@ Bintool: cst: Image generation for U-Boot This bintool supports running `cst` with some basic parameters as needed by binman. +cst (imx code signing tool) is used for sigining bootloader binaries for +various i.MX SoCs. + +See `Code Signing Tool Users Guide`_ for more information. + +.. _`Code Signing Tool Users Guide`: + https://community.nxp.com/pwmxy87654/attachments/pwmxy87654/imx-processors/202591/1/CST_UG.pdf + Bintool: fdt_add_pubkey: Add public key to control dtb (spl or u-boot proper) diff --git a/tools/binman/btool/cst.py b/tools/binman/btool/cst.py index 30e78bdbbd9..8a3981adc89 100644 --- a/tools/binman/btool/cst.py +++ b/tools/binman/btool/cst.py @@ -12,6 +12,14 @@ class Bintoolcst(bintool.Bintool): This bintool supports running `cst` with some basic parameters as needed by binman. + + cst (imx code signing tool) is used for sigining bootloader binaries for + various i.MX SoCs. + + See `Code Signing Tool Users Guide`_ for more information. + + .. _`Code Signing Tool Users Guide`: + https://community.nxp.com/pwmxy87654/attachments/pwmxy87654/imx-processors/202591/1/CST_UG.pdf """ def __init__(self, name): super().__init__(name, 'Sign NXP i.MX image') @@ -29,20 +37,17 @@ class Bintoolcst(bintool.Bintool): return self.run_cmd(*args) def fetch(self, method): - """Fetch handler for cst - - This installs cst using the apt utility. - - Args: - method (FETCH_...): Method to use - - Returns: - True if the file was fetched and now installed, None if a method - other than FETCH_BIN was requested - - Raises: - Valuerror: Fetching could not be completed - """ - if method != bintool.FETCH_BIN: + """Build cst from git""" + if method != bintool.FETCH_BUILD: return None - return self.apt_install('imx-code-signing-tool') + + from platform import architecture + arch = 'linux64' if architecture()[0] == '64bit' else 'linux32' + result = self.build_from_git( + 'https://gitlab.apertis.org/pkg/imx-code-signing-tool', + ['all'], + f'code/obj.{arch}/cst', + flags=[f'OSTYPE={arch}', 'ENCRYPTION=yes'], + git_branch='debian/unstable', + make_path=f'code/obj.{arch}/') + return result diff --git a/tools/binman/control.py b/tools/binman/control.py index e73c598298c..81f61e3e152 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -522,9 +522,13 @@ def _ProcessTemplates(parent): def _RemoveTemplates(parent): """Remove any templates in the binman description """ + del_nodes = [] for node in parent.subnodes: if node.name.startswith('template'): - node.Delete() + del_nodes.append(node) + + for node in del_nodes: + node.Delete() def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded, indir): """Prepare the images to be processed and select the device tree diff --git a/tools/binman/etype/fdtmap.py b/tools/binman/etype/fdtmap.py index f1f6217940f..2259404180c 100644 --- a/tools/binman/etype/fdtmap.py +++ b/tools/binman/etype/fdtmap.py @@ -106,6 +106,9 @@ class Entry_fdtmap(Entry): Returns: FDT map binary data """ + fsw = libfdt.FdtSw() + fsw.finish_reservemap() + def _AddNode(node): """Add a node to the FDT map""" for pname, prop in node.props.items(): @@ -134,8 +137,6 @@ class Entry_fdtmap(Entry): # Build a new tree with all nodes and properties starting from that # node - fsw = libfdt.FdtSw() - fsw.finish_reservemap() with fsw.add_node(''): fsw.property_string('image-node', node.name) _AddNode(node) diff --git a/tools/binman/etype/image_header.py b/tools/binman/etype/image_header.py index 24011884958..2114df8159f 100644 --- a/tools/binman/etype/image_header.py +++ b/tools/binman/etype/image_header.py @@ -62,6 +62,7 @@ class Entry_image_header(Entry): def _GetHeader(self): image_pos = self.GetSiblingImagePos('fdtmap') + offset = None if image_pos == False: self.Raise("'image_header' section must have an 'fdtmap' sibling") elif image_pos is None: diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py index 2e4c72359ff..00f1a896767 100644 --- a/tools/binman/etype/pre_load.py +++ b/tools/binman/etype/pre_load.py @@ -112,6 +112,8 @@ class Entry_pre_load(Entry_collection): # Compute the signature if padding_name is None: padding_name = "pkcs-1.5" + padding = None + padding_args = None if padding_name == "pss": salt_len = key.size_in_bytes() - hash_image.digest_size - 2 padding = pss diff --git a/tools/binman/etype/ti_board_config.py b/tools/binman/etype/ti_board_config.py index c10d66edcb1..7c6773ac7bc 100644 --- a/tools/binman/etype/ti_board_config.py +++ b/tools/binman/etype/ti_board_config.py @@ -119,12 +119,14 @@ class Entry_ti_board_config(Entry_section): array of bytes representing value """ size = 0 + br = bytearray() if (data_type == '#/definitions/u8'): size = 1 elif (data_type == '#/definitions/u16'): size = 2 else: size = 4 + br = None if type(val) == int: br = val.to_bytes(size, byteorder='little') return br diff --git a/tools/binman/etype/x509_cert.py b/tools/binman/etype/x509_cert.py index 29630d1b86c..25e6808b7f9 100644 --- a/tools/binman/etype/x509_cert.py +++ b/tools/binman/etype/x509_cert.py @@ -84,6 +84,7 @@ class Entry_x509_cert(Entry_collection): input_fname = tools.get_output_filename('input.%s' % uniq) config_fname = tools.get_output_filename('config.%s' % uniq) tools.write_file(input_fname, input_data) + stdout = None if type == 'generic': stdout = self.openssl.x509_cert( cert_fname=output_fname, diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 733169b99f6..948fcc02259 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -303,7 +303,7 @@ class TestFunctional(unittest.TestCase): def setUp(self): # Enable this to turn on debugging output # tout.init(tout.DEBUG) - command.test_result = None + command.TEST_RESULT = None def tearDown(self): """Remove the temporary output directory""" @@ -345,8 +345,9 @@ class TestFunctional(unittest.TestCase): Arguments to pass, as a list of strings kwargs: Arguments to pass to Command.RunPipe() """ - result = command.run_pipe([[self._binman_pathname] + list(args)], - capture=True, capture_stderr=True, raise_on_error=False) + all_args = [self._binman_pathname] + list(args) + result = command.run_one(*all_args, capture=True, capture_stderr=True, + raise_on_error=False) if result.return_code and kwargs.get('raise_on_error', True): raise Exception("Error running '%s': %s" % (' '.join(args), result.stdout + result.stderr)) @@ -762,6 +763,16 @@ class TestFunctional(unittest.TestCase): return False return True + def _CheckPreload(self, image, key, algo="sha256,rsa2048", + padding="pkcs-1.5"): + try: + tools.run('preload_check_sign', '-k', key, '-a', algo, '-p', + padding, '-f', image) + except: + self.fail('Expected image signed with a pre-load') + return False + return True + def testRun(self): """Test a basic run with valid args""" result = self._RunBinman('-h') @@ -780,11 +791,11 @@ class TestFunctional(unittest.TestCase): def testFullHelpInternal(self): """Test that the full help is displayed with -H""" try: - command.test_result = command.CommandResult() + command.TEST_RESULT = command.CommandResult() result = self._DoBinman('-H') help_file = os.path.join(self._binman_dir, 'README.rst') finally: - command.test_result = None + command.TEST_RESULT = None def testHelp(self): """Test that the basic help is displayed with -h""" @@ -1872,7 +1883,7 @@ class TestFunctional(unittest.TestCase): def testGbb(self): """Test for the Chromium OS Google Binary Block""" - command.test_result = self._HandleGbbCommand + command.TEST_RESULT = self._HandleGbbCommand entry_args = { 'keydir': 'devkeys', 'bmpblk': 'bmpblk.bin', @@ -1941,7 +1952,7 @@ class TestFunctional(unittest.TestCase): def testVblock(self): """Test for the Chromium OS Verified Boot Block""" self._hash_data = False - command.test_result = self._HandleVblockCommand + command.TEST_RESULT = self._HandleVblockCommand entry_args = { 'keydir': 'devkeys', } @@ -1974,7 +1985,7 @@ class TestFunctional(unittest.TestCase): def testVblockContent(self): """Test that the vblock signs the right data""" self._hash_data = True - command.test_result = self._HandleVblockCommand + command.TEST_RESULT = self._HandleVblockCommand entry_args = { 'keydir': 'devkeys', } @@ -5498,7 +5509,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap def testFitSubentryUsesBintool(self): """Test that binman FIT subentries can use bintools""" - command.test_result = self._HandleGbbCommand + command.TEST_RESULT = self._HandleGbbCommand entry_args = { 'keydir': 'devkeys', 'bmpblk': 'bmpblk.bin', @@ -5783,9 +5794,14 @@ fdt fdtmap Extract the devicetree blob from the fdtmap data = self._DoReadFileDtb( '230_pre_load.dts', entry_args=entry_args, extra_indirs=[os.path.join(self._binman_dir, 'test')])[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 testPreLoadNoKey(self): """Test an image with a pre-load heade0r with missing key""" @@ -6383,6 +6399,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap ename, prop = entry_m.group(1), entry_m.group(3) entry, entry_name, prop_name = image.LookupEntry(entries, name, msg) + expect_val = None if prop_name == 'offset': expect_val = entry.offset elif prop_name == 'image_pos': @@ -7973,5 +7990,12 @@ fdt fdtmap Extract the devicetree blob from the fdtmap """Test an image with an FIT with multiple FDT images using NAME""" self.CheckFitFdt('345_fit_fdt_name.dts', use_seq_num=False) + def testRemoveTemplate(self): + """Test whether template is removed""" + TestFunctional._MakeInputFile('my-blob.bin', b'blob') + TestFunctional._MakeInputFile('my-blob2.bin', b'other') + self._DoTestFile('346_remove_template.dts', + force_missing_bintools='openssl',) + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/requirements.txt b/tools/binman/requirements.txt new file mode 100644 index 00000000000..f068ef75a30 --- /dev/null +++ b/tools/binman/requirements.txt @@ -0,0 +1,5 @@ +importlib_resources==6.5.2 +jsonschema==4.23.0 +pycryptodomex==3.21.0 +pyelftools==0.31 +yamllint==1.35.1 diff --git a/tools/binman/setup.py b/tools/binman/setup.py index 9a9206eb044..bec078a3d9b 100644 --- a/tools/binman/setup.py +++ b/tools/binman/setup.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+ -from distutils.core import setup +from setuptools import setup setup(name='binman', version='1.0', license='GPL-2.0+', diff --git a/tools/binman/state.py b/tools/binman/state.py index 45bae40c525..6772d3678fe 100644 --- a/tools/binman/state.py +++ b/tools/binman/state.py @@ -406,10 +406,13 @@ def CheckSetHashValue(node, get_data_func): hash_node = node.FindNode('hash') if hash_node: algo = hash_node.props.get('algo').value + data = None if algo == 'sha256': m = hashlib.sha256() m.update(get_data_func()) data = m.digest() + if data is None: + raise ValueError(f"Node '{node.path}': Unknown hash algorithm '{algo}'") for n in GetUpdateNodes(hash_node): n.SetData('value', data) diff --git a/tools/binman/test/346_remove_template.dts b/tools/binman/test/346_remove_template.dts new file mode 100644 index 00000000000..e05229f3ebc --- /dev/null +++ b/tools/binman/test/346_remove_template.dts @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; +/ { + binman: binman { + multiple-images; + + template_1: template-1 { + section { + phandle1: my-blob.bin { + filename = "my-blob.bin"; + type = "blob-ext"; + }; + }; + }; + template_2: template-2 { + section { + ti-secure { + content = <&phandle2>; + keyfile = "key.pem"; + }; + phandle2: my-blob.bin { + filename = "my-blob.bin"; + type = "blob-ext"; + }; + }; + }; + template_3: template-3 { + section { + phandle3: my-blob.bin { + filename = "my-blob.bin"; + type = "blob-ext"; + }; + }; + }; + + file1 { + insert-template = <&template_1>; + }; + + file2 { + insert-template = <&template_2>; + }; + + file3 { + insert-template = <&template_3>; + }; + }; +}; |