From 5a4116f1a21e8a53147053d1a80cc71d26b03525 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Tue, 24 Nov 2020 14:39:47 +0100 Subject: [PATCH 1/6] tools: image-host: clean function fit_config_get_hash_list This commit creates a function fit_config_add_hash that will be used in the next commit to support several 'sub-images'. Signed-off-by: Philippe Reynes Reviewed-by: Simon Glass --- tools/image-host.c | 132 ++++++++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 56 deletions(-) diff --git a/tools/image-host.c b/tools/image-host.c index e32cc64257..ce829a8ec9 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -700,13 +700,84 @@ static const char *fit_config_get_image_list(void *fit, int noffset, return default_list; } +static int fit_config_add_hash(void *fit, const char *conf_name, const char *sig_name, + struct strlist *node_inc, const char *iname, int image_noffset) +{ + char name[200], path[200]; + int noffset; + int hash_count; + int ret; + + ret = fdt_get_path(fit, image_noffset, path, sizeof(path)); + if (ret < 0) + goto err_path; + if (strlist_add(node_inc, path)) + goto err_mem; + + snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH, + conf_name); + + /* Add all this image's hashes */ + hash_count = 0; + for (noffset = fdt_first_subnode(fit, image_noffset); + noffset >= 0; + noffset = fdt_next_subnode(fit, noffset)) { + const char *name = fit_get_name(fit, noffset, NULL); + + if (strncmp(name, FIT_HASH_NODENAME, + strlen(FIT_HASH_NODENAME))) + continue; + ret = fdt_get_path(fit, noffset, path, sizeof(path)); + if (ret < 0) + goto err_path; + if (strlist_add(node_inc, path)) + goto err_mem; + hash_count++; + } + + if (!hash_count) { + printf("Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n", + conf_name, sig_name, iname); + return -ENOMSG; + } + + /* Add this image's cipher node if present */ + noffset = fdt_subnode_offset(fit, image_noffset, + FIT_CIPHER_NODENAME); + if (noffset != -FDT_ERR_NOTFOUND) { + if (noffset < 0) { + printf("Failed to get cipher node in configuration '%s/%s' image '%s': %s\n", + conf_name, sig_name, iname, + fdt_strerror(noffset)); + return -EIO; + } + ret = fdt_get_path(fit, noffset, path, sizeof(path)); + if (ret < 0) + goto err_path; + if (strlist_add(node_inc, path)) + goto err_mem; + } + + return 0; + +err_mem: + printf("Out of memory processing configuration '%s/%s'\n", conf_name, + sig_name); + return -ENOMEM; + +err_path: + printf("Failed to get path for image '%s' in configuration '%s/%s': %s\n", + iname, conf_name, sig_name, fdt_strerror(ret)); + return -ENOENT; +} + static int fit_config_get_hash_list(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; - char name[200], path[200]; + char name[200]; int image_count; int ret, len; @@ -733,9 +804,7 @@ static int fit_config_get_hash_list(void *fit, int conf_noffset, end = prop + len; image_count = 0; for (iname = prop; iname < end; iname += strlen(iname) + 1) { - int noffset; int image_noffset; - int hash_count; image_noffset = fit_conf_get_prop_node(fit, conf_noffset, iname); @@ -748,55 +817,11 @@ static int fit_config_get_hash_list(void *fit, int conf_noffset, return -ENOENT; } - ret = fdt_get_path(fit, image_noffset, path, sizeof(path)); + ret = fit_config_add_hash(fit, conf_name, + sig_name, node_inc, + iname, image_noffset); if (ret < 0) - goto err_path; - if (strlist_add(node_inc, path)) - goto err_mem; - - snprintf(name, sizeof(name), "%s/%s", FIT_CONFS_PATH, - conf_name); - - /* Add all this image's hashes */ - hash_count = 0; - for (noffset = fdt_first_subnode(fit, image_noffset); - noffset >= 0; - noffset = fdt_next_subnode(fit, noffset)) { - const char *name = fit_get_name(fit, noffset, NULL); - - if (strncmp(name, FIT_HASH_NODENAME, - strlen(FIT_HASH_NODENAME))) - continue; - ret = fdt_get_path(fit, noffset, path, sizeof(path)); - if (ret < 0) - goto err_path; - if (strlist_add(node_inc, path)) - goto err_mem; - hash_count++; - } - - if (!hash_count) { - printf("Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n", - conf_name, sig_name, iname); - return -ENOMSG; - } - - /* Add this image's cipher node if present */ - noffset = fdt_subnode_offset(fit, image_noffset, - FIT_CIPHER_NODENAME); - if (noffset != -FDT_ERR_NOTFOUND) { - if (noffset < 0) { - printf("Failed to get cipher node in configuration '%s/%s' image '%s': %s\n", - conf_name, sig_name, iname, - fdt_strerror(noffset)); - return -EIO; - } - ret = fdt_get_path(fit, noffset, path, sizeof(path)); - if (ret < 0) - goto err_path; - if (strlist_add(node_inc, path)) - goto err_mem; - } + return ret; image_count++; } @@ -813,11 +838,6 @@ err_mem: printf("Out of memory processing configuration '%s/%s'\n", conf_name, sig_name); return -ENOMEM; - -err_path: - printf("Failed to get path for image '%s' in configuration '%s/%s': %s\n", - iname, conf_name, sig_name, fdt_strerror(ret)); - return -ENOENT; } static int fit_config_get_data(void *fit, int conf_noffset, int noffset, From edfeba7538a23fdb82e7d0784c4b75d600f3547a Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Tue, 24 Nov 2020 14:39:48 +0100 Subject: [PATCH 2/6] tools: image-host: add support for several sub-images The propoerty sign-images points to images in the configuration node. But thoses images may references severals "sub-images" (for example for images loadable). This commit adds the support of severals sub-images. Signed-off-by: Philippe Reynes --- tools/image-host.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/tools/image-host.c b/tools/image-host.c index ce829a8ec9..33a224129a 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -805,25 +805,31 @@ static int fit_config_get_hash_list(void *fit, int conf_noffset, image_count = 0; for (iname = prop; iname < end; iname += strlen(iname) + 1) { int image_noffset; + int index, max_index; - image_noffset = fit_conf_get_prop_node(fit, conf_noffset, - iname); - if (image_noffset < 0) { - printf("Failed to find image '%s' in configuration '%s/%s'\n", - iname, conf_name, sig_name); - if (allow_missing) - continue; + max_index = fdt_stringlist_count(fit, conf_noffset, iname); - return -ENOENT; + for (index = 0; index < max_index; index++) { + image_noffset = fit_conf_get_prop_node_index(fit, conf_noffset, + iname, index); + + if (image_noffset < 0) { + printf("Failed to find image '%s' in configuration '%s/%s'\n", + iname, conf_name, sig_name); + if (allow_missing) + continue; + + return -ENOENT; + } + + ret = fit_config_add_hash(fit, conf_name, + sig_name, node_inc, + iname, image_noffset); + if (ret < 0) + return ret; + + image_count++; } - - ret = fit_config_add_hash(fit, conf_name, - sig_name, node_inc, - iname, image_noffset); - if (ret < 0) - return ret; - - image_count++; } if (!image_count) { From 5d40d5f12edac9ffccce955509f4cb4a7aa763a2 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 8 Dec 2020 14:42:13 +1030 Subject: [PATCH 3/6] tools/Makefile: FIT_CIPHER requires libssl If CONFIG_FIT_CIPHER is enabled without CONFIG_FIT_SIGNATURE then mkimage/dumpimage will fail to link: /usr/bin/ld: tools/common/image-cipher.o: in function `fit_image_decrypt_data': image-cipher.c:(.text+0x9a): undefined reference to `image_get_host_blob' /usr/bin/ld: tools/common/image-cipher.o:(.data.rel+0x10): undefined reference to `EVP_aes_128_cbc' /usr/bin/ld: tools/common/image-cipher.o:(.data.rel+0x40): undefined reference to `EVP_aes_192_cbc' /usr/bin/ld: tools/common/image-cipher.o:(.data.rel+0x70): undefined reference to `EVP_aes_256_cbc' /usr/bin/ld: tools/lib/aes/aes-encrypt.o: in function `image_aes_encrypt': aes-encrypt.c:(.text+0x22): undefined reference to `EVP_CIPHER_CTX_new' /usr/bin/ld: aes-encrypt.c:(.text+0x6f): undefined reference to `EVP_EncryptInit_ex' /usr/bin/ld: aes-encrypt.c:(.text+0x8d): undefined reference to `EVP_EncryptUpdate' /usr/bin/ld: aes-encrypt.c:(.text+0xac): undefined reference to `EVP_CIPHER_CTX_free' /usr/bin/ld: aes-encrypt.c:(.text+0xf2): undefined reference to `EVP_EncryptFinal_ex' collect2: error: ld returned 1 exit status Signed-off-by: Joel Stanley --- tools/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Makefile b/tools/Makefile index 9b1aa51b10..2d550432ba 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -155,7 +155,7 @@ HOSTCFLAGS_kwbimage.o += -DCONFIG_KWB_SECURE endif # MXSImage needs LibSSL -ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_ARMADA_38X)$(CONFIG_ARMADA_39X)$(CONFIG_FIT_SIGNATURE),) +ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_ARMADA_38X)$(CONFIG_ARMADA_39X)$(CONFIG_FIT_SIGNATURE)$(CONFIG_FIT_CIPHER),) HOSTCFLAGS_kwbimage.o += \ $(shell pkg-config --cflags libssl libcrypto 2> /dev/null || echo "") HOSTLDLIBS_mkimage += \ From 93af80f3e8fb6fcbfb851a6dc384999a61ddaedb Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 8 Dec 2020 14:42:14 +1030 Subject: [PATCH 4/6] image-fit: Fix FIT_CIPHER linking When CONFIG_FIT_CIPHER=y and CONFIG_FIT_SIGNATURE=n is there is no implementation of image_get_host_blob for mkimage/dumpimage: /usr/bin/ld: tools/common/image-cipher.o: in function `fit_image_decrypt_data': image-cipher.c:(.text+0x9a): undefined reference to `image_get_host_blob' Move the implementation to a common file so it can be shaed between image-cipher.c and image-fit-sig.c. Signed-off-by: Joel Stanley --- common/image-fit-sig.c | 14 -------------- common/image-fit.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/common/image-fit-sig.c b/common/image-fit-sig.c index 5401d9411b..d39741e905 100644 --- a/common/image-fit-sig.c +++ b/common/image-fit-sig.c @@ -19,20 +19,6 @@ DECLARE_GLOBAL_DATA_PTR; #define IMAGE_MAX_HASHED_NODES 100 -#ifdef USE_HOSTCC -void *host_blob; - -void image_set_host_blob(void *blob) -{ - host_blob = blob; -} - -void *image_get_host_blob(void) -{ - return host_blob; -} -#endif - /** * fit_region_make_list() - Make a list of image regions * diff --git a/common/image-fit.c b/common/image-fit.c index 21c44bdf69..8660c3fd81 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -112,6 +112,21 @@ int fit_parse_subimage(const char *spec, ulong addr_curr, } #endif /* !USE_HOSTCC */ +#ifdef USE_HOSTCC +/* Host tools use these implementations for Cipher and Signature support */ +static void *host_blob; + +void image_set_host_blob(void *blob) +{ + host_blob = blob; +} + +void *image_get_host_blob(void) +{ + return host_blob; +} +#endif /* USE_HOSTCC */ + static void fit_get_debug(const void *fit, int noffset, char *prop_name, int err) { From 603e26f76346a36594eda78daa2b7d95ce96b497 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 8 Dec 2020 14:42:15 +1030 Subject: [PATCH 5/6] mkimage: Move padding commands outside of FIT_SIGNATURE These commands were disabled when CONFIG_FIT_SIGNATURE is disabled, but they do not depend on crypto support so they can be unconditionally enabled. Signed-off-by: Joel Stanley --- tools/mkimage.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/mkimage.c b/tools/mkimage.c index e78608293e..68d5206cb4 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -94,18 +94,18 @@ static void usage(const char *msg) " -x ==> set XIP (execute in place)\n", params.cmdname); fprintf(stderr, - " %s [-D dtc_options] [-f fit-image.its|-f auto|-F] [-b [-b ]] [-i ] fit-image\n" + " %s [-D dtc_options] [-f fit-image.its|-f auto|-F] [-b [-b ]] [-E] [-B size] [-i ] fit-image\n" " file is used with -f auto, it may occur multiple times.\n", params.cmdname); fprintf(stderr, " -D => set all options for device tree compiler\n" " -f => input filename for FIT source\n" - " -i => input filename for ramdisk file\n"); + " -i => input filename for ramdisk file\n" + " -E => place data outside of the FIT structure\n" + " -B => align size in hex for FIT structure and header\n"); #ifdef CONFIG_FIT_SIGNATURE fprintf(stderr, - "Signing / verified boot options: [-E] [-B size] [-k keydir] [-K dtb] [ -c ] [-p addr] [-r] [-N engine]\n" - " -E => place data outside of the FIT structure\n" - " -B => align size in hex for FIT structure and header\n" + "Signing / verified boot options: [-k keydir] [-K dtb] [ -c ] [-p addr] [-r] [-N engine]\n" " -k => set directory containing private keys\n" " -K => write public keys to this .dtb file\n" " -c => add comment in signature node\n" @@ -142,6 +142,7 @@ static int add_content(int type, const char *fname) return 0; } +#define OPT_STRING "a:A:b:B:c:C:d:D:e:Ef:Fk:i:K:ln:N:p:O:rR:qstT:vVx" static void process_args(int argc, char **argv) { char *ptr; From 09779488a924dbc4eb3b4ae145632f22b7f5a36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Hundeb=C3=B8ll?= Date: Mon, 30 Nov 2020 12:11:32 +0100 Subject: [PATCH 6/6] tools: env: return error if ubi_update_start() fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The UBI_IOCVOLUP ioctl can fail if exclusive access to the volume isn't obtained. If this happens, the flush operation doesn't return error, leaving the caller without knowledge of missing flush. Fix this by forwarding the error (-1) from ubi_update_start(). Fixes: 34255b92e6e ("tools: env: Add support for direct read/write UBI volumes") Signed-off-by: Martin Hundebøll --- tools/env/fw_env.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 66cb9d2a25..2a61a5d6f0 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -1208,7 +1208,7 @@ static int flash_write(int fd_current, int fd_target, int dev_target) if (IS_UBI(dev_target)) { if (ubi_update_start(fd_target, CUR_ENVSIZE) < 0) - return 0; + return -1; return ubi_write(fd_target, environment.image, CUR_ENVSIZE); }