Target-side configuration verification builds the signed-region list from
every image-reference property in the selected configuration. Host-side
signing still uses either the signature node sign-images property or the
legacy kernel/fdt/script default list.

This lets mkimage generate configuration signatures which U-Boot cannot
verify when the configuration references other image types, such as
firmware, loadables or ramdisk entries. It also lets the host and target
disagree when sign-images names only a subset of the configuration images.

Build the host-side signing list from the configuration properties in the
same way as target-side verification. This makes signed configurations
cover the root node, the configuration node, every referenced image node,
and its hash/cipher subnodes, regardless of image type.

Update the signed-configuration documentation to describe the same rule and
to stop recommending sign-images as a selection mechanism.

Fixes: 2092322b31cc ("boot: Add fit_config_get_hash_list() to build signed node 
list")
Signed-off-by: James Hilliard <[email protected]>
---
 doc/board/ti/k3.rst                | 10 ++--
 doc/usage/fit/beaglebone_vboot.rst |  5 +-
 doc/usage/fit/sign-configs.rst     |  7 ++-
 doc/usage/fit/signature.rst        | 25 ++++-----
 doc/usage/fit/uefi.rst             |  2 -
 tools/fit_image.c                  | 12 ++---
 tools/image-host.c                 | 82 ++++++++++++------------------
 7 files changed, 63 insertions(+), 80 deletions(-)

diff --git a/doc/board/ti/k3.rst b/doc/board/ti/k3.rst
index 21973d53b15..cc1a7396c3a 100644
--- a/doc/board/ti/k3.rst
+++ b/doc/board/ti/k3.rst
@@ -546,7 +546,6 @@ corresponding configuration node as follows.
             signature-1 {
                     algo = "sha512,rsa4096";
                     key-name-hint = "custMpk";
-                    sign-images = "kernel", "fdt";
             };
     };
     # Optional configurations
@@ -557,14 +556,13 @@ corresponding configuration node as follows.
             signature-1 {
                     algo = "sha512,rsa4096";
                     key-name-hint = "custMpk";
-                    sign-images = "fdt";
             };
     };
 
-Specify all images you need the signature to authenticate as a part of
-sign-images. The key-name-hint needs to be changed if you are using some
-other key other than the TI dummy key that we are using for this example.
-It should be the name of the file containing the keys.
+Signed configurations authenticate all images referenced by the configuration
+node. The key-name-hint needs to be changed if you are using some other key
+other than the TI dummy key that we are using for this example. It should be
+the name of the file containing the keys.
 
 .. note::
 
diff --git a/doc/usage/fit/beaglebone_vboot.rst 
b/doc/usage/fit/beaglebone_vboot.rst
index b15399441ee..27e80f47eb2 100644
--- a/doc/usage/fit/beaglebone_vboot.rst
+++ b/doc/usage/fit/beaglebone_vboot.rst
@@ -169,7 +169,6 @@ Put this into a file in that directory called sign.its::
                 signature-1 {
                     algo = "sha256,rsa2048";
                     key-name-hint = "dev";
-                    sign-images = "fdt", "kernel";
                 };
             };
         };
@@ -178,7 +177,8 @@ Put this into a file in that directory called sign.its::
 
 The explanation for this is all in the documentation you have already read.
 But briefly it packages a kernel and device tree, and provides a single
-configuration to be signed with a key named 'dev'. The kernel is compressed
+configuration to be signed with a key named 'dev'. The configuration signature
+covers all images referenced by the configuration. The kernel is compressed
 with LZO to make it smaller.
 
 
@@ -407,7 +407,6 @@ First we can check which nodes are actually hashed by the 
configuration::
     value
     algo
     key-name-hint
-    sign-images
 
     $ fdtget image.fit /configurations/conf-1/signature-1 hashed-nodes
     / /configurations/conf-1 /images/fdt-1 /images/fdt-1/hash /images/kernel 
/images/kernel/hash-1
diff --git a/doc/usage/fit/sign-configs.rst b/doc/usage/fit/sign-configs.rst
index 6d98d44430c..51a97b1b99f 100644
--- a/doc/usage/fit/sign-configs.rst
+++ b/doc/usage/fit/sign-configs.rst
@@ -45,8 +45,13 @@ Signed configurations
                 signature {
                     algo = "sha256,rsa2048";
                     key-name-hint = "dev";
-                    sign-images = "fdt", "kernel";
                 };
             };
         };
     };
+
+For signed configurations, mkimage signs every image referenced by the
+configuration node, such as ``kernel``, ``fdt``, ``ramdisk``, ``firmware`` and
+``loadables`` entries. No ``sign-images`` property is required. Older FIT
+source files may still include ``sign-images``, but current mkimage and U-Boot
+verification do not use it to limit the signed image list.
diff --git a/doc/usage/fit/signature.rst b/doc/usage/fit/signature.rst
index da08cc75c3a..32d11a9d27a 100644
--- a/doc/usage/fit/signature.rst
+++ b/doc/usage/fit/signature.rst
@@ -341,25 +341,26 @@ So the above example is adjusted to look like this::
 
 You can see that we have added hashes for all images (since they are no
 longer signed), and a signature to each configuration. In the above example,
-mkimage will sign configurations/conf-1, the kernel and fdt that are
-pointed to by the configuration (/images/kernel-1, /images/kernel-1/hash-1,
-/images/fdt-1, /images/fdt-1/hash-1) and the root structure of the image
-(so that it isn't possible to add or remove root nodes). The signature is
-written into /configurations/conf-1/signature-1/value. It can easily be
-verified later even if the FIT has been signed with other keys in the
-meantime.
+mkimage will sign configurations/conf-1, every image referenced by that
+configuration (kernel, fdt, ramdisk, firmware, loadables, etc.) and the root
+structure of the image (so that it isn't possible to add or remove root
+nodes). The signature is written into
+/configurations/conf-1/signature-1/value. It can easily be verified later
+even if the FIT has been signed with other keys in the meantime.
 
 
 Details
 -------
 The signature node contains a property ('hashed-nodes') which lists all the
-nodes that the signature was made over.  The signer (mkimage) writes this
-property as a record of what was included in the hash.  During verification,
+nodes that the signature was made over. The signer (mkimage) writes this
+property as a record of what was included in the hash. During verification,
 however, U-Boot does not read 'hashed-nodes'. Instead it rebuilds the node
 list from the configuration's own image references (kernel, fdt, ramdisk,
-etc.), since 'hashed-nodes' is not itself covered by the signature. The
-rebuilt list always includes the root node, the configuration node, each
-referenced image node and its hash/cipher subnodes.
+firmware, loadables, etc.), since 'hashed-nodes' is not itself covered by the
+signature. The rebuilt list always includes the root node, the configuration
+node, each referenced image node and its hash/cipher subnodes. Current mkimage
+uses the same rule when signing configurations. The older 'sign-images'
+property is not required and is not used to limit the signed image list.
 
 The image is walked in order and each tag processed as follows:
 
diff --git a/doc/usage/fit/uefi.rst b/doc/usage/fit/uefi.rst
index 3bbacb5cad0..86422bec7b4 100644
--- a/doc/usage/fit/uefi.rst
+++ b/doc/usage/fit/uefi.rst
@@ -55,7 +55,6 @@ relies on the FDT provided by the board emulator.
                 signature-1 {
                     algo = "sha256,rsa2048";
                     key-name-hint = "dev";
-                    sign-images = "kernel", "fdt";
                 };
             };
 
@@ -65,7 +64,6 @@ relies on the FDT provided by the board emulator.
                 signature-1 {
                     algo = "sha256,rsa2048";
                     key-name-hint = "dev";
-                    sign-images = "kernel";
                 };
             };
         };
diff --git a/tools/fit_image.c b/tools/fit_image.c
index 5831b07c090..4153b54e550 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -60,13 +60,11 @@ static int fit_estimate_hash_sig_size(struct 
image_tool_params *params, const ch
         * FDT by fit_image_process_verity().
         *
         * One could try to be more precise in the estimates by
-        * looking at the "algo" property and, in the case of
-        * configuration signatures, the sign-images property. Also,
-        * when signing an already created FIT image, the hash nodes
-        * already have properly sized value properties, so one could
-        * also take pre-existence of "value" properties in hash nodes
-        * into account. But this rather simple approach should work
-        * well enough in practice.
+        * looking at the "algo" property. Also, when signing an already
+        * created FIT image, the hash nodes already have properly sized value
+        * properties, so one could also take pre-existence of "value"
+        * properties in hash nodes into account. But this rather simple
+        * approach should work well enough in practice.
         */
        for (depth = 0, noffset = fdt_next_node(fdt, 0, &depth);
             noffset >= 0 && depth > 0;
diff --git a/tools/image-host.c b/tools/image-host.c
index 8f1e7be4066..6df6ea6df3b 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -1162,27 +1162,6 @@ static int strlist_add(struct strlist *list, const char 
*str)
        return 0;
 }
 
-static const char *fit_config_get_image_list(const void *fit, int noffset,
-                                            int *lenp, int *allow_missingp)
-{
-       static const char default_list[] = FIT_KERNEL_PROP "\0"
-                       FIT_FDT_PROP "\0" FIT_SCRIPT_PROP;
-       const char *prop;
-
-       /* If there is an "sign-image" property, use that */
-       prop = fdt_getprop(fit, noffset, "sign-images", lenp);
-       if (prop) {
-               *allow_missingp = 0;
-               return *lenp ? prop : NULL;
-       }
-
-       /* Default image list */
-       *allow_missingp = 1;
-       *lenp = sizeof(default_list);
-
-       return default_list;
-}
-
 /**
  * fit_config_add_hash() - Add a list of nodes to hash for an image
  *
@@ -1272,8 +1251,10 @@ err_path:
 /**
  * fit_config_get_hash_list() - Get the regions to sign
  *
- * This calculates a list of nodes to hash for this particular configuration,
- * returning it as a string list (struct strlist, not a devicetree string list)
+ * This calculates a list of nodes to hash for this particular configuration by
+ * walking the same image-reference properties as target-side verification.
+ * The result is returned as a string list (struct strlist, not a devicetree
+ * string list).
  *
  * @fit:       Pointer to the FIT format image header
  * @conf_noffset: Offset of configuration node to sign (child of
@@ -1286,12 +1267,11 @@ err_path:
 static int fit_config_get_hash_list(const void *fit, int conf_noffset,
                                    int sig_offset, struct strlist *node_inc)
 {
-       int allow_missing;
-       const char *prop, *iname, *end;
        const char *conf_name, *sig_name;
+       int prop_offset;
        char name[200];
        int image_count;
-       int ret, len;
+       int ret;
 
        conf_name = fit_get_name(fit, conf_noffset, NULL);
        sig_name = fit_get_name(fit, sig_offset, NULL);
@@ -1306,34 +1286,38 @@ static int fit_config_get_hash_list(const void *fit, 
int conf_noffset,
            strlist_add(node_inc, name))
                goto err_mem;
 
-       /* Get a list of images that we intend to sign */
-       prop = fit_config_get_image_list(fit, sig_offset, &len,
-                                       &allow_missing);
-       if (!prop)
-               return 0;
-
-       /* Locate the images */
-       end = prop + len;
+       /* Process each image referenced by the config */
        image_count = 0;
-       for (iname = prop; iname < end; iname += strlen(iname) + 1) {
-               int image_noffset;
-               int index, max_index;
+       fdt_for_each_property_offset(prop_offset, fit, conf_noffset) {
+               const char *prop_name;
+               int img_count, i;
+
+               fdt_getprop_by_offset(fit, prop_offset, &prop_name, NULL);
+               if (!prop_name)
+                       continue;
 
-               max_index = fdt_stringlist_count(fit, conf_noffset, iname);
+               /* Skip properties that are not image references */
+               if (!strcmp(prop_name, FIT_DESC_PROP) ||
+                   !strcmp(prop_name, FIT_COMPAT_PROP) ||
+                   !strcmp(prop_name, FIT_DEFAULT_PROP))
+                       continue;
 
-               for (index = 0; index < max_index; index++) {
-                       image_noffset = fit_conf_get_prop_node_index(fit, 
conf_noffset,
-                                                                    iname, 
index);
+               img_count = fdt_stringlist_count(fit, conf_noffset, prop_name);
+               for (i = 0; i < img_count; i++) {
+                       const char *iname;
+                       int image_noffset;
 
-                       if (image_noffset < 0) {
-                               fprintf(stderr,
-                                       "Failed to find image '%s' in  
configuration '%s/%s'\n",
-                                       iname, conf_name, sig_name);
-                               if (allow_missing)
-                                       continue;
+                       iname = fdt_stringlist_get(fit, conf_noffset, prop_name,
+                                                  i, NULL);
+                       if (!iname)
+                               continue;
 
-                               return -ENOENT;
-                       }
+                       image_noffset = fit_conf_get_prop_node_index(fit,
+                                                                    
conf_noffset,
+                                                                    prop_name,
+                                                                    i);
+                       if (image_noffset < 0)
+                               continue;
 
                        ret = fit_config_add_hash(fit, image_noffset, node_inc,
                                                  conf_name, sig_name, iname);
-- 
2.53.0

Reply via email to