Daniel Golle <daniel@makrotopia.org> says:
A signed FIT configuration can delegate the integrity of a (potentially
large) root filesystem image to the kernel's dm-verity instead of having
U-Boot hash the whole payload at boot: the FIT carries a "dm-verity"
subnode with the roothash, salt and block parameters, U-Boot passes the
roothash to Linux through the dm-mod.create bootargs, and dm-verity then
validates the filesystem block by block against it.
For that to be safe the roothash has to be trusted, and in a signed
configuration the only thing that establishes trust is the configuration
signature. The roothash was not covered by it. fit_config_add_hash()
collected the image node, its hash subnodes and its cipher subnode into
the signed region, but not the dm-verity subnode, so the roothash, the
sole integrity anchor for the filesystem, was left unsigned.
The result is a verified-boot bypass for the root filesystem: an
attacker who can rewrite the boot medium can replace the filesystem,
recompute a matching dm-verity tree, write the new roothash into the
unsigned dm-verity subnode, and the configuration signature still
verifies. dm-verity then faithfully validates the malicious filesystem
against the attacker's roothash.
This series closes the gap.
Link: https://lore.kernel.org/r/cover.1785276461.git.daniel@makrotopia.org
A dm-verity protected filesystem image is not hashed by U-Boot; its
integrity is delegated to the kernel, which trusts the roothash taken
from the FIT dm-verity subnode. For that chain of trust to hold, the
roothash (and salt) must be part of the region covered by the
configuration signature, otherwise an attacker can replace both the
filesystem and the roothash while keeping the signature valid.
Add two independent checks of this property:
- test/py/tests/test_fit_verity_sign.py signs a configuration that
references a filesystem image carrying a dm-verity subnode, then
confirms that tampering the roothash or the salt is rejected by
fit_check_sign. A control that tampers a byte known to be signed
proves the check can fail. A matching page is added under
doc/develop/pytest/ so the module documentation is rendered with
the rest of the generated docs.
- test/boot/fit_verity.c gains a runtime unit test that builds the
exact node list the configuration signature is computed over,
turns it into hashed regions and checks both that the roothash
bytes fall inside a signed region and that tampering them changes
the hash. It needs no private key, so it also runs on real devices
and uses the same hash path a device would.
To let the unit test build the signed-region node list, rename the
config node-list helper to fit_config_get_signed_nodes(), make it
non-static and declare it in image.h.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
A dm-verity protected filesystem image is not hashed by U-Boot when it
is loaded; its integrity is delegated to the kernel, which validates the
filesystem on the fly against the roothash taken from the FIT dm-verity
subnode. The roothash is therefore the sole integrity anchor for the
filesystem, yet fit_config_add_hash() only adds the image node, its
hash subnodes and its cipher subnode to the signed region, leaving the
dm-verity subnode (roothash, salt and block parameters) unsigned.
An attacker able to rewrite the boot medium could then replace both the
filesystem and the roothash, recompute a matching dm-verity tree and
keep the configuration signature valid, defeating verified boot for the
root filesystem.
Add the dm-verity subnode to the list of nodes covered by the
configuration signature, both when signing (tools/image-host.c) and when
verifying (boot/image-fit-sig.c), so the roothash and salt are
authenticated together with the rest of the configuration.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Both the boot-side and host-side fit_config_add_hash() repeat the same
sequence to append a node's path to the hashed-node list three times:
for the image node, for each hash subnode and for the cipher subnode.
Extract it into a helper, fit_config_add_node(), in each file, with no
functional change.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
MediaTek platforms may need the MTU3 controller before U-Boot proper is
available, but the driver is currently selected and built only with the
main U-Boot configuration symbols.
Add an explicit SPL controller option with host and gadget modes. Make
the driver build and its role checks phase-aware so each phase can select
the MTU3 role it needs without coupling it to the U-Boot proper controller
configuration.
The upstream binding locates the xHCI child registers through the parent
ranges property. Select SPL_OF_TRANSLATE for host mode so SPL can resolve
that address before mapping it.
Signed-off-by: Julien Masson <jmasson@baylibre.com>
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
Reviewed-by: Marek Vasut <marek.vasut+usb@mailbox.org>
The MTU3 glue driver expects a synthetic mediatek,ssusb child that
combines the device and xHCI register windows. Upstream devicetrees
instead put the device resources on the controller node and describe the
xHCI window with a standard child node, so U-Boot cannot use an upstream
topology.
Switch to the upstream layout. The controller owns the shared resources
and the device MAC, with the device register offsets relative to it as in
Linux. The gadget role binds as a node-less internal device, while the
host role binds to an enabled xHCI child and uses its own clocks,
supplies and register window. dr_mode selects the role and defaults to
otg, and the Kconfig choice constrains which role the build provides.
The legacy child layout is rejected explicitly so its combined register
window cannot be mistaken for the device MAC.
Convert the in-tree MT8183 and MT8512 devicetrees in the same commit so
neither platform is left without USB. MT8512 stays peripheral-only
because its xHCI host interrupt is not documented and the
mediatek,mtk-xhci binding requires it.
Reviewed-by: Marek Vasut <marek.vasut+usb@mailbox.org>
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
The MediaTek MTU3 and xHCI text bindings describe legacy U-Boot layouts
which have been superseded by the canonical Linux schemas. Those schemas
are already synchronized into `dts/upstream/Bindings/usb`.
Remove the duplicate text bindings so new devicetrees and driver changes
use the maintained YAML definitions.
Reviewed-by: Marek Vasut <marek.vasut+usb@mailbox.org>
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This includes temporary U-Boot DT ECC carveouts for R-Car Gen5, they
will be dropped from U-Boot DTs once OF_UPSTREAM DTs get re-synced.
This also includes RPC-IF support for R-Car Gen5 and env storage in RPC
HF.
This also includes an update for R-Car Gen5 UFS controller driver.
The DBSC5 DRAM controller protects DRAM content using inline ECC.
The inline ECC utilizes areas of DRAM for its operation, which are
in the DRAM address range, but must not be accessed or modified.
Describe the inline ECC carveout areas used by the DBSC5 controller
on this hardware as reserved-memory, which must not be accessed.
Include DRAM areas which are unprotected by ECC as well, those are
parts of the DRAM which directly precede the ECC carveout.
In case of high DRAM utilization, unless the inline ECC carveouts
are properly reserved, Linux may use and corrupt the memory used
by the DBSC5 DRAM controller for inline ECC, which would lead to
the system becoming unstable.
Ported from Linux 7.2-rc5 commit
6fa6ee724d8d ("arm64: dts: renesas: ironhide: Describe inline ECC carveouts")
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Fully describe all available DRAM in the DT, and describe regions which
are not accessible because they are used by firmware in reserved-memory
nodes.
Replace the first memory bank memory@60600000 with memory@40000000 and a
518 MiB long reserved-memory no-map subnode. This memory region is used
by other cores in the system.
Reserve 32 kiB of memory at 0x8c100000 for parameters shared by IPL,
SCP, TFA BL31 and TEE.
Reserve 512 kiB of memory at 0x8c200000 for TFA BL31. The upcoming
upstream TFA 2.15 BL31 uses memory from 0x8c200000..0x8c242fff; rounding
up to 512 kiB is slight future-proofing.
Reserve 32 MiB of memory at 0x8c400000 for OPTEE-OS, which is the entire
OPTEE-OS TZ protected DRAM area.
Neither TFA BL31 nor OPTEE-OS modify the DT passed to Linux in any way
with any new reserved-memory {} nodes to reserve memory areas used by
the TFA BL31 or OPTEE-OS to prevent the next stage from using those
areas, which lets Linux use all of the available DRAM as it is described
in the DT that was passed in by U-Boot, including the areas that are
newly utilized by TFA BL31 or OPTEE-OS.
In case of high DRAM utilization, unless the memory used by TFA BL31 or
OPTEE-OS is properly reserved, Linux may use and corrupt the memory used
by TFA BL31 or OPTEE-OS, which would lead to the system becoming
unresponsive.
Ported from Linux 7.2-rc5 commit
5250b3b1ad99 ("arm64: dts: renesas: ironhide: Describe all reserved memory")
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Store U-Boot environment in the last sector of HyperFlash on
R-Car R8A78000 X5H Cortex-M33 RSIP port. This allows the RSIP
port to have persistent environment, which is very useful for
development.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Enable RPC and HyperFlash support on R-Car R8A78000 X5H Cortex-M33 RSIP.
RPC is used both to update the HF content, which includes the U-Boot on
RSIP itself and SCP firmware, as well as access the U-Boot environment
for U-Boot on RSIP.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Bind RPC and HyperFlash in DT on R-Car R8A78000 X5H Cortex-M33 RSIP.
RPC is used both to update the HF content, which includes the U-Boot on
RSIP itself and SCP firmware, as well as access the U-Boot environment
for U-Boot on RSIP.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Disable MMC support on R-Car R8A78000 X5H Cortex-M33 RSIP port.
The MMC is never used by the RSIP core, disable the support.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Add device tree compatible string "renesas,rcar-gen5-rpc-if" to
the driver to match on upstream RPC DT node in R-Car Gen5 DTs.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Remove the IF from RPCIF to align the register macros with each other.
No functional change.
Fixes: d516246324 ("mtd: spi: renesas: Configure RPC PHY timing registers")
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Add device tree compatible string "renesas,rcar-gen5-rpc-if" to
the driver to match on upstream RPC DT node in R-Car Gen5 DTs.
Adjust Kconfig to allow driver enablement on all 64bit R-Car.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Simplify the DT register address parsing using dev_read_addr_name(),
switch away from raw fdt_*() functions. No functional change.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
CI: https://git.u-boot-project.org/u-boot/custodians/u-boot-imx/-/pipelines/906
- Fix a boot regression on i.MX7 related to the system counter.
- Add Aquila iMX95 0243 PID4.
- Update phycore_imx8mm DDR timings.
- Add FRDM-IMX95 initial support.
- Handle FCFB header during SPI NOR boot and CST backend selection.
With commit 623f6c5b6a ("boot: image-fdt: free old dtb reservations")
we now get:
ERROR: freeing fdt memory region failed (addr=3ef667e0 size=36 flags=2): -1
ERROR: freeing fdt memory region failed (addr=3ef663a0 size=400 flags=2): -1
on console when booting, which is non-fatal but leads to the test
failing. Disable this test for now.
Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Signed-off-by: Tom Rini <trini@konsulko.com>
* Clock fix for MT8188 (Genio 700/520)
* SPL support preparatory patch for MT8188.
* Compile error fix for when enabling LWIP network stack on some MediaTek targets.
* Fix a regression in clock driver binding from the previous PR.
* Add display-related clocks on MT8188.
* Another wave of clock driver refactoring and de-duplication.
In case the image that is wrapped in the nxp_imx8mcst already contains
an FCFB header which is mandatory for SPI NOR boot, then the IVT is at
offset 0x1000 instead of offset 0x0, but the whole image including the
FCFB header must be signed to prevent attacker from tampering with any
of the headers. Add the FCFB handling.
Signed-off-by: Marek Vasut <marex@nabladev.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Add boot support and peripherals like eMMC/SD, UART, I2C, GPIO, ENETC0/1
and PCIE0/1 for iMX95 15x15 FRDM.
Updated doc for build instructions.
Signed-off-by: Lei Xu <lei.xu@nxp.com>
Signed-off-by: Joseph Guo <qijian.guo@nxp.com>
MT8188 reset_cpu() checks the U-Boot proper PSCI symbol even when the
function is built for SPL. A standalone SPL download agent runs before
BL31, so fastboot acknowledges a reboot request and then stalls while
attempting an unavailable PSCI system reset.
Use the phase-aware configuration check so SPL falls back to the
watchdog reset provider. U-Boot proper continues to use PSCI as before.
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
Reviewed-by: Julien Stephan <jstephan@baylibre.com>
Link: https://patch.msgid.link/20260724-ccaione-upstream-mt8188-spl-reset-v1-1-08da6554ecd8@baylibre.com
Signed-off-by: David Lechner <dlechner@baylibre.com>
Add U-Boot support for Milk-V Duo 256M.
This board has a different SoC compared to the Milk-V Duo 64M, it uses
the Sophgo SG2002 instead of the Sophgo CV1800B. Both SoCs share many
common IP blocks, so this board reuses the existing cv1800b CPU support.
The board shares the same 'board.c' with Milk-V Duo 64MB (CV1800B), so
use the same file for now.
Link: https://milkv.io/docs/duo/getting-started/duo256m
Signed-off-by: Hiago De Franco <hfranco@baylibre.com>
Acked-by: Leo Yu-Chi Liang <leo.liang@sifive.com>
This will make easier for future boards to reuse the same driver (e.g.
Milk-V Duo 256MB).
Signed-off-by: Hiago De Franco <hfranco@baylibre.com>
Acked-by: Leo Yu-Chi Liang <leo.liang@sifive.com>
The MPFS mailbox driver currently checks the BUSY bit at the start of
mpfs_mbox_send() and immediately returns -EBUSY if the controller is
busy.
On MPFS, BUSY may be transiently asserted during early boot even though
no other U-Boot service is actively executing. In Linux, returning
-EBUSY here is retryable via the mailbox framework and scheduler, but in
U-Boot this results in a hard failure.
Replace the immediate BUSY check with a bounded wait using
regmap_read_poll_timeout(), waiting for the controller to become idle
before issuing a new request. This preserves the intent of the BUSY
check while avoiding spurious early-boot failures in U-Boot’s
synchronous, polled execution model.
The timeout is conservative and based on observed MPFS behaviour, where
BUSY clears within a few milliseconds.
Signed-off-by: Jamie Gibbons <jamie.gibbons@microchip.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
The MPFS mailbox driver used unbounded polling loops and treated the
BUSY bit as a fatal condition in several paths. On MPFS, BUSY may be
transiently reasserted even after response data is written, which is
observable in U-Boot’s synchronous, polled execution model.
Replace the unbounded loops with a bounded
regmap_read_poll_timeout()-based helper that waits for the controller to
become idle.
This preserves existing behaviour while preventing infinite stalls
and avoiding spurious failures during early boot.
Signed-off-by: Jamie Gibbons <jamie.gibbons@microchip.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Enable the MPFS hardware RNG and associated infrastructure in
the Microchip PolarFire SoC generic defconfig.
Signed-off-by: Jamie Gibbons <jamie.gibbons@microchip.com>
Reviewed-by: Leo Yu-Chi Liang <leo.liang@sifive.com>
Add a U-Boot RNG driver for Microchip's PolarFire SoC (MPFS). The
hardware RNG is accessed indirectly via the MPFS system controller using
the mailbox interface.
The driver implements the UCLASS_RNG interface, requesting random data
from the system controller and returning it to the caller.
This allows use of the PolarFire SoC hardware RNG via the
standard 'rng' command and DM RNG API.
Signed-off-by: Jamie Gibbons <jamie.gibbons@microchip.com>
Reviewed-by: Leo Yu-Chi Liang <leo.liang@sifive.com>
The MPFS RNG driver is not described by the device tree and is instead
registered dynamically by the system controller. Explicitly bind the
MPFS RNG driver as a child device during system controller probe.
This ensures the RNG device is instantiated and available via UCLASS_RNG
without requiring a device tree node.
Signed-off-by: Jamie Gibbons <jamie.gibbons@microchip.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
The MPFS system controller run_service() helper only submits the mailbox
request but does not read back the response data. However, the caller
must explicitly receive the response.
Add a public system controller helper to receive mailbox service
responses to populate the response buffer after issuing a system
controller request.
Without this, the drivers copy uninitialised stack data instead of
mailbox response data, resulting in deterministic output.
Signed-off-by: Jamie Gibbons <jamie.gibbons@microchip.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
The AST2700 reuses the AST2600 watchdog block unchanged. Bind the
driver to the aspeed,ast2700-wdt compatible and enable WDT_AST2600
on the AST2700.
Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
Reviewed-by: Stefan Roese <stefan.roese@mailbox.org>
It is possible that schedule(), and hence cyclic_run(), gets called
very early, perhaps even from assembly code. With
commit 9c1b13b3fd ("cyclic: reduce get_timer_us() calls inside
hlist_for_each_entry_safe()"), there is now an unconditional
get_timer_us(0) done outside the loop, and depending on the platform,
the timer infrastructure may not be set up yet. In at least one case,
that has caused a divide-by-0 and hence a failure to boot.
Platforms should really ensure their timers are ready ASAP, and in the
concrete case reported, that was indeed possible to fix that
way. However, it doesn't hurt to also insert an early return here, and
that could prevent other such hard-to-debug boot failures.
Reported-by: Emanuele Ghidoli <ghidoliemanuele@gmail.com>
Link: https://marc.info/?l=u-boot&m=178481834846283&w=2
Fixes: 9c1b13b3fd ("cyclic: reduce get_timer_us() calls inside hlist_for_each_entry_safe()")
Signed-off-by: Rasmus Villemoes <rv@rasmusvillemoes.dk>
Reviewed-by: Emanuele Ghidoli <emanuele.ghidoli@toradex.com>
Reviewed-by: Stefan Roese <stefan.roese@mailbox.org>
[sr: fix Fixes: tag SHA length and return statement indentation]
As the comment indicates, this was used to silence a warning without
having to add casts everywhere gd->cyclic_list was referenced. But
nowadays gd is not volatile qualified, so this helper is not needed
and only obfuscates the code somewhat, because the head of the list
being operated on with the hlist_ or list_ macros is usually not
obtained via a function call.
Remove the helper and refer to the list head using the idiomatic
&gd->cyclic_list.
Signed-off-by: Rasmus Villemoes <rv@rasmusvillemoes.dk>
Reviewed-by: Stefan Roese <stefan.roese@mailbox.org>
imx_gpcv2_init() calls udelay(), which through schedule() reaches
cyclic_run(). Since commit 9c1b13b3fd ("cyclic: reduce get_timer_us()
calls inside hlist_for_each_entry_safe()") get_timer_us() is called even
when no cyclic function is registered, so tick_to_time_us() divides by a
still zero CNTFRQ and __div0() hangs the board before the console is up.
The requested delay was a no-op as well, since us_to_tick() reads a CNTFRQ
of zero.
Initialize the system counter before imx_gpcv2_init(), and move the
"already initialized" guard from timer_get_boot_us() into timer_init() so
that the later timer_init() from the generic init sequence is a no-op.
Where the system counter timer_init() is not compiled in, the weak
definition is empty and the calling it is harmless.
Fixes: b059837850 ("imx: mx7: add gpc initialization for low power mode")
Fixes: 9c1b13b3fd ("cyclic: reduce get_timer_us() calls inside hlist_for_each_entry_safe()")
Signed-off-by: Emanuele Ghidoli <emanuele.ghidoli@toradex.com>
Reviewed-by: Stefan Roese <stefan.roese@mailbox.org>
Only print origin and errid fields when the corresponding valid bits
(MISC_BOOT_FLAG_ORG_VLD and MISC_BOOT_FLAG_ERR_VLD) are set. For a
normal power-on reset, these fields are not valid, and printing -1
is just noise.
Signed-off-by: Joseph Guo <qijian.guo@nxp.com>
Add support for setting the CST backend, both via DT property and
CST_BACKEND environment variable. The CST currently supports two
backends, 'ssl' and 'pkcs11', with 'ssl' being the default when
CST tool is invoked without any -b parameter. Keep 'ssl' backend
as the default, but explicitly pass it via the '-b' parameter,
unless the user selects 'pkcs11' via either method.
Signed-off-by: Marek Vasut <marex@nabladev.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
The Phytec Tauri L is sold with multiple memory configurations beyond the
base 2 GB variant. To support these alternative capacities seamlessly,
read the physical memory size directly from the EEPROM of the underlying
phyCORE module and apply the appropriate DDR timing parameters at runtime.
Alternatively, a fixed memory configuration can still be enforced via a
dedicated Kconfig option if dynamic detection is not desired.
Note that while U-Boot correctly discovers the full physical memory bank,
the device tree excludes the memory beyond 3 GB (below the 4 GB boundary).
This ensures that U-Boot allocations and early EFI staging buffers remain
safe from 32-bit interconnect DMA limitations inherent to some i.MX8MM
IP blocks.
Signed-off-by: INgo Rah <ingo.rah@linutronix.de>
Reviewed-by: Gregor Herburger <gregor.herburger@linutronix.de>
Reviewed-by: Benedikt Spranger <b.spranger@linutronix.de>
Reviewed-by: Yannic Moog <y.moog@phytec.de>
Tested-by: Yannic Moog <y.moog@phytec.de>