tools: binman: pass KEYDIR to FIT entries
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@gmail.com>
This commit is contained in:
@@ -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} \
|
||||
|
||||
@@ -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`.
|
||||
|
||||
+16
-12
@@ -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')
|
||||
|
||||
|
||||
@@ -8173,6 +8173,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"""
|
||||
@@ -8513,6 +8538,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:
|
||||
|
||||
Reference in New Issue
Block a user