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

Reply via email to