summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/binman/binman.rst5
-rw-r--r--tools/binman/btool/bootgen.py2
-rw-r--r--tools/binman/btool/mkeficapsule.py2
-rw-r--r--tools/binman/etype/fit.py28
-rw-r--r--tools/binman/etype/gbb.py2
-rw-r--r--tools/binman/etype/nxp_imx8mcst.py38
-rw-r--r--tools/binman/etype/nxp_imx8mimage.py95
-rw-r--r--tools/binman/ftest.py96
-rw-r--r--tools/binman/pyproject.toml2
-rw-r--r--tools/binman/test/vendor/nxp_imx8_csf_pkcs11.dts27
-rw-r--r--tools/binman/test/vendor/nxp_imx8m_fspi.dts1
-rw-r--r--tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts19
-rw-r--r--tools/binman/test/vendor/nxp_imx8m_fspi_fail_devicetype.dts (renamed from tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts)3
-rw-r--r--tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts19
-rw-r--r--tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts19
-rw-r--r--tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts19
-rw-r--r--tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts1
-rw-r--r--tools/buildman/board.py2
-rw-r--r--tools/buildman/func_test.py2
-rw-r--r--tools/buildman/pyproject.toml2
-rw-r--r--tools/docker/Dockerfile10
-rw-r--r--tools/dtoc/pyproject.toml2
-rw-r--r--tools/fit_image.c4
-rw-r--r--tools/image-host.c94
-rw-r--r--tools/patman/settings.py2
-rw-r--r--tools/u_boot_pylib/gitutil.py2
-rw-r--r--tools/u_boot_pylib/pyproject.toml2
27 files changed, 420 insertions, 80 deletions
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/btool/bootgen.py b/tools/binman/btool/bootgen.py
index 1bc9f0aa96f..f740381b704 100644
--- a/tools/binman/btool/bootgen.py
+++ b/tools/binman/btool/bootgen.py
@@ -7,7 +7,7 @@
bootgen allows creating bootable SPL for Zynq(MP)
Documentation is available via:
-https://www.xilinx.com/support/documents/sw_manuals/xilinx2022_1/ug1283-bootgen-user-guide.pdf
+https://docs.amd.com/r/en-US/ug1283-bootgen-user-guide/
Source code is available at:
https://github.com/Xilinx/bootgen
diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py
index 7638c941a8e..3d3ceb009c1 100644
--- a/tools/binman/btool/mkeficapsule.py
+++ b/tools/binman/btool/mkeficapsule.py
@@ -126,7 +126,7 @@ class Bintoolmkeficapsule(bintool.Bintool):
cmd = ['tools-only_defconfig', 'tools']
result = self.build_from_git(
- 'https://source.denx.de/u-boot/u-boot.git',
+ 'https://git.u-boot-project.org/u-boot/u-boot.git',
cmd,
'tools/mkeficapsule')
return result
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/etype/gbb.py b/tools/binman/etype/gbb.py
index cca18af6e2f..70067a54504 100644
--- a/tools/binman/etype/gbb.py
+++ b/tools/binman/etype/gbb.py
@@ -48,7 +48,7 @@ class Entry_gbb(Entry):
the root and recovery keys that are used to verify the boot process. Some
more details are here:
- https://www.chromium.org/chromium-os/firmware-porting-guide/2-concepts
+ https://www.chromium.org/chromium-os/developer-library/guides/firmware/firmware-porting-guide/2-concepts/
but note that the page dates from 2013 so is quite out of date. See
README.chromium for how to obtain the required keys and tools.
diff --git a/tools/binman/etype/nxp_imx8mcst.py b/tools/binman/etype/nxp_imx8mcst.py
index dd9f226b751..29a7451678d 100644
--- a/tools/binman/etype/nxp_imx8mcst.py
+++ b/tools/binman/etype/nxp_imx8mcst.py
@@ -20,8 +20,9 @@ from binman import elf
from dtoc import fdt_util
from u_boot_pylib import tools
-MAGIC_NXP_IMX_IVT = 0x412000d1
-MAGIC_FITIMAGE = 0xedfe0dd0
+MAGIC_NXP_IMX_IVT = 0x412000d1
+MAGIC_NXP_IMX_FCFB = 0x42464346
+MAGIC_FITIMAGE = 0xedfe0dd0
KEY_NAME = 'sha256_4096_65537_v3_usr_crt'
@@ -65,6 +66,13 @@ class Entry_nxp_imx8mcst(Entry_mkimage):
Properties / Entry arguments:
- nxp,loader-address - loader address (SPL text base)
+ - nxp,srk-table - full path to SRK_1_2_3_4_table.bin
+ - nxp,csf-crt - full path to the CSF Key CSF1_1_sha256_4096_65537_v3_usr_crt.pem
+ - nxp,img-crt - full path to the IMG Key IMG1_1_sha256_4096_65537_v3_usr_crt.pem
+ - nxp,fast-auth - enable fast authentication method
+ - nxp,srk-crt - full path to the SRK Key SRK1_sha256_4096_65537_v3_ca_crt.pem
+ - nxp,unlock - unlock CAAM in SPL
+ - nxp,cst-backend - CST tool backend, default is 'ssl', or selectable 'pkcs11'
"""
def __init__(self, section, etype, node):
@@ -90,6 +98,10 @@ class Entry_nxp_imx8mcst(Entry_mkimage):
'SRK_KEY', fdt_util.GetString(self._node, 'nxp,srk-crt',
f'SRK1_{KEY_NAME}.pem'))
+ self.backend = os.getenv(
+ 'CST_BACKEND', fdt_util.GetString(self._node, 'nxp,cst-backend',
+ 'ssl'))
+
self.unlock = fdt_util.GetBool(self._node, 'nxp,unlock')
self.ReadEntries()
@@ -101,6 +113,9 @@ class Entry_nxp_imx8mcst(Entry_mkimage):
# - If it is mkimage'd imx8mimage, then extract to be signed data size
# from imx8mimage header, and calculate CSF blob offset right past
# the SPL from this information.
+ # - If it is mkimage'd imx8mimage wrapped in FCFB, then extract to be
+ # signed data size from imx8mimage header past the FCFB header, and
+ # calculate CSF blob offset right past the SPL from this information.
# - If it is fitImage, then pad the image to 4k, add generated IVT and
# sign the whole payload, then append CSF blob at the end right past
# the IVT.
@@ -114,6 +129,17 @@ class Entry_nxp_imx8mcst(Entry_mkimage):
signsize = struct.unpack('<I', data[24:28])[0] - signbase
# Remove mkimage generated padding from the end of data
data = data[:signsize]
+ elif signtype == MAGIC_NXP_IMX_FCFB: # SPL/imx8mimage with FCFB
+ # Sign the payload including FCFB and imx8mimage headers
+ # (extra 0x1000 and 0x40 bytes before the payload)
+ signbase -= 0x1040
+ # Pull the end address from IVT offset 24 Bytes and subtract
+ # the start address to get amount of data to sign. The IVT
+ # itself is at offset 4096 Bytes, so the total end address
+ # offset in the image is 4120 Bytes.
+ signsize = struct.unpack('<I', data[4120:4124])[0] - signbase
+ # Remove mkimage generated padding from the end of data
+ data = data[:signsize]
elif signtype == MAGIC_FITIMAGE: # fitImage
# Align fitImage to 4k
signsize = tools.align(len(data), 0x1000)
@@ -161,8 +187,14 @@ class Entry_nxp_imx8mcst(Entry_mkimage):
with open(cfg_fname, 'w') as cfgf:
config.write(cfgf)
+ # SSL is the default backend, PKCS11 backend is optional
+ if self.backend == "pkcs11":
+ cst_backend = "pkcs11"
+ else:
+ cst_backend = "ssl"
+
output_fname = tools.get_output_filename(f'nxp.csf-output-blob.{uniq}')
- args = ['-i', cfg_fname, '-o', output_fname]
+ args = ['-i', cfg_fname, '-o', output_fname, '-b', cst_backend]
if self.cst.run_cmd(*args) is not None:
outdata = tools.read_file(output_fname)
# fixme: 0x2000 should be CONFIG_CSF_SIZE
diff --git a/tools/binman/etype/nxp_imx8mimage.py b/tools/binman/etype/nxp_imx8mimage.py
index 25c43438a87..38d31b1bc09 100644
--- a/tools/binman/etype/nxp_imx8mimage.py
+++ b/tools/binman/etype/nxp_imx8mimage.py
@@ -7,7 +7,7 @@
# configuration file and input data.
#
-import os
+import struct
from collections import OrderedDict
@@ -25,8 +25,26 @@ 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"' .
+
+ Properties / Entry arguments for FSPI boot mode (nxp,boot-from = "fspi"):
+ - nxp,fspi-columnaddresswidth - FSPI column address width
+ (3 - HyperFlash, 12/13 - Serial NAND, 0 - Otherwise (default))
+ - nxp,fspi-controllermisc-diffclk - FSPI differential clock enable (default off)
+ - nxp,fspi-controllermisc-wordaddr - FSPI word addressable enable (default off)
+ - nxp,fspi-controllermisc-safecfg - FSPI safe configuration frequency (default off)
+ - nxp,fspi-controllermisc-padovr - FSPI pad setting override (default off)
+ - nxp,fspi-controllermisc-ddrmode - FSPI DDR mode (default off)
+ - nxp,fspi-lutcustomseq - FSPI use LUT sequence parameters (default off)
+ - nxp,fspi-devicetype - FSPI device type
+ (1 - SPI NOR (default), 2 - Serial NAND)
+ - nxp,fspi-flasha1size - FSPI device size (default 0x10000000)
+ - nxp,fspi-flashpadtype - FSPI flash pad type
+ (1 - Single pad (default), 2 - Dual pads, 4 - Quad pads, 8 - Octal pads)
+ - nxp,fspi-readsampleclksrc - FSPI clock source
+ (0 - Internal loopback (default), 1 - loopback from DQS pad, 3 - Flash provided DQS).
+ - nxp,fspi-serialclkfreq - FSPI clock frequency
+ (1 - 30 MHz, 2 - 50 MHz (default), 3 - 60 MHz, 4 - 75 MHz, 5 - 80 MHz,
+ 6 - 100 MHz, 7 - 133 MHz, 8 - 166 MHz).
"""
def __init__(self, section, etype, node):
@@ -37,9 +55,30 @@ 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.fspi_columnadresswidth = fdt_util.GetInt(self._node, 'nxp,fspi-columnaddresswidth', 0)
+ self.fspi_controllermisc_diffclk = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-diffclk')
+ self.fspi_controllermisc_wordaddr = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-wordaddr')
+ self.fspi_controllermisc_safecfg = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-safecfg')
+ self.fspi_controllermisc_padovr = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-padovr')
+ self.fspi_controllermisc_ddrmode = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-ddrmode')
+ self.fspi_devicetype = fdt_util.GetInt(self._node, 'nxp,fspi-devicetype', 1)
+ self.fspi_flasha1size = fdt_util.GetInt(self._node, 'nxp,fspi-flasha1size', 0x10000000)
+ self.fspi_flashpadtype = fdt_util.GetInt(self._node, 'nxp,fspi-flashpadtype', 1)
+ self.fspi_lutcustomseq = fdt_util.GetBool(self._node, 'nxp,fspi-lutcustomseq')
+ self.fspi_readsampleclksrc = fdt_util.GetInt(self._node, 'nxp,fspi-readsampleclksrc', 0)
+ self.fspi_serialclkfreq = fdt_util.GetInt(self._node, 'nxp,fspi-serialclkfreq', 2)
self.loader_address = fdt_util.GetInt(self._node, 'nxp,loader-address')
self.rom_version = fdt_util.GetInt(self._node, 'nxp,rom-version')
+ if not self.fspi_columnadresswidth in [ 0, 3, 12, 13 ]:
+ self.Raise('nxp,fspi-columnaddresswidth can be 0, 3, 12, 13 only.')
+ if not self.fspi_devicetype in [ 1, 2 ]:
+ self.Raise('nxp,fspi-devicetype can be 1, 2 only.')
+ if not self.fspi_flashpadtype in [ 1, 2, 4, 8 ]:
+ self.Raise('nxp,fspi-flashpadtype can be 1, 2, 4, 8 only.')
+ if not self.fspi_readsampleclksrc in [ 0, 1, 3 ]:
+ self.Raise('nxp,fspi-readsampleclksrc can be 0, 1, 3 only.')
+ if not self.fspi_serialclkfreq in [ 1, 2, 3, 4, 5, 6, 7, 8 ]:
+ self.Raise('nxp,fspi-serialclkfreq can be 1..8 only.')
self.ReadEntries()
def BuildSectionData(self, required):
@@ -59,9 +98,51 @@ class Entry_nxp_imx8mimage(Entry_mkimage):
if self.mkimage.run_cmd(*args) is not None:
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")
+ # 0x00 ... Tag
+ spidata = struct.pack('<I', 0x42464346)
+ # 0x04 ... Version
+ spidata += struct.pack('<I', 0x56010000)
+ # 0x08 ... Reserved
+ spidata += struct.pack('<I', 0)
+ # 0x0c ... readSampleClkSrc (LSByte at 0x0c), dataHoldTime,
+ # dataSetupTime, columnAdressWidth (MSByte at 0x0f)
+ spidata += struct.pack('<I', 0x00030300 |
+ (self.fspi_columnadresswidth << 24) |
+ self.fspi_readsampleclksrc)
+
+ # 0x10..0x3f ... Padding
+ spidata += tools.get_bytes(0, 0x30)
+
+ # 0x40 ... controllerMiscOption
+ spidata += struct.pack('<I',
+ ((1 << 0) if self.fspi_controllermisc_diffclk else 0) |
+ ((1 << 3) if self.fspi_controllermisc_wordaddr else 0) |
+ ((1 << 4) if self.fspi_controllermisc_safecfg else 0) |
+ ((1 << 5) if self.fspi_controllermisc_padovr else 0) |
+ ((1 << 6) if self.fspi_controllermisc_ddrmode else 0))
+
+ # 0x44 ... deviceType (LSByte at 0x44), sflashPadType,
+ # serialClkFreq, lutCustomSeqEnable (MSByte at 0x47)
+ spidata += struct.pack('<I',
+ ((1 << 24) if self.fspi_lutcustomseq else 0) |
+ (self.fspi_serialclkfreq << 16) |
+ (self.fspi_flashpadtype << 8) |
+ self.fspi_devicetype)
+
+ # 0x48..0x4f ... Padding
+ spidata += tools.get_bytes(0, 0x8)
+
+ # 0x50 ... flashA1Size
+ spidata += struct.pack('<I', self.fspi_flasha1size)
+
+ # 0x54..0x7f ... Padding
+ spidata += tools.get_bytes(0, 0x2c)
+
+ # 0x80 ... lookupTable
+ spidata += struct.pack('<I', 0x0818040b)
+ spidata += struct.pack('<I', 0x24043008)
+
+ # 0x88..0xfff ... Padding (end of FSPI block is 0x1bf, align to 4k)
spidata += tools.get_bytes(0, 0x1000 - len(spidata))
outdata = spidata + outdata
return outdata
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index ea2fa6eb83a..a0e8bde7901 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -8029,6 +8029,39 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
err = stderr.getvalue()
self.assertRegex(err, "Image 'image'.*missing bintools.*: cst")
+ def testNxpImx8mCSTPKCS11(self):
+ """Test CST signing with IVT-format input (pkcs11 auth, no unlock)"""
+ # Create fake IVT blob: magic(4) + padding(20) + signsize_addr(4)
+ # + padding(36) = 64 bytes
+ ivt_data = struct.pack('<I', 0x412000d1)
+ ivt_data += b'\x00' * 20
+ ivt_data += struct.pack('<I', 0)
+ ivt_data += b'\x00' * 36
+ self._MakeInputFile('imx8m-ivt.bin', ivt_data)
+ with terminal.capture() as (_, stderr):
+ self._DoTestFile('vendor/nxp_imx8_csf_pkcs11.dts',
+ force_missing_bintools='cst')
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'image'.*missing bintools.*: cst")
+
+ def testNxpImx8mCSTFCFB(self):
+ """Test CST signing with FCFB-format input (normal auth, no unlock)"""
+ # Create fake FCFB blob: magic(4) + padding(4116)
+ ivt_data = struct.pack('<I', 0x42464346)
+ ivt_data += b'\x00' * 4116
+ # Create fake IVT blob: magic(4) + padding(20) + signsize_addr(4)
+ # + padding(36) = 64 bytes
+ ivt_data += struct.pack('<I', 0x412000d1)
+ ivt_data += b'\x00' * 20
+ ivt_data += struct.pack('<I', 0)
+ ivt_data += b'\x00' * 36
+ self._MakeInputFile('imx8m-ivt.bin', ivt_data)
+ with terminal.capture() as (_, stderr):
+ self._DoTestFile('vendor/nxp_imx8_csf.dts',
+ force_missing_bintools='cst')
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'image'.*missing bintools.*: cst")
+
def testNxpImx8mCSTFastAuth(self):
"""Test CST signing with fast-auth mode, unlock, and FIT format"""
# FIT magic covers the FIT-signing path; fast-auth/unlock cover the
@@ -8106,17 +8139,18 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
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)
+ self._DoTestFile('vendor/nxp_imx8m_fspi.dts')
+ self._DoTestFile('vendor/nxp_imx8m_fspi_pass.dts')
+ with self.assertRaises(ValueError) as e:
+ self._DoTestFile('vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts')
+ with self.assertRaises(ValueError) as e:
+ self._DoTestFile('vendor/nxp_imx8m_fspi_fail_devicetype.dts')
+ with self.assertRaises(ValueError) as e:
+ self._DoTestFile('vendor/nxp_imx8m_fspi_fail_flashpadtype.dts')
+ with self.assertRaises(ValueError) as e:
+ self._DoTestFile('vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts')
+ with self.assertRaises(ValueError) as e:
+ self._DoTestFile('vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts')
def testNxpHeaderDdrfw(self):
"""Test that binman can add a header to DDR PHY firmware images"""
@@ -8172,6 +8206,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"""
@@ -8512,6 +8571,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:
diff --git a/tools/binman/pyproject.toml b/tools/binman/pyproject.toml
index fd43a71b02b..46204f477ca 100644
--- a/tools/binman/pyproject.toml
+++ b/tools/binman/pyproject.toml
@@ -20,7 +20,7 @@ classifiers = [
[project.urls]
"Homepage" = "https://docs.u-boot-project.org/en/latest/develop/package/index.html"
-"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues"
+"Bug Tracker" = "https://git.u-boot-project.org/groups/u-boot/-/issues"
[project.scripts]
binman = "binman.main:start_binman"
diff --git a/tools/binman/test/vendor/nxp_imx8_csf_pkcs11.dts b/tools/binman/test/vendor/nxp_imx8_csf_pkcs11.dts
new file mode 100644
index 00000000000..835ea236826
--- /dev/null
+++ b/tools/binman/test/vendor/nxp_imx8_csf_pkcs11.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ nxp-imx8mcst {
+ args;
+ nxp,loader-address = <0x10>;
+ nxp,cst-backend = "pkcs11";
+
+ blob {
+ filename = "imx8m-ivt.bin";
+ };
+
+ imagename {
+ type = "section";
+
+ u-boot {
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi.dts b/tools/binman/test/vendor/nxp_imx8m_fspi.dts
index ae6cc5981e6..140e9bea2e7 100644
--- a/tools/binman/test/vendor/nxp_imx8m_fspi.dts
+++ b/tools/binman/test/vendor/nxp_imx8m_fspi.dts
@@ -10,7 +10,6 @@
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_columnadresswidth.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts
new file mode 100644
index 00000000000..95efa33b5bf
--- /dev/null
+++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts
@@ -0,0 +1,19 @@
+// 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,rom-version = <2>;
+ nxp,loader-address = <0x10>;
+ /* Bogus value */
+ nxp,fspi-columnaddresswidth = <1>;
+ };
+ };
+};
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_devicetype.dts
index 5a0d758e5a3..f3b343f942f 100644
--- a/tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts
+++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_devicetype.dts
@@ -10,9 +10,10 @@
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>;
+ /* Bogus value */
+ nxp,fspi-devicetype = <3>;
};
};
};
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts
new file mode 100644
index 00000000000..515f81ba9f4
--- /dev/null
+++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts
@@ -0,0 +1,19 @@
+// 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,rom-version = <2>;
+ nxp,loader-address = <0x10>;
+ /* Bogus value */
+ nxp,fspi-flashpadtype = <9>;
+ };
+ };
+};
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts
new file mode 100644
index 00000000000..b409a6099a3
--- /dev/null
+++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts
@@ -0,0 +1,19 @@
+// 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,rom-version = <2>;
+ nxp,loader-address = <0x10>;
+ /* Bogus value */
+ nxp,fspi-readsampleclksrc = <2>;
+ };
+ };
+};
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts
new file mode 100644
index 00000000000..a71522838e8
--- /dev/null
+++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts
@@ -0,0 +1,19 @@
+// 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,rom-version = <2>;
+ nxp,loader-address = <0x10>;
+ /* Bogus value */
+ nxp,fspi-serialclkfreq = <9>;
+ };
+ };
+};
diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts
index 448d93d277a..1545cf6e44c 100644
--- a/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts
+++ b/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts
@@ -10,7 +10,6 @@
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>;
};
diff --git a/tools/buildman/board.py b/tools/buildman/board.py
index 248d8bfff18..231454dc8cd 100644
--- a/tools/buildman/board.py
+++ b/tools/buildman/board.py
@@ -10,7 +10,7 @@ class Board:
"""Create a new board type.
Args:
- status: define whether the board is 'Active' or 'Orphaned'
+ status: define whether the board is 'Active' or 'Orphan'
arch: Architecture name (e.g. arm)
cpu: Cpu name (e.g. arm1136)
soc: Name of SOC, or '' if none (e.g. mx31)
diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py
index 51c6855420e..fce615ba8b8 100644
--- a/tools/buildman/func_test.py
+++ b/tools/buildman/func_test.py
@@ -951,7 +951,7 @@ Active aarch64 armv8 - armltd total_compute board2
self.assertEqual(["WARNING: no maintainers for 'board0'"], warnings)
# Mark a board as orphaned - this should give a warning
- lines = ['S: Orphaned' if line.startswith('S') else line
+ lines = ['S: Orphan' if line.startswith('S') else line
for line in orig_data.splitlines(keepends=True)]
tools.write_file(main, ''.join(lines), binary=False)
params_list, warnings = self._boards.build_board_list(config_dir, src)
diff --git a/tools/buildman/pyproject.toml b/tools/buildman/pyproject.toml
index 5f5c405afbf..8a27bbaf167 100644
--- a/tools/buildman/pyproject.toml
+++ b/tools/buildman/pyproject.toml
@@ -24,7 +24,7 @@ classifiers = [
[project.urls]
"Homepage" = "https://docs.u-boot-project.org/en/latest/build/buildman.html"
-"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues"
+"Bug Tracker" = "https://git.u-boot-project.org/groups/u-boot/-/issues"
[project.scripts]
buildman = "buildman.main:run_buildman"
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index a91a1060cc4..ebb679a5f46 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -358,11 +358,11 @@ USER uboot:uboot
# Populate the cache for pip to use. Get these via wget as the
# COPY / ADD directives don't work as we need them to.
-RUN wget -O /tmp/pytest-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/test/py/requirements.txt
-RUN wget -O /tmp/sphinx-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/doc/sphinx/requirements.txt
-RUN wget -O /tmp/binman-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/tools/binman/requirements.txt
-RUN wget -O /tmp/buildman-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/tools/buildman/requirements.txt
-RUN wget -O /tmp/u_boot_pylib-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/tools/u_boot_pylib/requirements.txt
+RUN wget -O /tmp/pytest-requirements.txt https://git.u-boot-project.org/u-boot/u-boot/-/raw/master/test/py/requirements.txt
+RUN wget -O /tmp/sphinx-requirements.txt https://git.u-boot-project.org/u-boot/u-boot/-/raw/master/doc/sphinx/requirements.txt
+RUN wget -O /tmp/binman-requirements.txt https://git.u-boot-project.org/u-boot/u-boot/-/raw/master/tools/binman/requirements.txt
+RUN wget -O /tmp/buildman-requirements.txt https://git.u-boot-project.org/u-boot/u-boot/-/raw/master/tools/buildman/requirements.txt
+RUN wget -O /tmp/u_boot_pylib-requirements.txt https://git.u-boot-project.org/u-boot/u-boot/-/raw/master/tools/u_boot_pylib/requirements.txt
RUN python3 -m venv /tmp/venv && \
. /tmp/venv/bin/activate && \
pip install -r /tmp/pytest-requirements.txt \
diff --git a/tools/dtoc/pyproject.toml b/tools/dtoc/pyproject.toml
index 53b09dba885..895bdc9b763 100644
--- a/tools/dtoc/pyproject.toml
+++ b/tools/dtoc/pyproject.toml
@@ -20,7 +20,7 @@ classifiers = [
[project.urls]
"Homepage" = "https://docs.u-boot-project.org/en/latest/develop/driver-model/of-plat.html"
-"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues"
+"Bug Tracker" = "https://git.u-boot-project.org/groups/u-boot/-/issues"
[project.scripts]
dtoc = "dtoc.main:run_dtoc"
diff --git a/tools/fit_image.c b/tools/fit_image.c
index 5831b07c090..7e59bc43b77 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -898,8 +898,6 @@ err:
static int fit_import_data(struct image_tool_params *params, const char *fname)
{
void *fdt, *old_fdt;
- void *data = NULL;
- const char *ext_data_prop = NULL;
int fit_size, new_size, size, data_base;
int fd;
struct stat sbuf;
@@ -941,6 +939,8 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
for (node = fdt_first_subnode(fdt, images);
node >= 0;
node = fdt_next_subnode(fdt, node)) {
+ const char *ext_data_prop = NULL;
+ void *data = NULL;
int buf_ptr;
int len;
diff --git a/tools/image-host.c b/tools/image-host.c
index 8f1e7be4066..16a5ad6c22d 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -1184,6 +1184,41 @@ static const char *fit_config_get_image_list(const void *fit, int noffset,
}
/**
+ * fit_config_add_node() - Add a node's path to a list of nodes to hash
+ *
+ * @fit: Pointer to the FIT format image header
+ * @noffset: Offset of the node whose path should be added
+ * @node_inc: List of nodes to add to
+ * @conf_name Configuration-node name, child of /configurations node (only
+ * used for error messages)
+ * @sig_name Signature-node name (only used for error messages)
+ * @iname: Name of image being processed (e.g. "kernel-1" (only used
+ * for error messages)
+ */
+static int fit_config_add_node(const void *fit, int noffset,
+ struct strlist *node_inc, const char *conf_name,
+ const char *sig_name, const char *iname)
+{
+ char path[200];
+ int ret;
+
+ ret = fdt_get_path(fit, noffset, path, sizeof(path));
+ if (ret < 0) {
+ fprintf(stderr,
+ "Failed to get path for image '%s' in configuration '%s/%s': %s\n",
+ iname, conf_name, sig_name, fdt_strerror(ret));
+ return -ENOENT;
+ }
+ if (strlist_add(node_inc, path)) {
+ fprintf(stderr, "Out of memory processing configuration '%s/%s'\n",
+ conf_name, sig_name);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/**
* fit_config_add_hash() - Add a list of nodes to hash for an image
*
* This adds a list of paths to image nodes (as referred to by a particular
@@ -1202,16 +1237,14 @@ static int fit_config_add_hash(const void *fit, int image_noffset,
struct strlist *node_inc, const char *conf_name,
const char *sig_name, const char *iname)
{
- char path[200];
int noffset;
int hash_count;
int ret;
- ret = fdt_get_path(fit, image_noffset, path, sizeof(path));
- if (ret < 0)
- goto err_path;
- if (strlist_add(node_inc, path))
- goto err_mem;
+ ret = fit_config_add_node(fit, image_noffset, node_inc, conf_name,
+ sig_name, iname);
+ if (ret)
+ return ret;
/* Add all this image's hashes */
hash_count = 0;
@@ -1223,11 +1256,10 @@ static int fit_config_add_hash(const void *fit, int image_noffset,
if (strncmp(name, FIT_HASH_NODENAME,
strlen(FIT_HASH_NODENAME)))
continue;
- ret = fdt_get_path(fit, noffset, path, sizeof(path));
- if (ret < 0)
- goto err_path;
- if (strlist_add(node_inc, path))
- goto err_mem;
+ ret = fit_config_add_node(fit, noffset, node_inc, conf_name,
+ sig_name, iname);
+ if (ret)
+ return ret;
hash_count++;
}
@@ -1249,24 +1281,34 @@ static int fit_config_add_hash(const void *fit, int image_noffset,
fdt_strerror(noffset));
return -EIO;
}
- ret = fdt_get_path(fit, noffset, path, sizeof(path));
- if (ret < 0)
- goto err_path;
- if (strlist_add(node_inc, path))
- goto err_mem;
+ ret = fit_config_add_node(fit, noffset, node_inc, conf_name,
+ sig_name, iname);
+ if (ret)
+ return ret;
}
- return 0;
-
-err_mem:
- fprintf(stderr, "Out of memory processing configuration '%s/%s'\n", conf_name,
- sig_name);
- return -ENOMEM;
+ /*
+ * Add this image's dm-verity node if present. Its roothash is the
+ * only integrity anchor for a dm-verity filesystem image, so it must
+ * be covered by the configuration signature.
+ */
+ noffset = fdt_subnode_offset(fit, image_noffset,
+ FIT_VERITY_NODENAME);
+ if (noffset != -FDT_ERR_NOTFOUND) {
+ if (noffset < 0) {
+ fprintf(stderr,
+ "Failed to get dm-verity node in configuration '%s/%s' image '%s': %s\n",
+ conf_name, sig_name, iname,
+ fdt_strerror(noffset));
+ return -EIO;
+ }
+ ret = fit_config_add_node(fit, noffset, node_inc, conf_name,
+ sig_name, iname);
+ if (ret)
+ return ret;
+ }
-err_path:
- fprintf(stderr, "Failed to get path for image '%s' in configuration '%s/%s': %s\n",
- iname, conf_name, sig_name, fdt_strerror(ret));
- return -ENOENT;
+ return 0;
}
/**
diff --git a/tools/patman/settings.py b/tools/patman/settings.py
index 17229e0d823..fe65b1d3fb7 100644
--- a/tools/patman/settings.py
+++ b/tools/patman/settings.py
@@ -162,7 +162,7 @@ class _ProjectConfigParser(ConfigParser.ConfigParser):
def ReadGitAliases(fname):
"""Read a git alias file. This is in the form used by git:
- alias uboot [email protected]
+ alias uboot [email protected]
alias wd Wolfgang Denk <[email protected]>
Args:
diff --git a/tools/u_boot_pylib/gitutil.py b/tools/u_boot_pylib/gitutil.py
index 34b4dbb4839..59688aa7147 100644
--- a/tools/u_boot_pylib/gitutil.py
+++ b/tools/u_boot_pylib/gitutil.py
@@ -528,7 +528,7 @@ send --cc-cmd cc-fname" cover p1 p2'
"Please add something like this to a commit\n"
"Series-to: Fred Bloggs <[email protected]>\n"
"Or do something like this\n"
- "git config sendemail.to [email protected]")
+ "git config sendemail.to [email protected]")
return None
cc = build_email_list(list(set(series.get('cc')) - set(series.get('to'))),
alias, '--cc', warn_on_error)
diff --git a/tools/u_boot_pylib/pyproject.toml b/tools/u_boot_pylib/pyproject.toml
index 1c6a023ee4b..300d14441c8 100644
--- a/tools/u_boot_pylib/pyproject.toml
+++ b/tools/u_boot_pylib/pyproject.toml
@@ -19,7 +19,7 @@ classifiers = [
[project.urls]
"Homepage" = "https://docs.u-boot-project.org"
-"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues"
+"Bug Tracker" = "https://git.u-boot-project.org/groups/u-boot/-/issues"
[tool.setuptools]
packages = ["u_boot_pylib"]