diff options
author | Massimo Pegorer <massimo.pegorer@vimar.com> | 2023-01-05 12:31:09 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-01-27 20:51:27 +0300 |
commit | b93a65209c4afae3f929262761b48b228ef58828 (patch) | |
tree | 1ba53d5ae8f5eed1a32a220e6807f38a45e80bdc /tools | |
parent | b75ca26b227a6fef9d5fffb9738655cbcbd8379b (diff) | |
download | u-boot-b93a65209c4afae3f929262761b48b228ef58828.tar.xz |
mkimage: fit: Support signed configurations in 'auto' FITs
Extend support for signing in auto-generated (-f auto) FIT. Previously,
it was possible to get signed 'images' subnodes in the FIT using
options -g and -o together with -f auto. This patch allows signing
'configurations' subnodes instead of 'images' ones (which are hashed),
using option -f auto-conf instead of -f auto. Adding also -K <dtb> and
-r options, will add public key to <dtb> file with required = "conf"
property.
Summary:
-f auto => FIT with crc32 images
-f auto -g ... -o ... => FIT with signed images
-f auto-conf -g ... -o ... => FIT with sha1 images and signed confs
Example: FIT with kernel, two device tree files, and signed
configurations; public key (needed to verify signatures) is
added to u-boot.dtb with required = "conf" property.
mkimage -f auto-conf -A arm -O linux -T kernel -C none -a 43e00000 \
-e 0 -d vmlinuz -b /path/to/first.dtb -b /path/to/second.dtb \
-k /folder/with/key-files -g keyname -o sha256,rsa4096 \
-K u-boot.dtb -r kernel.itb
Example: Add public key with required = "conf" property to u-boot.dtb
without needing to sign anything. This will also create a useless FIT
named unused.itb.
mkimage -f auto-conf -d /dev/null -k /folder/with/key-files \
-g keyname -o sha256,rsa4096 -K u-boot.dtb -r unused.itb
Signed-off-by: Massimo Pegorer <massimo.pegorer@vimar.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/fit_image.c | 75 | ||||
-rw-r--r-- | tools/imagetool.h | 10 | ||||
-rw-r--r-- | tools/mkimage.c | 21 |
3 files changed, 75 insertions, 31 deletions
diff --git a/tools/fit_image.c b/tools/fit_image.c index 8a18b1b0ba..8763a36d01 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -201,36 +201,59 @@ static void get_basename(char *str, int size, const char *fname) } /** - * add_hash_node() - Add a hash or signature node + * fit_add_hash_or_sign() - Add a hash or signature node * * @params: Image parameters * @fdt: Device tree to add to (in sequential-write mode) + * @is_images_subnode: true to add hash even if key name hint is provided * - * If there is a key name hint, try to sign the images. Otherwise, just add a - * CRC. - * - * Return: 0 on success, or -1 on failure + * If do_add_hash is false (default) and there is a key name hint, try to add + * a sign node to parent. Otherwise, just add a CRC. Rationale: if conf have + * to be signed, image/dt have to be hashed even if there is a key name hint. */ -static int add_hash_node(struct image_tool_params *params, void *fdt) +static void fit_add_hash_or_sign(struct image_tool_params *params, void *fdt, + bool is_images_subnode) { - if (params->keyname) { - if (!params->algo_name) { - fprintf(stderr, - "%s: Algorithm name must be specified\n", - params->cmdname); - return -1; + const char *hash_algo = "crc32"; + bool do_hash = false; + bool do_sign = false; + + switch (params->auto_fit) { + case AF_OFF: + break; + case AF_HASHED_IMG: + do_hash = is_images_subnode; + break; + case AF_SIGNED_IMG: + do_sign = is_images_subnode; + break; + case AF_SIGNED_CONF: + if (is_images_subnode) { + do_hash = true; + hash_algo = "sha1"; + } else { + do_sign = true; } + break; + default: + fprintf(stderr, + "%s: Unsupported auto FIT mode %u\n", + params->cmdname, params->auto_fit); + break; + } + + if (do_hash) { + fdt_begin_node(fdt, FIT_HASH_NODENAME); + fdt_property_string(fdt, FIT_ALGO_PROP, hash_algo); + fdt_end_node(fdt); + } - fdt_begin_node(fdt, "signature-1"); + if (do_sign) { + fdt_begin_node(fdt, FIT_SIG_NODENAME); fdt_property_string(fdt, FIT_ALGO_PROP, params->algo_name); fdt_property_string(fdt, FIT_KEY_HINT, params->keyname); - } else { - fdt_begin_node(fdt, "hash-1"); - fdt_property_string(fdt, FIT_ALGO_PROP, "crc32"); + fdt_end_node(fdt); } - - fdt_end_node(fdt); - return 0; } /** @@ -271,9 +294,7 @@ static int fit_write_images(struct image_tool_params *params, char *fdt) ret = fdt_property_file(params, fdt, FIT_DATA_PROP, params->datafile); if (ret) return ret; - ret = add_hash_node(params, fdt); - if (ret) - return ret; + fit_add_hash_or_sign(params, fdt, true); fdt_end_node(fdt); /* Now the device tree files if available */ @@ -296,7 +317,7 @@ static int fit_write_images(struct image_tool_params *params, char *fdt) genimg_get_arch_short_name(params->arch)); fdt_property_string(fdt, FIT_COMP_PROP, genimg_get_comp_short_name(IH_COMP_NONE)); - ret = add_hash_node(params, fdt); + fit_add_hash_or_sign(params, fdt, true); if (ret) return ret; fdt_end_node(fdt); @@ -316,7 +337,7 @@ static int fit_write_images(struct image_tool_params *params, char *fdt) params->fit_ramdisk); if (ret) return ret; - ret = add_hash_node(params, fdt); + fit_add_hash_or_sign(params, fdt, true); if (ret) return ret; fdt_end_node(fdt); @@ -368,6 +389,7 @@ static void fit_write_configs(struct image_tool_params *params, char *fdt) snprintf(str, sizeof(str), FIT_FDT_PROP "-%d", upto); fdt_property_string(fdt, FIT_FDT_PROP, str); + fit_add_hash_or_sign(params, fdt, false); fdt_end_node(fdt); } @@ -380,6 +402,7 @@ static void fit_write_configs(struct image_tool_params *params, char *fdt) if (params->fit_ramdisk) fdt_property_string(fdt, FIT_RAMDISK_PROP, FIT_RAMDISK_PROP "-1"); + fit_add_hash_or_sign(params, fdt, false); fdt_end_node(fdt); } @@ -723,7 +746,7 @@ static int fit_handle_file(struct image_tool_params *params) sprintf (tmpfile, "%s%s", params->imagefile, MKIMAGE_TMPFILE_SUFFIX); /* We either compile the source file, or use the existing FIT image */ - if (params->auto_its) { + if (params->auto_fit) { if (fit_build(params, tmpfile)) { fprintf(stderr, "%s: failed to build FIT\n", params->cmdname); @@ -907,7 +930,7 @@ static int fit_extract_contents(void *ptr, struct image_tool_params *params) static int fit_check_params(struct image_tool_params *params) { - if (params->auto_its) + if (params->auto_fit) return 0; return ((params->dflag && params->fflag) || (params->fflag && params->lflag) || diff --git a/tools/imagetool.h b/tools/imagetool.h index ca7c2e48ba..fdceea46c0 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -39,6 +39,14 @@ struct content_info { const char *fname; }; +/* FIT auto generation modes */ +enum af_mode { + AF_OFF = 0, /* Needs .its or existing FIT to be provided */ + AF_HASHED_IMG, /* Auto FIT with crc32 hashed images subnodes */ + AF_SIGNED_IMG, /* Auto FIT with signed images subnodes */ + AF_SIGNED_CONF, /* Auto FIT with sha1 images and signed configs */ +}; + /* * This structure defines all such variables those are initialized by * mkimage and dumpimage main core and need to be referred by image @@ -79,7 +87,7 @@ struct image_tool_params { int require_keys; /* 1 to mark signing keys as 'required' */ int file_size; /* Total size of output file */ int orig_file_size; /* Original size for file before padding */ - bool auto_its; /* Automatically create the .its file */ + enum af_mode auto_fit; /* Automatically create the FIT */ int fit_image_type; /* Image type to put into the FIT */ char *fit_ramdisk; /* Ramdisk file to include */ struct content_info *content_head; /* List of files to include */ diff --git a/tools/mkimage.c b/tools/mkimage.c index 8306861ce5..af7b0e09b3 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -104,7 +104,7 @@ static void usage(const char *msg) " -v ==> verbose\n", params.cmdname); fprintf(stderr, - " %s [-D dtc_options] [-f fit-image.its|-f auto|-F] [-b <dtb> [-b <dtb>]] [-E] [-B size] [-i <ramdisk.cpio.gz>] fit-image\n" + " %s [-D dtc_options] [-f fit-image.its|-f auto|-f auto-conf|-F] [-b <dtb> [-b <dtb>]] [-E] [-B size] [-i <ramdisk.cpio.gz>] fit-image\n" " <dtb> file is used with -f auto, it may occur multiple times.\n", params.cmdname); fprintf(stderr, @@ -271,7 +271,10 @@ static void process_args(int argc, char **argv) break; case 'f': datafile = optarg; - params.auto_its = !strcmp(datafile, "auto"); + if (!strcmp(datafile, "auto")) + params.auto_fit = AF_HASHED_IMG; + else if (!strcmp(datafile, "auto-conf")) + params.auto_fit = AF_SIGNED_CONF; /* fallthrough */ case 'F': /* @@ -283,6 +286,7 @@ static void process_args(int argc, char **argv) break; case 'g': params.keyname = optarg; + break; case 'G': params.keyfile = optarg; break; @@ -370,6 +374,15 @@ static void process_args(int argc, char **argv) if (optind < argc) params.imagefile = argv[optind]; + if (params.auto_fit == AF_SIGNED_CONF) { + if (!params.keyname || !params.algo_name) + usage("Missing key/algo for auto-FIT with signed configs (use -g -o)"); + } else if (params.auto_fit == AF_HASHED_IMG && params.keyname) { + params.auto_fit = AF_SIGNED_IMG; + if (!params.algo_name) + usage("Missing algorithm for auto-FIT with signed images (use -g)"); + } + /* * For auto-generated FIT images we need to know the image type to put * in the FIT, which is separate from the file's image type (which @@ -377,8 +390,8 @@ static void process_args(int argc, char **argv) */ if (params.type == IH_TYPE_FLATDT) { params.fit_image_type = type ? type : IH_TYPE_KERNEL; - /* For auto_its, datafile is always 'auto' */ - if (!params.auto_its) + /* For auto-FIT, datafile has to be provided with -d */ + if (!params.auto_fit) params.datafile = datafile; else if (!params.datafile) usage("Missing data file for auto-FIT (use -d)"); |