On Sun, Jul 12, 2026 at 01:33:46AM +0100, Daniel Golle wrote: > 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. > > - 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() and expose it > only when unit tests are built (VISIBLE_IF_UT), keeping it static in > normal builds. > > Signed-off-by: Daniel Golle <[email protected]> > --- > boot/image-fit-sig.c | 25 +++- > include/image.h | 25 ++++ > test/boot/fit_verity.c | 194 ++++++++++++++++++++++++++ > test/py/tests/test_fit_verity_sign.py | 162 +++++++++++++++++++++ > 4 files changed, 399 insertions(+), 7 deletions(-) > create mode 100644 test/py/tests/test_fit_verity_sign.py > > diff --git a/boot/image-fit-sig.c b/boot/image-fit-sig.c > index c2f09885492..1181fefb55f 100644 > --- a/boot/image-fit-sig.c > +++ b/boot/image-fit-sig.c > @@ -340,8 +340,19 @@ static int fit_config_add_hash(const void *fit, int > image_noffset, > return 0; > } > > +/* > + * fit_config_get_signed_nodes() is internal, but the fit_verity unit test > + * needs to build the same signed-region node list. Make it visible when unit > + * tests are built and keep it static otherwise. > + */ > +#if CONFIG_IS_ENABLED(UNIT_TEST) > +#define VISIBLE_IF_UT > +#else > +#define VISIBLE_IF_UT static > +#endif
I don't like this kind of "game", and I think it's why we generally just don't mark functions as static that could be, if not for UNIT_TEST. Finding a more general way to handle this would be good and an unrelated clean-up (after verifying that for example, marking a ton of stuff as now static results in a more compact binary or provides some obvious gain). My other comment would be that we should be doing like doc/develop/pytest//test_fit.rst for example and making sure we have good and usable generated documentation (so using pydoc comments, not "#" style). And FYI that usually means building and viewing the docs locally, not just making sure CI passes, it can be tricky I've found to get examples annotated correctly to render usefully. -- Tom
signature.asc
Description: PGP signature

