aboutsummaryrefslogtreecommitdiff
path: root/tools/binman
diff options
context:
space:
mode:
Diffstat (limited to 'tools/binman')
-rw-r--r--tools/binman/bintools.rst33
-rw-r--r--tools/binman/btool/fdt_add_pubkey.py67
-rw-r--r--tools/binman/control.py2
-rw-r--r--tools/binman/entries.rst125
-rw-r--r--tools/binman/etype/blob_dtb.py2
-rw-r--r--tools/binman/etype/encrypted.py138
-rw-r--r--tools/binman/etype/pre_load.py6
-rw-r--r--tools/binman/etype/section.py2
-rw-r--r--tools/binman/etype/u_boot_spl_pubkey_dtb.py112
-rw-r--r--tools/binman/ftest.py164
-rw-r--r--tools/binman/test/230_pre_load.dts2
-rw-r--r--tools/binman/test/231_pre_load_pkcs.dts2
-rw-r--r--tools/binman/test/232_pre_load_pss.dts2
-rw-r--r--tools/binman/test/233_pre_load_invalid_padding.dts2
-rw-r--r--tools/binman/test/234_pre_load_invalid_sha.dts2
-rw-r--r--tools/binman/test/235_pre_load_invalid_algo.dts2
-rw-r--r--tools/binman/test/236_pre_load_invalid_key.dts2
-rw-r--r--tools/binman/test/291_rockchip_tpl.dts (renamed from tools/binman/test/277_rockchip_tpl.dts)0
-rw-r--r--tools/binman/test/292_mkimage_missing_multiple.dts (renamed from tools/binman/test/278_mkimage_missing_multiple.dts)0
-rw-r--r--tools/binman/test/293_ti_board_cfg.dts (renamed from tools/binman/test/277_ti_board_cfg.dts)0
-rw-r--r--tools/binman/test/294_ti_board_cfg_combined.dts (renamed from tools/binman/test/278_ti_board_cfg_combined.dts)0
-rw-r--r--tools/binman/test/295_ti_board_cfg_no_type.dts (renamed from tools/binman/test/279_ti_board_cfg_no_type.dts)0
-rw-r--r--tools/binman/test/296_ti_secure.dts (renamed from tools/binman/test/279_ti_secure.dts)0
-rw-r--r--tools/binman/test/297_ti_secure_rom.dts (renamed from tools/binman/test/280_ti_secure_rom.dts)0
-rw-r--r--tools/binman/test/298_ti_secure_rom_combined.dts (renamed from tools/binman/test/281_ti_secure_rom_combined.dts)0
-rw-r--r--tools/binman/test/299_ti_secure_rom_a.dts (renamed from tools/binman/test/288_ti_secure_rom_a.dts)0
-rw-r--r--tools/binman/test/300_ti_secure_rom_b.dts (renamed from tools/binman/test/289_ti_secure_rom_b.dts)0
-rw-r--r--tools/binman/test/301_encrypted_no_algo.dts15
-rw-r--r--tools/binman/test/302_encrypted_invalid_iv_file.dts18
-rw-r--r--tools/binman/test/303_encrypted_missing_key.dts23
-rw-r--r--tools/binman/test/304_encrypted_key_source.dts24
-rw-r--r--tools/binman/test/305_encrypted_key_file.dts24
-rw-r--r--tools/binman/test/306_spl_pubkey_dtb.dts16
-rw-r--r--tools/binman/test/dev.key (renamed from tools/binman/test/230_dev.key)0
34 files changed, 748 insertions, 37 deletions
diff --git a/tools/binman/bintools.rst b/tools/binman/bintools.rst
index c30e7eb..20ee243 100644
--- a/tools/binman/bintools.rst
+++ b/tools/binman/bintools.rst
@@ -155,6 +155,17 @@ Support is provided for fetching this on Debian-like systems, using apt.
+Bintool: openssl: openssl tool
+------------------------------
+
+This bintool supports creating new openssl certificates.
+
+It also supports fetching a binary openssl
+
+Documentation about openssl is at https://www.openssl.org/
+
+
+
Bintool: xz: Compression/decompression using the xz algorithm
-------------------------------------------------------------
@@ -183,3 +194,25 @@ Documentation is available via::
+Bintool: fdt_add_pubkey: Add public key to device tree
+------------------------------------------------------
+
+This bintool supports running `fdt_add_pubkey` in order to add a public
+key coming from a certificate to a device-tree.
+
+Normally signing is done using `mkimage` in context of `binman sign`. However,
+in this process the public key is not added to the stage before u-boot proper.
+Using `fdt_add_pubkey` the key can be injected to the SPL independent of
+`mkimage`
+
+
+
+Bintool: bootgen: Sign ZynqMP FSBL image
+---------------------------------------------
+
+This bintool supports running `bootgen` in order to sign a SPL for ZynqMP
+devices.
+
+The bintool automatically creates an appropriate input image file (.bif) for
+bootgen based on the passed arguments. The output is a bootable,
+authenticated `boot.bin` file.
diff --git a/tools/binman/btool/fdt_add_pubkey.py b/tools/binman/btool/fdt_add_pubkey.py
new file mode 100644
index 0000000..a507742
--- /dev/null
+++ b/tools/binman/btool/fdt_add_pubkey.py
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (C) 2023 Weidmüller Interface GmbH & Co. KG
+# Lukas Funke <lukas.funke@weidmueller.com>
+#
+"""Bintool implementation for fdt_add_pubkey"""
+
+from binman import bintool
+
+class Bintoolfdt_add_pubkey(bintool.Bintool):
+ """Add public key to control dtb (spl or u-boot proper)
+
+ This bintool supports running `fdt_add_pubkey`.
+
+ Normally mkimage adds signature information to the control dtb. However
+ binman images are built independent from each other. Thus it is required
+ to add the public key separately from mkimage.
+ """
+ def __init__(self, name):
+ super().__init__(name, 'Generate image for U-Boot')
+
+ # pylint: disable=R0913
+ def run(self, input_fname, keydir, keyname, required, algo):
+ """Run fdt_add_pubkey
+
+ Args:
+ input_fname (str): dtb file to sign
+ keydir (str): Directory with public key. Optional parameter,
+ default value: '.' (current directory)
+ keyname (str): Public key name. Optional parameter,
+ default value: key
+ required (str): If present this indicates that the key must be
+ verified for the image / configuration to be considered valid.
+ algo (str): Cryptographic algorithm. Optional parameter,
+ default value: sha1,rsa2048
+ """
+ args = []
+ if algo:
+ args += ['-a', algo]
+ if keydir:
+ args += ['-k', keydir]
+ if keyname:
+ args += ['-n', keyname]
+ if required:
+ args += ['-r', required]
+
+ args += [ input_fname ]
+
+ return self.run_cmd(*args)
+
+ def fetch(self, method):
+ """Fetch handler for fdt_add_pubkey
+
+ This installs fdt_add_pubkey 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:
+ return None
+ return self.apt_install('u-boot-tools')
diff --git a/tools/binman/control.py b/tools/binman/control.py
index 25e6681..d1ee1d6 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -308,8 +308,8 @@ def BeforeReplace(image, allow_resize):
image: Image to prepare
"""
state.PrepareFromLoadedData(image)
- image.LoadData()
image.CollectBintools()
+ image.LoadData(decomp=False)
# If repacking, drop the old offset/size values except for the original
# ones, so we are only left with the constraints.
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index 1621ff3..f237693 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -468,6 +468,92 @@ updating the EC on startup via software sync.
+.. _etype_encrypted:
+
+Entry: encrypted: Externally built encrypted binary blob
+--------------------------------------------------------
+
+This entry provides the functionality to include information about how to
+decrypt an encrypted binary. This information is added to the
+resulting device tree by adding a new cipher node in the entry's parent
+node (i.e. the binary).
+
+The key that must be used to decrypt the binary is either directly embedded
+in the device tree or indirectly by specifying a key source. The key source
+can be used as an id of a key that is stored in an external device.
+
+Using an embedded key
+~~~~~~~~~~~~~~~~~~~~~
+
+This is an example using an embedded key::
+
+ blob-ext {
+ filename = "encrypted-blob.bin";
+ };
+
+ encrypted {
+ algo = "aes256-gcm";
+ iv-filename = "encrypted-blob.bin.iv";
+ key-filename = "encrypted-blob.bin.key";
+ };
+
+This entry generates the following device tree structure form the example
+above::
+
+ data = [...]
+ cipher {
+ algo = "aes256-gcm";
+ key = <0x...>;
+ iv = <0x...>;
+ };
+
+The data property is generated by the blob-ext etype, the cipher node and
+its content is generated by this etype.
+
+Using an external key
+~~~~~~~~~~~~~~~~~~~~~
+
+Instead of embedding the key itself into the device tree, it is also
+possible to address an externally stored key by specifying a 'key-source'
+instead of the 'key'::
+
+ blob-ext {
+ filename = "encrypted-blob.bin";
+ };
+
+ encrypted {
+ algo = "aes256-gcm";
+ iv-filename = "encrypted-blob.bin.iv";
+ key-source = "external-key-id";
+ };
+
+This entry generates the following device tree structure form the example
+above::
+
+ data = [...]
+ cipher {
+ algo = "aes256-gcm";
+ key-source = "external-key-id";
+ iv = <0x...>;
+ };
+
+Properties
+~~~~~~~~~~
+
+Properties / Entry arguments:
+ - algo: The encryption algorithm. Currently no algorithm is supported
+ out-of-the-box. Certain algorithms will be added in future
+ patches.
+ - iv-filename: The name of the file containing the initialization
+ vector (in short iv). See
+ https://en.wikipedia.org/wiki/Initialization_vector
+ - key-filename: The name of the file containing the key. Either
+ key-filename or key-source must be provided.
+ - key-source: The key that should be used. Either key-filename or
+ key-source must be provided.
+
+
+
.. _etype_fdtmap:
Entry: fdtmap: An entry which contains an FDT map
@@ -2031,6 +2117,45 @@ binman uses that to look up symbols to write into the SPL binary.
+.. _etype_u_boot_spl_pubkey_dtb:
+
+Entry: u-boot-spl-pubkey-dtb: U-Boot SPL device tree including public key
+-------------------------------------------------------------------------
+
+Properties / Entry arguments:
+ - key-name-hint: Public key name without extension (.crt).
+ Default is determined by underlying
+ bintool (fdt_add_pubkey), usually 'key'.
+ - algo: (Optional) Algorithm used for signing. Default is determined by
+ underlying bintool (fdt_add_pubkey), usually 'sha1,rsa2048'
+ - required: (Optional) If present this indicates that the key must be
+ verified for the image / configuration to be
+ considered valid
+
+The following example shows an image containing an SPL which
+is packed together with the dtb. Binman will add a signature
+node to the dtb.
+
+Example node::
+
+ image {
+ ...
+ spl {
+ filename = "spl.bin"
+
+ u-boot-spl-nodtb {
+ };
+ u-boot-spl-pubkey-dtb {
+ algo = "sha384,rsa4096";
+ required = "conf";
+ key-name-hint = "dev";
+ };
+ };
+ ...
+ }
+
+
+
.. _etype_u_boot_spl_with_ucode_ptr:
Entry: u-boot-spl-with-ucode-ptr: U-Boot SPL with embedded microcode pointer
diff --git a/tools/binman/etype/blob_dtb.py b/tools/binman/etype/blob_dtb.py
index 6a3fbc4..d543de9 100644
--- a/tools/binman/etype/blob_dtb.py
+++ b/tools/binman/etype/blob_dtb.py
@@ -38,7 +38,7 @@ class Entry_blob_dtb(Entry_blob):
self.Raise("Invalid prepend in '%s': '%s'" %
(self._node.name, self.prepend))
- def ObtainContents(self):
+ def ObtainContents(self, fake_size=0):
"""Get the device-tree from the list held by the 'state' module"""
self._filename = self.GetDefaultFilename()
self._pathname, _ = state.GetFdtContents(self.GetFdtEtype())
diff --git a/tools/binman/etype/encrypted.py b/tools/binman/etype/encrypted.py
new file mode 100644
index 0000000..53d0e76
--- /dev/null
+++ b/tools/binman/etype/encrypted.py
@@ -0,0 +1,138 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2023 Weidmüller Interface GmbH & Co. KG
+# Written by Christian Taedcke <christian.taedcke@weidmueller.com>
+#
+# Entry-type module for cipher information of encrypted blobs/binaries
+#
+
+from binman.etype.collection import Entry
+from dtoc import fdt_util
+from u_boot_pylib import tools
+
+# This is imported if needed
+state = None
+
+
+class Entry_encrypted(Entry):
+ """Externally built encrypted binary blob
+
+ This entry provides the functionality to include information about how to
+ decrypt an encrypted binary. This information is added to the
+ resulting device tree by adding a new cipher node in the entry's parent
+ node (i.e. the binary).
+
+ The key that must be used to decrypt the binary is either directly embedded
+ in the device tree or indirectly by specifying a key source. The key source
+ can be used as an id of a key that is stored in an external device.
+
+ Using an embedded key
+ ~~~~~~~~~~~~~~~~~~~~~
+
+ This is an example using an embedded key::
+
+ blob-ext {
+ filename = "encrypted-blob.bin";
+ };
+
+ encrypted {
+ algo = "aes256-gcm";
+ iv-filename = "encrypted-blob.bin.iv";
+ key-filename = "encrypted-blob.bin.key";
+ };
+
+ This entry generates the following device tree structure form the example
+ above::
+
+ data = [...]
+ cipher {
+ algo = "aes256-gcm";
+ key = <0x...>;
+ iv = <0x...>;
+ };
+
+ The data property is generated by the blob-ext etype, the cipher node and
+ its content is generated by this etype.
+
+ Using an external key
+ ~~~~~~~~~~~~~~~~~~~~~
+
+ Instead of embedding the key itself into the device tree, it is also
+ possible to address an externally stored key by specifying a 'key-source'
+ instead of the 'key'::
+
+ blob-ext {
+ filename = "encrypted-blob.bin";
+ };
+
+ encrypted {
+ algo = "aes256-gcm";
+ iv-filename = "encrypted-blob.bin.iv";
+ key-source = "external-key-id";
+ };
+
+ This entry generates the following device tree structure form the example
+ above::
+
+ data = [...]
+ cipher {
+ algo = "aes256-gcm";
+ key-source = "external-key-id";
+ iv = <0x...>;
+ };
+
+ Properties
+ ~~~~~~~~~~
+
+ Properties / Entry arguments:
+ - algo: The encryption algorithm. Currently no algorithm is supported
+ out-of-the-box. Certain algorithms will be added in future
+ patches.
+ - iv-filename: The name of the file containing the initialization
+ vector (in short iv). See
+ https://en.wikipedia.org/wiki/Initialization_vector
+ - key-filename: The name of the file containing the key. Either
+ key-filename or key-source must be provided.
+ - key-source: The key that should be used. Either key-filename or
+ key-source must be provided.
+ """
+
+ def __init__(self, section, etype, node):
+ # Put this here to allow entry-docs and help to work without libfdt
+ global state
+ from binman import state
+
+ super().__init__(section, etype, node)
+ self.required_props = ['algo', 'iv-filename']
+ self._algo = None
+ self._iv_filename = None
+ self._key_name_hint = None
+ self._key_filename = None
+
+ def ReadNode(self):
+ super().ReadNode()
+
+ self._algo = fdt_util.GetString(self._node, 'algo')
+ self._iv_filename = fdt_util.GetString(self._node, 'iv-filename')
+ self._key_filename = fdt_util.GetString(self._node, 'key-filename')
+ self._key_source = fdt_util.GetString(self._node, 'key-source')
+
+ if self._key_filename is None and self._key_source is None:
+ self.Raise("Provide either 'key-filename' or 'key-source'")
+
+ def gen_entries(self):
+ super().gen_entries()
+
+ iv_filename = tools.get_input_filename(self._iv_filename)
+ iv = tools.read_file(iv_filename, binary=True)
+
+ cipher_node = state.AddSubnode(self._node.parent, "cipher")
+ cipher_node.AddString("algo", self._algo)
+ cipher_node.AddData("iv", iv)
+
+ if self._key_filename:
+ key_filename = tools.get_input_filename(self._key_filename)
+ key = tools.read_file(key_filename, binary=True)
+ cipher_node.AddData("key", key)
+
+ if self._key_source:
+ cipher_node.AddString("key-source", self._key_source)
diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py
index bd3545b..2e4c723 100644
--- a/tools/binman/etype/pre_load.py
+++ b/tools/binman/etype/pre_load.py
@@ -81,7 +81,8 @@ class Entry_pre_load(Entry_collection):
def ReadNode(self):
super().ReadNode()
- self.key_path, = self.GetEntryArgsOrProps([EntryArg('pre-load-key-path', str)])
+ self.key_path, = self.GetEntryArgsOrProps(
+ [EntryArg('pre-load-key-path', str)])
if self.key_path is None:
self.key_path = ''
@@ -98,8 +99,7 @@ class Entry_pre_load(Entry_collection):
self.Raise(sign_name + " is not supported")
# Read the key
- with open(key_name, 'rb') as pem:
- key = RSA.import_key(pem.read())
+ key = RSA.import_key(tools.read_file(key_name))
# Check if the key has the expected size
if key.size_in_bytes() != RSAS[sign_name]:
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index 7c4d312..fb49e85 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -179,7 +179,7 @@ class Entry_section(Entry):
Returns:
bool: True if the node is a special one, else False
"""
- start_list = ('hash', 'signature', 'template')
+ start_list = ('cipher', 'hash', 'signature', 'template')
return any(node.name.startswith(name) for name in start_list)
def ReadNode(self):
diff --git a/tools/binman/etype/u_boot_spl_pubkey_dtb.py b/tools/binman/etype/u_boot_spl_pubkey_dtb.py
new file mode 100644
index 0000000..cb19606
--- /dev/null
+++ b/tools/binman/etype/u_boot_spl_pubkey_dtb.py
@@ -0,0 +1,112 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2023 Weidmueller GmbH
+# Written by Lukas Funke <lukas.funke@weidmueller.com>
+#
+# Entry-type module for 'u-boot-spl-pubkey.dtb'
+#
+
+import tempfile
+import os
+
+from binman.etype.blob_dtb import Entry_blob_dtb
+
+from dtoc import fdt_util
+
+from u_boot_pylib import tools
+
+# This is imported if needed
+state = None
+
+# pylint: disable=C0103
+class Entry_u_boot_spl_pubkey_dtb(Entry_blob_dtb):
+ """U-Boot SPL device tree including public key
+
+ Properties / Entry arguments:
+ - key-name-hint: Public key name without extension (.crt).
+ Default is determined by underlying
+ bintool (fdt_add_pubkey), usually 'key'.
+ - algo: (Optional) Algorithm used for signing. Default is determined by
+ underlying bintool (fdt_add_pubkey), usually 'sha1,rsa2048'
+ - required: (Optional) If present this indicates that the key must be
+ verified for the image / configuration to be
+ considered valid
+
+ The following example shows an image containing an SPL which
+ is packed together with the dtb. Binman will add a signature
+ node to the dtb.
+
+ Example node::
+
+ image {
+ ...
+ spl {
+ filename = "spl.bin"
+
+ u-boot-spl-nodtb {
+ };
+ u-boot-spl-pubkey-dtb {
+ algo = "sha384,rsa4096";
+ required = "conf";
+ key-name-hint = "dev";
+ };
+ };
+ ...
+ }
+ """
+
+ def __init__(self, section, etype, node):
+ # Put this here to allow entry-docs and help to work without libfdt
+ global state
+ from binman import state
+
+ super().__init__(section, etype, node)
+ self.required_props = ['key-name-hint']
+ self.fdt_add_pubkey = None
+ self._algo = fdt_util.GetString(self._node, 'algo')
+ self._required = fdt_util.GetString(self._node, 'required')
+ self._key_name_hint = fdt_util.GetString(self._node, 'key-name-hint')
+
+ def ObtainContents(self, fake_size=0):
+ """Add public key to SPL dtb
+
+ Add public key which is pointed out by
+ 'key-name-hint' to node 'signature' in the spl-dtb
+
+ This is equivalent to the '-K' option of 'mkimage'
+
+ Args:
+ fake_size (int): unused
+ """
+
+ # We don't pass fake_size upwards because this is currently
+ # not supported by the blob type
+ super().ObtainContents()
+
+ with tempfile.NamedTemporaryFile(prefix=os.path.basename(
+ self.GetFdtEtype()),
+ dir=tools.get_output_dir())\
+ as pubkey_tdb:
+ tools.write_file(pubkey_tdb.name, self.GetData())
+ keyname = tools.get_input_filename(self._key_name_hint + ".crt")
+ self.fdt_add_pubkey.run(pubkey_tdb.name,
+ os.path.dirname(keyname),
+ self._key_name_hint,
+ self._required, self._algo)
+ dtb = tools.read_file(pubkey_tdb.name)
+ self.SetContents(dtb)
+ state.UpdateFdtContents(self.GetFdtEtype(), dtb)
+
+ return True
+
+ # pylint: disable=R0201,C0116
+ def GetDefaultFilename(self):
+ return 'spl/u-boot-spl-pubkey.dtb'
+
+ # pylint: disable=R0201,C0116
+ def GetFdtEtype(self):
+ return 'u-boot-spl-dtb'
+
+ # pylint: disable=R0201,C0116
+ def AddBintools(self, btools):
+ super().AddBintools(btools)
+ self.fdt_add_pubkey = self.AddBintool(btools, 'fdt_add_pubkey')
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 3e8091e..1cfa349 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -94,6 +94,8 @@ ROCKCHIP_TPL_DATA = b'rockchip-tpl'
TEST_FDT1_DATA = b'fdt1'
TEST_FDT2_DATA = b'test-fdt2'
ENV_DATA = b'var1=1\nvar2="2"'
+ENCRYPTED_IV_DATA = b'123456'
+ENCRYPTED_KEY_DATA = b'abcde'
PRE_LOAD_MAGIC = b'UBSH'
PRE_LOAD_VERSION = 0x11223344.to_bytes(4, 'big')
PRE_LOAD_HDR_SIZE = 0x00001000.to_bytes(4, 'big')
@@ -232,6 +234,10 @@ class TestFunctional(unittest.TestCase):
# Newer OP_TEE file in v1 binary format
cls.make_tee_bin('tee.bin')
+ # test files for encrypted tests
+ TestFunctional._MakeInputFile('encrypted-file.iv', ENCRYPTED_IV_DATA)
+ TestFunctional._MakeInputFile('encrypted-file.key', ENCRYPTED_KEY_DATA)
+
cls.comp_bintools = {}
for name in COMP_BINTOOLS:
cls.comp_bintools[name] = bintool.Bintool.create(name)
@@ -648,6 +654,16 @@ class TestFunctional(unittest.TestCase):
tools.read_file(cls.ElfTestFile(src_fname)))
@classmethod
+ def _SetupPmuFwlElf(cls, src_fname='bss_data'):
+ """Set up an ELF file with a '_dt_ucode_base_size' symbol
+
+ Args:
+ Filename of ELF file to use as VPL
+ """
+ TestFunctional._MakeInputFile('pmu-firmware.elf',
+ tools.read_file(cls.ElfTestFile(src_fname)))
+
+ @classmethod
def _SetupDescriptor(cls):
with open(cls.TestFile('descriptor.bin'), 'rb') as fd:
TestFunctional._MakeInputFile('descriptor.bin', fd.read())
@@ -5647,41 +5663,61 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
def testPreLoad(self):
"""Test an image with a pre-load header"""
entry_args = {
- 'pre-load-key-path': '.',
+ 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
}
- data, _, _, _ = self._DoReadFileDtb('230_pre_load.dts',
- entry_args=entry_args)
- 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)])
- data = self._DoReadFile('230_pre_load.dts')
+ data = self._DoReadFileDtb(
+ '230_pre_load.dts', entry_args=entry_args,
+ extra_indirs=[os.path.join(self._binman_dir, 'test')])[0]
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)])
+ def testPreLoadNoKey(self):
+ """Test an image with a pre-load heade0r with missing key"""
+ with self.assertRaises(FileNotFoundError) as exc:
+ self._DoReadFile('230_pre_load.dts')
+ self.assertIn("No such file or directory: 'dev.key'",
+ str(exc.exception))
+
def testPreLoadPkcs(self):
"""Test an image with a pre-load header with padding pkcs"""
- data = self._DoReadFile('231_pre_load_pkcs.dts')
+ entry_args = {
+ 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+ }
+ data = self._DoReadFileDtb('231_pre_load_pkcs.dts',
+ entry_args=entry_args)[0]
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)])
def testPreLoadPss(self):
"""Test an image with a pre-load header with padding pss"""
- data = self._DoReadFile('232_pre_load_pss.dts')
+ entry_args = {
+ 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+ }
+ data = self._DoReadFileDtb('232_pre_load_pss.dts',
+ entry_args=entry_args)[0]
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)])
def testPreLoadInvalidPadding(self):
"""Test an image with a pre-load header with an invalid padding"""
+ entry_args = {
+ 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+ }
with self.assertRaises(ValueError) as e:
- data = self._DoReadFile('233_pre_load_invalid_padding.dts')
+ self._DoReadFileDtb('233_pre_load_invalid_padding.dts',
+ entry_args=entry_args)
def testPreLoadInvalidSha(self):
"""Test an image with a pre-load header with an invalid hash"""
+ entry_args = {
+ 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+ }
with self.assertRaises(ValueError) as e:
- data = self._DoReadFile('234_pre_load_invalid_sha.dts')
+ self._DoReadFileDtb('234_pre_load_invalid_sha.dts',
+ entry_args=entry_args)
def testPreLoadInvalidAlgo(self):
"""Test an image with a pre-load header with an invalid algo"""
@@ -5690,8 +5726,12 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
def testPreLoadInvalidKey(self):
"""Test an image with a pre-load header with an invalid key"""
+ entry_args = {
+ 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+ }
with self.assertRaises(ValueError) as e:
- data = self._DoReadFile('236_pre_load_invalid_key.dts')
+ data = self._DoReadFileDtb('236_pre_load_invalid_key.dts',
+ entry_args=entry_args)
def _CheckSafeUniqueNames(self, *images):
"""Check all entries of given images for unsafe unique names"""
@@ -6659,18 +6699,18 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
def testPackRockchipTpl(self):
"""Test that an image with a Rockchip TPL binary can be created"""
- data = self._DoReadFile('277_rockchip_tpl.dts')
+ data = self._DoReadFile('291_rockchip_tpl.dts')
self.assertEqual(ROCKCHIP_TPL_DATA, data[:len(ROCKCHIP_TPL_DATA)])
def testMkimageMissingBlobMultiple(self):
"""Test missing blob with mkimage entry and multiple-data-files"""
with test_util.capture_sys_output() as (stdout, stderr):
- self._DoTestFile('278_mkimage_missing_multiple.dts', allow_missing=True)
+ self._DoTestFile('292_mkimage_missing_multiple.dts', allow_missing=True)
err = stderr.getvalue()
self.assertIn("is missing external blobs and is non-functional", err)
with self.assertRaises(ValueError) as e:
- self._DoTestFile('278_mkimage_missing_multiple.dts', allow_missing=False)
+ self._DoTestFile('292_mkimage_missing_multiple.dts', allow_missing=False)
self.assertIn("not found in input path", str(e.exception))
def _PrepareSignEnv(self, dts='280_fit_sign.dts'):
@@ -6906,19 +6946,19 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
def testTIBoardConfig(self):
"""Test that a schema validated board config file can be generated"""
- data = self._DoReadFile('277_ti_board_cfg.dts')
+ data = self._DoReadFile('293_ti_board_cfg.dts')
self.assertEqual(TI_BOARD_CONFIG_DATA, data)
def testTIBoardConfigCombined(self):
"""Test that a schema validated combined board config file can be generated"""
- data = self._DoReadFile('278_ti_board_cfg_combined.dts')
+ data = self._DoReadFile('294_ti_board_cfg_combined.dts')
configlen_noheader = TI_BOARD_CONFIG_DATA * 4
self.assertGreater(data, configlen_noheader)
def testTIBoardConfigNoDataType(self):
"""Test that error is thrown when data type is not supported"""
with self.assertRaises(ValueError) as e:
- data = self._DoReadFile('279_ti_board_cfg_no_type.dts')
+ data = self._DoReadFile('295_ti_board_cfg_no_type.dts')
self.assertIn("Schema validation error", str(e.exception))
def testPackTiSecure(self):
@@ -6927,7 +6967,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
entry_args = {
'keyfile': keyfile,
}
- data = self._DoReadFileDtb('279_ti_secure.dts',
+ data = self._DoReadFileDtb('296_ti_secure.dts',
entry_args=entry_args)[0]
self.assertGreater(len(data), len(TI_UNSECURE_DATA))
@@ -6939,7 +6979,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
'keyfile': keyfile,
}
with test_util.capture_sys_output() as (_, stderr):
- self._DoTestFile('279_ti_secure.dts',
+ self._DoTestFile('296_ti_secure.dts',
force_missing_bintools='openssl',
entry_args=entry_args)
err = stderr.getvalue()
@@ -6951,11 +6991,11 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
entry_args = {
'keyfile': keyfile,
}
- data = self._DoReadFileDtb('280_ti_secure_rom.dts',
+ data = self._DoReadFileDtb('297_ti_secure_rom.dts',
entry_args=entry_args)[0]
- data_a = self._DoReadFileDtb('288_ti_secure_rom_a.dts',
+ data_a = self._DoReadFileDtb('299_ti_secure_rom_a.dts',
entry_args=entry_args)[0]
- data_b = self._DoReadFileDtb('289_ti_secure_rom_b.dts',
+ data_b = self._DoReadFileDtb('300_ti_secure_rom_b.dts',
entry_args=entry_args)[0]
self.assertGreater(len(data), len(TI_UNSECURE_DATA))
self.assertGreater(len(data_a), len(TI_UNSECURE_DATA))
@@ -6967,9 +7007,85 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
entry_args = {
'keyfile': keyfile,
}
- data = self._DoReadFileDtb('281_ti_secure_rom_combined.dts',
+ data = self._DoReadFileDtb('298_ti_secure_rom_combined.dts',
entry_args=entry_args)[0]
self.assertGreater(len(data), len(TI_UNSECURE_DATA))
+ def testEncryptedNoAlgo(self):
+ """Test encrypted node with missing required properties"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFileDtb('301_encrypted_no_algo.dts')
+ self.assertIn(
+ "Node '/binman/fit/images/u-boot/encrypted': 'encrypted' entry is missing properties: algo iv-filename",
+ str(e.exception))
+
+ def testEncryptedInvalidIvfile(self):
+ """Test encrypted node with invalid iv file"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFileDtb('302_encrypted_invalid_iv_file.dts')
+ self.assertIn("Filename 'invalid-iv-file' not found in input path",
+ str(e.exception))
+
+ def testEncryptedMissingKey(self):
+ """Test encrypted node with missing key properties"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFileDtb('303_encrypted_missing_key.dts')
+ self.assertIn(
+ "Node '/binman/fit/images/u-boot/encrypted': Provide either 'key-filename' or 'key-source'",
+ str(e.exception))
+
+ def testEncryptedKeySource(self):
+ """Test encrypted node with key-source property"""
+ data = self._DoReadFileDtb('304_encrypted_key_source.dts')[0]
+
+ dtb = fdt.Fdt.FromData(data)
+ dtb.Scan()
+
+ node = dtb.GetNode('/images/u-boot/cipher')
+ self.assertEqual('algo-name', node.props['algo'].value)
+ self.assertEqual('key-source-value', node.props['key-source'].value)
+ self.assertEqual(ENCRYPTED_IV_DATA,
+ tools.to_bytes(''.join(node.props['iv'].value)))
+ self.assertNotIn('key', node.props)
+
+ def testEncryptedKeyFile(self):
+ """Test encrypted node with key-filename property"""
+ data = self._DoReadFileDtb('305_encrypted_key_file.dts')[0]
+
+ dtb = fdt.Fdt.FromData(data)
+ dtb.Scan()
+
+ node = dtb.GetNode('/images/u-boot/cipher')
+ self.assertEqual('algo-name', node.props['algo'].value)
+ self.assertEqual(ENCRYPTED_IV_DATA,
+ tools.to_bytes(''.join(node.props['iv'].value)))
+ self.assertEqual(ENCRYPTED_KEY_DATA,
+ tools.to_bytes(''.join(node.props['key'].value)))
+ self.assertNotIn('key-source', node.props)
+
+
+ def testSplPubkeyDtb(self):
+ """Test u_boot_spl_pubkey_dtb etype"""
+ data = tools.read_file(self.TestFile("key.pem"))
+ self._MakeInputFile("key.crt", data)
+ self._DoReadFileRealDtb('306_spl_pubkey_dtb.dts')
+ image = control.images['image']
+ entries = image.GetEntries()
+ dtb_entry = entries['u-boot-spl-pubkey-dtb']
+ dtb_data = dtb_entry.GetData()
+ dtb = fdt.Fdt.FromData(dtb_data)
+ dtb.Scan()
+
+ signature_node = dtb.GetNode('/signature')
+ self.assertIsNotNone(signature_node)
+ key_node = signature_node.FindNode("key-key")
+ self.assertIsNotNone(key_node)
+ self.assertEqual(fdt_util.GetString(key_node, "required"),
+ "conf")
+ self.assertEqual(fdt_util.GetString(key_node, "algo"),
+ "sha384,rsa4096")
+ self.assertEqual(fdt_util.GetString(key_node, "key-name-hint"),
+ "key")
+
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/test/230_pre_load.dts b/tools/binman/test/230_pre_load.dts
index c0c2472..e6d9ef4 100644
--- a/tools/binman/test/230_pre_load.dts
+++ b/tools/binman/test/230_pre_load.dts
@@ -10,7 +10,7 @@
pre-load {
content = <&image>;
algo-name = "sha256,rsa2048";
- key-name = "tools/binman/test/230_dev.key";
+ key-name = "dev.key";
header-size = <4096>;
version = <0x11223344>;
};
diff --git a/tools/binman/test/231_pre_load_pkcs.dts b/tools/binman/test/231_pre_load_pkcs.dts
index 530638c..66268cd 100644
--- a/tools/binman/test/231_pre_load_pkcs.dts
+++ b/tools/binman/test/231_pre_load_pkcs.dts
@@ -11,7 +11,7 @@
content = <&image>;
algo-name = "sha256,rsa2048";
padding-name = "pkcs-1.5";
- key-name = "tools/binman/test/230_dev.key";
+ key-name = "dev.key";
header-size = <4096>;
version = <0x11223344>;
};
diff --git a/tools/binman/test/232_pre_load_pss.dts b/tools/binman/test/232_pre_load_pss.dts
index 371e0fd..3008d3f 100644
--- a/tools/binman/test/232_pre_load_pss.dts
+++ b/tools/binman/test/232_pre_load_pss.dts
@@ -11,7 +11,7 @@
content = <&image>;
algo-name = "sha256,rsa2048";
padding-name = "pss";
- key-name = "tools/binman/test/230_dev.key";
+ key-name = "dev.key";
header-size = <4096>;
version = <0x11223344>;
};
diff --git a/tools/binman/test/233_pre_load_invalid_padding.dts b/tools/binman/test/233_pre_load_invalid_padding.dts
index 9cb4cb5..bbe2d1b 100644
--- a/tools/binman/test/233_pre_load_invalid_padding.dts
+++ b/tools/binman/test/233_pre_load_invalid_padding.dts
@@ -11,7 +11,7 @@
content = <&image>;
algo-name = "sha256,rsa2048";
padding-name = "padding";
- key-name = "tools/binman/test/230_dev.key";
+ key-name = "dev.key";
header-size = <4096>;
version = <1>;
};
diff --git a/tools/binman/test/234_pre_load_invalid_sha.dts b/tools/binman/test/234_pre_load_invalid_sha.dts
index 8ded98d..29afd2e 100644
--- a/tools/binman/test/234_pre_load_invalid_sha.dts
+++ b/tools/binman/test/234_pre_load_invalid_sha.dts
@@ -11,7 +11,7 @@
content = <&image>;
algo-name = "sha2560,rsa2048";
padding-name = "pkcs-1.5";
- key-name = "tools/binman/test/230_dev.key";
+ key-name = "dev.key";
header-size = <4096>;
version = <1>;
};
diff --git a/tools/binman/test/235_pre_load_invalid_algo.dts b/tools/binman/test/235_pre_load_invalid_algo.dts
index 145286c..d6f6dd2 100644
--- a/tools/binman/test/235_pre_load_invalid_algo.dts
+++ b/tools/binman/test/235_pre_load_invalid_algo.dts
@@ -11,7 +11,7 @@
content = <&image>;
algo-name = "sha256,rsa20480";
padding-name = "pkcs-1.5";
- key-name = "tools/binman/test/230_dev.key";
+ key-name = "dev.key";
header-size = <4096>;
version = <1>;
};
diff --git a/tools/binman/test/236_pre_load_invalid_key.dts b/tools/binman/test/236_pre_load_invalid_key.dts
index df858c3..f93bc97 100644
--- a/tools/binman/test/236_pre_load_invalid_key.dts
+++ b/tools/binman/test/236_pre_load_invalid_key.dts
@@ -11,7 +11,7 @@
content = <&image>;
algo-name = "sha256,rsa4096";
padding-name = "pkcs-1.5";
- key-name = "tools/binman/test/230_dev.key";
+ key-name = "dev.key";
header-size = <4096>;
version = <1>;
};
diff --git a/tools/binman/test/277_rockchip_tpl.dts b/tools/binman/test/291_rockchip_tpl.dts
index 269f56e..269f56e 100644
--- a/tools/binman/test/277_rockchip_tpl.dts
+++ b/tools/binman/test/291_rockchip_tpl.dts
diff --git a/tools/binman/test/278_mkimage_missing_multiple.dts b/tools/binman/test/292_mkimage_missing_multiple.dts
index f84aea4..f84aea4 100644
--- a/tools/binman/test/278_mkimage_missing_multiple.dts
+++ b/tools/binman/test/292_mkimage_missing_multiple.dts
diff --git a/tools/binman/test/277_ti_board_cfg.dts b/tools/binman/test/293_ti_board_cfg.dts
index cda024c..cda024c 100644
--- a/tools/binman/test/277_ti_board_cfg.dts
+++ b/tools/binman/test/293_ti_board_cfg.dts
diff --git a/tools/binman/test/278_ti_board_cfg_combined.dts b/tools/binman/test/294_ti_board_cfg_combined.dts
index 95ef449..95ef449 100644
--- a/tools/binman/test/278_ti_board_cfg_combined.dts
+++ b/tools/binman/test/294_ti_board_cfg_combined.dts
diff --git a/tools/binman/test/279_ti_board_cfg_no_type.dts b/tools/binman/test/295_ti_board_cfg_no_type.dts
index 584b7ac..584b7ac 100644
--- a/tools/binman/test/279_ti_board_cfg_no_type.dts
+++ b/tools/binman/test/295_ti_board_cfg_no_type.dts
diff --git a/tools/binman/test/279_ti_secure.dts b/tools/binman/test/296_ti_secure.dts
index 941d0ab..941d0ab 100644
--- a/tools/binman/test/279_ti_secure.dts
+++ b/tools/binman/test/296_ti_secure.dts
diff --git a/tools/binman/test/280_ti_secure_rom.dts b/tools/binman/test/297_ti_secure_rom.dts
index d131376..d131376 100644
--- a/tools/binman/test/280_ti_secure_rom.dts
+++ b/tools/binman/test/297_ti_secure_rom.dts
diff --git a/tools/binman/test/281_ti_secure_rom_combined.dts b/tools/binman/test/298_ti_secure_rom_combined.dts
index bf87273..bf87273 100644
--- a/tools/binman/test/281_ti_secure_rom_combined.dts
+++ b/tools/binman/test/298_ti_secure_rom_combined.dts
diff --git a/tools/binman/test/288_ti_secure_rom_a.dts b/tools/binman/test/299_ti_secure_rom_a.dts
index 887138f..887138f 100644
--- a/tools/binman/test/288_ti_secure_rom_a.dts
+++ b/tools/binman/test/299_ti_secure_rom_a.dts
diff --git a/tools/binman/test/289_ti_secure_rom_b.dts b/tools/binman/test/300_ti_secure_rom_b.dts
index c6d6182..c6d6182 100644
--- a/tools/binman/test/289_ti_secure_rom_b.dts
+++ b/tools/binman/test/300_ti_secure_rom_b.dts
diff --git a/tools/binman/test/301_encrypted_no_algo.dts b/tools/binman/test/301_encrypted_no_algo.dts
new file mode 100644
index 0000000..03f7ffe
--- /dev/null
+++ b/tools/binman/test/301_encrypted_no_algo.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+ binman {
+ fit {
+ images {
+ u-boot {
+ encrypted {
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/302_encrypted_invalid_iv_file.dts b/tools/binman/test/302_encrypted_invalid_iv_file.dts
new file mode 100644
index 0000000..388a0a6
--- /dev/null
+++ b/tools/binman/test/302_encrypted_invalid_iv_file.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+ binman {
+ fit {
+ images {
+ u-boot {
+ encrypted {
+ algo = "some-algo";
+ key-source = "key";
+ iv-filename = "invalid-iv-file";
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/303_encrypted_missing_key.dts b/tools/binman/test/303_encrypted_missing_key.dts
new file mode 100644
index 0000000..d1daaa0
--- /dev/null
+++ b/tools/binman/test/303_encrypted_missing_key.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ fit {
+ description = "test desc";
+
+ images {
+ u-boot {
+ encrypted {
+ algo = "algo-name";
+ iv-filename = "encrypted-file.iv";
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/304_encrypted_key_source.dts b/tools/binman/test/304_encrypted_key_source.dts
new file mode 100644
index 0000000..884ec50
--- /dev/null
+++ b/tools/binman/test/304_encrypted_key_source.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ fit {
+ description = "test desc";
+
+ images {
+ u-boot {
+ encrypted {
+ algo = "algo-name";
+ key-source = "key-source-value";
+ iv-filename = "encrypted-file.iv";
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/305_encrypted_key_file.dts b/tools/binman/test/305_encrypted_key_file.dts
new file mode 100644
index 0000000..efd7ee5
--- /dev/null
+++ b/tools/binman/test/305_encrypted_key_file.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ fit {
+ description = "test desc";
+
+ images {
+ u-boot {
+ encrypted {
+ algo = "algo-name";
+ iv-filename = "encrypted-file.iv";
+ key-filename = "encrypted-file.key";
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/306_spl_pubkey_dtb.dts b/tools/binman/test/306_spl_pubkey_dtb.dts
new file mode 100644
index 0000000..3256ff9
--- /dev/null
+++ b/tools/binman/test/306_spl_pubkey_dtb.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ u-boot-spl-pubkey-dtb {
+ algo = "sha384,rsa4096";
+ required = "conf";
+ key-name-hint = "key";
+ };
+ };
+};
diff --git a/tools/binman/test/230_dev.key b/tools/binman/test/dev.key
index b36bad2..b36bad2 100644
--- a/tools/binman/test/230_dev.key
+++ b/tools/binman/test/dev.key