mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/8] FIT: Add support for opening images without a /configuration/
@ 2018-01-31 11:11 Sascha Hauer
  2018-01-31 11:11 ` [PATCH 1/8] bootm: FIT: do not depend on FIT pre-opened images Sascha Hauer
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Sascha Hauer @ 2018-01-31 11:11 UTC (permalink / raw)
  To: Barebox List

The images in FIT images can be opened in two different ways. Since now
we only support opening images as part of a configuration. The other way
is to open an image standalone, without an configuration. This series
adds support for it (though this functionality currently remains
unused). Users could be software updates inside FIT images.

Sascha

Sascha Hauer (8):
  bootm: FIT: do not depend on FIT pre-opened images
  FIT: Do not pre-open images
  FIT: Let user specify the configuration to use
  FIT: store device_nodes in fit_handle
  FIT: move handle->verify check to fit_verify_hash()
  FIT: factor out some helper functions
  FIT: Implement opening images with no configuration
  FIT: Allow to open buffer as FIT image

 common/bootm.c      |  53 +++++--
 common/image-fit.c  | 411 +++++++++++++++++++++++++++++++++++-----------------
 include/bootm.h     |   4 +
 include/image-fit.h |  25 ++--
 4 files changed, 330 insertions(+), 163 deletions(-)

-- 
2.15.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/8] bootm: FIT: do not depend on FIT pre-opened images
  2018-01-31 11:11 [PATCH 0/8] FIT: Add support for opening images without a /configuration/ Sascha Hauer
@ 2018-01-31 11:11 ` Sascha Hauer
  2018-01-31 11:11 ` [PATCH 2/8] FIT: Do not pre-open images Sascha Hauer
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2018-01-31 11:11 UTC (permalink / raw)
  To: Barebox List

When calling fit_open_configuration the FIT code already opens
the images "kernel", "ramdisk" and "dtb". This does not fit well
into the FIT code, so make the bootm code independent of these
pre-opened images so that we can drop the opening from the FIT
code in the next step.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/bootm.c  | 46 ++++++++++++++++++++++++++++++++--------------
 include/bootm.h |  3 +++
 2 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/common/bootm.c b/common/bootm.c
index 05314a0a10..8961c58c8b 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -111,13 +111,14 @@ int bootm_load_os(struct image_data *data, unsigned long load_address)
 		return -EINVAL;
 
 	if (data->os_fit) {
+		const void *kernel = data->fit_kernel;
+		unsigned long kernel_size = data->fit_kernel_size;
+
 		data->os_res = request_sdram_region("kernel",
-				load_address,
-				data->os_fit->kernel_size);
+				load_address, kernel_size);
 		if (!data->os_res)
 			return -ENOMEM;
-		memcpy((void *)load_address, data->os_fit->kernel,
-		       data->os_fit->kernel_size);
+		memcpy((void *)load_address, kernel, kernel_size);
 		return 0;
 	}
 
@@ -150,7 +151,8 @@ bool bootm_has_initrd(struct image_data *data)
 	if (!IS_ENABLED(CONFIG_BOOTM_INITRD))
 		return false;
 
-	if (data->os_fit && data->os_fit->initrd)
+	if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit &&
+	    fit_has_image(data->os_fit, "ramdisk"))
 		return true;
 
 	if (data->initrd_file)
@@ -211,14 +213,20 @@ int bootm_load_initrd(struct image_data *data, unsigned long load_address)
 	if (data->initrd_res)
 		return 0;
 
-	if (data->os_fit && data->os_fit->initrd) {
+	if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit &&
+	    fit_has_image(data->os_fit, "ramdisk")) {
+		const void *initrd;
+		unsigned long initrd_size;
+
+		ret = fit_open_image(data->os_fit, "ramdisk", &initrd,
+				     &initrd_size);
+
 		data->initrd_res = request_sdram_region("initrd",
 				load_address,
-				data->os_fit->initrd_size);
+				initrd_size);
 		if (!data->initrd_res)
 			return -ENOMEM;
-		memcpy((void *)load_address, data->os_fit->initrd,
-		       data->os_fit->initrd_size);
+		memcpy((void *)load_address, initrd, initrd_size);
 		printf("Loaded initrd from FIT image\n");
 		goto done1;
 	}
@@ -335,11 +343,16 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
 	if (!IS_ENABLED(CONFIG_OFTREE))
 		return 0;
 
-	if (data->os_fit && data->os_fit->oftree) {
-		data->of_root_node = of_unflatten_dtb(data->os_fit->oftree);
+	if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit &&
+	    fit_has_image(data->os_fit, "dtb")) {
+		const void *of_tree;
+		unsigned long of_size;
 
-		if (IS_ERR(data->of_root_node))
-			data->of_root_node = NULL;
+		ret = fit_open_image(data->os_fit, "dtb", &of_tree, &of_size);
+		if (ret)
+			return ret;
+
+		data->of_root_node = of_unflatten_dtb(of_tree);
 	} else if (data->oftree_file) {
 		size_t size;
 
@@ -429,7 +442,7 @@ int bootm_get_os_size(struct image_data *data)
 	if (data->os)
 		return uimage_get_size(data->os, uimage_part_num(data->os_part));
 	if (data->os_fit)
-		return data->os_fit->kernel_size;
+		return data->fit_kernel_size;
 
 	if (data->os_file) {
 		struct stat s;
@@ -584,6 +597,11 @@ int bootm_boot(struct bootm_data *bootm_data)
 			       data->os_part ? data->os_part : "default");
 			goto err_out;
 		}
+
+		ret = fit_open_image(data->os_fit, "kernel", &data->fit_kernel,
+				     &data->fit_kernel_size);
+		if (ret)
+			goto err_out;;
 	}
 
 	if (os_type == filetype_uimage) {
diff --git a/include/bootm.h b/include/bootm.h
index 6e9777a9ac..7ba7b8b96f 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -73,6 +73,9 @@ struct image_data {
 	char *oftree_file;
 	char *oftree_part;
 
+	const void *fit_kernel;
+	unsigned long fit_kernel_size;
+
 	struct device_node *of_root_node;
 	struct fdt_header *oftree;
 	struct resource *oftree_res;
-- 
2.15.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/8] FIT: Do not pre-open images
  2018-01-31 11:11 [PATCH 0/8] FIT: Add support for opening images without a /configuration/ Sascha Hauer
  2018-01-31 11:11 ` [PATCH 1/8] bootm: FIT: do not depend on FIT pre-opened images Sascha Hauer
@ 2018-01-31 11:11 ` Sascha Hauer
  2018-01-31 11:11 ` [PATCH 3/8] FIT: Let user specify the configuration to use Sascha Hauer
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2018-01-31 11:11 UTC (permalink / raw)
  To: Barebox List

Only do what fit_open_configuration() suggests: open the configuration,
but not the images in it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/image-fit.c  | 21 ---------------------
 include/image-fit.h |  7 -------
 2 files changed, 28 deletions(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 12379a67ff..8715689cfb 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -581,27 +581,6 @@ int fit_open_configuration(struct fit_handle *handle, const char *name)
 
 	handle->conf_node = conf_node;
 
-	if (fit_has_image(handle, "kernel")) {
-		ret = fit_open_image(handle, "kernel", &handle->kernel,
-				     &handle->kernel_size);
-		if (ret)
-			return ret;
-	}
-
-	if (fit_has_image(handle, "ramdisk")) {
-		ret = fit_open_image(handle, "ramdisk", &handle->initrd,
-				     &handle->initrd_size);
-		if (ret)
-			return ret;
-	}
-
-	if (fit_has_image(handle, "fdt")) {
-		ret = fit_open_image(handle, "fdt", &handle->oftree,
-				     &handle->oftree_size);
-		if (ret)
-			return ret;
-	}
-
 	return 0;
 }
 
diff --git a/include/image-fit.h b/include/image-fit.h
index 62f44dcc8d..0e26a40ef7 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -30,13 +30,6 @@ struct fit_handle {
 
 	struct device_node *root;
 	struct device_node *conf_node;
-
-	const void *kernel;
-	unsigned long kernel_size;
-	const void *oftree;
-	unsigned long oftree_size;
-	const void *initrd;
-	unsigned long initrd_size;
 };
 
 struct fit_handle *fit_open(const char *filename, bool verbose,
-- 
2.15.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 3/8] FIT: Let user specify the configuration to use
  2018-01-31 11:11 [PATCH 0/8] FIT: Add support for opening images without a /configuration/ Sascha Hauer
  2018-01-31 11:11 ` [PATCH 1/8] bootm: FIT: do not depend on FIT pre-opened images Sascha Hauer
  2018-01-31 11:11 ` [PATCH 2/8] FIT: Do not pre-open images Sascha Hauer
@ 2018-01-31 11:11 ` Sascha Hauer
  2018-01-31 11:11 ` [PATCH 4/8] FIT: store device_nodes in fit_handle Sascha Hauer
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2018-01-31 11:11 UTC (permalink / raw)
  To: Barebox List

The images in FIT images can be opened in two different ways. They
can be either opened directly based on their names in the images/
node or as part of a configuration based on their names in the
corresponding /configuration/ node.

So far we only supported the latter. To prepare supporting the former
we return a cookie belonging to the configuration from
fit_open_configuration() which we use in fit_open_image() to refer
to the desired configuration.

While at it document fit_open_configuration().

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/bootm.c      | 25 ++++++++++++++-----------
 common/image-fit.c  | 37 ++++++++++++++++++++++++-------------
 include/bootm.h     |  1 +
 include/image-fit.h | 11 ++++++-----
 4 files changed, 45 insertions(+), 29 deletions(-)

diff --git a/common/bootm.c b/common/bootm.c
index 8961c58c8b..6f6178575f 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -152,7 +152,7 @@ bool bootm_has_initrd(struct image_data *data)
 		return false;
 
 	if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit &&
-	    fit_has_image(data->os_fit, "ramdisk"))
+	    fit_has_image(data->os_fit, data->fit_config, "ramdisk"))
 		return true;
 
 	if (data->initrd_file)
@@ -214,12 +214,12 @@ int bootm_load_initrd(struct image_data *data, unsigned long load_address)
 		return 0;
 
 	if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit &&
-	    fit_has_image(data->os_fit, "ramdisk")) {
+	    fit_has_image(data->os_fit, data->fit_config, "ramdisk")) {
 		const void *initrd;
 		unsigned long initrd_size;
 
-		ret = fit_open_image(data->os_fit, "ramdisk", &initrd,
-				     &initrd_size);
+		ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk",
+				     &initrd, &initrd_size);
 
 		data->initrd_res = request_sdram_region("initrd",
 				load_address,
@@ -344,11 +344,12 @@ int bootm_load_devicetree(struct image_data *data, unsigned long load_address)
 		return 0;
 
 	if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit &&
-	    fit_has_image(data->os_fit, "dtb")) {
+	    fit_has_image(data->os_fit, data->fit_config, "dtb")) {
 		const void *of_tree;
 		unsigned long of_size;
 
-		ret = fit_open_image(data->os_fit, "dtb", &of_tree, &of_size);
+		ret = fit_open_image(data->os_fit, data->fit_config, "dtb",
+				     &of_tree, &of_size);
 		if (ret)
 			return ret;
 
@@ -591,17 +592,19 @@ int bootm_boot(struct bootm_data *bootm_data)
 
 		data->os_fit = fit;
 
-		ret = fit_open_configuration(data->os_fit, data->os_part);
-		if (ret) {
+		data->fit_config = fit_open_configuration(data->os_fit,
+							  data->os_part);
+		if (IS_ERR(data->fit_config)) {
 			printf("Cannot open FIT image configuration '%s'\n",
 			       data->os_part ? data->os_part : "default");
+			ret = PTR_ERR(data->fit_config);
 			goto err_out;
 		}
 
-		ret = fit_open_image(data->os_fit, "kernel", &data->fit_kernel,
-				     &data->fit_kernel_size);
+		ret = fit_open_image(data->os_fit, data->fit_config, "kernel",
+				     &data->fit_kernel, &data->fit_kernel_size);
 		if (ret)
-			goto err_out;;
+			goto err_out;
 	}
 
 	if (os_type == filetype_uimage) {
diff --git a/common/image-fit.c b/common/image-fit.c
index 8715689cfb..138696ab78 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -397,10 +397,11 @@ err_digest_free:
 	return ret;
 }
 
-int fit_has_image(struct fit_handle *handle, const char *name)
+int fit_has_image(struct fit_handle *handle, void *configuration,
+		  const char *name)
 {
 	const char *unit;
-	struct device_node *conf_node = handle->conf_node;
+	struct device_node *conf_node = configuration;
 
 	if (!conf_node)
 		return -EINVAL;
@@ -411,15 +412,16 @@ int fit_has_image(struct fit_handle *handle, const char *name)
 	return 1;
 }
 
-int fit_open_image(struct fit_handle *handle, const char *name,
-		   const void **outdata, unsigned long *outsize)
+int fit_open_image(struct fit_handle *handle, void *configuration,
+		   const char *name, const void **outdata,
+		   unsigned long *outsize)
 {
 	struct device_node *image = NULL, *hash;
 	const char *unit, *type = NULL, *desc= "(no description)";
 	const void *data;
 	int data_len;
 	int ret = 0;
-	struct device_node *conf_node = handle->conf_node;
+	struct device_node *conf_node = configuration;
 
 	if (!conf_node)
 		return -EINVAL;
@@ -546,7 +548,18 @@ default_unit:
 	return -ENOENT;
 }
 
-int fit_open_configuration(struct fit_handle *handle, const char *name)
+/**
+ * fit_open_configuration - open a FIT configuration
+ * @handle: The FIT image handle
+ * @name: The name of the configuration
+ *
+ * This opens a FIT configuration and eventually checks the signature
+ * depending on the verify mode the FIT image is opened with.
+ *
+ * Return: If successful a pointer to a valid configuration node,
+ *         otherwise a ERR_PTR()
+ */
+void *fit_open_configuration(struct fit_handle *handle, const char *name)
 {
 	struct device_node *conf_node = NULL;
 	const char *unit, *desc = "(no description)";
@@ -554,7 +567,7 @@ int fit_open_configuration(struct fit_handle *handle, const char *name)
 
 	conf_node = of_get_child_by_name(handle->root, "configurations");
 	if (!conf_node)
-		return -ENOENT;
+		return ERR_PTR(-ENOENT);
 
 	if (name) {
 		unit = name;
@@ -562,14 +575,14 @@ int fit_open_configuration(struct fit_handle *handle, const char *name)
 		ret = fit_find_compatible_unit(conf_node, &unit);
 		if (ret) {
 			pr_info("Couldn't get a valid configuration. Aborting.\n");
-			return ret;
+			return ERR_PTR(ret);
 		}
 	}
 
 	conf_node = of_get_child_by_name(conf_node, unit);
 	if (!conf_node) {
 		pr_err("configuration '%s' not found\n", unit);
-		return -ENOENT;
+		return ERR_PTR(-ENOENT);
 	}
 
 	of_property_read_string(conf_node, "description", &desc);
@@ -577,11 +590,9 @@ int fit_open_configuration(struct fit_handle *handle, const char *name)
 
 	ret = fit_config_verify_signature(handle, conf_node);
 	if (ret)
-		return ret;
+		return ERR_PTR(ret);
 
-	handle->conf_node = conf_node;
-
-	return 0;
+	return conf_node;
 }
 
 struct fit_handle *fit_open(const char *filename, bool verbose,
diff --git a/include/bootm.h b/include/bootm.h
index 7ba7b8b96f..35c18dc276 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -75,6 +75,7 @@ struct image_data {
 
 	const void *fit_kernel;
 	unsigned long fit_kernel_size;
+	void *fit_config;
 
 	struct device_node *of_root_node;
 	struct fdt_header *oftree;
diff --git a/include/image-fit.h b/include/image-fit.h
index 0e26a40ef7..31e23b235a 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -29,15 +29,16 @@ struct fit_handle {
 	enum bootm_verify verify;
 
 	struct device_node *root;
-	struct device_node *conf_node;
 };
 
 struct fit_handle *fit_open(const char *filename, bool verbose,
 			    enum bootm_verify verify);
-int fit_open_configuration(struct fit_handle *handle, const char *name);
-int fit_has_image(struct fit_handle *handle, const char *name);
-int fit_open_image(struct fit_handle *handle, const char *name,
-		   const void **outdata, unsigned long *outsize);
+void *fit_open_configuration(struct fit_handle *handle, const char *name);
+int fit_has_image(struct fit_handle *handle, void *configuration,
+		  const char *name);
+int fit_open_image(struct fit_handle *handle, void *configuration,
+		   const char *name, const void **outdata,
+		   unsigned long *outsize);
 
 void fit_close(struct fit_handle *handle);
 
-- 
2.15.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 4/8] FIT: store device_nodes in fit_handle
  2018-01-31 11:11 [PATCH 0/8] FIT: Add support for opening images without a /configuration/ Sascha Hauer
                   ` (2 preceding siblings ...)
  2018-01-31 11:11 ` [PATCH 3/8] FIT: Let user specify the configuration to use Sascha Hauer
@ 2018-01-31 11:11 ` Sascha Hauer
  2018-01-31 11:11 ` [PATCH 5/8] FIT: move handle->verify check to fit_verify_hash() Sascha Hauer
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2018-01-31 11:11 UTC (permalink / raw)
  To: Barebox List

We need the /images and /configurations nodes more than once,
so store them in the fit_handle rather than searching for them
each time again.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/image-fit.c  | 20 ++++++++++++--------
 include/image-fit.h |  2 ++
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 138696ab78..21b547a1da 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -416,7 +416,7 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
 		   const char *name, const void **outdata,
 		   unsigned long *outsize)
 {
-	struct device_node *image = NULL, *hash;
+	struct device_node *image, *hash;
 	const char *unit, *type = NULL, *desc= "(no description)";
 	const void *data;
 	int data_len;
@@ -431,11 +431,7 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
 		return -ENOENT;
 	}
 
-	image = of_get_child_by_name(handle->root, "images");
-	if (!image)
-		return -ENOENT;
-
-	image = of_get_child_by_name(image, unit);
+	image = of_get_child_by_name(handle->images, unit);
 	if (!image)
 		return -ENOENT;
 
@@ -561,11 +557,10 @@ default_unit:
  */
 void *fit_open_configuration(struct fit_handle *handle, const char *name)
 {
-	struct device_node *conf_node = NULL;
+	struct device_node *conf_node = handle->configurations;
 	const char *unit, *desc = "(no description)";
 	int ret;
 
-	conf_node = of_get_child_by_name(handle->root, "configurations");
 	if (!conf_node)
 		return ERR_PTR(-ENOENT);
 
@@ -622,6 +617,15 @@ struct fit_handle *fit_open(const char *filename, bool verbose,
 	handle->root = root;
 	handle->verify = verify;
 
+	handle->images = of_get_child_by_name(handle->root, "images");
+	if (!handle->images) {
+		ret = -ENOENT;
+		goto err;
+	}
+
+	handle->configurations = of_get_child_by_name(handle->root,
+						      "configurations");
+
 	of_property_read_string(handle->root, "description", &desc);
 	pr_info("'%s': %s\n", filename, desc);
 
diff --git a/include/image-fit.h b/include/image-fit.h
index 31e23b235a..79b8101b83 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -29,6 +29,8 @@ struct fit_handle {
 	enum bootm_verify verify;
 
 	struct device_node *root;
+	struct device_node *images;
+	struct device_node *configurations;
 };
 
 struct fit_handle *fit_open(const char *filename, bool verbose,
-- 
2.15.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 5/8] FIT: move handle->verify check to fit_verify_hash()
  2018-01-31 11:11 [PATCH 0/8] FIT: Add support for opening images without a /configuration/ Sascha Hauer
                   ` (3 preceding siblings ...)
  2018-01-31 11:11 ` [PATCH 4/8] FIT: store device_nodes in fit_handle Sascha Hauer
@ 2018-01-31 11:11 ` Sascha Hauer
  2018-01-31 11:11 ` [PATCH 6/8] FIT: factor out some helper functions Sascha Hauer
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2018-01-31 11:11 UTC (permalink / raw)
  To: Barebox List

Preparation for the next step which will allow to open
images which are not part of a configuration.

This has one change inside: We used to iterate over all
subnodes of a image expecting all of them containing a hash,
so it could happen that we check multiple hashes if more exist
or that we falsely interpret some unrelated subnode as hash node.
With this patch we expect the hash in a subnode named "hash@1"
as required by the FIT image format description.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/image-fit.c | 45 +++++++++++++++++++++++++--------------------
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 21b547a1da..9948c1fa77 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -344,13 +344,33 @@ static int fit_verify_signature(struct device_node *sig_node, void *fit)
 	return ret;
 }
 
-static int fit_verify_hash(struct device_node *hash, const void *data, int data_len)
+static int fit_verify_hash(struct fit_handle *handle, struct device_node *image,
+			   const void *data, int data_len)
 {
 	struct digest *d;
 	const char *algo;
 	const char *value_read;
 	char *value_calc;
 	int hash_len, ret;
+	struct device_node *hash;
+
+	switch (handle->verify) {
+	case BOOTM_VERIFY_NONE:
+		return 0;
+	case BOOTM_VERIFY_AVAILABLE:
+		ret = 0;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	hash = of_get_child_by_name(image, "hash@1");
+	if (!hash) {
+		if (ret)
+			pr_err("image %s does not have hashes\n",
+			       image->full_name);
+		return ret;
+	}
 
 	value_read = of_get_property(hash, "value", &hash_len);
 	if (!value_read) {
@@ -416,7 +436,7 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
 		   const char *name, const void **outdata,
 		   unsigned long *outsize)
 {
-	struct device_node *image, *hash;
+	struct device_node *image;
 	const char *unit, *type = NULL, *desc= "(no description)";
 	const void *data;
 	int data_len;
@@ -450,24 +470,9 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
 		return -EINVAL;
 	}
 
-	if (handle->verify > BOOTM_VERIFY_NONE) {
-		if (handle->verify == BOOTM_VERIFY_AVAILABLE)
-			ret = 0;
-		else
-			ret = -EINVAL;
-		for_each_child_of_node(image, hash) {
-			if (handle->verbose)
-				of_print_nodes(hash, 0);
-			ret = fit_verify_hash(hash, data, data_len);
-			if (ret < 0)
-				return ret;
-		}
-
-		if (ret < 0) {
-			pr_err("image '%s': '%s' does not have hashes\n", unit, desc);
-			return ret;
-		}
-	}
+	ret = fit_verify_hash(handle, image, data, data_len);
+	if (ret < 0)
+		return ret;
 
 	*outdata = data;
 	*outsize = data_len;
-- 
2.15.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 6/8] FIT: factor out some helper functions
  2018-01-31 11:11 [PATCH 0/8] FIT: Add support for opening images without a /configuration/ Sascha Hauer
                   ` (4 preceding siblings ...)
  2018-01-31 11:11 ` [PATCH 5/8] FIT: move handle->verify check to fit_verify_hash() Sascha Hauer
@ 2018-01-31 11:11 ` Sascha Hauer
  2018-01-31 11:11 ` [PATCH 7/8] FIT: Implement opening images with no configuration Sascha Hauer
  2018-01-31 11:11 ` [PATCH 8/8] FIT: Allow to open buffer as FIT image Sascha Hauer
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2018-01-31 11:11 UTC (permalink / raw)
  To: Barebox List

Create and use fit_alloc_digest() and fit_read_rsa_public_key()
which we can use a second time in the next step.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/image-fit.c | 121 ++++++++++++++++++++++++++++++++---------------------
 1 file changed, 74 insertions(+), 47 deletions(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 9948c1fa77..86516f0ba9 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -230,28 +230,18 @@ static int fit_digest(void *fit, struct digest *digest,
 	return 0;
 }
 
-/*
- * The consistency of the FTD structure was already checked by of_unflatten_dtb()
- */
-static int fit_verify_signature(struct device_node *sig_node, void *fit)
+static struct digest *fit_alloc_digest(struct device_node *sig_node,
+				       enum hash_algo *algo_out)
 {
-	uint32_t hashed_strings_start, hashed_strings_size;
-	struct string_list inc_nodes, exc_props;
-	struct rsa_public_key key = {};
 	struct digest *digest;
-	int sig_len;
-	const char *algo_name, *key_name, *sig_value;
-	char *key_path;
-	struct device_node *key_node;
 	enum hash_algo algo;
-	void *hash;
-	int ret;
+	const char *algo_name;
 
 	if (of_property_read_string(sig_node, "algo", &algo_name)) {
-		pr_err("algo not found\n");
-		ret = -EINVAL;
-		goto out;
+		pr_err("algo property not found\n");
+		return ERR_PTR(-EINVAL);
 	}
+
 	if (strcmp(algo_name, "sha1,rsa2048") == 0) {
 		algo = HASH_ALGO_SHA1;
 	} else if (strcmp(algo_name, "sha256,rsa2048") == 0) {
@@ -260,53 +250,87 @@ static int fit_verify_signature(struct device_node *sig_node, void *fit)
 		algo = HASH_ALGO_SHA256;
 	} else	{
 		pr_err("unknown algo %s\n", algo_name);
-		ret = -EINVAL;
-		goto out;
+		return ERR_PTR(-EINVAL);
 	}
+
 	digest = digest_alloc_by_algo(algo);
 	if (!digest) {
 		pr_err("unsupported algo %s\n", algo_name);
-		ret = -EINVAL;
-		goto out;
+		return ERR_PTR(-EINVAL);
 	}
 
+	digest_init(digest);
+
+	*algo_out = algo;
+
+	return digest;
+}
+
+static int fit_check_rsa_signature(struct device_node *sig_node,
+				   enum hash_algo algo, void *hash)
+{
+	struct rsa_public_key key = {};
+	const char *key_name;
+	char *key_path;
+	struct device_node *key_node;
+	int sig_len;
+	const char *sig_value;
+	int ret;
+
 	sig_value = of_get_property(sig_node, "value", &sig_len);
 	if (!sig_value) {
 		pr_err("signature value not found in %s\n", sig_node->full_name);
-		ret = -EINVAL;
-		goto out_free_digest;
+		return -EINVAL;
 	}
 
 	if (of_property_read_string(sig_node, "key-name-hint", &key_name)) {
 		pr_err("key name not found in %s\n", sig_node->full_name);
-		ret = -EINVAL;
-		goto out_free_digest;
+		return -EINVAL;
 	}
 	key_path = xasprintf("/signature/key-%s", key_name);
 	key_node = of_find_node_by_path(key_path);
 	free(key_path);
 	if (!key_node) {
 		pr_info("failed to find key node\n");
-		ret = -ENOENT;
-		goto out_free_digest;
+		return -ENOENT;
 	}
 
 	ret = rsa_of_read_key(key_node, &key);
 	if (ret) {
 		pr_info("failed to read key in %s\n", key_node->full_name);
-		ret = -ENOENT;
-		goto out_free_digest;
+		return -ENOENT;
 	}
 
-	if (of_property_read_u32_index(sig_node, "hashed-strings", 0, &hashed_strings_start)) {
+	ret = rsa_verify(&key, sig_value, sig_len, hash, algo);
+	if (ret)
+		pr_err("image signature BAD\n");
+	else
+		pr_info("image signature OK\n");
+
+	return ret;
+}
+
+/*
+ * The consistency of the FTD structure was already checked by of_unflatten_dtb()
+ */
+static int fit_verify_signature(struct device_node *sig_node, void *fit)
+{
+	uint32_t hashed_strings_start, hashed_strings_size;
+	struct string_list inc_nodes, exc_props;
+	struct digest *digest;
+	void *hash;
+	enum hash_algo algo = 0;
+	int ret;
+
+	if (of_property_read_u32_index(sig_node, "hashed-strings", 0,
+	    &hashed_strings_start)) {
 		pr_err("hashed-strings start not found in %s\n", sig_node->full_name);
-		ret = -EINVAL;
-		goto out_free_digest;
+		return -EINVAL;
 	}
-	if (of_property_read_u32_index(sig_node, "hashed-strings", 1, &hashed_strings_size)) {
+	if (of_property_read_u32_index(sig_node, "hashed-strings", 1,
+	    &hashed_strings_size)) {
 		pr_err("hashed-strings size not found in %s\n", sig_node->full_name);
-		ret = -EINVAL;
-		goto out_free_digest;
+		return -EINVAL;
 	}
 
 	string_list_init(&inc_nodes);
@@ -320,27 +344,30 @@ static int fit_verify_signature(struct device_node *sig_node, void *fit)
 
 	string_list_add(&exc_props, "data");
 
-	digest_init(digest);
-	ret = fit_digest(fit, digest, &inc_nodes, &exc_props, hashed_strings_start, hashed_strings_size);
+	digest = fit_alloc_digest(sig_node, &algo);
+	if (IS_ERR(digest)) {
+		ret = PTR_ERR(digest);
+		goto out_sl;
+	}
+
+	ret = fit_digest(fit, digest, &inc_nodes, &exc_props, hashed_strings_start,
+			 hashed_strings_size);
 	hash = xzalloc(digest_length(digest));
 	digest_final(digest, hash);
 
-	ret = rsa_verify(&key, sig_value, sig_len, hash, algo);
-	if (ret) {
-		pr_info("image signature BAD\n");
-		ret = -EBADMSG;
-	} else {
-		pr_info("image signature OK\n");
-		ret = 0;
-	}
+	ret = fit_check_rsa_signature(sig_node, algo, hash);
+	if (ret)
+		goto out_free_hash;
 
+	ret = 0;
+
+ out_free_hash:
 	free(hash);
+	digest_free(digest);
  out_sl:
 	string_list_free(&inc_nodes);
 	string_list_free(&exc_props);
- out_free_digest:
-	digest_free(digest);
- out:
+ 
 	return ret;
 }
 
-- 
2.15.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 7/8] FIT: Implement opening images with no configuration
  2018-01-31 11:11 [PATCH 0/8] FIT: Add support for opening images without a /configuration/ Sascha Hauer
                   ` (5 preceding siblings ...)
  2018-01-31 11:11 ` [PATCH 6/8] FIT: factor out some helper functions Sascha Hauer
@ 2018-01-31 11:11 ` Sascha Hauer
  2018-01-31 11:11 ` [PATCH 8/8] FIT: Allow to open buffer as FIT image Sascha Hauer
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2018-01-31 11:11 UTC (permalink / raw)
  To: Barebox List

different images can be grouped together to build a FIT configuration.
So far we only supported opening images as parts of configurations.
This patch adds support for opening images that are not part of a
configuration. This mode is used when the configuration parameter of
fit_open_image is NULL.

The main difference is in the way the RSA signature is checked. When
being part of a configuration all involved nodes (including the hash
nodes of the images, but not the image itself) are covered by the
signature, thus during opening an image only the validity of the image
data hash has to be checked. When not being part of a configuration,
the image data itself is signed and must be checked.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/image-fit.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 75 insertions(+), 7 deletions(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 86516f0ba9..4ebd4b8c42 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -444,6 +444,52 @@ err_digest_free:
 	return ret;
 }
 
+static int fit_image_verify_signature(struct fit_handle *handle,
+				      struct device_node *image,
+				      const void *data, int data_len)
+{
+	struct digest *digest;
+	struct device_node *sig_node;
+	enum hash_algo algo = 0;
+	void *hash;
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_FITIMAGE_SIGNATURE))
+		return 0;
+
+	switch (handle->verify) {
+	case BOOTM_VERIFY_NONE:
+		return 0;
+	case BOOTM_VERIFY_AVAILABLE:
+		ret = 0;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	sig_node = of_get_child_by_name(image, "signature@1");
+	if (!sig_node) {
+		pr_err("Image %s has no signature\n", image->full_name);
+		return ret;
+	}
+
+	digest = fit_alloc_digest(sig_node, &algo);
+	if (IS_ERR(digest))
+		return PTR_ERR(digest);
+
+	digest_update(digest, data, data_len);
+	hash = xzalloc(digest_length(digest));
+	digest_final(digest, hash);
+
+	ret = fit_check_rsa_signature(sig_node, algo, hash);
+
+	free(hash);
+
+	digest_free(digest);
+
+	return ret;
+}
+
 int fit_has_image(struct fit_handle *handle, void *configuration,
 		  const char *name)
 {
@@ -459,6 +505,23 @@ int fit_has_image(struct fit_handle *handle, void *configuration,
 	return 1;
 }
 
+/**
+ * fit_open_image - Open an image in a FIT image
+ * @handle: The FIT image handle
+ * @name: The name of the image to open
+ * @outdata: The returned image
+ * @outsize: Size of the returned image
+ *
+ * Open an image in a FIT image. The returned image is freed during fit_close().
+ * @configuration holds the cookie returned from fit_open_configuration() if
+ * the image is opened as part of a configuration, or NULL if the image is
+ * opened without a configuration. If @configuration is NULL then the RSA
+ * signature of the image is checked if desired, if @configuration is non NULL,
+ * then only the hash is checked (because opening the configuration already
+ * checks the RSA signature of all involved nodes).
+ *
+ * Return: 0 for success, negative error code otherwise
+ */
 int fit_open_image(struct fit_handle *handle, void *configuration,
 		   const char *name, const void **outdata,
 		   unsigned long *outsize)
@@ -470,12 +533,13 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
 	int ret = 0;
 	struct device_node *conf_node = configuration;
 
-	if (!conf_node)
-		return -EINVAL;
-
-	if (of_property_read_string(conf_node, name, &unit)) {
-		pr_err("No image named '%s'\n", name);
-		return -ENOENT;
+	if (conf_node) {
+		if (of_property_read_string(conf_node, name, &unit)) {
+			pr_err("No image named '%s'\n", name);
+			return -ENOENT;
+		}
+	} else {
+		unit = name;
 	}
 
 	image = of_get_child_by_name(handle->images, unit);
@@ -497,7 +561,11 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
 		return -EINVAL;
 	}
 
-	ret = fit_verify_hash(handle, image, data, data_len);
+	if (conf_node)
+		ret = fit_verify_hash(handle, image, data, data_len);
+	else
+		ret = fit_image_verify_signature(handle, image, data, data_len);
+
 	if (ret < 0)
 		return ret;
 
-- 
2.15.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 8/8] FIT: Allow to open buffer as FIT image
  2018-01-31 11:11 [PATCH 0/8] FIT: Add support for opening images without a /configuration/ Sascha Hauer
                   ` (6 preceding siblings ...)
  2018-01-31 11:11 ` [PATCH 7/8] FIT: Implement opening images with no configuration Sascha Hauer
@ 2018-01-31 11:11 ` Sascha Hauer
  7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2018-01-31 11:11 UTC (permalink / raw)
  To: Barebox List

This adds fit_open_buf() which can open a buffer as FIT image.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/image-fit.c  | 113 +++++++++++++++++++++++++++++++++++++---------------
 include/image-fit.h |   5 ++-
 2 files changed, 85 insertions(+), 33 deletions(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index 4ebd4b8c42..3fab52db2e 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -74,11 +74,11 @@ static int of_read_string_list(struct device_node *np, const char *name, struct
 	return prop ? 0 : -EINVAL;
 }
 
-static int fit_digest(void *fit, struct digest *digest,
+static int fit_digest(const void *fit, struct digest *digest,
 		      struct string_list *inc_nodes, struct string_list *exc_props,
 		      uint32_t hashed_strings_start, uint32_t hashed_strings_size)
 {
-	struct fdt_header *fdt = fit;
+	const struct fdt_header *fdt = fit;
 	uint32_t dt_struct;
 	void *dt_strings;
 	struct fdt_header f = {};
@@ -313,7 +313,7 @@ static int fit_check_rsa_signature(struct device_node *sig_node,
 /*
  * The consistency of the FTD structure was already checked by of_unflatten_dtb()
  */
-static int fit_verify_signature(struct device_node *sig_node, void *fit)
+static int fit_verify_signature(struct device_node *sig_node, const void *fit)
 {
 	uint32_t hashed_strings_start, hashed_strings_size;
 	struct string_list inc_nodes, exc_props;
@@ -690,61 +690,110 @@ void *fit_open_configuration(struct fit_handle *handle, const char *name)
 	return conf_node;
 }
 
-struct fit_handle *fit_open(const char *filename, bool verbose,
-			    enum bootm_verify verify)
+static int fit_do_open(struct fit_handle *handle)
 {
-	struct fit_handle *handle = NULL;
 	const char *desc = "(no description)";
 	struct device_node *root;
+
+	root = of_unflatten_dtb(handle->fit);
+	if (IS_ERR(root))
+		return PTR_ERR(root);
+
+	handle->root = root;
+
+	handle->images = of_get_child_by_name(handle->root, "images");
+	if (!handle->images)
+		return -ENOENT;
+
+	handle->configurations = of_get_child_by_name(handle->root,
+						      "configurations");
+
+	of_property_read_string(handle->root, "description", &desc);
+	pr_info("Opened FIT image: %s\n", desc);
+
+	return 0;
+}
+
+/**
+ * fit_open_buf - open a FIT image from a buffer
+ * @buf:	The buffer containing the FIT image
+ * @size:	Size of the FIT image
+ * @verbose:	If true, be more verbose
+ * @verify:	The verify mode
+ *
+ * This opens a FIT image found in buf. The returned handle is used as
+ * context for the other FIT functions.
+ *
+ * Return: A handle to a FIT image or a ERR_PTR
+ */
+struct fit_handle *fit_open_buf(const void *buf, size_t size, bool verbose,
+				enum bootm_verify verify)
+{
+	struct fit_handle *handle;
 	int ret;
 
 	handle = xzalloc(sizeof(struct fit_handle));
 
 	handle->verbose = verbose;
+	handle->fit = buf;
+	handle->size = size;
+	handle->verify = verify;
 
-	ret = read_file_2(filename, &handle->size, &handle->fit, FILESIZE_MAX);
+	ret = fit_do_open(handle);
 	if (ret) {
-		pr_err("unable to read %s: %s\n", filename, strerror(-ret));
-		goto err;
+		fit_close(handle);
+		return ERR_PTR(ret);
 	}
 
-	root = of_unflatten_dtb(handle->fit);
-	if (IS_ERR(root)) {
-		ret = PTR_ERR(root);
-		goto err;
-	}
+	return handle;
+}
 
-	handle->root = root;
+/**
+ * fit_open - open a FIT image
+ * @filename:	The filename of the FIT image
+ * @verbose:	If true, be more verbose
+ * @verify:	The verify mode
+ *
+ * This opens a FIT image found in @filename. The returned handle is used as
+ * context for the other FIT functions.
+ *
+ * Return: A handle to a FIT image or a ERR_PTR
+ */
+struct fit_handle *fit_open(const char *filename, bool verbose,
+			    enum bootm_verify verify)
+{
+	struct fit_handle *handle;
+	int ret;
+
+	handle = xzalloc(sizeof(struct fit_handle));
+
+	handle->verbose = verbose;
 	handle->verify = verify;
 
-	handle->images = of_get_child_by_name(handle->root, "images");
-	if (!handle->images) {
-		ret = -ENOENT;
-		goto err;
+	ret = read_file_2(filename, &handle->size, &handle->fit_alloc,
+			  FILESIZE_MAX);
+	if (ret) {
+		pr_err("unable to read %s: %s\n", filename, strerror(-ret));
+		return ERR_PTR(ret);
 	}
 
-	handle->configurations = of_get_child_by_name(handle->root,
-						      "configurations");
+	handle->fit = handle->fit_alloc;
 
-	of_property_read_string(handle->root, "description", &desc);
-	pr_info("'%s': %s\n", filename, desc);
+	ret = fit_do_open(handle);
+	if (ret) {
+		fit_close(handle);
+		return ERR_PTR(ret);
+	}
 
 	return handle;
- err:
-	if (handle->root)
-		of_delete_node(handle->root);
-	free(handle->fit);
-	free(handle);
-
-	return ERR_PTR(ret);
 }
 
 void fit_close(struct fit_handle *handle)
 {
 	if (handle->root)
 		of_delete_node(handle->root);
-	if (handle->fit)
-		free(handle->fit);
+
+	free(handle->fit_alloc);
 	free(handle);
 }
 
diff --git a/include/image-fit.h b/include/image-fit.h
index 79b8101b83..fc0883b5dc 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -22,7 +22,8 @@
 #include <bootm.h>
 
 struct fit_handle {
-	void *fit;
+	const void *fit;
+	void *fit_alloc;
 	size_t size;
 
 	bool verbose;
@@ -35,6 +36,8 @@ struct fit_handle {
 
 struct fit_handle *fit_open(const char *filename, bool verbose,
 			    enum bootm_verify verify);
+struct fit_handle *fit_open_buf(const void *buf, size_t len, bool verbose,
+				enum bootm_verify verify);
 void *fit_open_configuration(struct fit_handle *handle, const char *name);
 int fit_has_image(struct fit_handle *handle, void *configuration,
 		  const char *name);
-- 
2.15.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2018-01-31 11:11 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-31 11:11 [PATCH 0/8] FIT: Add support for opening images without a /configuration/ Sascha Hauer
2018-01-31 11:11 ` [PATCH 1/8] bootm: FIT: do not depend on FIT pre-opened images Sascha Hauer
2018-01-31 11:11 ` [PATCH 2/8] FIT: Do not pre-open images Sascha Hauer
2018-01-31 11:11 ` [PATCH 3/8] FIT: Let user specify the configuration to use Sascha Hauer
2018-01-31 11:11 ` [PATCH 4/8] FIT: store device_nodes in fit_handle Sascha Hauer
2018-01-31 11:11 ` [PATCH 5/8] FIT: move handle->verify check to fit_verify_hash() Sascha Hauer
2018-01-31 11:11 ` [PATCH 6/8] FIT: factor out some helper functions Sascha Hauer
2018-01-31 11:11 ` [PATCH 7/8] FIT: Implement opening images with no configuration Sascha Hauer
2018-01-31 11:11 ` [PATCH 8/8] FIT: Allow to open buffer as FIT image Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox