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.
Daniel Golle (3):
boot: fit: factor out node-path collection in fit_config_add_hash()
boot: fit: cover the dm-verity roothash with the config signature
test: fit: verify dm-verity roothash is covered by the config
signature
boot/image-fit-sig.c | 119 ++++++++++------
include/image.h | 25 ++++
test/boot/fit_verity.c | 194 ++++++++++++++++++++++++++
test/py/tests/test_fit_verity_sign.py | 162 +++++++++++++++++++++
tools/image-host.c | 22 +++
5 files changed, 483 insertions(+), 39 deletions(-)
create mode 100644 test/py/tests/test_fit_verity_sign.py
base-commit: 6741b0dfb41dc82a284ab1cff4c58af6ef2f3f9c
--
2.55.0