[PATCH v6 08/11] mkimage: Add a 'keyfile' argument for image signing

Alexandru Gagniuc mr.nuke.me at gmail.com
Fri Feb 19 19:45:17 CET 2021


It's not always desirable to use 'keydir' and some ad-hoc heuristics
to get the filename of the signing key. More often, just passing the
filename is the simpler, easier, and logical thing to do.

Since mkimage doesn't use long options, we're slowly running out of
letters. I've chosen '-G' because it was available.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
Reviewed-by: Simon Glass <sjg at chromium.org>
---
 include/image.h    | 16 +++++++++----
 tools/fit_image.c  |  3 ++-
 tools/image-host.c | 58 +++++++++++++++++++++++++---------------------
 tools/imagetool.h  |  1 +
 tools/mkimage.c    |  6 ++++-
 5 files changed, 52 insertions(+), 32 deletions(-)

diff --git a/include/image.h b/include/image.h
index 37feb5d56f..5bb7922a66 100644
--- a/include/image.h
+++ b/include/image.h
@@ -1131,9 +1131,10 @@ int fit_cipher_data(const char *keydir, void *keydest, void *fit,
  *     0, on success
  *     libfdt error code, on failure
  */
-int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
-			      const char *comment, int require_keys,
-			      const char *engine_id, const char *cmdname);
+int fit_add_verification_data(const char *keydir, const char *keyfile,
+			      void *keydest, void *fit, const char *comment,
+			      int require_keys, const char *engine_id,
+			      const char *cmdname);
 
 int fit_image_verify_with_data(const void *fit, int image_noffset,
 			       const void *data, size_t size);
@@ -1251,10 +1252,17 @@ void image_set_host_blob(void *host_blob);
 #endif
 #endif /* IMAGE_ENABLE_FIT */
 
-/* Information passed to the signing routines */
+/*
+ * Information passed to the signing routines
+ *
+ * Either 'keydir',  'keyname', or 'keyfile' can be NULL. However, either
+ * 'keyfile', or both 'keydir' and 'keyname' should have valid values. If
+ * neither are valid, some operations might fail with EINVAL.
+ */
 struct image_sign_info {
 	const char *keydir;		/* Directory conaining keys */
 	const char *keyname;		/* Name of key to use */
+	const char *keyfile;		/* Filename of private or public key */
 	void *fit;			/* Pointer to FIT blob */
 	int node_offset;		/* Offset of signature node */
 	const char *name;		/* Algorithm name */
diff --git a/tools/fit_image.c b/tools/fit_image.c
index d440d143c6..ae30f80783 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -68,7 +68,8 @@ static int fit_add_file_data(struct image_tool_params *params, size_t size_inc,
 	}
 
 	if (!ret) {
-		ret = fit_add_verification_data(params->keydir, dest_blob, ptr,
+		ret = fit_add_verification_data(params->keydir,
+						params->keyfile, dest_blob, ptr,
 						params->comment,
 						params->require_keys,
 						params->engine_id,
diff --git a/tools/image-host.c b/tools/image-host.c
index 33a224129a..270d36fe45 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -153,8 +153,9 @@ static int fit_image_write_sig(void *fit, int noffset, uint8_t *value,
 }
 
 static int fit_image_setup_sig(struct image_sign_info *info,
-		const char *keydir, void *fit, const char *image_name,
-		int noffset, const char *require_keys, const char *engine_id)
+		const char *keydir, const char *keyfile, void *fit,
+		const char *image_name, int noffset, const char *require_keys,
+		const char *engine_id)
 {
 	const char *node_name;
 	char *algo_name;
@@ -171,6 +172,7 @@ static int fit_image_setup_sig(struct image_sign_info *info,
 
 	memset(info, '\0', sizeof(*info));
 	info->keydir = keydir;
+	info->keyfile = keyfile;
 	info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
 	info->fit = fit;
 	info->node_offset = noffset;
@@ -207,8 +209,8 @@ static int fit_image_setup_sig(struct image_sign_info *info,
  * @engine_id:	Engine to use for signing
  * @return 0 if ok, -1 on error
  */
-static int fit_image_process_sig(const char *keydir, void *keydest,
-		void *fit, const char *image_name,
+static int fit_image_process_sig(const char *keydir, const char *keyfile,
+		void *keydest, void *fit, const char *image_name,
 		int noffset, const void *data, size_t size,
 		const char *comment, int require_keys, const char *engine_id,
 		const char *cmdname)
@@ -220,8 +222,9 @@ static int fit_image_process_sig(const char *keydir, void *keydest,
 	uint value_len;
 	int ret;
 
-	if (fit_image_setup_sig(&info, keydir, fit, image_name, noffset,
-				require_keys ? "image" : NULL, engine_id))
+	if (fit_image_setup_sig(&info, keydir, keyfile, fit, image_name,
+				noffset, require_keys ? "image" : NULL,
+				engine_id))
 		return -1;
 
 	node_name = fit_get_name(fit, noffset, NULL);
@@ -598,9 +601,10 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
  * @engine_id:	Engine to use for signing
  * @return: 0 on success, <0 on failure
  */
-int fit_image_add_verification_data(const char *keydir, void *keydest,
-		void *fit, int image_noffset, const char *comment,
-		int require_keys, const char *engine_id, const char *cmdname)
+int fit_image_add_verification_data(const char *keydir, const char *keyfile,
+		void *keydest, void *fit, int image_noffset,
+		const char *comment, int require_keys, const char *engine_id,
+		const char *cmdname)
 {
 	const char *image_name;
 	const void *data;
@@ -632,10 +636,10 @@ int fit_image_add_verification_data(const char *keydir, void *keydest,
 			     strlen(FIT_HASH_NODENAME))) {
 			ret = fit_image_process_hash(fit, image_name, noffset,
 						data, size);
-		} else if (IMAGE_ENABLE_SIGN && keydir &&
+		} else if (IMAGE_ENABLE_SIGN && (keydir || keyfile) &&
 			   !strncmp(node_name, FIT_SIG_NODENAME,
 				strlen(FIT_SIG_NODENAME))) {
-			ret = fit_image_process_sig(keydir, keydest,
+			ret = fit_image_process_sig(keydir, keyfile, keydest,
 				fit, image_name, noffset, data, size,
 				comment, require_keys, engine_id, cmdname);
 		}
@@ -918,10 +922,10 @@ static int fit_config_get_data(void *fit, int conf_noffset, int noffset,
 	return 0;
 }
 
-static int fit_config_process_sig(const char *keydir, void *keydest,
-		void *fit, const char *conf_name, int conf_noffset,
-		int noffset, const char *comment, int require_keys,
-		const char *engine_id, const char *cmdname)
+static int fit_config_process_sig(const char *keydir, const char *keyfile,
+		void *keydest,	void *fit, const char *conf_name,
+		int conf_noffset, int noffset, const char *comment,
+		int require_keys, const char *engine_id, const char *cmdname)
 {
 	struct image_sign_info info;
 	const char *node_name;
@@ -938,7 +942,7 @@ static int fit_config_process_sig(const char *keydir, void *keydest,
 				&region_count, &region_prop, &region_proplen))
 		return -1;
 
-	if (fit_image_setup_sig(&info, keydir, fit, conf_name, noffset,
+	if (fit_image_setup_sig(&info, keydir, keyfile, fit, conf_name, noffset,
 				require_keys ? "conf" : NULL, engine_id))
 		return -1;
 
@@ -983,9 +987,10 @@ static int fit_config_process_sig(const char *keydir, void *keydest,
 	return 0;
 }
 
-static int fit_config_add_verification_data(const char *keydir, void *keydest,
-		void *fit, int conf_noffset, const char *comment,
-		int require_keys, const char *engine_id, const char *cmdname)
+static int fit_config_add_verification_data(const char *keydir,
+		const char *keyfile, void *keydest, void *fit, int conf_noffset,
+		const char *comment, int require_keys, const char *engine_id,
+		const char *cmdname)
 {
 	const char *conf_name;
 	int noffset;
@@ -1002,7 +1007,7 @@ static int fit_config_add_verification_data(const char *keydir, void *keydest,
 		node_name = fit_get_name(fit, noffset, NULL);
 		if (!strncmp(node_name, FIT_SIG_NODENAME,
 			     strlen(FIT_SIG_NODENAME))) {
-			ret = fit_config_process_sig(keydir, keydest,
+			ret = fit_config_process_sig(keydir, keyfile, keydest,
 				fit, conf_name, conf_noffset, noffset, comment,
 				require_keys, engine_id, cmdname);
 		}
@@ -1048,9 +1053,10 @@ int fit_cipher_data(const char *keydir, void *keydest, void *fit,
 	return 0;
 }
 
-int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
-			      const char *comment, int require_keys,
-			      const char *engine_id, const char *cmdname)
+int fit_add_verification_data(const char *keydir, const char *keyfile,
+			      void *keydest, void *fit, const char *comment,
+			      int require_keys, const char *engine_id,
+			      const char *cmdname)
 {
 	int images_noffset, confs_noffset;
 	int noffset;
@@ -1072,7 +1078,7 @@ int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
 		 * Direct child node of the images parent node,
 		 * i.e. component image node.
 		 */
-		ret = fit_image_add_verification_data(keydir, keydest,
+		ret = fit_image_add_verification_data(keydir, keyfile, keydest,
 				fit, noffset, comment, require_keys, engine_id,
 				cmdname);
 		if (ret)
@@ -1080,7 +1086,7 @@ int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
 	}
 
 	/* If there are no keys, we can't sign configurations */
-	if (!IMAGE_ENABLE_SIGN || !keydir)
+	if (!IMAGE_ENABLE_SIGN || !(keydir || keyfile))
 		return 0;
 
 	/* Find configurations parent node offset */
@@ -1095,7 +1101,7 @@ int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
 	for (noffset = fdt_first_subnode(fit, confs_noffset);
 	     noffset >= 0;
 	     noffset = fdt_next_subnode(fit, noffset)) {
-		ret = fit_config_add_verification_data(keydir, keydest,
+		ret = fit_config_add_verification_data(keydir, keyfile, keydest,
 						       fit, noffset, comment,
 						       require_keys,
 						       engine_id, cmdname);
diff --git a/tools/imagetool.h b/tools/imagetool.h
index 8726792c8c..8400e87e62 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -67,6 +67,7 @@ struct image_tool_params {
 	const char *outfile;	/* Output filename */
 	const char *keydir;	/* Directory holding private keys */
 	const char *keydest;	/* Destination .dtb for public key */
+	const char *keyfile;	/* Filename of private or public key */
 	const char *comment;	/* Comment to add to signature node */
 	int require_keys;	/* 1 to mark signing keys as 'required' */
 	int file_size;		/* Total size of output file */
diff --git a/tools/mkimage.c b/tools/mkimage.c
index 68d5206cb4..cc7b242faf 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -108,6 +108,7 @@ static void usage(const char *msg)
 		"Signing / verified boot options: [-k keydir] [-K dtb] [ -c <comment>] [-p addr] [-r] [-N engine]\n"
 		"          -k => set directory containing private keys\n"
 		"          -K => write public keys to this .dtb file\n"
+		"          -G => use this signing key (in lieu of -k)\n"
 		"          -c => add comment in signature node\n"
 		"          -F => re-sign existing FIT image\n"
 		"          -p => place external data at a static position\n"
@@ -151,7 +152,7 @@ static void process_args(int argc, char **argv)
 	int opt;
 
 	while ((opt = getopt(argc, argv,
-		   "a:A:b:B:c:C:d:D:e:Ef:Fk:i:K:ln:N:p:O:rR:qstT:vVx")) != -1) {
+		   "a:A:b:B:c:C:d:D:e:Ef:FG:k:i:K:ln:N:p:O:rR:qstT:vVx")) != -1) {
 		switch (opt) {
 		case 'a':
 			params.addr = strtoull(optarg, &ptr, 16);
@@ -226,6 +227,9 @@ static void process_args(int argc, char **argv)
 			params.type = IH_TYPE_FLATDT;
 			params.fflag = 1;
 			break;
+		case 'G':
+			params.keyfile = optarg;
+			break;
 		case 'i':
 			params.fit_ramdisk = optarg;
 			break;
-- 
2.26.2



More information about the U-Boot mailing list