The iminfo command already verifies hashes of images. This change
also verifies signatures of configurations if enabled.
If FIT_REQUIRE_CONFIG_SIGS is enabled, iminfo also fails if
signatures are missing.

While at it print "OK\n" in success case of fit_all_image_verify()
too so iminfo output matches bootm. This will simplify the tests.

Adjusts error output slightly to be on stderr

Signed-off-by: Ludwig Nussel <[email protected]>

---

Changes in v5:
- rely on inline dummy for fit_all_configurations_verify
- use CONFIG_IS_ENABLED(FIT_SIGNATURE) to guard fit_all_configurations_verify
- print warning if /configurations node is missing
- print "OK\n" in fit_all_image_verify()

Changes in v4:
- fix documentation to use kdoc style

Changes in v3:
- use log_err instead of printf in fit_config_verify_required_keys()
- don't make iminfo fail unless FIT_SIGNATURE_REQUIRED is set
- update fit_all_configurations_verify documentation
- stub fit_all_configurations_verify unless FIT_SIGNATURES

Changes in v2:
- document fit_all_configurations_verify()

 boot/image-fit.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-
 cmd/bootm.c      |  8 +++++++
 include/image.h  |  8 +++++++
 3 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/boot/image-fit.c b/boot/image-fit.c
index b0fcaf6e17f..7b5c51fab73 100644
--- a/boot/image-fit.c
+++ b/boot/image-fit.c
@@ -1506,12 +1506,65 @@ int fit_all_image_verify(const void *fit)
 
                        if (!fit_image_verify(fit, noffset))
                                return 0;
-                       printf("\n");
+                       printf("OK\n");
                }
        }
        return 1;
 }
 
+/**
+ * fit_all_configurations_verify() - verify signatures of all configurations
+ * @fit: pointer to the FIT format image header
+ *
+ * fit_all_configurations_verify() iterates over all configurations
+ * in the FIT and checks the signatures. Returns success if all
+ * configurations have valid signatures. See documentation at
+ * fit_config_verify_required_keys() or fit_config_verify_key().
+ *
+ * Return:
+ * * 0, all configurations have valid signatures
+ * * -ENOENT, no configurations found
+ * * < 0, -errno
+ */
+#if CONFIG_IS_ENABLED(FIT_SIGNATURE)
+int fit_all_configurations_verify(const void *fit)
+{
+       int confs_noffset;
+       int noffset;
+       int r = -ENOENT;
+
+       /* Find configurations parent node offset */
+       confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
+       if (confs_noffset < 0) {
+               log_info("Missing '%s' node: %s\n",
+                        FIT_CONFS_PATH, fdt_strerror(confs_noffset));
+               return r;
+       }
+
+       /* Process all config subnodes, check signature for each */
+       log_info("## Checking configuration signatures ...\n");
+
+       fdt_for_each_subnode(noffset, fit, confs_noffset) {
+               int ret;
+
+               log_info("   %s ... ", fit_get_name(fit, noffset, NULL));
+               ret = fit_config_verify(fit, noffset);
+               if (ret) {
+                       r = ret;
+                       log_err("FAIL\n");
+                       continue;
+               }
+               /* valid config found */
+               if (r == -ENOENT)
+                       r = 0;
+
+               log_info("OK\n");
+       }
+
+       return r;
+}
+#endif
+
 static int fit_image_uncipher(const void *fit, int image_noffset,
                              void **data, size_t *size)
 {
diff --git a/cmd/bootm.c b/cmd/bootm.c
index ca7cec91fad..ea12639d288 100644
--- a/cmd/bootm.c
+++ b/cmd/bootm.c
@@ -329,6 +329,14 @@ static int image_info(ulong addr)
 
                fit_print_contents(hdr);
 
+               int ret = fit_all_configurations_verify(hdr);
+
+               if (ret != 0 && (ret != -ENOENT ||
+                                CONFIG_IS_ENABLED(FIT_REQUIRE_CONFIG_SIGS))) {
+                       unmap_sysmem(hdr);
+                       return 1;
+               }
+
                if (!fit_all_image_verify(hdr)) {
                        puts("Bad hash in FIT image!\n");
                        unmap_sysmem(hdr);
diff --git a/include/image.h b/include/image.h
index 34efac6056d..841b6fb77cf 100644
--- a/include/image.h
+++ b/include/image.h
@@ -1355,6 +1355,14 @@ static inline int fit_config_verify(const void *fit, int 
conf_noffset)
 }
 #endif
 int fit_all_image_verify(const void *fit);
+#if CONFIG_IS_ENABLED(FIT_SIGNATURE)
+int fit_all_configurations_verify(const void *fit);
+#else
+static inline int fit_all_configurations_verify(const void *fit)
+{
+       return 0;
+}
+#endif
 int fit_config_decrypt(const void *fit, int conf_noffset);
 int fit_image_check_os(const void *fit, int noffset, uint8_t os);
 int fit_image_check_arch(const void *fit, int noffset, uint8_t arch);
-- 
2.43.0

Reply via email to