fit_image_verify_required_sigs() and fit_config_verify_required_keys()
both look up the "/signature" node of the U-Boot control devicetree, and
both return 0 when it is absent. There are then no keys marked
'required', so nothing downstream can fail the image: a FIT whose
signatures are absent, malformed or invalid verifies successfully. The
only indication is a debug() call, which is compiled out of a normal
build.
In the configuration path reqd_sigs also stays at 0, so the closing
"if (reqd_sigs && !verified)" check never fires either.
On sandbox, 'iminfo' against a FIT with no keys at all in the control
devicetree reports verification success:
## Checking hash(es) for FIT Image at 10400100 ...
Hash(es) for Image 0 (kernel): sha256+
Hash(es) for Image 1 (fdt-1): sha256+
Add FIT_REQUIRE_CONFIG_SIGS, which turns a missing "/signature" node,
and a "/signature" node holding no required keys, into a verification
failure on both gates.
The new console message is printed only when the option is enabled.
Boards which enable FIT_SIGNATURE for image hash integrity alone, and
which legitimately have no "/signature" node, keep both their existing
behaviour and a quiet console.
The option defaults to n. Enabling it changes behaviour for existing
configurations: with CONFIG_FIT_REQUIRE_CONFIG_SIGS=y, 13 of the 32
sandbox test_vboot cases fail, because test_vboot's first step boots an
unsigned-images FIT against a key-less devicetree and expects that to
succeed. Making it default y would require test_vboot to be
restructured first.
Signed-off-by: Eva Crystal <[email protected]>
---
boot/Kconfig | 27 +++++++++++++++++++++++++++
boot/image-fit-sig.c | 15 +++++++++++++++
2 files changed, 42 insertions(+)
diff --git a/boot/Kconfig b/boot/Kconfig
index c67dc0ba49..c1dd1de6ed 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -137,6 +137,25 @@ config FIT_SIGNATURE
format support in this case, enable it using
CONFIG_LEGACY_IMAGE_FORMAT.
+config FIT_REQUIRE_CONFIG_SIGS
+ bool "Fail verification when the control FDT has no /signature node"
+ depends on FIT_SIGNATURE
+ help
+ Without this option both required-signature gates return success
+ when the U-Boot control devicetree contains no "/signature" node.
+ Verified boot is then silently disabled: a FIT image whose
+ signatures are absent, malformed or invalid verifies successfully
+ and the only indication is a debug() message, which is compiled
+ out of a normal build.
+
+ Enable this option to treat a missing "/signature" node, and a
+ "/signature" node which holds no keys marked required="conf", as a
+ verification failure instead.
+
+ Say N if the same U-Boot binary must also run in setups which carry
+ no keys, or which enable FIT_SIGNATURE only for image hash
+ integrity checking rather than for signature enforcement.
+
config FIT_SIGNATURE_MAX_SIZE
hex "Max size of signed FIT structures"
depends on FIT_SIGNATURE
@@ -259,6 +278,14 @@ config SPL_FIT_SIGNATURE_MAX_SIZE
device memory. Assure this size does not extend past expected storage
space.
+config SPL_FIT_REQUIRE_CONFIG_SIGS
+ bool "Fail verification when the SPL control FDT has no /signature node"
+ depends on SPL_FIT_SIGNATURE
+ select FIT_REQUIRE_CONFIG_SIGS
+ help
+ Enable the FIT_REQUIRE_CONFIG_SIGS behaviour in SPL. See the help text
+ of FIT_REQUIRE_CONFIG_SIGS for details.
+
config SPL_LOAD_FIT
bool "Enable SPL loading U-Boot as a FIT (basic fitImage features)"
depends on SPL
diff --git a/boot/image-fit-sig.c b/boot/image-fit-sig.c
index a0c50bba4c..06ec0f39d8 100644
--- a/boot/image-fit-sig.c
+++ b/boot/image-fit-sig.c
@@ -201,6 +201,11 @@ int fit_image_verify_required_sigs(const void *fit, int
image_noffset,
*no_sigsp = 1;
key_node = fdt_subnode_offset(key_blob, 0, FIT_SIG_NODENAME);
if (key_node < 0) {
+ if (CONFIG_IS_ENABLED(FIT_REQUIRE_CONFIG_SIGS)) {
+ printf("No signature node in control FDT: %s\n",
+ fdt_strerror(key_node));
+ return -ENOENT;
+ }
debug("%s: No signature node found: %s\n", __func__,
fdt_strerror(key_node));
return 0;
@@ -684,6 +689,11 @@ static int fit_config_verify_required_keys(const void
*fit, int conf_noffset,
/* Work out what we need to verify */
key_node = fdt_subnode_offset(key_blob, 0, FIT_SIG_NODENAME);
if (key_node < 0) {
+ if (CONFIG_IS_ENABLED(FIT_REQUIRE_CONFIG_SIGS)) {
+ printf("No signature node in control FDT: %s\n",
+ fdt_strerror(key_node));
+ return -ENOENT;
+ }
debug("%s: No signature node found: %s\n", __func__,
fdt_strerror(key_node));
return 0;
@@ -735,6 +745,11 @@ static int fit_config_verify_required_keys(const void
*fit, int conf_noffset,
return -EPERM;
}
+ if (!reqd_sigs && CONFIG_IS_ENABLED(FIT_REQUIRE_CONFIG_SIGS)) {
+ printf("No required keys found for configuration
verification\n");
+ return -EPERM;
+ }
+
return 0;
}
--
2.53.0