All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] mkimage: fit: only process one cipher node
@ 2020-07-17  7:28 patrick.oppenlander at gmail.com
  2020-07-17  7:28 ` [PATCH 2/3] mkimage: fit: handle FDT_ERR_NOSPACE when ciphering patrick.oppenlander at gmail.com
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: patrick.oppenlander at gmail.com @ 2020-07-17  7:28 UTC (permalink / raw)
  To: u-boot

From: Patrick Oppenlander <patrick.oppenlander@gmail.com>

Previously mkimage would process any node matching the regex cipher.*
and apply the ciphers to the image data in the order they appeared in
the FDT. This meant that data could be inadvertently ciphered multiple
times.

Switch to processing a single cipher node which exactly matches
FIT_CIPHER_NODENAME.

Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
---
 tools/image-host.c | 56 +++++++++++++++++-----------------------------
 1 file changed, 21 insertions(+), 35 deletions(-)

diff --git a/tools/image-host.c b/tools/image-host.c
index 9a83b7f675..8fa1b9aba7 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -323,15 +323,15 @@ err:
 static int fit_image_setup_cipher(struct image_cipher_info *info,
 				  const char *keydir, void *fit,
 				  const char *image_name, int image_noffset,
-				  const char *node_name, int noffset)
+				  int noffset)
 {
 	char *algo_name;
 	char filename[128];
 	int ret = -1;
 
 	if (fit_image_cipher_get_algo(fit, noffset, &algo_name)) {
-		printf("Can't get algo name for cipher '%s' in image '%s'\n",
-		       node_name, image_name);
+		printf("Can't get algo name for cipher in image '%s'\n",
+		       image_name);
 		goto out;
 	}
 
@@ -340,16 +340,16 @@ static int fit_image_setup_cipher(struct image_cipher_info *info,
 	/* Read the key name */
 	info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
 	if (!info->keyname) {
-		printf("Can't get key name for cipher '%s' in image '%s'\n",
-		       node_name, image_name);
+		printf("Can't get key name for cipher in image '%s'\n",
+		       image_name);
 		goto out;
 	}
 
 	/* Read the IV name */
 	info->ivname = fdt_getprop(fit, noffset, "iv-name-hint", NULL);
 	if (!info->ivname) {
-		printf("Can't get iv name for cipher '%s' in image '%s'\n",
-		       node_name, image_name);
+		printf("Can't get iv name for cipher in image '%s'\n",
+		       image_name);
 		goto out;
 	}
 
@@ -428,8 +428,7 @@ int fit_image_write_cipher(void *fit, int image_noffset, int noffset,
 static int
 fit_image_process_cipher(const char *keydir, void *keydest, void *fit,
 			 const char *image_name, int image_noffset,
-			 const char *node_name, int node_noffset,
-			 const void *data, size_t size,
+			 int node_noffset, const void *data, size_t size,
 			 const char *cmdname)
 {
 	struct image_cipher_info info;
@@ -440,7 +439,7 @@ fit_image_process_cipher(const char *keydir, void *keydest, void *fit,
 	memset(&info, 0, sizeof(info));
 
 	ret = fit_image_setup_cipher(&info, keydir, fit, image_name,
-				     image_noffset, node_name, node_noffset);
+				     image_noffset, node_noffset);
 	if (ret)
 		goto out;
 
@@ -482,7 +481,7 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
 	const char *image_name;
 	const void *data;
 	size_t size;
-	int node_noffset;
+	int cipher_node_offset;
 
 	/* Get image name */
 	image_name = fit_get_name(fit, image_noffset, NULL);
@@ -497,32 +496,19 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
 		return -1;
 	}
 
-	/* Process all hash subnodes of the component image node */
-	for (node_noffset = fdt_first_subnode(fit, image_noffset);
-	     node_noffset >= 0;
-	     node_noffset = fdt_next_subnode(fit, node_noffset)) {
-		const char *node_name;
-		int ret = 0;
-
-		node_name = fit_get_name(fit, node_noffset, NULL);
-		if (!node_name) {
-			printf("Can't get node name\n");
-			return -1;
-		}
 
-		if (IMAGE_ENABLE_ENCRYPT && keydir &&
-		    !strncmp(node_name, FIT_CIPHER_NODENAME,
-			     strlen(FIT_CIPHER_NODENAME)))
-			ret = fit_image_process_cipher(keydir, keydest,
-						       fit, image_name,
-						       image_noffset,
-						       node_name, node_noffset,
-						       data, size, cmdname);
-		if (ret)
-			return ret;
+	/* Process cipher node if present */
+	cipher_node_offset = fdt_subnode_offset(fit, image_noffset, "cipher");
+	if (cipher_node_offset == -FDT_ERR_NOTFOUND)
+		return 0;
+	if (cipher_node_offset < 0) {
+		printf("Failure getting cipher node\n");
+		return -1;
 	}
-
-	return 0;
+	if (!IMAGE_ENABLE_ENCRYPT || !keydir)
+		return 0;
+	return fit_image_process_cipher(keydir, keydest, fit, image_name,
+		image_noffset, cipher_node_offset, data, size, cmdname);
 }
 
 /**
-- 
2.27.0

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

* [PATCH 2/3] mkimage: fit: handle FDT_ERR_NOSPACE when ciphering
  2020-07-17  7:28 [PATCH 1/3] mkimage: fit: only process one cipher node patrick.oppenlander at gmail.com
@ 2020-07-17  7:28 ` patrick.oppenlander at gmail.com
  2020-07-29 15:02   ` Philippe REYNES
  2020-07-17  7:28 ` [PATCH 3/3] mkimage: fit: don't cipher ciphered data patrick.oppenlander at gmail.com
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: patrick.oppenlander at gmail.com @ 2020-07-17  7:28 UTC (permalink / raw)
  To: u-boot

From: Patrick Oppenlander <patrick.oppenlander@gmail.com>

This meant that the order of operations had to change. If we replace the
data property first then fail to add the data-size-unciphered property
the data will be ciphered again when retrying.

Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
---
 tools/image-host.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/tools/image-host.c b/tools/image-host.c
index 8fa1b9aba7..87ef79ef53 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -399,25 +399,26 @@ int fit_image_write_cipher(void *fit, int image_noffset, int noffset,
 {
 	int ret = -1;
 
-	/* Remove unciphered data */
-	ret = fdt_delprop(fit, image_noffset, FIT_DATA_PROP);
+	/* add non ciphered data size */
+	ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
+	if (ret == -FDT_ERR_NOSPACE) {
+		ret = -ENOSPC;
+		goto out;
+	}
 	if (ret) {
-		printf("Can't remove data (err = %d)\n", ret);
+		printf("Can't add unciphered data size (err = %d)\n", ret);
 		goto out;
 	}
 
 	/* Add ciphered data */
 	ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP,
 			  data_ciphered, data_ciphered_len);
-	if (ret) {
-		printf("Can't add ciphered data (err = %d)\n", ret);
+	if (ret == -FDT_ERR_NOSPACE) {
+		ret = -ENOSPC;
 		goto out;
 	}
-
-	/* add non ciphered data size */
-	ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
 	if (ret) {
-		printf("Can't add unciphered data size (err = %d)\n", ret);
+		printf("Can't add ciphered data (err = %d)\n", ret);
 		goto out;
 	}
 
-- 
2.27.0

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

* [PATCH 3/3] mkimage: fit: don't cipher ciphered data
  2020-07-17  7:28 [PATCH 1/3] mkimage: fit: only process one cipher node patrick.oppenlander at gmail.com
  2020-07-17  7:28 ` [PATCH 2/3] mkimage: fit: handle FDT_ERR_NOSPACE when ciphering patrick.oppenlander at gmail.com
@ 2020-07-17  7:28 ` patrick.oppenlander at gmail.com
  2020-07-29 17:17   ` Philippe REYNES
  2020-07-27 23:45 ` [PATCH 1/3] mkimage: fit: only process one cipher node Simon Glass
  2020-07-29 14:50 ` Philippe REYNES
  3 siblings, 1 reply; 9+ messages in thread
From: patrick.oppenlander at gmail.com @ 2020-07-17  7:28 UTC (permalink / raw)
  To: u-boot

From: Patrick Oppenlander <patrick.oppenlander@gmail.com>

Previously, mkimage -F could be run multiple times causing already
ciphered image data to be ciphered again.

Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
---
 tools/image-host.c | 47 +++++++++++++++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 15 deletions(-)

diff --git a/tools/image-host.c b/tools/image-host.c
index 87ef79ef53..12de9b5ec0 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -397,33 +397,43 @@ int fit_image_write_cipher(void *fit, int image_noffset, int noffset,
 			   const void *data, size_t size,
 			   unsigned char *data_ciphered, int data_ciphered_len)
 {
-	int ret = -1;
+	/*
+	 * fit_image_cipher_data() uses the presence of the data-size-unciphered
+	 * property as a sentinel to detect whether the data for this image is
+	 * already encrypted. This is important as:
+	 * - 'mkimage -F' can be run multiple times on a FIT image
+	 * - This function is in a retry loop to handle ENOSPC
+	 */
 
-	/* add non ciphered data size */
+	int ret;
+
+	/* Add unciphered data size */
 	ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
-	if (ret == -FDT_ERR_NOSPACE) {
-		ret = -ENOSPC;
-		goto out;
-	}
+	if (ret == -FDT_ERR_NOSPACE)
+		return -ENOSPC;
 	if (ret) {
 		printf("Can't add unciphered data size (err = %d)\n", ret);
-		goto out;
+		return -EIO;
 	}
 
-	/* Add ciphered data */
+	/* Replace contents of data property with data_ciphered */
 	ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP,
 			  data_ciphered, data_ciphered_len);
 	if (ret == -FDT_ERR_NOSPACE) {
-		ret = -ENOSPC;
-		goto out;
+		/* Remove data-size-unciphered; data is not ciphered */
+		ret = fdt_delprop(fit, image_noffset, "data-size-unciphered");
+		if (ret) {
+			printf("Can't remove unciphered data size (err = %d)\n", ret);
+			return -EIO;
+		}
+		return -ENOSPC;
 	}
 	if (ret) {
-		printf("Can't add ciphered data (err = %d)\n", ret);
-		goto out;
+		printf("Can't replace data with ciphered data (err = %d)\n", ret);
+		return -EIO;
 	}
 
- out:
-	return ret;
+	return 0;
 }
 
 static int
@@ -482,7 +492,7 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
 	const char *image_name;
 	const void *data;
 	size_t size;
-	int cipher_node_offset;
+	int cipher_node_offset, len;
 
 	/* Get image name */
 	image_name = fit_get_name(fit, image_noffset, NULL);
@@ -497,6 +507,13 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
 		return -1;
 	}
 
+	/* Don't cipher ciphered data */
+	if (fdt_getprop(fit, image_noffset, "data-size-unciphered", &len))
+		return 0;
+	if (len != -FDT_ERR_NOTFOUND) {
+		printf("Failure testing for data-size-unciphered\n");
+		return -1;
+	}
 
 	/* Process cipher node if present */
 	cipher_node_offset = fdt_subnode_offset(fit, image_noffset, "cipher");
-- 
2.27.0

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

* [PATCH 1/3] mkimage: fit: only process one cipher node
  2020-07-17  7:28 [PATCH 1/3] mkimage: fit: only process one cipher node patrick.oppenlander at gmail.com
  2020-07-17  7:28 ` [PATCH 2/3] mkimage: fit: handle FDT_ERR_NOSPACE when ciphering patrick.oppenlander at gmail.com
  2020-07-17  7:28 ` [PATCH 3/3] mkimage: fit: don't cipher ciphered data patrick.oppenlander at gmail.com
@ 2020-07-27 23:45 ` Simon Glass
  2020-07-29 14:50 ` Philippe REYNES
  3 siblings, 0 replies; 9+ messages in thread
From: Simon Glass @ 2020-07-27 23:45 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

On Fri, 17 Jul 2020 at 05:30, <patrick.oppenlander@gmail.com> wrote:
>
> From: Patrick Oppenlander <patrick.oppenlander@gmail.com>
>
> Previously mkimage would process any node matching the regex cipher.*
> and apply the ciphers to the image data in the order they appeared in
> the FDT. This meant that data could be inadvertently ciphered multiple
> times.
>
> Switch to processing a single cipher node which exactly matches
> FIT_CIPHER_NODENAME.
>
> Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
> ---
>  tools/image-host.c | 56 +++++++++++++++++-----------------------------
>  1 file changed, 21 insertions(+), 35 deletions(-)

+Philippe Reynes for a review on these three patches too.

>
> diff --git a/tools/image-host.c b/tools/image-host.c
> index 9a83b7f675..8fa1b9aba7 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -323,15 +323,15 @@ err:
>  static int fit_image_setup_cipher(struct image_cipher_info *info,
>                                   const char *keydir, void *fit,
>                                   const char *image_name, int image_noffset,
> -                                 const char *node_name, int noffset)
> +                                 int noffset)
>  {
>         char *algo_name;
>         char filename[128];
>         int ret = -1;
>
>         if (fit_image_cipher_get_algo(fit, noffset, &algo_name)) {
> -               printf("Can't get algo name for cipher '%s' in image '%s'\n",
> -                      node_name, image_name);
> +               printf("Can't get algo name for cipher in image '%s'\n",
> +                      image_name);
>                 goto out;
>         }
>
> @@ -340,16 +340,16 @@ static int fit_image_setup_cipher(struct image_cipher_info *info,
>         /* Read the key name */
>         info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
>         if (!info->keyname) {
> -               printf("Can't get key name for cipher '%s' in image '%s'\n",
> -                      node_name, image_name);
> +               printf("Can't get key name for cipher in image '%s'\n",
> +                      image_name);
>                 goto out;
>         }
>
>         /* Read the IV name */
>         info->ivname = fdt_getprop(fit, noffset, "iv-name-hint", NULL);
>         if (!info->ivname) {
> -               printf("Can't get iv name for cipher '%s' in image '%s'\n",
> -                      node_name, image_name);
> +               printf("Can't get iv name for cipher in image '%s'\n",
> +                      image_name);
>                 goto out;
>         }
>
> @@ -428,8 +428,7 @@ int fit_image_write_cipher(void *fit, int image_noffset, int noffset,
>  static int
>  fit_image_process_cipher(const char *keydir, void *keydest, void *fit,
>                          const char *image_name, int image_noffset,
> -                        const char *node_name, int node_noffset,
> -                        const void *data, size_t size,
> +                        int node_noffset, const void *data, size_t size,
>                          const char *cmdname)
>  {
>         struct image_cipher_info info;
> @@ -440,7 +439,7 @@ fit_image_process_cipher(const char *keydir, void *keydest, void *fit,
>         memset(&info, 0, sizeof(info));
>
>         ret = fit_image_setup_cipher(&info, keydir, fit, image_name,
> -                                    image_noffset, node_name, node_noffset);
> +                                    image_noffset, node_noffset);
>         if (ret)
>                 goto out;
>
> @@ -482,7 +481,7 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
>         const char *image_name;
>         const void *data;
>         size_t size;
> -       int node_noffset;
> +       int cipher_node_offset;
>
>         /* Get image name */
>         image_name = fit_get_name(fit, image_noffset, NULL);
> @@ -497,32 +496,19 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
>                 return -1;
>         }
>
> -       /* Process all hash subnodes of the component image node */
> -       for (node_noffset = fdt_first_subnode(fit, image_noffset);
> -            node_noffset >= 0;
> -            node_noffset = fdt_next_subnode(fit, node_noffset)) {
> -               const char *node_name;
> -               int ret = 0;
> -
> -               node_name = fit_get_name(fit, node_noffset, NULL);
> -               if (!node_name) {
> -                       printf("Can't get node name\n");
> -                       return -1;
> -               }
>
> -               if (IMAGE_ENABLE_ENCRYPT && keydir &&
> -                   !strncmp(node_name, FIT_CIPHER_NODENAME,
> -                            strlen(FIT_CIPHER_NODENAME)))
> -                       ret = fit_image_process_cipher(keydir, keydest,
> -                                                      fit, image_name,
> -                                                      image_noffset,
> -                                                      node_name, node_noffset,
> -                                                      data, size, cmdname);
> -               if (ret)
> -                       return ret;
> +       /* Process cipher node if present */
> +       cipher_node_offset = fdt_subnode_offset(fit, image_noffset, "cipher");
> +       if (cipher_node_offset == -FDT_ERR_NOTFOUND)
> +               return 0;
> +       if (cipher_node_offset < 0) {
> +               printf("Failure getting cipher node\n");
> +               return -1;
>         }
> -
> -       return 0;
> +       if (!IMAGE_ENABLE_ENCRYPT || !keydir)
> +               return 0;
> +       return fit_image_process_cipher(keydir, keydest, fit, image_name,
> +               image_noffset, cipher_node_offset, data, size, cmdname);
>  }
>
>  /**
> --
> 2.27.0
>

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

* [PATCH 1/3] mkimage: fit: only process one cipher node
  2020-07-17  7:28 [PATCH 1/3] mkimage: fit: only process one cipher node patrick.oppenlander at gmail.com
                   ` (2 preceding siblings ...)
  2020-07-27 23:45 ` [PATCH 1/3] mkimage: fit: only process one cipher node Simon Glass
@ 2020-07-29 14:50 ` Philippe REYNES
  3 siblings, 0 replies; 9+ messages in thread
From: Philippe REYNES @ 2020-07-29 14:50 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

> From: Patrick Oppenlander <patrick.oppenlander@gmail.com>
> 
> Previously mkimage would process any node matching the regex cipher.*
> and apply the ciphers to the image data in the order they appeared in
> the FDT. This meant that data could be inadvertently ciphered multiple
> times.
> 
> Switch to processing a single cipher node which exactly matches
> FIT_CIPHER_NODENAME.
> 
> Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
> ---
> tools/image-host.c | 56 +++++++++++++++++-----------------------------
> 1 file changed, 21 insertions(+), 35 deletions(-)
> 
> diff --git a/tools/image-host.c b/tools/image-host.c
> index 9a83b7f675..8fa1b9aba7 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -323,15 +323,15 @@ err:
> static int fit_image_setup_cipher(struct image_cipher_info *info,
> const char *keydir, void *fit,
> const char *image_name, int image_noffset,
> - const char *node_name, int noffset)
> + int noffset)
> {
> char *algo_name;
> char filename[128];
> int ret = -1;
> 
> if (fit_image_cipher_get_algo(fit, noffset, &algo_name)) {
> - printf("Can't get algo name for cipher '%s' in image '%s'\n",
> - node_name, image_name);
> + printf("Can't get algo name for cipher in image '%s'\n",
> + image_name);
> goto out;
> }
> 
> @@ -340,16 +340,16 @@ static int fit_image_setup_cipher(struct image_cipher_info
> *info,
> /* Read the key name */
> info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
> if (!info->keyname) {
> - printf("Can't get key name for cipher '%s' in image '%s'\n",
> - node_name, image_name);
> + printf("Can't get key name for cipher in image '%s'\n",
> + image_name);
> goto out;
> }
> 
> /* Read the IV name */
> info->ivname = fdt_getprop(fit, noffset, "iv-name-hint", NULL);
> if (!info->ivname) {
> - printf("Can't get iv name for cipher '%s' in image '%s'\n",
> - node_name, image_name);
> + printf("Can't get iv name for cipher in image '%s'\n",
> + image_name);
> goto out;
> }
> 
> @@ -428,8 +428,7 @@ int fit_image_write_cipher(void *fit, int image_noffset, int
> noffset,
> static int
> fit_image_process_cipher(const char *keydir, void *keydest, void *fit,
> const char *image_name, int image_noffset,
> - const char *node_name, int node_noffset,
> - const void *data, size_t size,
> + int node_noffset, const void *data, size_t size,
> const char *cmdname)
> {
> struct image_cipher_info info;
> @@ -440,7 +439,7 @@ fit_image_process_cipher(const char *keydir, void *keydest,
> void *fit,
> memset(&info, 0, sizeof(info));
> 
> ret = fit_image_setup_cipher(&info, keydir, fit, image_name,
> - image_noffset, node_name, node_noffset);
> + image_noffset, node_noffset);
> if (ret)
> goto out;
> 
> @@ -482,7 +481,7 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
> const char *image_name;
> const void *data;
> size_t size;
> - int node_noffset;
> + int cipher_node_offset;
> 
> /* Get image name */
> image_name = fit_get_name(fit, image_noffset, NULL);
> @@ -497,32 +496,19 @@ int fit_image_cipher_data(const char *keydir, void
> *keydest,
> return -1;
> }
> 
> - /* Process all hash subnodes of the component image node */
> - for (node_noffset = fdt_first_subnode(fit, image_noffset);
> - node_noffset >= 0;
> - node_noffset = fdt_next_subnode(fit, node_noffset)) {
> - const char *node_name;
> - int ret = 0;
> -
> - node_name = fit_get_name(fit, node_noffset, NULL);
> - if (!node_name) {
> - printf("Can't get node name\n");
> - return -1;
> - }
> 
> - if (IMAGE_ENABLE_ENCRYPT && keydir &&
> - !strncmp(node_name, FIT_CIPHER_NODENAME,
> - strlen(FIT_CIPHER_NODENAME)))
> - ret = fit_image_process_cipher(keydir, keydest,
> - fit, image_name,
> - image_noffset,
> - node_name, node_noffset,
> - data, size, cmdname);
> - if (ret)
> - return ret;
> + /* Process cipher node if present */
> + cipher_node_offset = fdt_subnode_offset(fit, image_noffset, "cipher");

use FIT_CIPHER_NODENAME instead of hardcoded "cipher"

> + if (cipher_node_offset == -FDT_ERR_NOTFOUND)
> + return 0;
> + if (cipher_node_offset < 0) {
> + printf("Failure getting cipher node\n");
> + return -1;
> }
> -
> - return 0;
> + if (!IMAGE_ENABLE_ENCRYPT || !keydir)
> + return 0;
> + return fit_image_process_cipher(keydir, keydest, fit, image_name,
> + image_noffset, cipher_node_offset, data, size, cmdname);
> }
> 
> /**
> --
> 2.27.0


Other than this little remark:

Reviewed-by: Philippe Reynes <philippe.reynes@softathome.com>

Regards,
Philippe

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

* [PATCH 2/3] mkimage: fit: handle FDT_ERR_NOSPACE when ciphering
  2020-07-17  7:28 ` [PATCH 2/3] mkimage: fit: handle FDT_ERR_NOSPACE when ciphering patrick.oppenlander at gmail.com
@ 2020-07-29 15:02   ` Philippe REYNES
  2020-07-30  1:19     ` Patrick Oppenlander
  0 siblings, 1 reply; 9+ messages in thread
From: Philippe REYNES @ 2020-07-29 15:02 UTC (permalink / raw)
  To: u-boot

Hi Patrick

> From: Patrick Oppenlander <patrick.oppenlander@gmail.com>
> 
> This meant that the order of operations had to change. If we replace the
> data property first then fail to add the data-size-unciphered property
> the data will be ciphered again when retrying.


This patch is good, but I disagree with the comment. It is not mandatory
to change the order of operation because when signing/ciphering we always
start from "fresh" file.

This "trick" is done in the function fit_handle_file(...)

Just before the loop, the tmpfile is rename in bakfile

	sprintf(bakfile, "%s%s", tmpfile, ".bak");
	rename(tmpfile, bakfile);

And in the loop, the first operation is to copy bakfile to tmpfile:

	for (size_inc = 0; size_inc < 64 * 1024; size_inc += 1024) {
		if (copyfile(bakfile, tmpfile) < 0) {
			printf("Can't copy %s to %s\n", bakfile, tmpfile);
			ret = -EIO;
			break;
		}
		ret = fit_add_file_data(params, size_inc, tmpfile);
		if (!ret || ret != -ENOSPC)
			break;
	}

So I think that we always cipher with unciphered data.


> Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
> ---
> tools/image-host.c | 19 ++++++++++---------
> 1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/tools/image-host.c b/tools/image-host.c
> index 8fa1b9aba7..87ef79ef53 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -399,25 +399,26 @@ int fit_image_write_cipher(void *fit, int image_noffset,
> int noffset,
> {
> int ret = -1;
> 
> - /* Remove unciphered data */
> - ret = fdt_delprop(fit, image_noffset, FIT_DATA_PROP);
> + /* add non ciphered data size */
> + ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
> + if (ret == -FDT_ERR_NOSPACE) {
> + ret = -ENOSPC;
> + goto out;
> + }
> if (ret) {
> - printf("Can't remove data (err = %d)\n", ret);
> + printf("Can't add unciphered data size (err = %d)\n", ret);
> goto out;
> }
> 
> /* Add ciphered data */
> ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP,
> data_ciphered, data_ciphered_len);
> - if (ret) {
> - printf("Can't add ciphered data (err = %d)\n", ret);
> + if (ret == -FDT_ERR_NOSPACE) {
> + ret = -ENOSPC;
> goto out;
> }
> -
> - /* add non ciphered data size */
> - ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
> if (ret) {
> - printf("Can't add unciphered data size (err = %d)\n", ret);
> + printf("Can't add ciphered data (err = %d)\n", ret);
> goto out;
> }
> 
> --
> 2.27.0


Regards,
Philippe

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

* [PATCH 3/3] mkimage: fit: don't cipher ciphered data
  2020-07-17  7:28 ` [PATCH 3/3] mkimage: fit: don't cipher ciphered data patrick.oppenlander at gmail.com
@ 2020-07-29 17:17   ` Philippe REYNES
  2020-07-30  1:27     ` Patrick Oppenlander
  0 siblings, 1 reply; 9+ messages in thread
From: Philippe REYNES @ 2020-07-29 17:17 UTC (permalink / raw)
  To: u-boot

Hi Patrick,


> From: Patrick Oppenlander <patrick.oppenlander@gmail.com>
> 
> Previously, mkimage -F could be run multiple times causing already
> ciphered image data to be ciphered again.


Good catch, mkimage -F cipher data that are already ciphered,
generating a broken FIT image.


> Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
> ---
> tools/image-host.c | 47 +++++++++++++++++++++++++++++++---------------
> 1 file changed, 32 insertions(+), 15 deletions(-)
> 
> diff --git a/tools/image-host.c b/tools/image-host.c
> index 87ef79ef53..12de9b5ec0 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -397,33 +397,43 @@ int fit_image_write_cipher(void *fit, int image_noffset,
> int noffset,
> const void *data, size_t size,
> unsigned char *data_ciphered, int data_ciphered_len)
> {
> - int ret = -1;
> + /*
> + * fit_image_cipher_data() uses the presence of the data-size-unciphered
> + * property as a sentinel to detect whether the data for this image is
> + * already encrypted. This is important as:
> + * - 'mkimage -F' can be run multiple times on a FIT image
> + * - This function is in a retry loop to handle ENOSPC
> + */
> 
> - /* add non ciphered data size */
> + int ret;
> +
> + /* Add unciphered data size */
> ret = fdt_setprop_u32(fit, image_noffset, "data-size-unciphered", size);
> - if (ret == -FDT_ERR_NOSPACE) {
> - ret = -ENOSPC;
> - goto out;
> - }
> + if (ret == -FDT_ERR_NOSPACE)
> + return -ENOSPC;
> if (ret) {
> printf("Can't add unciphered data size (err = %d)\n", ret);
> - goto out;
> + return -EIO;
> }
> 
> - /* Add ciphered data */
> + /* Replace contents of data property with data_ciphered */
> ret = fdt_setprop(fit, image_noffset, FIT_DATA_PROP,
> data_ciphered, data_ciphered_len);
> if (ret == -FDT_ERR_NOSPACE) {
> - ret = -ENOSPC;
> - goto out;
> + /* Remove data-size-unciphered; data is not ciphered */
> + ret = fdt_delprop(fit, image_noffset, "data-size-unciphered");
> + if (ret) {
> + printf("Can't remove unciphered data size (err = %d)\n", ret);
> + return -EIO;
> + }
> + return -ENOSPC;
> }
> if (ret) {
> - printf("Can't add ciphered data (err = %d)\n", ret);
> - goto out;
> + printf("Can't replace data with ciphered data (err = %d)\n", ret);
> + return -EIO;
> }
> 
> - out:
> - return ret;
> + return 0;
> }

As for the second patch, I think that the loop is not an issue because
it always start with "fresh/clean" value (using a backup file).

So I am not sure that changes in this function are needed.


> static int
> @@ -482,7 +492,7 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
> const char *image_name;
> const void *data;
> size_t size;
> - int cipher_node_offset;
> + int cipher_node_offset, len;
> 
> /* Get image name */
> image_name = fit_get_name(fit, image_noffset, NULL);
> @@ -497,6 +507,13 @@ int fit_image_cipher_data(const char *keydir, void
> *keydest,
> return -1;
> }
> 
> + /* Don't cipher ciphered data */
> + if (fdt_getprop(fit, image_noffset, "data-size-unciphered", &len))
> + return 0;
> + if (len != -FDT_ERR_NOTFOUND) {
> + printf("Failure testing for data-size-unciphered\n");
> + return -1;
> + }

From my point of view, it fixes an issue. But I see this solution more
as "workaround" than a clean solution.

As it fixes a real issue, we may start with it and then try to found a
"clean" solution.


> /* Process cipher node if present */
> cipher_node_offset = fdt_subnode_offset(fit, image_noffset, "cipher");
> --
> 2.27.0


Regards,
Philippe

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

* [PATCH 2/3] mkimage: fit: handle FDT_ERR_NOSPACE when ciphering
  2020-07-29 15:02   ` Philippe REYNES
@ 2020-07-30  1:19     ` Patrick Oppenlander
  0 siblings, 0 replies; 9+ messages in thread
From: Patrick Oppenlander @ 2020-07-30  1:19 UTC (permalink / raw)
  To: u-boot

On Thu, Jul 30, 2020 at 1:02 AM Philippe REYNES
<philippe.reynes@softathome.com> wrote:
>
> Hi Patrick
>
> > From: Patrick Oppenlander <patrick.oppenlander@gmail.com>
> >
> > This meant that the order of operations had to change. If we replace the
> > data property first then fail to add the data-size-unciphered property
> > the data will be ciphered again when retrying.
>
>
> This patch is good, but I disagree with the comment. It is not mandatory
> to change the order of operation because when signing/ciphering we always
> start from "fresh" file.
>
> This "trick" is done in the function fit_handle_file(...)
>
> Just before the loop, the tmpfile is rename in bakfile
>
>         sprintf(bakfile, "%s%s", tmpfile, ".bak");
>         rename(tmpfile, bakfile);
>
> And in the loop, the first operation is to copy bakfile to tmpfile:
>
>         for (size_inc = 0; size_inc < 64 * 1024; size_inc += 1024) {
>                 if (copyfile(bakfile, tmpfile) < 0) {
>                         printf("Can't copy %s to %s\n", bakfile, tmpfile);
>                         ret = -EIO;
>                         break;
>                 }
>                 ret = fit_add_file_data(params, size_inc, tmpfile);
>                 if (!ret || ret != -ENOSPC)
>                         break;
>         }
>
> So I think that we always cipher with unciphered data.
>

Hi Philip,

I don't think that is the case if you use "mkimage -F". The input can
already be ciphered.

Patrick

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

* [PATCH 3/3] mkimage: fit: don't cipher ciphered data
  2020-07-29 17:17   ` Philippe REYNES
@ 2020-07-30  1:27     ` Patrick Oppenlander
  0 siblings, 0 replies; 9+ messages in thread
From: Patrick Oppenlander @ 2020-07-30  1:27 UTC (permalink / raw)
  To: u-boot

On Thu, Jul 30, 2020 at 3:17 AM Philippe REYNES
<philippe.reynes@softathome.com> wrote:
>
> As for the second patch, I think that the loop is not an issue because
> it always start with "fresh/clean" value (using a backup file).
>
> So I am not sure that changes in this function are needed.
>

OK, I overlooked this.

I will resubmit a simplified patch series.

>
> > static int
> > @@ -482,7 +492,7 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
> > const char *image_name;
> > const void *data;
> > size_t size;
> > - int cipher_node_offset;
> > + int cipher_node_offset, len;
> >
> > /* Get image name */
> > image_name = fit_get_name(fit, image_noffset, NULL);
> > @@ -497,6 +507,13 @@ int fit_image_cipher_data(const char *keydir, void
> > *keydest,
> > return -1;
> > }
> >
> > + /* Don't cipher ciphered data */
> > + if (fdt_getprop(fit, image_noffset, "data-size-unciphered", &len))
> > + return 0;
> > + if (len != -FDT_ERR_NOTFOUND) {
> > + printf("Failure testing for data-size-unciphered\n");
> > + return -1;
> > + }
>
> From my point of view, it fixes an issue. But I see this solution more
> as "workaround" than a clean solution.
>
> As it fixes a real issue, we may start with it and then try to found a
> "clean" solution.
>

True, it's not ideal. But at least it fixes the bug :)

Thanks for the review,

Patrick

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

end of thread, other threads:[~2020-07-30  1:27 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-17  7:28 [PATCH 1/3] mkimage: fit: only process one cipher node patrick.oppenlander at gmail.com
2020-07-17  7:28 ` [PATCH 2/3] mkimage: fit: handle FDT_ERR_NOSPACE when ciphering patrick.oppenlander at gmail.com
2020-07-29 15:02   ` Philippe REYNES
2020-07-30  1:19     ` Patrick Oppenlander
2020-07-17  7:28 ` [PATCH 3/3] mkimage: fit: don't cipher ciphered data patrick.oppenlander at gmail.com
2020-07-29 17:17   ` Philippe REYNES
2020-07-30  1:27     ` Patrick Oppenlander
2020-07-27 23:45 ` [PATCH 1/3] mkimage: fit: only process one cipher node Simon Glass
2020-07-29 14:50 ` Philippe REYNES

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.