[PATCH v2] tools: binman: pass KEYDIR to FIT entries
James Hilliard
james.hilliard1 at gmail.com
Thu Jul 9 04:29:00 CEST 2026
U-Boot's Makefile passes KEYDIR to direct mkimage invocations, but
internal binman FIT builds only receive the generic BINMAN_INDIRS search
path. Adding KEYDIR to BINMAN_INDIRS treats it as one more input-file
search path: FIT entries still auto-detect a key directory from all
include directories, so an explicit KEYDIR may not be the directory that
gets passed to mkimage. It also makes a key-only directory part of the
generic blob lookup path.
Forward KEYDIR as a binman entry argument named keydir, matching the
existing entry-argument mechanism used for BL31, TEE, of-list and other
U-Boot build inputs. FIT entries use that directory directly for
mkimage -k when fit,sign or fit,encrypt is enabled, falling back to the
include-directory autodetection when keydir is not provided.
Signed-off-by: James Hilliard <james.hilliard1 at gmail.com>
---
Changes v1 -> v2:
- Use the existing EntryArg mechanism instead of adding a binman build
-k/--keydir option and global state
- Explain why KEYDIR should not just be added to BINMAN_INDIRS
- Clarify KEYDIR documentation as a Makefile-forwarded EntryArg
---
Makefile | 1 +
tools/binman/binman.rst | 5 +++++
tools/binman/etype/fit.py | 28 +++++++++++++++------------
tools/binman/ftest.py | 40 +++++++++++++++++++++++++++++++++++++++
4 files changed, 62 insertions(+), 12 deletions(-)
diff --git a/Makefile b/Makefile
index d8287323c43..c8ac56d36e4 100644
--- a/Makefile
+++ b/Makefile
@@ -1689,6 +1689,7 @@ cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \
-I . -I $(srctree)/board/$(BOARDDIR) -I $(srctree) \
$(foreach f,$(of_list_dirs),-I $(f)) -a of-list=$(of_list) \
$(foreach f,$(BINMAN_INDIRS),-I $(f)) \
+ $(if $(KEYDIR),-a keydir=$(KEYDIR)) \
-a atf-bl1-path=${BL1} \
-a atf-bl31-path=${BL31} \
-a tee-os-path=${TEE} \
diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst
index 366491089ad..3a860421a69 100644
--- a/tools/binman/binman.rst
+++ b/tools/binman/binman.rst
@@ -2161,6 +2161,11 @@ BINMAN_INDIRS
Sets the search path for input files used by binman by adding one or more
`-I` arguments. See :ref:`External blobs`.
+KEYDIR
+ Sets the key directory passed to FIT entries by adding a
+ `-a keydir=$(KEYDIR)` argument. FIT entries use this directory for
+ mkimage's `-k` argument when `fit,sign` or `fit,encrypt` is enabled.
+
BINMAN_TOOLPATHS
Sets the search path for external tool used by binman by adding one or more
`--toolpath` arguments. See :ref:`External tools`.
diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
index f28b1e6b4cb..32caa03a7e1 100644
--- a/tools/binman/etype/fit.py
+++ b/tools/binman/etype/fit.py
@@ -105,18 +105,20 @@ class Entry_fit(Entry_section):
fit,sign
Enable signing FIT images via mkimage as described in
verified-boot.rst.
- If the property is found and fit,engine is not set, the private
- keys path is detected among binman include directories and passed to
- mkimage via -k flag. All the keys required for signing FIT must be
- available at time of signing and must be located in single include
- directory.
+ If the property is found and fit,engine is not set, the `keydir`
+ entry argument is passed to mkimage via the -k flag. If no key
+ directory is provided, the private keys path is detected among
+ binman include directories. All the keys required for signing FIT
+ must be available at time of signing and must be located in a
+ single directory.
fit,encrypt
Enable data encryption in FIT images via mkimage. If the property
- is found, the keys path is detected among binman include
- directories and passed to mkimage via -k flag. All the keys
- required for encrypting the FIT must be available at the time of
- encrypting and must be located in a single include directory.
+ is found, the `keydir` entry argument is passed to mkimage via the
+ -k flag. If no key directory is provided, the keys path is detected
+ among binman include directories. All the keys required for
+ encrypting the FIT must be available at the time of encrypting and
+ must be located in a single directory.
Incompatible with fit,engine.
@@ -485,6 +487,7 @@ class Entry_fit(Entry_section):
includes 'generator' entries which are used to create the FIT,
but should not be processed as real entries. This is set up once
we have the entries
+ _keydir (str): Key directory from the keydir EntryArg, if provided
_loadables (list of str): List of generated split-elf nodes, each
a node name
_remove_props (list of str): Value of of-spl-remove-props EntryArg,
@@ -502,8 +505,9 @@ class Entry_fit(Entry_section):
self._priv_entries = {}
self._loadables = []
self._remove_props = []
- props = self.GetEntryArgsOrProps(
- [EntryArg('of-spl-remove-props', str)], required=False)[0]
+ props, self._keydir = self.GetEntryArgsOrProps(
+ [EntryArg('of-spl-remove-props', str),
+ EntryArg('keydir', str)], required=False)
if props:
self._remove_props = props.split()
self.mkimage = None
@@ -701,7 +705,7 @@ class Entry_fit(Entry_section):
args.update({'engine': engine})
# If no engine, keys must exist locally, find them
if engine is None:
- keydir = self._get_keys_dir(data)
+ keydir = self._keydir or self._get_keys_dir(data)
elif self._fit_props.get('fit,encrypt') is not None:
self.Raise('fit,engine currently does not support encryption')
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index bf98b268ac1..7b84d79eec0 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -8167,6 +8167,31 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self.assertIsNotNone(signature)
self.assertIsNotNone(signature.props.get('value'))
+ def testFitSignKeydir(self):
+ """Test that the keydir EntryArg is passed to mkimage"""
+ if not elf.ELF_TOOLS:
+ self.skipTest('Python elftools not available')
+ data = tools.read_file(self.TestFile("fit/rsa2048.key"))
+ self._MakeInputFile("keys/rsa2048.key", data)
+
+ test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
+ keys_subdir = os.path.join(self._indir, "keys")
+ entry_args = {
+ 'of-list': 'test-fdt1',
+ 'default-dt': 'test-fdt1',
+ 'atf-bl31-path': 'bl31.elf',
+ 'keydir': keys_subdir,
+ }
+ data = self._DoReadFileDtb(
+ 'fit/signature.dts',
+ entry_args=entry_args,
+ extra_indirs=[test_subdir])[0]
+
+ dtb = fdt.Fdt.FromData(data)
+ dtb.Scan()
+ signature = dtb.GetNode('/configurations/conf-uboot-1/signature')
+ self.assertIsNotNone(signature.props.get('value'))
+
def testFitSignEngineSimple(self):
"""Test that image with FIT and signature nodes can be signed with an
OpenSSL Engine"""
@@ -8507,6 +8532,21 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
dec_data = file.read()
self.assertEqual(U_BOOT_NODTB_DATA, dec_data.encode('ascii'))
+ def testSimpleFitEncryptedDataKeydir(self):
+ """Test that encrypted FIT data uses the keydir EntryArg"""
+ 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(
+ 'fit/encrypt_data.dts',
+ entry_args={'keydir': keys_subdir})[0]
+
+ fit = fdt.Fdt.FromData(data)
+ fit.Scan()
+ node = fit.GetNode('/images/u-boot')
+ self.assertIn('data-size-unciphered', fit.GetProps(node))
+
def testSimpleFitEncryptedDataMissingKey(self):
"""Test an image with a FIT containing data to be encrypted but with a missing key"""
with self.assertRaises(ValueError) as e:
--
2.53.0
More information about the U-Boot
mailing list