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>
This commit is contained in:
committed by
Tom Rini
parent
b75ca26b22
commit
b93a65209c
@@ -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;
|
||||
|
||||
fdt_begin_node(fdt, "signature-1");
|
||||
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");
|
||||
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;
|
||||
}
|
||||
|
||||
fdt_end_node(fdt);
|
||||
return 0;
|
||||
if (do_hash) {
|
||||
fdt_begin_node(fdt, FIT_HASH_NODENAME);
|
||||
fdt_property_string(fdt, FIT_ALGO_PROP, hash_algo);
|
||||
fdt_end_node(fdt);
|
||||
}
|
||||
|
||||
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);
|
||||
fdt_end_node(fdt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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) ||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)");
|
||||
|
||||
Reference in New Issue
Block a user