All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 0/8] common, fit, rsa: enhancements
@ 2014-02-09  5:34 Heiko Schocher
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 1/8] tools/image-host: fix sign-images bug Heiko Schocher
                   ` (7 more replies)
  0 siblings, 8 replies; 20+ messages in thread
From: Heiko Schocher @ 2014-02-09  5:34 UTC (permalink / raw)
  To: u-boot

- add sha256,rsa2048 and sha256,rsa4098 support to u-boot.
- add "fdt sign" command to u-boot cmdshell. This command
  checks, if a fdt is correct signed.
- add hosttool "fit_info" which prints the offset and
  the len of a property from in a fdt file. This
  values can be used, to extract the data from a property
  (for example with "dd")
- add hosttool "fit_check_sign". This does the same as
  the u-boot cmdshell tool "fdt sign". It checks, if
  fit image is correct signed

- changes for v2:
  - add comments from Simon Glass
  - add new patch: "[PATCH v2 6/8] gen: Add progressive hash API"
    from Hung-ying Tyan <tyanh@chromium.org> as
    Simon Glass mentioned

Heiko Schocher (8):
  tools/image-host: fix sign-images bug
  fdt: add "fdt checksign" command
  fit: add sha256 support
  rsa: add sha256-rsa2048 algorithm
  rsa: add sha256,rsa4096 algorithm
  gen: Add progressive hash API
  tools, fit: add fit_info host command
  tools, fit_check_sign: verify a signed fit image

 Makefile                                           |   2 +
 common/cmd_fdt.c                                   |  42 +++++-
 common/hash.c                                      | 116 +++++++++++++--
 common/image-fit.c                                 |   5 +
 common/image-sig.c                                 |  66 +++++++++
 doc/uImage.FIT/signature.txt                       |  33 ++++-
 include/fdt_support.h                              |   5 +
 include/hash.h                                     |  48 ++++++
 include/image.h                                    |  37 ++++-
 include/rsa-checksum.h                             |  26 ++++
 include/rsa.h                                      |  24 +++
 lib/libfdt/fdt_wip.c                               |  17 +++
 lib/rsa/Makefile                                   |   2 +-
 lib/rsa/rsa-checksum.c                             | 163 +++++++++++++++++++++
 lib/rsa/rsa-sign.c                                 |  10 +-
 lib/rsa/rsa-verify.c                               | 107 +++++---------
 lib/sha256.c                                       |   2 +-
 .../{sign-configs.its => sign-configs-sha1.its}    |   0
 test/vboot/sign-configs-sha256.its                 |  45 ++++++
 .../{sign-images.its => sign-images-sha1.its}      |   0
 test/vboot/sign-images-sha256.its                  |  42 ++++++
 test/vboot/vboot_test.sh                           |  54 ++++++-
 tools/Makefile                                     |  42 +++++-
 tools/fdt_host.h                                   |   2 +
 tools/fit_check_sign.c                             | 119 +++++++++++++++
 tools/fit_common.c                                 |  81 ++++++++++
 tools/fit_common.h                                 |  22 +++
 tools/fit_image.c                                  |  62 +-------
 tools/fit_info.c                                   | 116 +++++++++++++++
 tools/image-host.c                                 |  15 +-
 30 files changed, 1148 insertions(+), 157 deletions(-)
 create mode 100644 include/rsa-checksum.h
 create mode 100644 lib/rsa/rsa-checksum.c
 rename test/vboot/{sign-configs.its => sign-configs-sha1.its} (100%)
 create mode 100644 test/vboot/sign-configs-sha256.its
 rename test/vboot/{sign-images.its => sign-images-sha1.its} (100%)
 create mode 100644 test/vboot/sign-images-sha256.its
 create mode 100644 tools/fit_check_sign.c
 create mode 100644 tools/fit_common.c
 create mode 100644 tools/fit_common.h
 create mode 100644 tools/fit_info.c

Cc: Simon Glass <sjg@chromium.org>
Cc: Hung-ying Tyan <tyanh@chromium.org>
Cc: andreas at oetken.name

-- 
1.8.3.1

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

* [U-Boot] [PATCH v2 1/8] tools/image-host: fix sign-images bug
  2014-02-09  5:34 [U-Boot] [PATCH v2 0/8] common, fit, rsa: enhancements Heiko Schocher
@ 2014-02-09  5:34 ` Heiko Schocher
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 2/8] fdt: add "fdt checksign" command Heiko Schocher
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: Heiko Schocher @ 2014-02-09  5:34 UTC (permalink / raw)
  To: u-boot

property "sign-images" is never found, fix this.

Signed-off-by: Heiko Schocher <hs@denx.de>
Acked-by: Simon Glass <sjg@chromium.org>

---
changes for v2:
- add Acked-by from Simon Glass

 tools/image-host.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/image-host.c b/tools/image-host.c
index 0d5c88c..8e185ec 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -403,7 +403,7 @@ static int fit_config_get_hash_list(void *fit, int conf_noffset,
 		goto err_mem;
 
 	/* Get a list of images that we intend to sign */
-	prop = fit_config_get_image_list(fit, conf_noffset, &len,
+	prop = fit_config_get_image_list(fit, sig_offset, &len,
 					&allow_missing);
 	if (!prop)
 		return 0;
-- 
1.8.3.1

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

* [U-Boot] [PATCH v2 2/8] fdt: add "fdt checksign" command
  2014-02-09  5:34 [U-Boot] [PATCH v2 0/8] common, fit, rsa: enhancements Heiko Schocher
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 1/8] tools/image-host: fix sign-images bug Heiko Schocher
@ 2014-02-09  5:34 ` Heiko Schocher
  2014-02-14 16:17   ` Simon Glass
  2014-02-15 23:00   ` Simon Glass
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 3/8] fit: add sha256 support Heiko Schocher
                   ` (5 subsequent siblings)
  7 siblings, 2 replies; 20+ messages in thread
From: Heiko Schocher @ 2014-02-09  5:34 UTC (permalink / raw)
  To: u-boot

check if a fdt is correct signed
pass an optional addr value. Contains the addr of the key blob

Signed-off-by: Heiko Schocher <hs@denx.de>
Cc: Simon Glass <sjg@chromium.org>

---
changes vor v2:
- add comment from Simon Glass:
  - rename "fdt sign" to "fdt checksign"
    -> rename patch subject from "fdt: add "fdt sign" command"
       to "fdt: add "fdt checksign" command"
  - add error message

 common/cmd_fdt.c | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c
index 3a9edd6..a6744ed 100644
--- a/common/cmd_fdt.c
+++ b/common/cmd_fdt.c
@@ -570,7 +570,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		ft_board_setup(working_fdt, gd->bd);
 #endif
 	/* Create a chosen node */
-	else if (argv[1][0] == 'c') {
+	else if (strncmp(argv[1], "cho", 3) == 0) {
 		unsigned long initrd_start = 0, initrd_end = 0;
 
 		if ((argc != 2) && (argc != 4))
@@ -583,6 +583,41 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 		fdt_chosen(working_fdt, 1);
 		fdt_initrd(working_fdt, initrd_start, initrd_end, 1);
+
+#if defined(CONFIG_FIT_SIGNATURE)
+	} else if (strncmp(argv[1], "che", 3) == 0) {
+		int cfg_noffset;
+		int ret;
+		unsigned long addr;
+		struct fdt_header *blob;
+
+		if (!working_fdt)
+			return CMD_RET_FAILURE;
+
+		if (argc > 2) {
+			addr = simple_strtoul(argv[2], NULL, 16);
+			blob = map_sysmem(addr, 0);
+		} else {
+			blob = (struct fdt_header *)gd->fdt_blob;
+		}
+		if (!fdt_valid(&blob))
+			return 1;
+
+		gd->fdt_blob = blob;
+		cfg_noffset = fit_conf_get_node(working_fdt, NULL);
+		if (!cfg_noffset) {
+			printf("Could not find configuration node: %s\n",
+			       fdt_strerror(cfg_noffset));
+			return CMD_RET_FAILURE;
+		}
+
+		ret = fit_config_verify(working_fdt, cfg_noffset);
+		if (ret == 1)
+			return CMD_RET_SUCCESS;
+		else
+			return CMD_RET_FAILURE;
+#endif
+
 	}
 	/* resize the fdt */
 	else if (strncmp(argv[1], "re", 2) == 0) {
@@ -992,6 +1027,11 @@ static char fdt_help_text[] =
 	"fdt rsvmem delete <index>           - Delete a mem reserves\n"
 	"fdt chosen [<start> <end>]          - Add/update the /chosen branch in the tree\n"
 	"                                        <start>/<end> - initrd start/end addr\n"
+#if defined(CONFIG_FIT_SIGNATURE)
+	"fdt checksign [<addr>]              - check FIT signature\n"
+	"                                        <start> - addr of key blob\n"
+	"                                                  default gd->fdt_blob\n"
+#endif
 	"NOTE: Dereference aliases by omiting the leading '/', "
 		"e.g. fdt print ethernet0.";
 #endif
-- 
1.8.3.1

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

* [U-Boot] [PATCH v2 3/8] fit: add sha256 support
  2014-02-09  5:34 [U-Boot] [PATCH v2 0/8] common, fit, rsa: enhancements Heiko Schocher
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 1/8] tools/image-host: fix sign-images bug Heiko Schocher
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 2/8] fdt: add "fdt checksign" command Heiko Schocher
@ 2014-02-09  5:34 ` Heiko Schocher
  2014-02-15 22:47   ` Simon Glass
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 4/8] rsa: add sha256-rsa2048 algorithm Heiko Schocher
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Heiko Schocher @ 2014-02-09  5:34 UTC (permalink / raw)
  To: u-boot

add sha256 support to fit images

Signed-off-by: Heiko Schocher <hs@denx.de>
Acked-by: Simon Glass <sjg@chromium.org>

---
changes for v2:
- add Acked-by from Simon Glass

 common/image-fit.c | 5 +++++
 include/image.h    | 9 +++++++++
 lib/sha256.c       | 2 +-
 tools/Makefile     | 3 +++
 4 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/common/image-fit.c b/common/image-fit.c
index cf4b67e..f32feb6 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -22,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #include <bootstage.h>
 #include <sha1.h>
+#include <sha256.h>
 #include <u-boot/crc.h>
 #include <u-boot/md5.h>
 
@@ -882,6 +883,10 @@ int calculate_hash(const void *data, int data_len, const char *algo,
 		sha1_csum_wd((unsigned char *)data, data_len,
 			     (unsigned char *)value, CHUNKSZ_SHA1);
 		*value_len = 20;
+	} else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) {
+		sha256_csum_wd((unsigned char *)data, data_len,
+			       (unsigned char *)value, CHUNKSZ_SHA256);
+		*value_len = SHA256_SUM_LEN;
 	} else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) {
 		md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
 		*value_len = 16;
diff --git a/include/image.h b/include/image.h
index 7de2bb2..f001a5f 100644
--- a/include/image.h
+++ b/include/image.h
@@ -57,13 +57,18 @@ struct lmb;
 #  ifdef CONFIG_SPL_SHA1_SUPPORT
 #   define IMAGE_ENABLE_SHA1	1
 #  endif
+#  ifdef CONFIG_SPL_SHA256_SUPPORT
+#   define IMAGE_ENABLE_SHA256	1
+#  endif
 # else
 #  define CONFIG_CRC32		/* FIT images need CRC32 support */
 #  define CONFIG_MD5		/* and MD5 */
 #  define CONFIG_SHA1		/* and SHA1 */
+#  define CONFIG_SHA256		/* and SHA256 */
 #  define IMAGE_ENABLE_CRC32	1
 #  define IMAGE_ENABLE_MD5	1
 #  define IMAGE_ENABLE_SHA1	1
+#  define IMAGE_ENABLE_SHA256	1
 # endif
 
 #ifndef IMAGE_ENABLE_CRC32
@@ -78,6 +83,10 @@ struct lmb;
 #define IMAGE_ENABLE_SHA1	0
 #endif
 
+#ifndef IMAGE_ENABLE_SHA256
+#define IMAGE_ENABLE_SHA256	0
+#endif
+
 #endif /* CONFIG_FIT */
 
 #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
diff --git a/lib/sha256.c b/lib/sha256.c
index 7348162..5766de2 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -258,7 +258,7 @@ void sha256_csum_wd(const unsigned char *input, unsigned int ilen,
 {
 	sha256_context ctx;
 #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
-	unsigned char *end, *curr;
+	const unsigned char *end, *curr;
 	int chunk;
 #endif
 
diff --git a/tools/Makefile b/tools/Makefile
index 328cea3..5e36e5e 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -71,6 +71,7 @@ EXT_OBJ_FILES-y += common/image-sig.o
 EXT_OBJ_FILES-y += lib/crc32.o
 EXT_OBJ_FILES-y += lib/md5.o
 EXT_OBJ_FILES-y += lib/sha1.o
+EXT_OBJ_FILES-y += lib/sha256.o
 
 # Source files located in the tools directory
 NOPED_OBJ_FILES-y += aisimage.o
@@ -223,6 +224,7 @@ $(obj)dumpimage$(SFX):	$(obj)aisimage.o \
 			$(obj)os_support.o \
 			$(obj)pblimage.o \
 			$(obj)sha1.o \
+			$(obj)sha256.o \
 			$(obj)ublimage.o \
 			$(LIBFDT_OBJS) \
 			$(RSA_OBJS)
@@ -252,6 +254,7 @@ $(obj)mkimage$(SFX):	$(obj)aisimage.o \
 			$(obj)os_support.o \
 			$(obj)pblimage.o \
 			$(obj)sha1.o \
+			$(obj)sha256.o \
 			$(obj)ublimage.o \
 			$(LIBFDT_OBJS) \
 			$(RSA_OBJS)
-- 
1.8.3.1

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

* [U-Boot] [PATCH v2 4/8] rsa: add sha256-rsa2048 algorithm
  2014-02-09  5:34 [U-Boot] [PATCH v2 0/8] common, fit, rsa: enhancements Heiko Schocher
                   ` (2 preceding siblings ...)
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 3/8] fit: add sha256 support Heiko Schocher
@ 2014-02-09  5:34 ` Heiko Schocher
  2014-02-15 23:11   ` Simon Glass
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 5/8] rsa: add sha256,rsa4096 algorithm Heiko Schocher
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Heiko Schocher @ 2014-02-09  5:34 UTC (permalink / raw)
  To: u-boot

based on patch from andreas at oetken.name:

http://patchwork.ozlabs.org/patch/294318/
commit message:
I currently need support for rsa-sha256 signatures in u-boot and found out that
the code for signatures is not very generic. Thus adding of different
hash-algorithms for rsa-signatures is not easy to do without copy-pasting the
rsa-code. I attached a patch for how I think it could be better and included
support for rsa-sha256. This is a fast first shot.

aditionally work:
- removed checkpatch warnings
- removed compiler warnings
- rebased against current head

Signed-off-by: Heiko Schocher <hs@denx.de>
Cc: andreas at oetken.name
Cc: Simon Glass <sjg@chromium.org>

---
changes for v2:
- add comment from Simon Glass:
  - add commit message from original patch
  - remove unnecessary function declaration
    rsa_verify_256()
  - sandbox: add sha256 tests

 common/image-sig.c                                 | 33 ++++++++
 doc/uImage.FIT/signature.txt                       | 25 +++++-
 include/image.h                                    | 21 +++++
 include/rsa-checksum.h                             | 25 ++++++
 include/rsa.h                                      | 14 ++++
 lib/rsa/Makefile                                   |  2 +-
 lib/rsa/rsa-checksum.c                             | 98 ++++++++++++++++++++++
 lib/rsa/rsa-sign.c                                 | 10 ++-
 lib/rsa/rsa-verify.c                               | 83 ++++++------------
 .../{sign-configs.its => sign-configs-sha1.its}    |  0
 test/vboot/sign-configs-sha256.its                 | 45 ++++++++++
 .../{sign-images.its => sign-images-sha1.its}      |  0
 test/vboot/sign-images-sha256.its                  | 42 ++++++++++
 test/vboot/vboot_test.sh                           | 18 ++--
 14 files changed, 346 insertions(+), 70 deletions(-)
 create mode 100644 include/rsa-checksum.h
 create mode 100644 lib/rsa/rsa-checksum.c
 rename test/vboot/{sign-configs.its => sign-configs-sha1.its} (100%)
 create mode 100644 test/vboot/sign-configs-sha256.its
 rename test/vboot/{sign-images.its => sign-images-sha1.its} (100%)
 create mode 100644 test/vboot/sign-images-sha256.its

diff --git a/common/image-sig.c b/common/image-sig.c
index 973b06d..8b212a7 100644
--- a/common/image-sig.c
+++ b/common/image-sig.c
@@ -14,15 +14,47 @@ DECLARE_GLOBAL_DATA_PTR;
 #endif /* !USE_HOSTCC*/
 #include <image.h>
 #include <rsa.h>
+#include <rsa-checksum.h>
 
 #define IMAGE_MAX_HASHED_NODES		100
 
+#if defined(CONFIG_FIT_SIGNATURE)
+struct checksum_algo checksum_algos[] = {
+	{
+		"sha1",
+		SHA1_SUM_LEN,
+#if IMAGE_ENABLE_SIGN
+		EVP_sha1,
+#else
+		sha1_calculate,
+		padding_sha1_rsa2048,
+#endif
+	},
+	{
+		"sha256",
+		SHA256_SUM_LEN,
+#if IMAGE_ENABLE_SIGN
+		EVP_sha256,
+#else
+		sha256_calculate,
+		padding_sha256_rsa2048,
+#endif
+	}
+};
 struct image_sig_algo image_sig_algos[] = {
 	{
 		"sha1,rsa2048",
 		rsa_sign,
 		rsa_add_verify_data,
 		rsa_verify,
+		&checksum_algos[0],
+	},
+	{
+		"sha256,rsa2048",
+		rsa_sign,
+		rsa_add_verify_data,
+		rsa_verify,
+		&checksum_algos[1],
 	}
 };
 
@@ -407,3 +439,4 @@ int fit_config_verify(const void *fit, int conf_noffset)
 	return !fit_config_verify_required_sigs(fit, conf_noffset,
 						gd_fdt_blob());
 }
+#endif
diff --git a/doc/uImage.FIT/signature.txt b/doc/uImage.FIT/signature.txt
index bc9f3fa..5bd229f 100644
--- a/doc/uImage.FIT/signature.txt
+++ b/doc/uImage.FIT/signature.txt
@@ -346,6 +346,7 @@ Simple Verified Boot Test
 
 Please see doc/uImage.FIT/verified-boot.txt for more information
 
+/home/hs/ids/u-boot/sandbox/tools/mkimage -D -I dts -O dtb -p 2000
 Build keys
 Build FIT with signed images
 Test Verified Boot Run: unsigned signatures:: OK
@@ -355,9 +356,31 @@ Build FIT with signed configuration
 Test Verified Boot Run: unsigned config: OK
 Sign images
 Test Verified Boot Run: signed config: OK
+Test Verified Boot Run: signed config with bad hash: OK
 
-Test passed
+Test sha1 passed
 
+Or for testing sha256:
+
+$ O=sandbox ./test/vboot/vboot_test.sh sha256
+Simple Verified Boot Test
+=========================
+
+Please see doc/uImage.FIT/verified-boot.txt for more information
+
+/home/hs/ids/u-boot/sandbox/tools/mkimage -D -I dts -O dtb -p 2000
+Build keys
+Build FIT with signed images
+Test Verified Boot Run: unsigned signatures:: OK
+Sign images
+Test Verified Boot Run: signed images: OK
+Build FIT with signed configuration
+Test Verified Boot Run: unsigned config: OK
+Sign images
+Test Verified Boot Run: signed config: OK
+Test Verified Boot Run: signed config with bad hash: OK
+
+Test sha256 passed
 
 Future Work
 -----------
diff --git a/include/image.h b/include/image.h
index f001a5f..eb3429f 100644
--- a/include/image.h
+++ b/include/image.h
@@ -832,6 +832,7 @@ int calculate_hash(const void *data, int data_len, const char *algo,
 # ifdef USE_HOSTCC
 #  define IMAGE_ENABLE_SIGN	1
 #  define IMAGE_ENABLE_VERIFY	0
+# include  <openssl/evp.h>
 #else
 #  define IMAGE_ENABLE_SIGN	0
 #  define IMAGE_ENABLE_VERIFY	1
@@ -871,6 +872,23 @@ struct image_region {
 	int size;
 };
 
+#if IMAGE_ENABLE_VERIFY
+# include <rsa-checksum.h>
+#endif
+struct checksum_algo {
+	const char *name;
+	const int checksum_len;
+#if IMAGE_ENABLE_SIGN
+	const EVP_MD *(*calculate)(void);
+#else
+#if IMAGE_ENABLE_VERIFY
+	void (*calculate)(const struct image_region region[],
+			  int region_count, uint8_t *checksum);
+	const uint8_t *rsa_padding;
+#endif
+#endif
+};
+
 struct image_sig_algo {
 	const char *name;		/* Name of algorithm */
 
@@ -921,6 +939,9 @@ struct image_sig_algo {
 	int (*verify)(struct image_sign_info *info,
 		      const struct image_region region[], int region_count,
 		      uint8_t *sig, uint sig_len);
+
+	/* pointer to checksum algorithm */
+	struct checksum_algo *checksum;
 };
 
 /**
diff --git a/include/rsa-checksum.h b/include/rsa-checksum.h
new file mode 100644
index 0000000..12494a6
--- /dev/null
+++ b/include/rsa-checksum.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013, Andreas Oetken.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+*/
+
+#ifndef _RSA_CHECKSUM_H
+#define _RSA_CHECKSUM_H
+
+#include <errno.h>
+#include <image.h>
+#include <sha1.h>
+#include <sha256.h>
+
+#if IMAGE_ENABLE_VERIFY
+extern const uint8_t padding_sha256_rsa2048[];
+extern const uint8_t padding_sha1_rsa2048[];
+
+void sha256_calculate(const struct image_region region[], int region_count,
+		      uint8_t *checksum);
+void sha1_calculate(const struct image_region region[], int region_count,
+		    uint8_t *checksum);
+#endif
+
+#endif
diff --git a/include/rsa.h b/include/rsa.h
index add4c78..0367671 100644
--- a/include/rsa.h
+++ b/include/rsa.h
@@ -15,6 +15,20 @@
 #include <errno.h>
 #include <image.h>
 
+/**
+ * struct rsa_public_key - holder for a public key
+ *
+ * An RSA public key consists of a modulus (typically called N), the inverse
+ * and R^2, where R is 2^(# key bits).
+ */
+
+struct rsa_public_key {
+	uint len;        /* Length of modulus[] in number of uint32_t */
+	uint32_t n0inv;        /* -1 / modulus[0] mod 2^32 */
+	uint32_t *modulus;    /* modulus as little endian array */
+	uint32_t *rr;        /* R^2 as little endian array */
+};
+
 #if IMAGE_ENABLE_SIGN
 /**
  * sign() - calculate and return signature for given input data
diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile
index 164ab39..a5a96cb6 100644
--- a/lib/rsa/Makefile
+++ b/lib/rsa/Makefile
@@ -7,4 +7,4 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o
+obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o
diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c
new file mode 100644
index 0000000..e520e1c
--- /dev/null
+++ b/lib/rsa/rsa-checksum.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2013, Andreas Oetken.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <rsa.h>
+#include <sha1.h>
+#include <sha256.h>
+#include <asm/byteorder.h>
+#include <asm/errno.h>
+#include <asm/unaligned.h>
+
+#define RSA2048_BYTES 256
+
+/* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */
+
+const uint8_t padding_sha256_rsa2048[RSA2048_BYTES - SHA256_SUM_LEN] = {
+0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
+0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+0x00, 0x04, 0x20
+};
+
+const uint8_t padding_sha1_rsa2048[RSA2048_BYTES - SHA1_SUM_LEN] = {
+	0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30,
+	0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
+	0x05, 0x00, 0x04, 0x14
+};
+
+void sha1_calculate(const struct image_region region[], int region_count,
+		    uint8_t *checksum)
+{
+	sha1_context ctx;
+	uint32_t i;
+	i = 0;
+
+	sha1_starts(&ctx);
+	for (i = 0; i < region_count; i++)
+		sha1_update(&ctx, region[i].data, region[i].size);
+	sha1_finish(&ctx, checksum);
+}
+
+void sha256_calculate(const struct image_region region[], int region_count,
+		      uint8_t *checksum)
+{
+	sha256_context ctx;
+	uint32_t i;
+	i = 0;
+
+	sha256_starts(&ctx);
+	for (i = 0; i < region_count; i++)
+		sha256_update(&ctx, region[i].data, region[i].size);
+	sha256_finish(&ctx, checksum);
+}
diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index 549130e..0fe6e9f 100644
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -159,8 +159,9 @@ static void rsa_remove(void)
 	EVP_cleanup();
 }
 
-static int rsa_sign_with_key(RSA *rsa, const struct image_region region[],
-		int region_count, uint8_t **sigp, uint *sig_size)
+static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo,
+		const struct image_region region[], int region_count,
+		uint8_t **sigp, uint *sig_size)
 {
 	EVP_PKEY *key;
 	EVP_MD_CTX *context;
@@ -192,7 +193,7 @@ static int rsa_sign_with_key(RSA *rsa, const struct image_region region[],
 		goto err_create;
 	}
 	EVP_MD_CTX_init(context);
-	if (!EVP_SignInit(context, EVP_sha1())) {
+	if (!EVP_SignInit(context, checksum_algo->calculate())) {
 		ret = rsa_err("Signer setup failed");
 		goto err_sign;
 	}
@@ -242,7 +243,8 @@ int rsa_sign(struct image_sign_info *info,
 	ret = rsa_get_priv_key(info->keydir, info->keyname, &rsa);
 	if (ret)
 		goto err_priv;
-	ret = rsa_sign_with_key(rsa, region, region_count, sigp, sig_len);
+	ret = rsa_sign_with_key(rsa, info->algo->checksum, region,
+				region_count, sigp, sig_len);
 	if (ret)
 		goto err_sign;
 
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index 02cc4e3..b3573a8 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -8,23 +8,11 @@
 #include <fdtdec.h>
 #include <rsa.h>
 #include <sha1.h>
+#include <sha256.h>
 #include <asm/byteorder.h>
 #include <asm/errno.h>
 #include <asm/unaligned.h>
 
-/**
- * struct rsa_public_key - holder for a public key
- *
- * An RSA public key consists of a modulus (typically called N), the inverse
- * and R^2, where R is 2^(# key bits).
- */
-struct rsa_public_key {
-	uint len;		/* Length of modulus[] in number of uint32_t */
-	uint32_t n0inv;		/* -1 / modulus[0] mod 2^32 */
-	uint32_t *modulus;	/* modulus as little endian array */
-	uint32_t *rr;		/* R^2 as little endian array */
-};
-
 #define UINT64_MULT32(v, multby)  (((uint64_t)(v)) * ((uint32_t)(multby)))
 
 #define RSA2048_BYTES	(2048 / 8)
@@ -36,39 +24,6 @@ struct rsa_public_key {
 /* This is the maximum signature length that we support, in bits */
 #define RSA_MAX_SIG_BITS	2048
 
-static const uint8_t padding_sha1_rsa2048[RSA2048_BYTES - SHA1_SUM_LEN] = {
-	0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30,
-	0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
-	0x05, 0x00, 0x04, 0x14
-};
-
 /**
  * subtract_modulus() - subtract modulus from the given value
  *
@@ -209,13 +164,14 @@ static int pow_mod(const struct rsa_public_key *key, uint32_t *inout)
 }
 
 static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
-		const uint32_t sig_len, const uint8_t *hash)
+			  const uint32_t sig_len, const uint8_t *hash,
+			  struct checksum_algo *algo)
 {
 	const uint8_t *padding;
 	int pad_len;
 	int ret;
 
-	if (!key || !sig || !hash)
+	if (!key || !sig || !hash || !algo)
 		return -EIO;
 
 	if (sig_len != (key->len * sizeof(uint32_t))) {
@@ -223,6 +179,8 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
 		return -EINVAL;
 	}
 
+	debug("Checksum algorithm: %s", algo->name);
+
 	/* Sanity check for stack size */
 	if (sig_len > RSA_MAX_SIG_BITS / 8) {
 		debug("Signature length %u exceeds maximum %d\n", sig_len,
@@ -238,9 +196,8 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
 	if (ret)
 		return ret;
 
-	/* Determine padding to use depending on the signature type. */
-	padding = padding_sha1_rsa2048;
-	pad_len = RSA2048_BYTES - SHA1_SUM_LEN;
+	padding = algo->rsa_padding;
+	pad_len = RSA2048_BYTES - algo->checksum_len;
 
 	/* Check pkcs1.5 padding bytes. */
 	if (memcmp(buf, padding, pad_len)) {
@@ -309,7 +266,7 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
 	}
 
 	debug("key length %d\n", key.len);
-	ret = rsa_verify_key(&key, sig, sig_len, hash);
+	ret = rsa_verify_key(&key, sig, sig_len, hash, info->algo->checksum);
 	if (ret) {
 		printf("%s: RSA failed to verify: %d\n", __func__, ret);
 		return ret;
@@ -323,12 +280,22 @@ int rsa_verify(struct image_sign_info *info,
 	       uint8_t *sig, uint sig_len)
 {
 	const void *blob = info->fdt_blob;
-	uint8_t hash[SHA1_SUM_LEN];
+	/* Reserve memory for maximum checksum-length */
+	uint8_t hash[RSA2048_BYTES];
 	int ndepth, noffset;
 	int sig_node, node;
 	char name[100];
-	sha1_context ctx;
-	int ret, i;
+	int ret;
+
+	/*
+	 * Verify that the checksum-length does not exceed the
+	 * rsa-signature-length
+	 */
+	if (info->algo->checksum->checksum_len > RSA2048_BYTES) {
+		debug("%s: invlaid checksum-algorithm %s for RSA2048\n",
+		      __func__, info->algo->checksum->name);
+		return -EINVAL;
+	}
 
 	sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME);
 	if (sig_node < 0) {
@@ -336,10 +303,8 @@ int rsa_verify(struct image_sign_info *info,
 		return -ENOENT;
 	}
 
-	sha1_starts(&ctx);
-	for (i = 0; i < region_count; i++)
-		sha1_update(&ctx, region[i].data, region[i].size);
-	sha1_finish(&ctx, hash);
+	/* Calculate checksum with checksum-algorithm */
+	info->algo->checksum->calculate(region, region_count, hash);
 
 	/* See if we must use a particular key */
 	if (info->required_keynode != -1) {
diff --git a/test/vboot/sign-configs.its b/test/vboot/sign-configs-sha1.its
similarity index 100%
rename from test/vboot/sign-configs.its
rename to test/vboot/sign-configs-sha1.its
diff --git a/test/vboot/sign-configs-sha256.its b/test/vboot/sign-configs-sha256.its
new file mode 100644
index 0000000..1b3432e
--- /dev/null
+++ b/test/vboot/sign-configs-sha256.its
@@ -0,0 +1,45 @@
+/dts-v1/;
+
+/ {
+	description = "Chrome OS kernel image with one or more FDT blobs";
+	#address-cells = <1>;
+
+	images {
+		kernel at 1 {
+			data = /incbin/("test-kernel.bin");
+			type = "kernel_noload";
+			arch = "sandbox";
+			os = "linux";
+			compression = "none";
+			load = <0x4>;
+			entry = <0x8>;
+			kernel-version = <1>;
+			hash at 1 {
+				algo = "sha256";
+			};
+		};
+		fdt at 1 {
+			description = "snow";
+			data = /incbin/("sandbox-kernel.dtb");
+			type = "flat_dt";
+			arch = "sandbox";
+			compression = "none";
+			fdt-version = <1>;
+			hash at 1 {
+				algo = "sha256";
+			};
+		};
+	};
+	configurations {
+		default = "conf at 1";
+		conf at 1 {
+			kernel = "kernel at 1";
+			fdt = "fdt at 1";
+			signature at 1 {
+				algo = "sha256,rsa2048";
+				key-name-hint = "dev";
+				sign-images = "fdt", "kernel";
+			};
+		};
+	};
+};
diff --git a/test/vboot/sign-images.its b/test/vboot/sign-images-sha1.its
similarity index 100%
rename from test/vboot/sign-images.its
rename to test/vboot/sign-images-sha1.its
diff --git a/test/vboot/sign-images-sha256.its b/test/vboot/sign-images-sha256.its
new file mode 100644
index 0000000..e6aa9fc
--- /dev/null
+++ b/test/vboot/sign-images-sha256.its
@@ -0,0 +1,42 @@
+/dts-v1/;
+
+/ {
+	description = "Chrome OS kernel image with one or more FDT blobs";
+	#address-cells = <1>;
+
+	images {
+		kernel at 1 {
+			data = /incbin/("test-kernel.bin");
+			type = "kernel_noload";
+			arch = "sandbox";
+			os = "linux";
+			compression = "none";
+			load = <0x4>;
+			entry = <0x8>;
+			kernel-version = <1>;
+			signature at 1 {
+				algo = "sha256,rsa2048";
+				key-name-hint = "dev";
+			};
+		};
+		fdt at 1 {
+			description = "snow";
+			data = /incbin/("sandbox-kernel.dtb");
+			type = "flat_dt";
+			arch = "sandbox";
+			compression = "none";
+			fdt-version = <1>;
+			signature at 1 {
+				algo = "sha256,rsa2048";
+				key-name-hint = "dev";
+			};
+		};
+	};
+	configurations {
+		default = "conf at 1";
+		conf at 1 {
+			kernel = "kernel at 1";
+			fdt = "fdt at 1";
+		};
+	};
+};
diff --git a/test/vboot/vboot_test.sh b/test/vboot/vboot_test.sh
index bb2c605..27b221a 100755
--- a/test/vboot/vboot_test.sh
+++ b/test/vboot/vboot_test.sh
@@ -6,6 +6,14 @@
 #
 # SPDX-License-Identifier:	GPL-2.0+
 
+# Args:
+#	$1:	sha256 or sha1 (default)
+if [ -z "$1" ]; then
+	sha=sha1
+else
+	sha=$1
+fi
+
 set -e
 
 # Run U-Boot and report the result
@@ -70,7 +78,7 @@ head -c 5000 /dev/zero >test-kernel.bin
 
 # Build the FIT, but don't sign anything yet
 echo Build FIT with signed images
-${mkimage} -D "${dtc}" -f sign-images.its test.fit >${tmp}
+${mkimage} -D "${dtc}" -f sign-images-$sha.its test.fit >${tmp}
 
 run_uboot "unsigned signatures:" "dev-"
 
@@ -85,9 +93,9 @@ run_uboot "signed images" "dev+"
 dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
 
 echo Build FIT with signed configuration
-${mkimage} -D "${dtc}" -f sign-configs.its test.fit >${tmp}
+${mkimage} -D "${dtc}" -f sign-configs-$sha.its test.fit >${tmp}
 
-run_uboot "unsigned config" "sha1+ OK"
+run_uboot "unsigned config" $sha"+ OK"
 
 # Sign images with our dev keys
 echo Sign images
@@ -107,7 +115,7 @@ popd >/dev/null
 
 echo
 if ${ok}; then
-	echo "Test passed"
+	echo "Test $sha passed"
 else
-	echo "Test failed"
+	echo "Test $sha failed"
 fi
-- 
1.8.3.1

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

* [U-Boot] [PATCH v2 5/8] rsa: add sha256,rsa4096 algorithm
  2014-02-09  5:34 [U-Boot] [PATCH v2 0/8] common, fit, rsa: enhancements Heiko Schocher
                   ` (3 preceding siblings ...)
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 4/8] rsa: add sha256-rsa2048 algorithm Heiko Schocher
@ 2014-02-09  5:34 ` Heiko Schocher
  2014-02-15 23:12   ` Simon Glass
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 6/8] gen: Add progressive hash API Heiko Schocher
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Heiko Schocher @ 2014-02-09  5:34 UTC (permalink / raw)
  To: u-boot

Add support for sha256,rsa4096 signatures in u-boot.

Signed-off-by: Heiko Schocher <hs@denx.de>
Cc: Simon Glass <sjg@chromium.org>
Cc: andreas at oetken.name

---
changes for v2:
- add comment from Simon Glass:
  - add a commit message

 common/image-sig.c     | 23 ++++++++++++++++++
 include/image.h        |  1 +
 include/rsa-checksum.h |  1 +
 include/rsa.h          | 10 ++++++++
 lib/rsa/rsa-checksum.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++--
 lib/rsa/rsa-verify.c   | 20 +++++-----------
 6 files changed, 104 insertions(+), 16 deletions(-)

diff --git a/common/image-sig.c b/common/image-sig.c
index 8b212a7..199e634 100644
--- a/common/image-sig.c
+++ b/common/image-sig.c
@@ -23,6 +23,7 @@ struct checksum_algo checksum_algos[] = {
 	{
 		"sha1",
 		SHA1_SUM_LEN,
+		RSA2048_BYTES,
 #if IMAGE_ENABLE_SIGN
 		EVP_sha1,
 #else
@@ -33,14 +34,28 @@ struct checksum_algo checksum_algos[] = {
 	{
 		"sha256",
 		SHA256_SUM_LEN,
+		RSA2048_BYTES,
 #if IMAGE_ENABLE_SIGN
 		EVP_sha256,
 #else
 		sha256_calculate,
 		padding_sha256_rsa2048,
 #endif
+	},
+	{
+		"sha256",
+		SHA256_SUM_LEN,
+		RSA4096_BYTES,
+#if IMAGE_ENABLE_SIGN
+		EVP_sha256,
+#else
+		sha256_calculate,
+		padding_sha256_rsa4096,
+#endif
 	}
+
 };
+
 struct image_sig_algo image_sig_algos[] = {
 	{
 		"sha1,rsa2048",
@@ -55,7 +70,15 @@ struct image_sig_algo image_sig_algos[] = {
 		rsa_add_verify_data,
 		rsa_verify,
 		&checksum_algos[1],
+	},
+	{
+		"sha256,rsa4096",
+		rsa_sign,
+		rsa_add_verify_data,
+		rsa_verify,
+		&checksum_algos[2],
 	}
+
 };
 
 struct image_sig_algo *image_get_sig_algo(const char *name)
diff --git a/include/image.h b/include/image.h
index eb3429f..6e4745a 100644
--- a/include/image.h
+++ b/include/image.h
@@ -878,6 +878,7 @@ struct image_region {
 struct checksum_algo {
 	const char *name;
 	const int checksum_len;
+	const int pad_len;
 #if IMAGE_ENABLE_SIGN
 	const EVP_MD *(*calculate)(void);
 #else
diff --git a/include/rsa-checksum.h b/include/rsa-checksum.h
index 12494a6..a7b553c 100644
--- a/include/rsa-checksum.h
+++ b/include/rsa-checksum.h
@@ -13,6 +13,7 @@
 #include <sha256.h>
 
 #if IMAGE_ENABLE_VERIFY
+extern const uint8_t padding_sha256_rsa4096[];
 extern const uint8_t padding_sha256_rsa2048[];
 extern const uint8_t padding_sha1_rsa2048[];
 
diff --git a/include/rsa.h b/include/rsa.h
index 0367671..a388233 100644
--- a/include/rsa.h
+++ b/include/rsa.h
@@ -103,4 +103,14 @@ static inline int rsa_verify(struct image_sign_info *info,
 }
 #endif
 
+#define RSA2048_BYTES	(2048 / 8)
+#define RSA4096_BYTES	(4096 / 8)
+
+/* This is the minimum/maximum key size we support, in bits */
+#define RSA_MIN_KEY_BITS	2048
+#define RSA_MAX_KEY_BITS	4096
+
+/* This is the maximum signature length that we support, in bits */
+#define RSA_MAX_SIG_BITS	4096
+
 #endif
diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c
index e520e1c..a9d096d 100644
--- a/lib/rsa/rsa-checksum.c
+++ b/lib/rsa/rsa-checksum.c
@@ -13,8 +13,6 @@
 #include <asm/errno.h>
 #include <asm/unaligned.h>
 
-#define RSA2048_BYTES 256
-
 /* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */
 
 const uint8_t padding_sha256_rsa2048[RSA2048_BYTES - SHA256_SUM_LEN] = {
@@ -71,6 +69,69 @@ const uint8_t padding_sha1_rsa2048[RSA2048_BYTES - SHA1_SUM_LEN] = {
 	0x05, 0x00, 0x04, 0x14
 };
 
+const uint8_t padding_sha256_rsa4096[RSA4096_BYTES - SHA256_SUM_LEN] = {
+	0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
+	0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+	0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+};
+
 void sha1_calculate(const struct image_region region[], int region_count,
 		    uint8_t *checksum)
 {
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index b3573a8..09268ca 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -15,15 +15,6 @@
 
 #define UINT64_MULT32(v, multby)  (((uint64_t)(v)) * ((uint32_t)(multby)))
 
-#define RSA2048_BYTES	(2048 / 8)
-
-/* This is the minimum/maximum key size we support, in bits */
-#define RSA_MIN_KEY_BITS	2048
-#define RSA_MAX_KEY_BITS	2048
-
-/* This is the maximum signature length that we support, in bits */
-#define RSA_MAX_SIG_BITS	2048
-
 /**
  * subtract_modulus() - subtract modulus from the given value
  *
@@ -197,7 +188,7 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
 		return ret;
 
 	padding = algo->rsa_padding;
-	pad_len = RSA2048_BYTES - algo->checksum_len;
+	pad_len = algo->pad_len - algo->checksum_len;
 
 	/* Check pkcs1.5 padding bytes. */
 	if (memcmp(buf, padding, pad_len)) {
@@ -281,7 +272,7 @@ int rsa_verify(struct image_sign_info *info,
 {
 	const void *blob = info->fdt_blob;
 	/* Reserve memory for maximum checksum-length */
-	uint8_t hash[RSA2048_BYTES];
+	uint8_t hash[info->algo->checksum->pad_len];
 	int ndepth, noffset;
 	int sig_node, node;
 	char name[100];
@@ -291,9 +282,10 @@ int rsa_verify(struct image_sign_info *info,
 	 * Verify that the checksum-length does not exceed the
 	 * rsa-signature-length
 	 */
-	if (info->algo->checksum->checksum_len > RSA2048_BYTES) {
-		debug("%s: invlaid checksum-algorithm %s for RSA2048\n",
-		      __func__, info->algo->checksum->name);
+	if (info->algo->checksum->checksum_len >
+	    info->algo->checksum->pad_len) {
+		debug("%s: invlaid checksum-algorithm %s for %s\n",
+		      __func__, info->algo->checksum->name, info->algo->name);
 		return -EINVAL;
 	}
 
-- 
1.8.3.1

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

* [U-Boot] [PATCH v2 6/8] gen: Add progressive hash API
  2014-02-09  5:34 [U-Boot] [PATCH v2 0/8] common, fit, rsa: enhancements Heiko Schocher
                   ` (4 preceding siblings ...)
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 5/8] rsa: add sha256,rsa4096 algorithm Heiko Schocher
@ 2014-02-09  5:34 ` Heiko Schocher
  2014-02-15 23:14   ` Simon Glass
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 7/8] tools, fit: add fit_info host command Heiko Schocher
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 8/8] tools, fit_check_sign: verify a signed fit image Heiko Schocher
  7 siblings, 1 reply; 20+ messages in thread
From: Heiko Schocher @ 2014-02-09  5:34 UTC (permalink / raw)
  To: u-boot

From: Hung-ying Tyan <tyanh@chromium.org>

Add hash_init(), hash_update() and hash_finish() to the
hash_algo struct. Add hash_lookup_algo() to look up the
struct given an algorithm name.

Signed-off-by: Hung-ying Tyan <tyanh@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heiko Schocher <hs@denx.de>

---
changes for v2:
- new in v2

 common/hash.c  | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 include/hash.h |  48 ++++++++++++++++++++++++
 2 files changed, 153 insertions(+), 11 deletions(-)

diff --git a/common/hash.c b/common/hash.c
index 872cd85..7627b84 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -12,6 +12,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <malloc.h>
 #include <hw_sha.h>
 #include <hash.h>
 #include <sha1.h>
@@ -19,6 +20,88 @@
 #include <asm/io.h>
 #include <asm/errno.h>
 
+#ifdef CONFIG_CMD_SHA1SUM
+static int hash_init_sha1(struct hash_algo *algo, void **ctxp)
+{
+	sha1_context *ctx = malloc(sizeof(sha1_context));
+	sha1_starts(ctx);
+	*ctxp = ctx;
+	return 0;
+}
+
+static int hash_update_sha1(struct hash_algo *algo, void *ctx, const void *buf,
+			    unsigned int size, int is_last)
+{
+	sha1_update((sha1_context *)ctx, buf, size);
+	return 0;
+}
+
+static int hash_finish_sha1(struct hash_algo *algo, void *ctx, void *dest_buf,
+			    int size)
+{
+	if (size < algo->digest_size)
+		return -1;
+
+	sha1_finish((sha1_context *)ctx, dest_buf);
+	free(ctx);
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_SHA256
+static int hash_init_sha256(struct hash_algo *algo, void **ctxp)
+{
+	sha256_context *ctx = malloc(sizeof(sha256_context));
+	sha256_starts(ctx);
+	*ctxp = ctx;
+	return 0;
+}
+
+static int hash_update_sha256(struct hash_algo *algo, void *ctx,
+			      const void *buf, unsigned int size, int is_last)
+{
+	sha256_update((sha256_context *)ctx, buf, size);
+	return 0;
+}
+
+static int hash_finish_sha256(struct hash_algo *algo, void *ctx, void
+			      *dest_buf, int size)
+{
+	if (size < algo->digest_size)
+		return -1;
+
+	sha256_finish((sha256_context *)ctx, dest_buf);
+	free(ctx);
+	return 0;
+}
+#endif
+
+static int hash_init_crc32(struct hash_algo *algo, void **ctxp)
+{
+	uint32_t *ctx = malloc(sizeof(uint32_t));
+	*ctx = 0;
+	*ctxp = ctx;
+	return 0;
+}
+
+static int hash_update_crc32(struct hash_algo *algo, void *ctx,
+			     const void *buf, unsigned int size, int is_last)
+{
+	*((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), buf, size);
+	return 0;
+}
+
+static int hash_finish_crc32(struct hash_algo *algo, void *ctx, void *dest_buf,
+			     int size)
+{
+	if (size < algo->digest_size)
+		return -1;
+
+	*((uint32_t *)dest_buf) = *((uint32_t *)ctx);
+	free(ctx);
+	return 0;
+}
+
 /*
  * These are the hash algorithms we support. Chips which support accelerated
  * crypto could perhaps add named version of these algorithms here. Note that
@@ -53,6 +136,9 @@ static struct hash_algo hash_algo[] = {
 		SHA1_SUM_LEN,
 		sha1_csum_wd,
 		CHUNKSZ_SHA1,
+		hash_init_sha1,
+		hash_update_sha1,
+		hash_finish_sha1,
 	},
 #define MULTI_HASH
 #endif
@@ -62,6 +148,9 @@ static struct hash_algo hash_algo[] = {
 		SHA256_SUM_LEN,
 		sha256_csum_wd,
 		CHUNKSZ_SHA256,
+		hash_init_sha256,
+		hash_update_sha256,
+		hash_finish_sha256,
 	},
 #define MULTI_HASH
 #endif
@@ -70,6 +159,9 @@ static struct hash_algo hash_algo[] = {
 		4,
 		crc32_wd_buf,
 		CHUNKSZ_CRC32,
+		hash_init_crc32,
+		hash_update_crc32,
+		hash_finish_crc32,
 	},
 };
 
@@ -204,16 +296,19 @@ static int parse_verify_sum(struct hash_algo *algo, char *verify_str, u8 *vsum,
 	return 0;
 }
 
-static struct hash_algo *find_hash_algo(const char *name)
+int hash_lookup_algo(const char *algo_name, struct hash_algo **algop)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
-		if (!strcmp(name, hash_algo[i].name))
-			return &hash_algo[i];
+		if (!strcmp(algo_name, hash_algo[i].name)) {
+			*algop = &hash_algo[i];
+			return 0;
+		}
 	}
 
-	return NULL;
+	debug("Unknown hash algorithm '%s'\n", algo_name);
+	return -EPROTONOSUPPORT;
 }
 
 static void show_hash(struct hash_algo *algo, ulong addr, ulong len,
@@ -230,12 +325,12 @@ int hash_block(const char *algo_name, const void *data, unsigned int len,
 	       uint8_t *output, int *output_size)
 {
 	struct hash_algo *algo;
+	int ret;
+
+	ret = hash_lookup_algo(algo_name, &algo);
+	if (ret)
+		return ret;
 
-	algo = find_hash_algo(algo_name);
-	if (!algo) {
-		debug("Unknown hash algorithm '%s'\n", algo_name);
-		return -EPROTONOSUPPORT;
-	}
 	if (output_size && *output_size < algo->digest_size) {
 		debug("Output buffer size %d too small (need %d bytes)",
 		      *output_size, algo->digest_size);
@@ -265,8 +360,7 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
 		u8 vsum[HASH_MAX_DIGEST_SIZE];
 		void *buf;
 
-		algo = find_hash_algo(algo_name);
-		if (!algo) {
+		if (hash_lookup_algo(algo_name, &algo)) {
 			printf("Unknown hash algorithm '%s'\n", algo_name);
 			return CMD_RET_USAGE;
 		}
diff --git a/include/hash.h b/include/hash.h
index e92d272..dc21678 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -27,6 +27,42 @@ struct hash_algo {
 	void (*hash_func_ws)(const unsigned char *input, unsigned int ilen,
 		unsigned char *output, unsigned int chunk_sz);
 	int chunk_size;				/* Watchdog chunk size */
+	/*
+	 * hash_init: Create the context for progressive hashing
+	 *
+	 * @algo: Pointer to the hash_algo struct
+	 * @ctxp: Pointer to the pointer of the context for hashing
+	 * @return 0 if ok, -1 on error
+	 */
+	int (*hash_init)(struct hash_algo *algo, void **ctxp);
+	/*
+	 * hash_update: Perform hashing on the given buffer
+	 *
+	 * The context is freed by this function if an error occurs.
+	 *
+	 * @algo: Pointer to the hash_algo struct
+	 * @ctx: Pointer to the context for hashing
+	 * @buf: Pointer to the buffer being hashed
+	 * @size: Size of the buffer being hashed
+	 * @is_last: 1 if this is the last update; 0 otherwise
+	 * @return 0 if ok, -1 on error
+	 */
+	int (*hash_update)(struct hash_algo *algo, void *ctx, const void *buf,
+			   unsigned int size, int is_last);
+	/*
+	 * hash_finish: Write the hash result to the given buffer
+	 *
+	 * The context is freed by this function.
+	 *
+	 * @algo: Pointer to the hash_algo struct
+	 * @ctx: Pointer to the context for hashing
+	 * @dest_buf: Pointer to the buffer for the result
+	 * @size: Size of the buffer for the result
+	 * @return 0 if ok, -ENOSPC if size of the result buffer is too small
+	 *   or -1 on other errors
+	 */
+	int (*hash_finish)(struct hash_algo *algo, void *ctx, void *dest_buf,
+			   int size);
 };
 
 /*
@@ -77,4 +113,16 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
 int hash_block(const char *algo_name, const void *data, unsigned int len,
 	       uint8_t *output, int *output_size);
 
+/**
+ * hash_lookup_algo() - Look up the hash_algo struct for an algorithm
+ *
+ * The function returns the pointer to the struct or -EPROTONOSUPPORT if the
+ * algorithm is not available.
+ *
+ * @algo_name: Hash algorithm to look up
+ * @algop: Pointer to the hash_algo struct if found
+ *
+ * @return 0 if ok, -EPROTONOSUPPORT for an unknown algorithm.
+ */
+int hash_lookup_algo(const char *algo_name, struct hash_algo **algop);
 #endif
-- 
1.8.3.1

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

* [U-Boot] [PATCH v2 7/8] tools, fit: add fit_info host command
  2014-02-09  5:34 [U-Boot] [PATCH v2 0/8] common, fit, rsa: enhancements Heiko Schocher
                   ` (5 preceding siblings ...)
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 6/8] gen: Add progressive hash API Heiko Schocher
@ 2014-02-09  5:34 ` Heiko Schocher
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 8/8] tools, fit_check_sign: verify a signed fit image Heiko Schocher
  7 siblings, 0 replies; 20+ messages in thread
From: Heiko Schocher @ 2014-02-09  5:34 UTC (permalink / raw)
  To: u-boot

add fit_info command to the host tools. This command prints
the name, offset and the len from a property from a node in
a fit file. This info can be used to extract a properties
data with linux tools, for example "dd".

Signed-off-by: Heiko Schocher <hs@denx.de>
---
- no changes for v2

 Makefile           |   1 +
 tools/Makefile     |  20 +++++++++
 tools/fit_common.c |  81 +++++++++++++++++++++++++++++++++++++
 tools/fit_common.h |  22 ++++++++++
 tools/fit_image.c  |  62 ++--------------------------
 tools/fit_info.c   | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 244 insertions(+), 58 deletions(-)
 create mode 100644 tools/fit_common.c
 create mode 100644 tools/fit_common.h
 create mode 100644 tools/fit_info.c

diff --git a/Makefile b/Makefile
index 47a03e3..a2e424d 100644
--- a/Makefile
+++ b/Makefile
@@ -794,6 +794,7 @@ clean:
 	@rm -f $(obj)tools/bmp_logo	   $(obj)tools/easylogo/easylogo  \
 	       $(obj)tools/env/fw_printenv				  \
 	       $(obj)tools/envcrc					  \
+	       $(obj)tools/fit_info					  \
 	       $(obj)tools/gdb/{gdbcont,gdbsend}			  \
 	       $(obj)tools/gen_eth_addr    $(obj)tools/img2srec		  \
 	       $(obj)tools/dump{env,}image		  \
diff --git a/tools/Makefile b/tools/Makefile
index 5e36e5e..d079bc9 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -53,6 +53,7 @@ BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
 BIN_FILES-y += dumpimage$(SFX)
 BIN_FILES-y += mkenvimage$(SFX)
 BIN_FILES-y += mkimage$(SFX)
+BIN_FILES-y += fit_info$(SFX)
 BIN_FILES-$(CONFIG_EXYNOS5250) += mk$(BOARD)spl$(SFX)
 BIN_FILES-$(CONFIG_EXYNOS5420) += mk$(BOARD)spl$(SFX)
 BIN_FILES-$(CONFIG_MX23) += mxsboot$(SFX)
@@ -77,6 +78,7 @@ EXT_OBJ_FILES-y += lib/sha256.o
 NOPED_OBJ_FILES-y += aisimage.o
 NOPED_OBJ_FILES-y += default_image.o
 NOPED_OBJ_FILES-y += dumpimage.o
+NOPED_OBJ_FILES-y += fit_common.o
 NOPED_OBJ_FILES-y += fit_image.o
 NOPED_OBJ_FILES-y += image-host.o
 NOPED_OBJ_FILES-y += imximage.o
@@ -84,6 +86,7 @@ NOPED_OBJ_FILES-y += kwbimage.o
 NOPED_OBJ_FILES-y += imagetool.o
 NOPED_OBJ_FILES-y += mkenvimage.o
 NOPED_OBJ_FILES-y += mkimage.o
+NOPED_OBJ_FILES-y += fit_info.o
 NOPED_OBJ_FILES-y += mxsimage.o
 NOPED_OBJ_FILES-y += omapimage.o
 NOPED_OBJ_FILES-y += os_support.o
@@ -210,6 +213,7 @@ $(obj)dumpimage$(SFX):	$(obj)aisimage.o \
 			$(FIT_SIG_OBJS) \
 			$(obj)crc32.o \
 			$(obj)default_image.o \
+			$(obj)fit_common.o \
 			$(obj)fit_image.o \
 			$(obj)image-fit.o \
 			$(obj)image.o \
@@ -240,6 +244,7 @@ $(obj)mkimage$(SFX):	$(obj)aisimage.o \
 			$(FIT_SIG_OBJS) \
 			$(obj)crc32.o \
 			$(obj)default_image.o \
+			$(obj)fit_common.o \
 			$(obj)fit_image.o \
 			$(obj)image-fit.o \
 			$(obj)image-host.o \
@@ -261,6 +266,21 @@ $(obj)mkimage$(SFX):	$(obj)aisimage.o \
 	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ $(HOSTLIBS)
 	$(HOSTSTRIP) $@
 
+$(obj)fit_info$(SFX):	$(obj)fit_info.o \
+			$(FIT_SIG_OBJS) \
+			$(obj)crc32.o \
+			$(obj)fit_common.o \
+			$(obj)image-fit.o \
+			$(obj)image-host.o \
+			$(obj)image.o \
+			$(obj)md5.o \
+			$(obj)sha1.o \
+			$(obj)sha256.o \
+			$(LIBFDT_OBJS) \
+			$(RSA_OBJS)
+	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ $(HOSTLIBS)
+	$(HOSTSTRIP) $@
+
 $(obj)mk$(BOARD)spl$(SFX):	$(obj)mkexynosspl.o
 	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 	$(HOSTSTRIP) $@
diff --git a/tools/fit_common.c b/tools/fit_common.c
new file mode 100644
index 0000000..26b6c8d
--- /dev/null
+++ b/tools/fit_common.c
@@ -0,0 +1,81 @@
+/*
+ * (C) Copyright 2014
+ * DENX Software Engineering
+ * Heiko Schocher <hs@denx.de>
+ *
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2004
+ * DENX Software Engineering
+ * Wolfgang Denk, wd at denx.de
+ *
+ * Updated-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *		FIT image specific code abstracted from mkimage.c
+ *		some functions added to address abstraction
+ *
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include "imagetool.h"
+#include "mkimage.h"
+#include "fit_common.h"
+#include <image.h>
+#include <u-boot/crc.h>
+
+int fit_verify_header(unsigned char *ptr, int image_size,
+			struct image_tool_params *params)
+{
+	return fdt_check_header(ptr);
+}
+
+int fit_check_image_types(uint8_t type)
+{
+	if (type == IH_TYPE_FLATDT)
+		return EXIT_SUCCESS;
+	else
+		return EXIT_FAILURE;
+}
+
+int mmap_fdt(char *cmdname, const char *fname, void **blobp,
+		struct stat *sbuf)
+{
+	void *ptr;
+	int fd;
+
+	/* Load FIT blob into memory (we need to write hashes/signatures) */
+	fd = open(fname, O_RDWR | O_BINARY);
+
+	if (fd < 0) {
+		fprintf(stderr, "%s: Can't open %s: %s\n",
+			cmdname, fname, strerror(errno));
+		unlink(fname);
+		return -1;
+	}
+
+	if (fstat(fd, sbuf) < 0) {
+		fprintf(stderr, "%s: Can't stat %s: %s\n",
+			cmdname, fname, strerror(errno));
+		unlink(fname);
+		return -1;
+	}
+
+	ptr = mmap(0, sbuf->st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+	if (ptr == MAP_FAILED) {
+		fprintf(stderr, "%s: Can't read %s: %s\n",
+			cmdname, fname, strerror(errno));
+		unlink(fname);
+		return -1;
+	}
+
+	/* check if ptr has a valid blob */
+	if (fdt_check_header(ptr)) {
+		fprintf(stderr, "%s: Invalid FIT blob\n", cmdname);
+		unlink(fname);
+		return -1;
+	}
+
+	*blobp = ptr;
+	return fd;
+}
diff --git a/tools/fit_common.h b/tools/fit_common.h
new file mode 100644
index 0000000..e745f10
--- /dev/null
+++ b/tools/fit_common.h
@@ -0,0 +1,22 @@
+/*
+ * (C) Copyright 2014
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _FIT_COMMON_H_
+#define _FIT_COMMON_H_
+
+#include "imagetool.h"
+#include "mkimage.h"
+#include <image.h>
+
+int fit_verify_header(unsigned char *ptr, int image_size,
+			struct image_tool_params *params);
+
+int fit_check_image_types(uint8_t type);
+
+int mmap_fdt(char *cmdname, const char *fname, void **blobp,
+		struct stat *sbuf);
+
+#endif /* _FIT_COMMON_H_ */
diff --git a/tools/fit_image.c b/tools/fit_image.c
index 1466164..d4430bc 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -15,68 +15,13 @@
  */
 
 #include "imagetool.h"
+#include "fit_common.h"
 #include "mkimage.h"
 #include <image.h>
 #include <u-boot/crc.h>
 
 static image_header_t header;
 
-static int fit_verify_header (unsigned char *ptr, int image_size,
-			struct image_tool_params *params)
-{
-	return fdt_check_header(ptr);
-}
-
-static int fit_check_image_types (uint8_t type)
-{
-	if (type == IH_TYPE_FLATDT)
-		return EXIT_SUCCESS;
-	else
-		return EXIT_FAILURE;
-}
-
-int mmap_fdt(struct image_tool_params *params, const char *fname, void **blobp,
-		struct stat *sbuf)
-{
-	void *ptr;
-	int fd;
-
-	/* Load FIT blob into memory (we need to write hashes/signatures) */
-	fd = open(fname, O_RDWR | O_BINARY);
-
-	if (fd < 0) {
-		fprintf(stderr, "%s: Can't open %s: %s\n",
-			params->cmdname, fname, strerror(errno));
-		unlink(fname);
-		return -1;
-	}
-
-	if (fstat(fd, sbuf) < 0) {
-		fprintf(stderr, "%s: Can't stat %s: %s\n",
-			params->cmdname, fname, strerror(errno));
-		unlink(fname);
-		return -1;
-	}
-
-	ptr = mmap(0, sbuf->st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-	if (ptr == MAP_FAILED) {
-		fprintf(stderr, "%s: Can't read %s: %s\n",
-			params->cmdname, fname, strerror(errno));
-		unlink(fname);
-		return -1;
-	}
-
-	/* check if ptr has a valid blob */
-	if (fdt_check_header(ptr)) {
-		fprintf(stderr, "%s: Invalid FIT blob\n", params->cmdname);
-		unlink(fname);
-		return -1;
-	}
-
-	*blobp = ptr;
-	return fd;
-}
-
 /**
  * fit_handle_file - main FIT file processing function
  *
@@ -129,13 +74,14 @@ static int fit_handle_file(struct image_tool_params *params)
 	}
 
 	if (params->keydest) {
-		destfd = mmap_fdt(params, params->keydest, &dest_blob, &sbuf);
+		destfd = mmap_fdt(params->cmdname, params->keydest,
+				  &dest_blob, &sbuf);
 		if (destfd < 0)
 			goto err_keydest;
 		destfd_size = sbuf.st_size;
 	}
 
-	tfd = mmap_fdt(params, tmpfile, &ptr, &sbuf);
+	tfd = mmap_fdt(params->cmdname, tmpfile, &ptr, &sbuf);
 	if (tfd < 0)
 		goto err_mmap;
 
diff --git a/tools/fit_info.c b/tools/fit_info.c
new file mode 100644
index 0000000..4c5a1a1
--- /dev/null
+++ b/tools/fit_info.c
@@ -0,0 +1,116 @@
+/*
+ * (C) Copyright 2014
+ * DENX Software Engineering
+ * Heiko Schocher <hs@denx.de>
+ *
+ * fit_info: print the offset and the len of a property from
+ *	     node in a fit file.
+ *
+ * Based on:
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2004
+ * DENX Software Engineering
+ * Wolfgang Denk, wd at denx.de
+ *
+ * Updated-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *		FIT image specific code abstracted from mkimage.c
+ *		some functions added to address abstraction
+ *
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include "mkimage.h"
+#include "fit_common.h"
+#include <image.h>
+#include <u-boot/crc.h>
+
+void usage(char *cmdname)
+{
+	fprintf(stderr, "Usage: %s -f fit file [<node> <property>]\n"
+			 "          -f ==> set fit file which is used'\n",
+		cmdname);
+	exit(EXIT_FAILURE);
+}
+
+void *key_blob;
+
+void *get_blob(void)
+{
+	return key_blob;
+}
+
+int main(int argc, char **argv)
+{
+	int ffd = -1;
+	struct stat fsbuf;
+	void *fit_blob;
+	int len;
+	int  nodeoffset;	/* node offset from libfdt */
+	const void *nodep;	/* property node pointer */
+	char *fdtfile = NULL;
+	char cmdname[50];
+
+	strcpy(cmdname, *argv);
+
+	while (--argc > 0 && **++argv == '-') {
+		while (*++*argv) {
+			switch (**argv) {
+			case 'f':
+				if (--argc <= 0)
+					usage(cmdname);
+				fdtfile = *++argv;
+				goto NXTARG;
+
+			default:
+				usage(cmdname);
+			}
+		}
+NXTARG:;
+	}
+
+	if (argc != 2)
+		usage(cmdname);
+
+	ffd = mmap_fdt(cmdname, fdtfile, &fit_blob, &fsbuf);
+
+	if (ffd < 0) {
+		printf("Could not open %s\n", fdtfile);
+		exit(EXIT_FAILURE);
+	}
+
+	nodeoffset = fdt_path_offset(fit_blob, argv[0]);
+	if (nodeoffset < 0) {
+		printf("%s not found.", argv[0]);
+		exit(EXIT_FAILURE);
+	}
+	nodep = fdt_getprop(fit_blob, nodeoffset, argv[1], &len);
+	if (len == 0) {
+		printf("len == 0 %s\n", argv[1]);
+		exit(EXIT_FAILURE);
+	}
+
+	printf("NAME: %s\n", fit_get_name(fit_blob, nodeoffset, NULL));
+	printf("LEN: %d\n", len);
+	printf("OFF: %d\n", (int)(nodep - fit_blob));
+	(void) munmap((void *)fit_blob, fsbuf.st_size);
+
+	/* We're a bit of paranoid */
+#if defined(_POSIX_SYNCHRONIZED_IO) && \
+	!defined(__sun__) && \
+	!defined(__FreeBSD__) && \
+	!defined(__APPLE__)
+	(void) fdatasync(ffd);
+#else
+	(void) fsync(ffd);
+#endif
+
+	if (close(ffd)) {
+		fprintf(stderr, "%s: Write error on %s: %s\n",
+			cmdname, fdtfile, strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+	exit(EXIT_SUCCESS);
+}
-- 
1.8.3.1

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

* [U-Boot] [PATCH v2 8/8] tools, fit_check_sign: verify a signed fit image
  2014-02-09  5:34 [U-Boot] [PATCH v2 0/8] common, fit, rsa: enhancements Heiko Schocher
                   ` (6 preceding siblings ...)
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 7/8] tools, fit: add fit_info host command Heiko Schocher
@ 2014-02-09  5:34 ` Heiko Schocher
  2014-02-15 23:22   ` Simon Glass
  7 siblings, 1 reply; 20+ messages in thread
From: Heiko Schocher @ 2014-02-09  5:34 UTC (permalink / raw)
  To: u-boot

add host tool "fit_check_sign" which verifies, if a fit image is
signed correct.

Signed-off-by: Heiko Schocher <hs@denx.de>
Cc: Simon Glass <sjg@chromium.org>

---
- changes for v2:
  - fixed compile error for sandbox
  - add fit_check_sign test to test/vboot/vboot_test.sh

 Makefile                     |   1 +
 common/image-sig.c           |  22 +++++---
 doc/uImage.FIT/signature.txt |   8 +++
 include/fdt_support.h        |   5 ++
 include/image.h              |  16 +++---
 lib/libfdt/fdt_wip.c         |  17 +++++++
 lib/rsa/rsa-checksum.c       |  10 ++--
 lib/rsa/rsa-sign.c           |   2 +-
 lib/rsa/rsa-verify.c         |  18 +++++--
 test/vboot/vboot_test.sh     |  36 ++++++++++++-
 tools/Makefile               |  19 ++++++-
 tools/fdt_host.h             |   2 +
 tools/fit_check_sign.c       | 119 +++++++++++++++++++++++++++++++++++++++++++
 tools/image-host.c           |  13 +++++
 14 files changed, 265 insertions(+), 23 deletions(-)
 create mode 100644 tools/fit_check_sign.c

diff --git a/Makefile b/Makefile
index a2e424d..900d8f7 100644
--- a/Makefile
+++ b/Makefile
@@ -794,6 +794,7 @@ clean:
 	@rm -f $(obj)tools/bmp_logo	   $(obj)tools/easylogo/easylogo  \
 	       $(obj)tools/env/fw_printenv				  \
 	       $(obj)tools/envcrc					  \
+	       $(obj)tools/fit_check_sign				  \
 	       $(obj)tools/fit_info					  \
 	       $(obj)tools/gdb/{gdbcont,gdbsend}			  \
 	       $(obj)tools/gen_eth_addr    $(obj)tools/img2srec		  \
diff --git a/common/image-sig.c b/common/image-sig.c
index 199e634..5b19ea8 100644
--- a/common/image-sig.c
+++ b/common/image-sig.c
@@ -19,6 +19,14 @@ DECLARE_GLOBAL_DATA_PTR;
 #define IMAGE_MAX_HASHED_NODES		100
 
 #if defined(CONFIG_FIT_SIGNATURE)
+
+#ifdef USE_HOSTCC
+__attribute__((weak)) void *get_blob(void)
+{
+	return NULL;
+}
+#endif
+
 struct checksum_algo checksum_algos[] = {
 	{
 		"sha1",
@@ -26,10 +34,9 @@ struct checksum_algo checksum_algos[] = {
 		RSA2048_BYTES,
 #if IMAGE_ENABLE_SIGN
 		EVP_sha1,
-#else
+#endif
 		sha1_calculate,
 		padding_sha1_rsa2048,
-#endif
 	},
 	{
 		"sha256",
@@ -37,10 +44,9 @@ struct checksum_algo checksum_algos[] = {
 		RSA2048_BYTES,
 #if IMAGE_ENABLE_SIGN
 		EVP_sha256,
-#else
+#endif
 		sha256_calculate,
 		padding_sha256_rsa2048,
-#endif
 	},
 	{
 		"sha256",
@@ -48,10 +54,9 @@ struct checksum_algo checksum_algos[] = {
 		RSA4096_BYTES,
 #if IMAGE_ENABLE_SIGN
 		EVP_sha256,
-#else
+#endif
 		sha256_calculate,
 		padding_sha256_rsa4096,
-#endif
 	}
 
 };
@@ -462,4 +467,9 @@ int fit_config_verify(const void *fit, int conf_noffset)
 	return !fit_config_verify_required_sigs(fit, conf_noffset,
 						gd_fdt_blob());
 }
+#else
+int fit_config_verify(const void *fit, int conf_noffset)
+{
+	return 0;
+}
 #endif
diff --git a/doc/uImage.FIT/signature.txt b/doc/uImage.FIT/signature.txt
index 5bd229f..171af2a 100644
--- a/doc/uImage.FIT/signature.txt
+++ b/doc/uImage.FIT/signature.txt
@@ -355,7 +355,11 @@ Test Verified Boot Run: signed images: OK
 Build FIT with signed configuration
 Test Verified Boot Run: unsigned config: OK
 Sign images
+check signed config on the host
+OK
 Test Verified Boot Run: signed config: OK
+check bad signed config on the host
+OK
 Test Verified Boot Run: signed config with bad hash: OK
 
 Test sha1 passed
@@ -377,7 +381,11 @@ Test Verified Boot Run: signed images: OK
 Build FIT with signed configuration
 Test Verified Boot Run: unsigned config: OK
 Sign images
+check signed config on the host
+OK
 Test Verified Boot Run: signed config: OK
+check bad signed config on the host
+OK
 Test Verified Boot Run: signed config with bad hash: OK
 
 Test sha256 passed
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 9871e2f..76c9b2e 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -115,4 +115,9 @@ static inline int fdt_status_disabled_by_alias(void *fdt, const char* alias)
 }
 
 #endif /* ifdef CONFIG_OF_LIBFDT */
+
+#ifdef USE_HOSTCC
+int fdtdec_get_int(const void *blob, int node, const char *prop_name,
+		int default_val);
+#endif
 #endif /* ifndef __FDT_SUPPORT_H */
diff --git a/include/image.h b/include/image.h
index 6e4745a..260a396 100644
--- a/include/image.h
+++ b/include/image.h
@@ -831,7 +831,7 @@ int calculate_hash(const void *data, int data_len, const char *algo,
 #if defined(CONFIG_FIT_SIGNATURE)
 # ifdef USE_HOSTCC
 #  define IMAGE_ENABLE_SIGN	1
-#  define IMAGE_ENABLE_VERIFY	0
+#  define IMAGE_ENABLE_VERIFY	1
 # include  <openssl/evp.h>
 #else
 #  define IMAGE_ENABLE_SIGN	0
@@ -843,7 +843,8 @@ int calculate_hash(const void *data, int data_len, const char *algo,
 #endif
 
 #ifdef USE_HOSTCC
-# define gd_fdt_blob()		NULL
+void *get_blob(void);
+# define gd_fdt_blob()		get_blob()
 #else
 # define gd_fdt_blob()		(gd->fdt_blob)
 #endif
@@ -880,14 +881,11 @@ struct checksum_algo {
 	const int checksum_len;
 	const int pad_len;
 #if IMAGE_ENABLE_SIGN
-	const EVP_MD *(*calculate)(void);
-#else
-#if IMAGE_ENABLE_VERIFY
+	const EVP_MD *(*calculate_sign)(void);
+#endif
 	void (*calculate)(const struct image_region region[],
 			  int region_count, uint8_t *checksum);
 	const uint8_t *rsa_padding;
-#endif
-#endif
 };
 
 struct image_sig_algo {
@@ -1008,7 +1006,11 @@ struct image_region *fit_region_make_list(const void *fit,
 
 static inline int fit_image_check_target_arch(const void *fdt, int node)
 {
+#ifndef USE_HOSTCC
 	return fit_image_check_arch(fdt, node, IH_ARCH_DEFAULT);
+#else
+	return 0;
+#endif
 }
 
 #ifdef CONFIG_FIT_VERBOSE
diff --git a/lib/libfdt/fdt_wip.c b/lib/libfdt/fdt_wip.c
index 3f2dfa5..4babdbc 100644
--- a/lib/libfdt/fdt_wip.c
+++ b/lib/libfdt/fdt_wip.c
@@ -31,6 +31,23 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
 	return 0;
 }
 
+#ifdef USE_HOSTCC
+int fdtdec_get_int(const void *blob, int node, const char *prop_name,
+		int default_val)
+{
+	const int *cell;
+	int len;
+
+	cell = fdt_getprop_w((void *)blob, node, prop_name, &len);
+	if (cell && len >= sizeof(int)) {
+		int val = fdt32_to_cpu(cell[0]);
+
+		return val;
+	}
+	return default_val;
+}
+#endif
+
 static void _fdt_nop_region(void *start, int len)
 {
 	fdt32_t *p;
diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c
index a9d096d..32d6602 100644
--- a/lib/rsa/rsa-checksum.c
+++ b/lib/rsa/rsa-checksum.c
@@ -4,14 +4,18 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#ifndef USE_HOSTCC
 #include <common.h>
 #include <fdtdec.h>
-#include <rsa.h>
-#include <sha1.h>
-#include <sha256.h>
 #include <asm/byteorder.h>
 #include <asm/errno.h>
 #include <asm/unaligned.h>
+#else
+#include "fdt_host.h"
+#endif
+#include <rsa.h>
+#include <sha1.h>
+#include <sha256.h>
 
 /* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */
 
diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index 0fe6e9f..ca8c120 100644
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -193,7 +193,7 @@ static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo,
 		goto err_create;
 	}
 	EVP_MD_CTX_init(context);
-	if (!EVP_SignInit(context, checksum_algo->calculate())) {
+	if (!EVP_SignInit(context, checksum_algo->calculate_sign())) {
 		ret = rsa_err("Signer setup failed");
 		goto err_sign;
 	}
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index 09268ca..587da5b 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -4,17 +4,28 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#ifndef USE_HOSTCC
 #include <common.h>
 #include <fdtdec.h>
-#include <rsa.h>
-#include <sha1.h>
-#include <sha256.h>
+#include <asm/types.h>
 #include <asm/byteorder.h>
 #include <asm/errno.h>
+#include <asm/types.h>
 #include <asm/unaligned.h>
+#else
+#include "fdt_host.h"
+#include "mkimage.h"
+#include <fdt_support.h>
+#endif
+#include <rsa.h>
+#include <sha1.h>
+#include <sha256.h>
 
 #define UINT64_MULT32(v, multby)  (((uint64_t)(v)) * ((uint32_t)(multby)))
 
+#define get_unaligned_be32(a) fdt32_to_cpu(*(uint32_t *)a)
+#define put_unaligned_be32(a, b) (*(uint32_t *)(b) = cpu_to_fdt32(a))
+
 /**
  * subtract_modulus() - subtract modulus from the given value
  *
@@ -150,7 +161,6 @@ static int pow_mod(const struct rsa_public_key *key, uint32_t *inout)
 	/* Convert to bigendian byte array */
 	for (i = key->len - 1, ptr = inout; (int)i >= 0; i--, ptr++)
 		put_unaligned_be32(result[i], ptr);
-
 	return 0;
 }
 
diff --git a/test/vboot/vboot_test.sh b/test/vboot/vboot_test.sh
index 27b221a..fc33f2d 100755
--- a/test/vboot/vboot_test.sh
+++ b/test/vboot/vboot_test.sh
@@ -55,6 +55,7 @@ O=$(readlink -f ${O})
 dtc="-I dts -O dtb -p 2000"
 uboot="${O}/u-boot"
 mkimage="${O}/tools/mkimage"
+fit_check_sign="${O}/tools/fit_check_sign"
 keys="${dir}/dev-keys"
 echo ${mkimage} -D "${dtc}"
 
@@ -88,7 +89,6 @@ ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb -r test.fit >${tmp}
 
 run_uboot "signed images" "dev+"
 
-
 # Create a fresh .dtb without the public keys
 dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
 
@@ -101,6 +101,23 @@ run_uboot "unsigned config" $sha"+ OK"
 echo Sign images
 ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb -r test.fit >${tmp}
 
+echo check signed config on the host
+if ! ${fit_check_sign} -f test.fit -k sandbox-u-boot.dtb >${tmp}; then
+	echo
+	echo "Verified boot key check on host failed, output follows:"
+	cat ${tmp}
+	false
+else
+	if ! grep -q "dev+" ${tmp}; then
+		echo
+		echo "Verified boot key check failed, output follows:"
+		cat ${tmp}
+		false
+	else
+		echo "OK"
+	fi
+fi
+
 run_uboot "signed config" "dev+"
 
 # Increment the first byte of the signature, which should cause failure
@@ -109,6 +126,23 @@ newbyte=$(printf %x $((0x${sig:0:2} + 1)))
 sig="${newbyte} ${sig:2}"
 fdtput -t bx test.fit /configurations/conf at 1/signature at 1 value ${sig}
 
+echo check bad signed config on the host
+if ${fit_check_sign} -f test.fit -k sandbox-u-boot.dtb >${tmp}; then
+	echo
+	echo "Verified boot key check on host failed, output follows:"
+	cat ${tmp}
+	false
+else
+	if ! grep -q "failed" ${tmp}; then
+		echo
+		echo "Verified boot key check failed, output follows:"
+		cat ${tmp}
+		false
+	else
+		echo "OK"
+	fi
+fi
+
 run_uboot "signed config with bad hash" "Bad Data Hash"
 
 popd >/dev/null
diff --git a/tools/Makefile b/tools/Makefile
index d079bc9..874705a 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -53,6 +53,7 @@ BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
 BIN_FILES-y += dumpimage$(SFX)
 BIN_FILES-y += mkenvimage$(SFX)
 BIN_FILES-y += mkimage$(SFX)
+BIN_FILES-y += fit_check_sign$(SFX)
 BIN_FILES-y += fit_info$(SFX)
 BIN_FILES-$(CONFIG_EXYNOS5250) += mk$(BOARD)spl$(SFX)
 BIN_FILES-$(CONFIG_EXYNOS5420) += mk$(BOARD)spl$(SFX)
@@ -86,6 +87,7 @@ NOPED_OBJ_FILES-y += kwbimage.o
 NOPED_OBJ_FILES-y += imagetool.o
 NOPED_OBJ_FILES-y += mkenvimage.o
 NOPED_OBJ_FILES-y += mkimage.o
+NOPED_OBJ_FILES-y += fit_check_sign.o
 NOPED_OBJ_FILES-y += fit_info.o
 NOPED_OBJ_FILES-y += mxsimage.o
 NOPED_OBJ_FILES-y += omapimage.o
@@ -122,7 +124,7 @@ LIBFDT_OBJ_FILES-y += fdt_strerror.o
 LIBFDT_OBJ_FILES-y += fdt_wip.o
 
 # RSA objects
-RSA_OBJ_FILES-$(CONFIG_FIT_SIGNATURE) += rsa-sign.o
+RSA_OBJ_FILES-$(CONFIG_FIT_SIGNATURE) += rsa-sign.o rsa-verify.o rsa-checksum.o
 
 # Generated LCD/video logo
 LOGO_H = $(OBJTREE)/include/bmp_logo.h
@@ -266,6 +268,21 @@ $(obj)mkimage$(SFX):	$(obj)aisimage.o \
 	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ $(HOSTLIBS)
 	$(HOSTSTRIP) $@
 
+$(obj)fit_check_sign$(SFX):	$(obj)fit_check_sign.o \
+			$(FIT_SIG_OBJS) \
+			$(obj)crc32.o \
+			$(obj)fit_common.o \
+			$(obj)image-fit.o \
+			$(obj)image-host.o \
+			$(obj)image.o \
+			$(obj)md5.o \
+			$(obj)sha1.o \
+			$(obj)sha256.o \
+			$(LIBFDT_OBJS) \
+			$(RSA_OBJS)
+	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ $(HOSTLIBS)
+	$(HOSTSTRIP) $@
+
 $(obj)fit_info$(SFX):	$(obj)fit_info.o \
 			$(FIT_SIG_OBJS) \
 			$(obj)crc32.o \
diff --git a/tools/fdt_host.h b/tools/fdt_host.h
index c2b23c6..134d965 100644
--- a/tools/fdt_host.h
+++ b/tools/fdt_host.h
@@ -11,4 +11,6 @@
 #include "../include/libfdt.h"
 #include "../include/fdt_support.h"
 
+int fit_check_sign(const void *working_fdt, const void *key);
+
 #endif /* __FDT_HOST_H__ */
diff --git a/tools/fit_check_sign.c b/tools/fit_check_sign.c
new file mode 100644
index 0000000..63c7295
--- /dev/null
+++ b/tools/fit_check_sign.c
@@ -0,0 +1,119 @@
+/*
+ * (C) Copyright 2014
+ * DENX Software Engineering
+ * Heiko Schocher <hs@denx.de>
+ *
+ * Based on:
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2004
+ * DENX Software Engineering
+ * Wolfgang Denk, wd at denx.de
+ *
+ * Updated-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *		FIT image specific code abstracted from mkimage.c
+ *		some functions added to address abstraction
+ *
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include "mkimage.h"
+#include "fit_common.h"
+#include <image.h>
+#include <u-boot/crc.h>
+
+void *key_blob;
+
+void usage(char *cmdname)
+{
+	fprintf(stderr, "Usage: %s -f fit file -k key file\n"
+			 "          -f ==> set fit file which should be checked'\n"
+			 "          -k ==> set key file which contains the key'\n",
+		cmdname);
+	exit(EXIT_FAILURE);
+}
+
+void *get_blob(void)
+{
+	return key_blob;
+}
+
+int main(int argc, char **argv)
+{
+	int ffd = -1;
+	int kfd = -1;
+	struct stat fsbuf;
+	struct stat ksbuf;
+	void *fit_blob;
+	char *fdtfile = NULL;
+	char *keyfile = NULL;
+	char cmdname[50];
+	int ret;
+
+	strcpy(cmdname, *argv);
+
+	while (--argc > 0 && **++argv == '-') {
+		while (*++*argv) {
+			switch (**argv) {
+			case 'f':
+				if (--argc <= 0)
+					usage(cmdname);
+				fdtfile = *++argv;
+				goto NXTARG;
+
+			case 'k':
+				if (--argc <= 0)
+					usage(cmdname);
+				keyfile = *++argv;
+				goto NXTARG;
+
+			default:
+				usage(cmdname);
+			}
+		}
+NXTARG:;
+	}
+
+	if (argc != 0)
+		usage(cmdname);
+
+	ffd = mmap_fdt(cmdname, fdtfile, &fit_blob, &fsbuf);
+	kfd = mmap_fdt(cmdname, keyfile, &key_blob, &ksbuf);
+
+	ret = fit_check_sign(fit_blob, key_blob);
+
+	if (ret)
+		ret = EXIT_SUCCESS;
+	else
+		ret = EXIT_FAILURE;
+
+	(void) munmap((void *)fit_blob, fsbuf.st_size);
+	(void) munmap((void *)key_blob, ksbuf.st_size);
+
+	/* We're a bit of paranoid */
+#if defined(_POSIX_SYNCHRONIZED_IO) && \
+	!defined(__sun__) && \
+	!defined(__FreeBSD__) && \
+	!defined(__APPLE__)
+	(void) fdatasync(ffd);
+	(void) fdatasync(kfd);
+#else
+	(void) fsync(ffd);
+	(void) fsync(kfd);
+#endif
+
+	if (close(ffd)) {
+		fprintf(stderr, "%s: Write error on %s: %s\n",
+			cmdname, fdtfile, strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+	if (close(kfd)) {
+		fprintf(stderr, "%s: Write error on %s: %s\n",
+			cmdname, keyfile, strerror(errno));
+		exit(EXIT_FAILURE);
+	}
+
+	exit(ret);
+}
diff --git a/tools/image-host.c b/tools/image-host.c
index 8e185ec..65e3932 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -695,3 +695,16 @@ int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
 
 	return 0;
 }
+
+int fit_check_sign(const void *working_fdt, const void *key)
+{
+	int cfg_noffset;
+	int ret;
+
+	cfg_noffset = fit_conf_get_node(working_fdt, NULL);
+	if (!cfg_noffset)
+		return -1;
+
+	ret = fit_config_verify(working_fdt, cfg_noffset);
+	return ret;
+}
-- 
1.8.3.1

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

* [U-Boot] [PATCH v2 2/8] fdt: add "fdt checksign" command
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 2/8] fdt: add "fdt checksign" command Heiko Schocher
@ 2014-02-14 16:17   ` Simon Glass
  2014-02-15 23:00   ` Simon Glass
  1 sibling, 0 replies; 20+ messages in thread
From: Simon Glass @ 2014-02-14 16:17 UTC (permalink / raw)
  To: u-boot

On 8 February 2014 22:34, Heiko Schocher <hs@denx.de> wrote:
> check if a fdt is correct signed
> pass an optional addr value. Contains the addr of the key blob
>
> Signed-off-by: Heiko Schocher <hs@denx.de>
> Cc: Simon Glass <sjg@chromium.org>

Acked-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [PATCH v2 3/8] fit: add sha256 support
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 3/8] fit: add sha256 support Heiko Schocher
@ 2014-02-15 22:47   ` Simon Glass
  2014-02-17  6:33     ` Heiko Schocher
  0 siblings, 1 reply; 20+ messages in thread
From: Simon Glass @ 2014-02-15 22:47 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

On 8 February 2014 22:34, Heiko Schocher <hs@denx.de> wrote:
> add sha256 support to fit images
>
> Signed-off-by: Heiko Schocher <hs@denx.de>
> Acked-by: Simon Glass <sjg@chromium.org>

Sorry I spotted a few things since.

>
> ---
> changes for v2:
> - add Acked-by from Simon Glass
>
>  common/image-fit.c | 5 +++++
>  include/image.h    | 9 +++++++++
>  lib/sha256.c       | 2 +-
>  tools/Makefile     | 3 +++
>  4 files changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/common/image-fit.c b/common/image-fit.c
> index cf4b67e..f32feb6 100644
> --- a/common/image-fit.c
> +++ b/common/image-fit.c
> @@ -22,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR;
>
>  #include <bootstage.h>
>  #include <sha1.h>
> +#include <sha256.h>
>  #include <u-boot/crc.h>
>  #include <u-boot/md5.h>
>
> @@ -882,6 +883,10 @@ int calculate_hash(const void *data, int data_len, const char *algo,
>                 sha1_csum_wd((unsigned char *)data, data_len,
>                              (unsigned char *)value, CHUNKSZ_SHA1);
>                 *value_len = 20;
> +       } else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) {
> +               sha256_csum_wd((unsigned char *)data, data_len,
> +                              (unsigned char *)value, CHUNKSZ_SHA256);
> +               *value_len = SHA256_SUM_LEN;
>         } else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) {
>                 md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
>                 *value_len = 16;
> diff --git a/include/image.h b/include/image.h
> index 7de2bb2..f001a5f 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -57,13 +57,18 @@ struct lmb;
>  #  ifdef CONFIG_SPL_SHA1_SUPPORT
>  #   define IMAGE_ENABLE_SHA1   1
>  #  endif
> +#  ifdef CONFIG_SPL_SHA256_SUPPORT
> +#   define IMAGE_ENABLE_SHA256 1
> +#  endif
>  # else
>  #  define CONFIG_CRC32         /* FIT images need CRC32 support */
>  #  define CONFIG_MD5           /* and MD5 */
>  #  define CONFIG_SHA1          /* and SHA1 */
> +#  define CONFIG_SHA256                /* and SHA256 */

Thinking about this again, I wonder if we want to force SHA256 to be
enabled when FIT is used? Should we just hold the existing
CONFIG_SHA256 setting in the board file and change:

>  #  define IMAGE_ENABLE_CRC32   1
>  #  define IMAGE_ENABLE_MD5     1
>  #  define IMAGE_ENABLE_SHA1    1
> +#  define IMAGE_ENABLE_SHA256  1

this to:

#ifdef CONFIG_SHA256
 +#  define IMAGE_ENABLE_SHA256  0
#endif

?

>  # endif
>
>  #ifndef IMAGE_ENABLE_CRC32
> @@ -78,6 +83,10 @@ struct lmb;
>  #define IMAGE_ENABLE_SHA1      0
>  #endif
>
> +#ifndef IMAGE_ENABLE_SHA256
> +#define IMAGE_ENABLE_SHA256    0
> +#endif
> +
>  #endif /* CONFIG_FIT */
>
>  #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
> diff --git a/lib/sha256.c b/lib/sha256.c
> index 7348162..5766de2 100644
> --- a/lib/sha256.c
> +++ b/lib/sha256.c
> @@ -258,7 +258,7 @@ void sha256_csum_wd(const unsigned char *input, unsigned int ilen,
>  {
>         sha256_context ctx;
>  #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
> -       unsigned char *end, *curr;
> +       const unsigned char *end, *curr;

Why remove the const here?

>         int chunk;
>  #endif
>
> diff --git a/tools/Makefile b/tools/Makefile
> index 328cea3..5e36e5e 100644
> --- a/tools/Makefile
> +++ b/tools/Makefile
> @@ -71,6 +71,7 @@ EXT_OBJ_FILES-y += common/image-sig.o
>  EXT_OBJ_FILES-y += lib/crc32.o
>  EXT_OBJ_FILES-y += lib/md5.o
>  EXT_OBJ_FILES-y += lib/sha1.o
> +EXT_OBJ_FILES-y += lib/sha256.o
>
>  # Source files located in the tools directory
>  NOPED_OBJ_FILES-y += aisimage.o
> @@ -223,6 +224,7 @@ $(obj)dumpimage$(SFX):      $(obj)aisimage.o \
>                         $(obj)os_support.o \
>                         $(obj)pblimage.o \
>                         $(obj)sha1.o \
> +                       $(obj)sha256.o \
>                         $(obj)ublimage.o \
>                         $(LIBFDT_OBJS) \
>                         $(RSA_OBJS)
> @@ -252,6 +254,7 @@ $(obj)mkimage$(SFX):        $(obj)aisimage.o \
>                         $(obj)os_support.o \
>                         $(obj)pblimage.o \
>                         $(obj)sha1.o \
> +                       $(obj)sha256.o \
>                         $(obj)ublimage.o \
>                         $(LIBFDT_OBJS) \
>                         $(RSA_OBJS)
> --
> 1.8.3.1
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

Regards,
Simon

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

* [U-Boot] [PATCH v2 2/8] fdt: add "fdt checksign" command
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 2/8] fdt: add "fdt checksign" command Heiko Schocher
  2014-02-14 16:17   ` Simon Glass
@ 2014-02-15 23:00   ` Simon Glass
  2014-02-15 23:07     ` Simon Glass
  1 sibling, 1 reply; 20+ messages in thread
From: Simon Glass @ 2014-02-15 23:00 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

On 8 February 2014 22:34, Heiko Schocher <hs@denx.de> wrote:
> check if a fdt is correct signed
> pass an optional addr value. Contains the addr of the key blob
>
> Signed-off-by: Heiko Schocher <hs@denx.de>
> Cc: Simon Glass <sjg@chromium.org>
>
> ---
> changes vor v2:
> - add comment from Simon Glass:
>   - rename "fdt sign" to "fdt checksign"
>     -> rename patch subject from "fdt: add "fdt sign" command"
>        to "fdt: add "fdt checksign" command"
>   - add error message
>
>  common/cmd_fdt.c | 42 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 41 insertions(+), 1 deletion(-)
>
> diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c
> index 3a9edd6..a6744ed 100644
> --- a/common/cmd_fdt.c
> +++ b/common/cmd_fdt.c
> @@ -570,7 +570,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>                 ft_board_setup(working_fdt, gd->bd);
>  #endif
>         /* Create a chosen node */
> -       else if (argv[1][0] == 'c') {
> +       else if (strncmp(argv[1], "cho", 3) == 0) {

Sorry, I missed this earlier - I think this should be "che" if the
command is checksig.

Regards,
Simon

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

* [U-Boot] [PATCH v2 2/8] fdt: add "fdt checksign" command
  2014-02-15 23:00   ` Simon Glass
@ 2014-02-15 23:07     ` Simon Glass
  0 siblings, 0 replies; 20+ messages in thread
From: Simon Glass @ 2014-02-15 23:07 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

On 15 February 2014 16:00, Simon Glass <sjg@chromium.org> wrote:
> Hi Heiko,
>
> On 8 February 2014 22:34, Heiko Schocher <hs@denx.de> wrote:
>> check if a fdt is correct signed
>> pass an optional addr value. Contains the addr of the key blob
>>
>> Signed-off-by: Heiko Schocher <hs@denx.de>
>> Cc: Simon Glass <sjg@chromium.org>
>>
>> ---
>> changes vor v2:
>> - add comment from Simon Glass:
>>   - rename "fdt sign" to "fdt checksign"
>>     -> rename patch subject from "fdt: add "fdt sign" command"
>>        to "fdt: add "fdt checksign" command"
>>   - add error message
>>
>>  common/cmd_fdt.c | 42 +++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 41 insertions(+), 1 deletion(-)
>>
>> diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c
>> index 3a9edd6..a6744ed 100644
>> --- a/common/cmd_fdt.c
>> +++ b/common/cmd_fdt.c
>> @@ -570,7 +570,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>>                 ft_board_setup(working_fdt, gd->bd);
>>  #endif
>>         /* Create a chosen node */
>> -       else if (argv[1][0] == 'c') {
>> +       else if (strncmp(argv[1], "cho", 3) == 0) {
>
> Sorry, I missed this earlier - I think this should be "che" if the
> command is checksig.

Hmm, ignore this, I was looking in the wrong place.

Regards,
Simon

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

* [U-Boot] [PATCH v2 4/8] rsa: add sha256-rsa2048 algorithm
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 4/8] rsa: add sha256-rsa2048 algorithm Heiko Schocher
@ 2014-02-15 23:11   ` Simon Glass
  0 siblings, 0 replies; 20+ messages in thread
From: Simon Glass @ 2014-02-15 23:11 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

On 8 February 2014 22:34, Heiko Schocher <hs@denx.de> wrote:
> based on patch from andreas at oetken.name:
>
> http://patchwork.ozlabs.org/patch/294318/
> commit message:
> I currently need support for rsa-sha256 signatures in u-boot and found out that
> the code for signatures is not very generic. Thus adding of different
> hash-algorithms for rsa-signatures is not easy to do without copy-pasting the
> rsa-code. I attached a patch for how I think it could be better and included
> support for rsa-sha256. This is a fast first shot.
>
> aditionally work:
> - removed checkpatch warnings
> - removed compiler warnings
> - rebased against current head
>
> Signed-off-by: Heiko Schocher <hs@denx.de>
> Cc: andreas at oetken.name
> Cc: Simon Glass <sjg@chromium.org>
>
> ---
> changes for v2:
> - add comment from Simon Glass:
>   - add commit message from original patch
>   - remove unnecessary function declaration
>     rsa_verify_256()
>   - sandbox: add sha256 tests
>
>  common/image-sig.c                                 | 33 ++++++++
>  doc/uImage.FIT/signature.txt                       | 25 +++++-
>  include/image.h                                    | 21 +++++
>  include/rsa-checksum.h                             | 25 ++++++
>  include/rsa.h                                      | 14 ++++
>  lib/rsa/Makefile                                   |  2 +-
>  lib/rsa/rsa-checksum.c                             | 98 ++++++++++++++++++++++
>  lib/rsa/rsa-sign.c                                 | 10 ++-
>  lib/rsa/rsa-verify.c                               | 83 ++++++------------
>  .../{sign-configs.its => sign-configs-sha1.its}    |  0
>  test/vboot/sign-configs-sha256.its                 | 45 ++++++++++
>  .../{sign-images.its => sign-images-sha1.its}      |  0
>  test/vboot/sign-images-sha256.its                  | 42 ++++++++++
>  test/vboot/vboot_test.sh                           | 18 ++--
>  14 files changed, 346 insertions(+), 70 deletions(-)
>  create mode 100644 include/rsa-checksum.h
>  create mode 100644 lib/rsa/rsa-checksum.c
>  rename test/vboot/{sign-configs.its => sign-configs-sha1.its} (100%)
>  create mode 100644 test/vboot/sign-configs-sha256.its
>  rename test/vboot/{sign-images.its => sign-images-sha1.its} (100%)
>  create mode 100644 test/vboot/sign-images-sha256.its
>
> diff --git a/common/image-sig.c b/common/image-sig.c
> index 973b06d..8b212a7 100644
> --- a/common/image-sig.c
> +++ b/common/image-sig.c
> @@ -14,15 +14,47 @@ DECLARE_GLOBAL_DATA_PTR;
>  #endif /* !USE_HOSTCC*/
>  #include <image.h>
>  #include <rsa.h>
> +#include <rsa-checksum.h>
>
>  #define IMAGE_MAX_HASHED_NODES         100
>
> +#if defined(CONFIG_FIT_SIGNATURE)

This is already in the Makefile for image-sig.c

> +struct checksum_algo checksum_algos[] = {
> +       {
> +               "sha1",
> +               SHA1_SUM_LEN,
> +#if IMAGE_ENABLE_SIGN
> +               EVP_sha1,
> +#else
> +               sha1_calculate,
> +               padding_sha1_rsa2048,
> +#endif
> +       },
> +       {
> +               "sha256",
> +               SHA256_SUM_LEN,
> +#if IMAGE_ENABLE_SIGN
> +               EVP_sha256,
> +#else
> +               sha256_calculate,
> +               padding_sha256_rsa2048,
> +#endif
> +       }
> +};
>  struct image_sig_algo image_sig_algos[] = {
>         {
>                 "sha1,rsa2048",
>                 rsa_sign,
>                 rsa_add_verify_data,
>                 rsa_verify,
> +               &checksum_algos[0],
> +       },
> +       {
> +               "sha256,rsa2048",
> +               rsa_sign,
> +               rsa_add_verify_data,
> +               rsa_verify,
> +               &checksum_algos[1],
>         }
>  };
>
> @@ -407,3 +439,4 @@ int fit_config_verify(const void *fit, int conf_noffset)
>         return !fit_config_verify_required_sigs(fit, conf_noffset,
>                                                 gd_fdt_blob());
>  }
> +#endif
> diff --git a/doc/uImage.FIT/signature.txt b/doc/uImage.FIT/signature.txt
> index bc9f3fa..5bd229f 100644
> --- a/doc/uImage.FIT/signature.txt
> +++ b/doc/uImage.FIT/signature.txt
> @@ -346,6 +346,7 @@ Simple Verified Boot Test
>
>  Please see doc/uImage.FIT/verified-boot.txt for more information
>
> +/home/hs/ids/u-boot/sandbox/tools/mkimage -D -I dts -O dtb -p 2000
>  Build keys
>  Build FIT with signed images
>  Test Verified Boot Run: unsigned signatures:: OK
> @@ -355,9 +356,31 @@ Build FIT with signed configuration
>  Test Verified Boot Run: unsigned config: OK
>  Sign images
>  Test Verified Boot Run: signed config: OK
> +Test Verified Boot Run: signed config with bad hash: OK
>
> -Test passed
> +Test sha1 passed
>
> +Or for testing sha256:
> +
> +$ O=sandbox ./test/vboot/vboot_test.sh sha256
> +Simple Verified Boot Test
> +=========================
> +
> +Please see doc/uImage.FIT/verified-boot.txt for more information
> +
> +/home/hs/ids/u-boot/sandbox/tools/mkimage -D -I dts -O dtb -p 2000
> +Build keys
> +Build FIT with signed images
> +Test Verified Boot Run: unsigned signatures:: OK
> +Sign images
> +Test Verified Boot Run: signed images: OK
> +Build FIT with signed configuration
> +Test Verified Boot Run: unsigned config: OK
> +Sign images
> +Test Verified Boot Run: signed config: OK
> +Test Verified Boot Run: signed config with bad hash: OK
> +
> +Test sha256 passed
>
>  Future Work
>  -----------
> diff --git a/include/image.h b/include/image.h
> index f001a5f..eb3429f 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -832,6 +832,7 @@ int calculate_hash(const void *data, int data_len, const char *algo,
>  # ifdef USE_HOSTCC
>  #  define IMAGE_ENABLE_SIGN    1
>  #  define IMAGE_ENABLE_VERIFY  0
> +# include  <openssl/evp.h>
>  #else
>  #  define IMAGE_ENABLE_SIGN    0
>  #  define IMAGE_ENABLE_VERIFY  1
> @@ -871,6 +872,23 @@ struct image_region {
>         int size;
>  };
>
> +#if IMAGE_ENABLE_VERIFY
> +# include <rsa-checksum.h>
> +#endif
> +struct checksum_algo {
> +       const char *name;
> +       const int checksum_len;
> +#if IMAGE_ENABLE_SIGN
> +       const EVP_MD *(*calculate)(void);
> +#else
> +#if IMAGE_ENABLE_VERIFY
> +       void (*calculate)(const struct image_region region[],
> +                         int region_count, uint8_t *checksum);
> +       const uint8_t *rsa_padding;
> +#endif
> +#endif
> +};
> +
>  struct image_sig_algo {
>         const char *name;               /* Name of algorithm */
>
> @@ -921,6 +939,9 @@ struct image_sig_algo {
>         int (*verify)(struct image_sign_info *info,
>                       const struct image_region region[], int region_count,
>                       uint8_t *sig, uint sig_len);
> +
> +       /* pointer to checksum algorithm */
> +       struct checksum_algo *checksum;
>  };
>
>  /**
> diff --git a/include/rsa-checksum.h b/include/rsa-checksum.h
> new file mode 100644
> index 0000000..12494a6
> --- /dev/null
> +++ b/include/rsa-checksum.h
> @@ -0,0 +1,25 @@
> +/*
> + * Copyright (c) 2013, Andreas Oetken.
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> +*/
> +
> +#ifndef _RSA_CHECKSUM_H
> +#define _RSA_CHECKSUM_H
> +
> +#include <errno.h>
> +#include <image.h>
> +#include <sha1.h>
> +#include <sha256.h>
> +
> +#if IMAGE_ENABLE_VERIFY

I don't think we need this in a header file.


> +extern const uint8_t padding_sha256_rsa2048[];
> +extern const uint8_t padding_sha1_rsa2048[];
> +
> +void sha256_calculate(const struct image_region region[], int region_count,
> +                     uint8_t *checksum);
> +void sha1_calculate(const struct image_region region[], int region_count,
> +                   uint8_t *checksum);
> +#endif
> +
> +#endif
> diff --git a/include/rsa.h b/include/rsa.h
> index add4c78..0367671 100644
> --- a/include/rsa.h
> +++ b/include/rsa.h
> @@ -15,6 +15,20 @@
>  #include <errno.h>
>  #include <image.h>
>
> +/**
> + * struct rsa_public_key - holder for a public key
> + *
> + * An RSA public key consists of a modulus (typically called N), the inverse
> + * and R^2, where R is 2^(# key bits).
> + */
> +
> +struct rsa_public_key {
> +       uint len;        /* Length of modulus[] in number of uint32_t */
> +       uint32_t n0inv;        /* -1 / modulus[0] mod 2^32 */
> +       uint32_t *modulus;    /* modulus as little endian array */
> +       uint32_t *rr;        /* R^2 as little endian array */

Nice to left-align the comments?

> +};
> +
>  #if IMAGE_ENABLE_SIGN
>  /**
>   * sign() - calculate and return signature for given input data
> diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile
> index 164ab39..a5a96cb6 100644
> --- a/lib/rsa/Makefile
> +++ b/lib/rsa/Makefile
> @@ -7,4 +7,4 @@
>  # SPDX-License-Identifier:     GPL-2.0+
>  #
>
> -obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o
> +obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o
> diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c
> new file mode 100644
> index 0000000..e520e1c
> --- /dev/null
> +++ b/lib/rsa/rsa-checksum.c
> @@ -0,0 +1,98 @@
> +/*
> + * Copyright (c) 2013, Andreas Oetken.
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <fdtdec.h>
> +#include <rsa.h>
> +#include <sha1.h>
> +#include <sha256.h>
> +#include <asm/byteorder.h>
> +#include <asm/errno.h>
> +#include <asm/unaligned.h>
> +
> +#define RSA2048_BYTES 256
> +
> +/* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */
> +
> +const uint8_t padding_sha256_rsa2048[RSA2048_BYTES - SHA256_SUM_LEN] = {
> +0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
> +0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
> +0x00, 0x04, 0x20
> +};
> +
> +const uint8_t padding_sha1_rsa2048[RSA2048_BYTES - SHA1_SUM_LEN] = {
> +       0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> +       0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30,
> +       0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
> +       0x05, 0x00, 0x04, 0x14
> +};
> +
> +void sha1_calculate(const struct image_region region[], int region_count,
> +                   uint8_t *checksum)
> +{
> +       sha1_context ctx;
> +       uint32_t i;
> +       i = 0;
> +
> +       sha1_starts(&ctx);
> +       for (i = 0; i < region_count; i++)
> +               sha1_update(&ctx, region[i].data, region[i].size);
> +       sha1_finish(&ctx, checksum);
> +}
> +
> +void sha256_calculate(const struct image_region region[], int region_count,
> +                     uint8_t *checksum)
> +{
> +       sha256_context ctx;
> +       uint32_t i;
> +       i = 0;
> +
> +       sha256_starts(&ctx);
> +       for (i = 0; i < region_count; i++)
> +               sha256_update(&ctx, region[i].data, region[i].size);
> +       sha256_finish(&ctx, checksum);
> +}
> diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
> index 549130e..0fe6e9f 100644
> --- a/lib/rsa/rsa-sign.c
> +++ b/lib/rsa/rsa-sign.c
> @@ -159,8 +159,9 @@ static void rsa_remove(void)
>         EVP_cleanup();
>  }
>
> -static int rsa_sign_with_key(RSA *rsa, const struct image_region region[],
> -               int region_count, uint8_t **sigp, uint *sig_size)
> +static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo,
> +               const struct image_region region[], int region_count,
> +               uint8_t **sigp, uint *sig_size)
>  {
>         EVP_PKEY *key;
>         EVP_MD_CTX *context;
> @@ -192,7 +193,7 @@ static int rsa_sign_with_key(RSA *rsa, const struct image_region region[],
>                 goto err_create;
>         }
>         EVP_MD_CTX_init(context);
> -       if (!EVP_SignInit(context, EVP_sha1())) {
> +       if (!EVP_SignInit(context, checksum_algo->calculate())) {
>                 ret = rsa_err("Signer setup failed");
>                 goto err_sign;
>         }
> @@ -242,7 +243,8 @@ int rsa_sign(struct image_sign_info *info,
>         ret = rsa_get_priv_key(info->keydir, info->keyname, &rsa);
>         if (ret)
>                 goto err_priv;
> -       ret = rsa_sign_with_key(rsa, region, region_count, sigp, sig_len);
> +       ret = rsa_sign_with_key(rsa, info->algo->checksum, region,
> +                               region_count, sigp, sig_len);
>         if (ret)
>                 goto err_sign;
>
> diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
> index 02cc4e3..b3573a8 100644
> --- a/lib/rsa/rsa-verify.c
> +++ b/lib/rsa/rsa-verify.c
> @@ -8,23 +8,11 @@
>  #include <fdtdec.h>
>  #include <rsa.h>
>  #include <sha1.h>
> +#include <sha256.h>
>  #include <asm/byteorder.h>
>  #include <asm/errno.h>
>  #include <asm/unaligned.h>
>
> -/**
> - * struct rsa_public_key - holder for a public key
> - *
> - * An RSA public key consists of a modulus (typically called N), the inverse
> - * and R^2, where R is 2^(# key bits).
> - */
> -struct rsa_public_key {
> -       uint len;               /* Length of modulus[] in number of uint32_t */
> -       uint32_t n0inv;         /* -1 / modulus[0] mod 2^32 */
> -       uint32_t *modulus;      /* modulus as little endian array */
> -       uint32_t *rr;           /* R^2 as little endian array */
> -};
> -
>  #define UINT64_MULT32(v, multby)  (((uint64_t)(v)) * ((uint32_t)(multby)))
>
>  #define RSA2048_BYTES  (2048 / 8)
> @@ -36,39 +24,6 @@ struct rsa_public_key {
>  /* This is the maximum signature length that we support, in bits */
>  #define RSA_MAX_SIG_BITS       2048
>
> -static const uint8_t padding_sha1_rsa2048[RSA2048_BYTES - SHA1_SUM_LEN] = {
> -       0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> -       0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30,
> -       0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
> -       0x05, 0x00, 0x04, 0x14
> -};
> -
>  /**
>   * subtract_modulus() - subtract modulus from the given value
>   *
> @@ -209,13 +164,14 @@ static int pow_mod(const struct rsa_public_key *key, uint32_t *inout)
>  }
>
>  static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
> -               const uint32_t sig_len, const uint8_t *hash)
> +                         const uint32_t sig_len, const uint8_t *hash,
> +                         struct checksum_algo *algo)
>  {
>         const uint8_t *padding;
>         int pad_len;
>         int ret;
>
> -       if (!key || !sig || !hash)
> +       if (!key || !sig || !hash || !algo)
>                 return -EIO;
>
>         if (sig_len != (key->len * sizeof(uint32_t))) {
> @@ -223,6 +179,8 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
>                 return -EINVAL;
>         }
>
> +       debug("Checksum algorithm: %s", algo->name);
> +
>         /* Sanity check for stack size */
>         if (sig_len > RSA_MAX_SIG_BITS / 8) {
>                 debug("Signature length %u exceeds maximum %d\n", sig_len,
> @@ -238,9 +196,8 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
>         if (ret)
>                 return ret;
>
> -       /* Determine padding to use depending on the signature type. */
> -       padding = padding_sha1_rsa2048;
> -       pad_len = RSA2048_BYTES - SHA1_SUM_LEN;
> +       padding = algo->rsa_padding;
> +       pad_len = RSA2048_BYTES - algo->checksum_len;
>
>         /* Check pkcs1.5 padding bytes. */
>         if (memcmp(buf, padding, pad_len)) {
> @@ -309,7 +266,7 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
>         }
>
>         debug("key length %d\n", key.len);
> -       ret = rsa_verify_key(&key, sig, sig_len, hash);
> +       ret = rsa_verify_key(&key, sig, sig_len, hash, info->algo->checksum);
>         if (ret) {
>                 printf("%s: RSA failed to verify: %d\n", __func__, ret);
>                 return ret;
> @@ -323,12 +280,22 @@ int rsa_verify(struct image_sign_info *info,
>                uint8_t *sig, uint sig_len)
>  {
>         const void *blob = info->fdt_blob;
> -       uint8_t hash[SHA1_SUM_LEN];
> +       /* Reserve memory for maximum checksum-length */
> +       uint8_t hash[RSA2048_BYTES];
>         int ndepth, noffset;
>         int sig_node, node;
>         char name[100];
> -       sha1_context ctx;
> -       int ret, i;
> +       int ret;
> +
> +       /*
> +        * Verify that the checksum-length does not exceed the
> +        * rsa-signature-length
> +        */
> +       if (info->algo->checksum->checksum_len > RSA2048_BYTES) {
> +               debug("%s: invlaid checksum-algorithm %s for RSA2048\n",
> +                     __func__, info->algo->checksum->name);
> +               return -EINVAL;
> +       }
>
>         sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME);
>         if (sig_node < 0) {
> @@ -336,10 +303,8 @@ int rsa_verify(struct image_sign_info *info,
>                 return -ENOENT;
>         }
>
> -       sha1_starts(&ctx);
> -       for (i = 0; i < region_count; i++)
> -               sha1_update(&ctx, region[i].data, region[i].size);
> -       sha1_finish(&ctx, hash);
> +       /* Calculate checksum with checksum-algorithm */
> +       info->algo->checksum->calculate(region, region_count, hash);
>
>         /* See if we must use a particular key */
>         if (info->required_keynode != -1) {
> diff --git a/test/vboot/sign-configs.its b/test/vboot/sign-configs-sha1.its
> similarity index 100%
> rename from test/vboot/sign-configs.its
> rename to test/vboot/sign-configs-sha1.its
> diff --git a/test/vboot/sign-configs-sha256.its b/test/vboot/sign-configs-sha256.its
> new file mode 100644
> index 0000000..1b3432e
> --- /dev/null
> +++ b/test/vboot/sign-configs-sha256.its
> @@ -0,0 +1,45 @@
> +/dts-v1/;
> +
> +/ {
> +       description = "Chrome OS kernel image with one or more FDT blobs";
> +       #address-cells = <1>;
> +
> +       images {
> +               kernel at 1 {
> +                       data = /incbin/("test-kernel.bin");
> +                       type = "kernel_noload";
> +                       arch = "sandbox";
> +                       os = "linux";
> +                       compression = "none";
> +                       load = <0x4>;
> +                       entry = <0x8>;
> +                       kernel-version = <1>;
> +                       hash at 1 {
> +                               algo = "sha256";
> +                       };
> +               };
> +               fdt at 1 {
> +                       description = "snow";
> +                       data = /incbin/("sandbox-kernel.dtb");
> +                       type = "flat_dt";
> +                       arch = "sandbox";
> +                       compression = "none";
> +                       fdt-version = <1>;
> +                       hash at 1 {
> +                               algo = "sha256";
> +                       };
> +               };
> +       };
> +       configurations {
> +               default = "conf at 1";
> +               conf at 1 {
> +                       kernel = "kernel at 1";
> +                       fdt = "fdt at 1";
> +                       signature at 1 {
> +                               algo = "sha256,rsa2048";
> +                               key-name-hint = "dev";
> +                               sign-images = "fdt", "kernel";
> +                       };
> +               };
> +       };
> +};
> diff --git a/test/vboot/sign-images.its b/test/vboot/sign-images-sha1.its
> similarity index 100%
> rename from test/vboot/sign-images.its
> rename to test/vboot/sign-images-sha1.its
> diff --git a/test/vboot/sign-images-sha256.its b/test/vboot/sign-images-sha256.its
> new file mode 100644
> index 0000000..e6aa9fc
> --- /dev/null
> +++ b/test/vboot/sign-images-sha256.its
> @@ -0,0 +1,42 @@
> +/dts-v1/;
> +
> +/ {
> +       description = "Chrome OS kernel image with one or more FDT blobs";
> +       #address-cells = <1>;
> +
> +       images {
> +               kernel at 1 {
> +                       data = /incbin/("test-kernel.bin");
> +                       type = "kernel_noload";
> +                       arch = "sandbox";
> +                       os = "linux";
> +                       compression = "none";
> +                       load = <0x4>;
> +                       entry = <0x8>;
> +                       kernel-version = <1>;
> +                       signature at 1 {
> +                               algo = "sha256,rsa2048";
> +                               key-name-hint = "dev";
> +                       };
> +               };
> +               fdt at 1 {
> +                       description = "snow";
> +                       data = /incbin/("sandbox-kernel.dtb");
> +                       type = "flat_dt";
> +                       arch = "sandbox";
> +                       compression = "none";
> +                       fdt-version = <1>;
> +                       signature at 1 {
> +                               algo = "sha256,rsa2048";
> +                               key-name-hint = "dev";
> +                       };
> +               };
> +       };
> +       configurations {
> +               default = "conf at 1";
> +               conf at 1 {
> +                       kernel = "kernel at 1";
> +                       fdt = "fdt at 1";
> +               };
> +       };
> +};
> diff --git a/test/vboot/vboot_test.sh b/test/vboot/vboot_test.sh
> index bb2c605..27b221a 100755
> --- a/test/vboot/vboot_test.sh
> +++ b/test/vboot/vboot_test.sh
> @@ -6,6 +6,14 @@
>  #
>  # SPDX-License-Identifier:     GPL-2.0+
>
> +# Args:
> +#      $1:     sha256 or sha1 (default)
> +if [ -z "$1" ]; then
> +       sha=sha1
> +else
> +       sha=$1
> +fi

The test looks good, but can we please do both sha1 and sha256? It is
supposed to be an automated test so running it twice or with arguments
is not very friendly.

> +
>  set -e
>
>  # Run U-Boot and report the result
> @@ -70,7 +78,7 @@ head -c 5000 /dev/zero >test-kernel.bin
>
>  # Build the FIT, but don't sign anything yet
>  echo Build FIT with signed images
> -${mkimage} -D "${dtc}" -f sign-images.its test.fit >${tmp}
> +${mkimage} -D "${dtc}" -f sign-images-$sha.its test.fit >${tmp}
>
>  run_uboot "unsigned signatures:" "dev-"
>
> @@ -85,9 +93,9 @@ run_uboot "signed images" "dev+"
>  dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
>
>  echo Build FIT with signed configuration
> -${mkimage} -D "${dtc}" -f sign-configs.its test.fit >${tmp}
> +${mkimage} -D "${dtc}" -f sign-configs-$sha.its test.fit >${tmp}
>
> -run_uboot "unsigned config" "sha1+ OK"
> +run_uboot "unsigned config" $sha"+ OK"
>
>  # Sign images with our dev keys
>  echo Sign images
> @@ -107,7 +115,7 @@ popd >/dev/null
>
>  echo
>  if ${ok}; then
> -       echo "Test passed"
> +       echo "Test $sha passed"
>  else
> -       echo "Test failed"
> +       echo "Test $sha failed"
>  fi
> --
> 1.8.3.1
>

Regards,
Simon

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

* [U-Boot] [PATCH v2 5/8] rsa: add sha256,rsa4096 algorithm
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 5/8] rsa: add sha256,rsa4096 algorithm Heiko Schocher
@ 2014-02-15 23:12   ` Simon Glass
  0 siblings, 0 replies; 20+ messages in thread
From: Simon Glass @ 2014-02-15 23:12 UTC (permalink / raw)
  To: u-boot

On 8 February 2014 22:34, Heiko Schocher <hs@denx.de> wrote:
> Add support for sha256,rsa4096 signatures in u-boot.
>
> Signed-off-by: Heiko Schocher <hs@denx.de>
> Cc: Simon Glass <sjg@chromium.org>
> Cc: andreas at oetken.name

Acked-by: Simon Glass <sjg@chromium.org>

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

* [U-Boot] [PATCH v2 6/8] gen: Add progressive hash API
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 6/8] gen: Add progressive hash API Heiko Schocher
@ 2014-02-15 23:14   ` Simon Glass
  0 siblings, 0 replies; 20+ messages in thread
From: Simon Glass @ 2014-02-15 23:14 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

On 8 February 2014 22:34, Heiko Schocher <hs@denx.de> wrote:
> From: Hung-ying Tyan <tyanh@chromium.org>
>
> Add hash_init(), hash_update() and hash_finish() to the
> hash_algo struct. Add hash_lookup_algo() to look up the
> struct given an algorithm name.
>
> Signed-off-by: Hung-ying Tyan <tyanh@chromium.org>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Heiko Schocher <hs@denx.de>

Acked-by: Simon Glass <sjg@chromium.org>

I think this is crying out for another patch - an integration to get
rid of lib/rsa/rsa-checksum.c. You should be able to look up the hash
algorithm name using the hash.h file and get the pad length, etc. from
that. Then you can call this progressive hashing API instead of adding
new code in lib/rsa/rsa-checksum.c.

There may be a catch, but I can't see one at present.

Regards,
Simon

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

* [U-Boot] [PATCH v2 8/8] tools, fit_check_sign: verify a signed fit image
  2014-02-09  5:34 ` [U-Boot] [PATCH v2 8/8] tools, fit_check_sign: verify a signed fit image Heiko Schocher
@ 2014-02-15 23:22   ` Simon Glass
  0 siblings, 0 replies; 20+ messages in thread
From: Simon Glass @ 2014-02-15 23:22 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

On 8 February 2014 22:34, Heiko Schocher <hs@denx.de> wrote:
> add host tool "fit_check_sign" which verifies, if a fit image is
> signed correct.
>
> Signed-off-by: Heiko Schocher <hs@denx.de>
> Cc: Simon Glass <sjg@chromium.org>

Overall this seems reasonable, and very useful. I'm just a little
nervous about some of the work-arounds to make the code run on the
host. So a few minor comments.

>
> ---
> - changes for v2:
>   - fixed compile error for sandbox
>   - add fit_check_sign test to test/vboot/vboot_test.sh
>
>  Makefile                     |   1 +
>  common/image-sig.c           |  22 +++++---
>  doc/uImage.FIT/signature.txt |   8 +++
>  include/fdt_support.h        |   5 ++
>  include/image.h              |  16 +++---
>  lib/libfdt/fdt_wip.c         |  17 +++++++
>  lib/rsa/rsa-checksum.c       |  10 ++--
>  lib/rsa/rsa-sign.c           |   2 +-
>  lib/rsa/rsa-verify.c         |  18 +++++--
>  test/vboot/vboot_test.sh     |  36 ++++++++++++-
>  tools/Makefile               |  19 ++++++-
>  tools/fdt_host.h             |   2 +
>  tools/fit_check_sign.c       | 119 +++++++++++++++++++++++++++++++++++++++++++
>  tools/image-host.c           |  13 +++++
>  14 files changed, 265 insertions(+), 23 deletions(-)
>  create mode 100644 tools/fit_check_sign.c
>
> diff --git a/Makefile b/Makefile
> index a2e424d..900d8f7 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -794,6 +794,7 @@ clean:
>         @rm -f $(obj)tools/bmp_logo        $(obj)tools/easylogo/easylogo  \
>                $(obj)tools/env/fw_printenv                                \
>                $(obj)tools/envcrc                                         \
> +              $(obj)tools/fit_check_sign                                 \
>                $(obj)tools/fit_info                                       \
>                $(obj)tools/gdb/{gdbcont,gdbsend}                          \
>                $(obj)tools/gen_eth_addr    $(obj)tools/img2srec           \
> diff --git a/common/image-sig.c b/common/image-sig.c
> index 199e634..5b19ea8 100644
> --- a/common/image-sig.c
> +++ b/common/image-sig.c
> @@ -19,6 +19,14 @@ DECLARE_GLOBAL_DATA_PTR;
>  #define IMAGE_MAX_HASHED_NODES         100
>
>  #if defined(CONFIG_FIT_SIGNATURE)
> +
> +#ifdef USE_HOSTCC
> +__attribute__((weak)) void *get_blob(void)
> +{
> +       return NULL;
> +}
> +#endif
> +

Why make this weak? A better name would be something like
image_get_host_blob(). I think we should get a compile error if it is
not defined.


>  struct checksum_algo checksum_algos[] = {
>         {
>                 "sha1",
> @@ -26,10 +34,9 @@ struct checksum_algo checksum_algos[] = {
>                 RSA2048_BYTES,
>  #if IMAGE_ENABLE_SIGN
>                 EVP_sha1,
> -#else
> +#endif
>                 sha1_calculate,
>                 padding_sha1_rsa2048,
> -#endif
>         },
>         {
>                 "sha256",
> @@ -37,10 +44,9 @@ struct checksum_algo checksum_algos[] = {
>                 RSA2048_BYTES,
>  #if IMAGE_ENABLE_SIGN
>                 EVP_sha256,
> -#else
> +#endif
>                 sha256_calculate,
>                 padding_sha256_rsa2048,
> -#endif
>         },
>         {
>                 "sha256",
> @@ -48,10 +54,9 @@ struct checksum_algo checksum_algos[] = {
>                 RSA4096_BYTES,
>  #if IMAGE_ENABLE_SIGN
>                 EVP_sha256,
> -#else
> +#endif
>                 sha256_calculate,
>                 padding_sha256_rsa4096,
> -#endif
>         }
>
>  };
> @@ -462,4 +467,9 @@ int fit_config_verify(const void *fit, int conf_noffset)
>         return !fit_config_verify_required_sigs(fit, conf_noffset,
>                                                 gd_fdt_blob());
>  }
> +#else
> +int fit_config_verify(const void *fit, int conf_noffset)
> +{
> +       return 0;
> +}
>  #endif
> diff --git a/doc/uImage.FIT/signature.txt b/doc/uImage.FIT/signature.txt
> index 5bd229f..171af2a 100644
> --- a/doc/uImage.FIT/signature.txt
> +++ b/doc/uImage.FIT/signature.txt
> @@ -355,7 +355,11 @@ Test Verified Boot Run: signed images: OK
>  Build FIT with signed configuration
>  Test Verified Boot Run: unsigned config: OK
>  Sign images
> +check signed config on the host
> +OK
>  Test Verified Boot Run: signed config: OK
> +check bad signed config on the host
> +OK
>  Test Verified Boot Run: signed config with bad hash: OK
>
>  Test sha1 passed
> @@ -377,7 +381,11 @@ Test Verified Boot Run: signed images: OK
>  Build FIT with signed configuration
>  Test Verified Boot Run: unsigned config: OK
>  Sign images
> +check signed config on the host
> +OK
>  Test Verified Boot Run: signed config: OK
> +check bad signed config on the host
> +OK
>  Test Verified Boot Run: signed config with bad hash: OK
>
>  Test sha256 passed
> diff --git a/include/fdt_support.h b/include/fdt_support.h
> index 9871e2f..76c9b2e 100644
> --- a/include/fdt_support.h
> +++ b/include/fdt_support.h
> @@ -115,4 +115,9 @@ static inline int fdt_status_disabled_by_alias(void *fdt, const char* alias)
>  }
>
>  #endif /* ifdef CONFIG_OF_LIBFDT */
> +
> +#ifdef USE_HOSTCC
> +int fdtdec_get_int(const void *blob, int node, const char *prop_name,
> +               int default_val);
> +#endif
>  #endif /* ifndef __FDT_SUPPORT_H */
> diff --git a/include/image.h b/include/image.h
> index 6e4745a..260a396 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -831,7 +831,7 @@ int calculate_hash(const void *data, int data_len, const char *algo,
>  #if defined(CONFIG_FIT_SIGNATURE)
>  # ifdef USE_HOSTCC
>  #  define IMAGE_ENABLE_SIGN    1
> -#  define IMAGE_ENABLE_VERIFY  0
> +#  define IMAGE_ENABLE_VERIFY  1
>  # include  <openssl/evp.h>
>  #else
>  #  define IMAGE_ENABLE_SIGN    0
> @@ -843,7 +843,8 @@ int calculate_hash(const void *data, int data_len, const char *algo,
>  #endif
>
>  #ifdef USE_HOSTCC
> -# define gd_fdt_blob()         NULL
> +void *get_blob(void);
> +# define gd_fdt_blob()         get_blob()

image_get_host_blob()

>  #else
>  # define gd_fdt_blob()         (gd->fdt_blob)
>  #endif
> @@ -880,14 +881,11 @@ struct checksum_algo {
>         const int checksum_len;
>         const int pad_len;
>  #if IMAGE_ENABLE_SIGN
> -       const EVP_MD *(*calculate)(void);
> -#else
> -#if IMAGE_ENABLE_VERIFY
> +       const EVP_MD *(*calculate_sign)(void);
> +#endif
>         void (*calculate)(const struct image_region region[],
>                           int region_count, uint8_t *checksum);
>         const uint8_t *rsa_padding;
> -#endif
> -#endif
>  };
>
>  struct image_sig_algo {
> @@ -1008,7 +1006,11 @@ struct image_region *fit_region_make_list(const void *fit,
>
>  static inline int fit_image_check_target_arch(const void *fdt, int node)
>  {
> +#ifndef USE_HOSTCC
>         return fit_image_check_arch(fdt, node, IH_ARCH_DEFAULT);
> +#else
> +       return 0;
> +#endif
>  }
>
>  #ifdef CONFIG_FIT_VERBOSE
> diff --git a/lib/libfdt/fdt_wip.c b/lib/libfdt/fdt_wip.c
> index 3f2dfa5..4babdbc 100644
> --- a/lib/libfdt/fdt_wip.c
> +++ b/lib/libfdt/fdt_wip.c
> @@ -31,6 +31,23 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
>         return 0;
>  }
>
> +#ifdef USE_HOSTCC
> +int fdtdec_get_int(const void *blob, int node, const char *prop_name,
> +               int default_val)
> +{
> +       const int *cell;
> +       int len;
> +
> +       cell = fdt_getprop_w((void *)blob, node, prop_name, &len);
> +       if (cell && len >= sizeof(int)) {
> +               int val = fdt32_to_cpu(cell[0]);
> +
> +               return val;
> +       }
> +       return default_val;
> +}
> +#endif

I don't think you can put this function here - it is an upstream
library. If you don't want to include fdtdec.c into the hostcc
compilation, then perhaps add this function into a host file
somewhere, with a comment as to why it is here.

> +
>  static void _fdt_nop_region(void *start, int len)
>  {
>         fdt32_t *p;
> diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c
> index a9d096d..32d6602 100644
> --- a/lib/rsa/rsa-checksum.c
> +++ b/lib/rsa/rsa-checksum.c
> @@ -4,14 +4,18 @@
>   * SPDX-License-Identifier:    GPL-2.0+
>   */
>
> +#ifndef USE_HOSTCC
>  #include <common.h>
>  #include <fdtdec.h>
> -#include <rsa.h>
> -#include <sha1.h>
> -#include <sha256.h>
>  #include <asm/byteorder.h>
>  #include <asm/errno.h>
>  #include <asm/unaligned.h>
> +#else
> +#include "fdt_host.h"
> +#endif
> +#include <rsa.h>
> +#include <sha1.h>
> +#include <sha256.h>
>
>  /* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */
>
> diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
> index 0fe6e9f..ca8c120 100644
> --- a/lib/rsa/rsa-sign.c
> +++ b/lib/rsa/rsa-sign.c
> @@ -193,7 +193,7 @@ static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo,
>                 goto err_create;
>         }
>         EVP_MD_CTX_init(context);
> -       if (!EVP_SignInit(context, checksum_algo->calculate())) {
> +       if (!EVP_SignInit(context, checksum_algo->calculate_sign())) {
>                 ret = rsa_err("Signer setup failed");
>                 goto err_sign;
>         }
> diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
> index 09268ca..587da5b 100644
> --- a/lib/rsa/rsa-verify.c
> +++ b/lib/rsa/rsa-verify.c
> @@ -4,17 +4,28 @@
>   * SPDX-License-Identifier:    GPL-2.0+
>   */
>
> +#ifndef USE_HOSTCC
>  #include <common.h>
>  #include <fdtdec.h>
> -#include <rsa.h>
> -#include <sha1.h>
> -#include <sha256.h>
> +#include <asm/types.h>
>  #include <asm/byteorder.h>
>  #include <asm/errno.h>
> +#include <asm/types.h>
>  #include <asm/unaligned.h>
> +#else
> +#include "fdt_host.h"
> +#include "mkimage.h"
> +#include <fdt_support.h>
> +#endif
> +#include <rsa.h>
> +#include <sha1.h>
> +#include <sha256.h>
>
>  #define UINT64_MULT32(v, multby)  (((uint64_t)(v)) * ((uint32_t)(multby)))
>
> +#define get_unaligned_be32(a) fdt32_to_cpu(*(uint32_t *)a)
> +#define put_unaligned_be32(a, b) (*(uint32_t *)(b) = cpu_to_fdt32(a))
> +
>  /**
>   * subtract_modulus() - subtract modulus from the given value
>   *
> @@ -150,7 +161,6 @@ static int pow_mod(const struct rsa_public_key *key, uint32_t *inout)
>         /* Convert to bigendian byte array */
>         for (i = key->len - 1, ptr = inout; (int)i >= 0; i--, ptr++)
>                 put_unaligned_be32(result[i], ptr);
> -
>         return 0;
>  }
>
> diff --git a/test/vboot/vboot_test.sh b/test/vboot/vboot_test.sh
> index 27b221a..fc33f2d 100755
> --- a/test/vboot/vboot_test.sh
> +++ b/test/vboot/vboot_test.sh
> @@ -55,6 +55,7 @@ O=$(readlink -f ${O})
>  dtc="-I dts -O dtb -p 2000"
>  uboot="${O}/u-boot"
>  mkimage="${O}/tools/mkimage"
> +fit_check_sign="${O}/tools/fit_check_sign"
>  keys="${dir}/dev-keys"
>  echo ${mkimage} -D "${dtc}"
>
> @@ -88,7 +89,6 @@ ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb -r test.fit >${tmp}
>
>  run_uboot "signed images" "dev+"
>
> -
>  # Create a fresh .dtb without the public keys
>  dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
>
> @@ -101,6 +101,23 @@ run_uboot "unsigned config" $sha"+ OK"
>  echo Sign images
>  ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb -r test.fit >${tmp}
>
> +echo check signed config on the host
> +if ! ${fit_check_sign} -f test.fit -k sandbox-u-boot.dtb >${tmp}; then
> +       echo
> +       echo "Verified boot key check on host failed, output follows:"
> +       cat ${tmp}
> +       false
> +else
> +       if ! grep -q "dev+" ${tmp}; then
> +               echo
> +               echo "Verified boot key check failed, output follows:"
> +               cat ${tmp}
> +               false
> +       else
> +               echo "OK"
> +       fi
> +fi
> +
>  run_uboot "signed config" "dev+"
>
>  # Increment the first byte of the signature, which should cause failure
> @@ -109,6 +126,23 @@ newbyte=$(printf %x $((0x${sig:0:2} + 1)))
>  sig="${newbyte} ${sig:2}"
>  fdtput -t bx test.fit /configurations/conf at 1/signature at 1 value ${sig}
>
> +echo check bad signed config on the host
> +if ${fit_check_sign} -f test.fit -k sandbox-u-boot.dtb >${tmp}; then
> +       echo
> +       echo "Verified boot key check on host failed, output follows:"
> +       cat ${tmp}
> +       false
> +else
> +       if ! grep -q "failed" ${tmp}; then
> +               echo
> +               echo "Verified boot key check failed, output follows:"
> +               cat ${tmp}
> +               false
> +       else
> +               echo "OK"
> +       fi
> +fi
> +
>  run_uboot "signed config with bad hash" "Bad Data Hash"
>
>  popd >/dev/null
> diff --git a/tools/Makefile b/tools/Makefile
> index d079bc9..874705a 100644
> --- a/tools/Makefile
> +++ b/tools/Makefile
> @@ -53,6 +53,7 @@ BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
>  BIN_FILES-y += dumpimage$(SFX)
>  BIN_FILES-y += mkenvimage$(SFX)
>  BIN_FILES-y += mkimage$(SFX)
> +BIN_FILES-y += fit_check_sign$(SFX)
>  BIN_FILES-y += fit_info$(SFX)
>  BIN_FILES-$(CONFIG_EXYNOS5250) += mk$(BOARD)spl$(SFX)
>  BIN_FILES-$(CONFIG_EXYNOS5420) += mk$(BOARD)spl$(SFX)
> @@ -86,6 +87,7 @@ NOPED_OBJ_FILES-y += kwbimage.o
>  NOPED_OBJ_FILES-y += imagetool.o
>  NOPED_OBJ_FILES-y += mkenvimage.o
>  NOPED_OBJ_FILES-y += mkimage.o
> +NOPED_OBJ_FILES-y += fit_check_sign.o
>  NOPED_OBJ_FILES-y += fit_info.o
>  NOPED_OBJ_FILES-y += mxsimage.o
>  NOPED_OBJ_FILES-y += omapimage.o
> @@ -122,7 +124,7 @@ LIBFDT_OBJ_FILES-y += fdt_strerror.o
>  LIBFDT_OBJ_FILES-y += fdt_wip.o
>
>  # RSA objects
> -RSA_OBJ_FILES-$(CONFIG_FIT_SIGNATURE) += rsa-sign.o
> +RSA_OBJ_FILES-$(CONFIG_FIT_SIGNATURE) += rsa-sign.o rsa-verify.o rsa-checksum.o
>
>  # Generated LCD/video logo
>  LOGO_H = $(OBJTREE)/include/bmp_logo.h
> @@ -266,6 +268,21 @@ $(obj)mkimage$(SFX):       $(obj)aisimage.o \
>         $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ $(HOSTLIBS)
>         $(HOSTSTRIP) $@
>
> +$(obj)fit_check_sign$(SFX):    $(obj)fit_check_sign.o \
> +                       $(FIT_SIG_OBJS) \
> +                       $(obj)crc32.o \
> +                       $(obj)fit_common.o \
> +                       $(obj)image-fit.o \
> +                       $(obj)image-host.o \
> +                       $(obj)image.o \
> +                       $(obj)md5.o \
> +                       $(obj)sha1.o \
> +                       $(obj)sha256.o \
> +                       $(LIBFDT_OBJS) \
> +                       $(RSA_OBJS)
> +       $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ $(HOSTLIBS)
> +       $(HOSTSTRIP) $@
> +
>  $(obj)fit_info$(SFX):  $(obj)fit_info.o \
>                         $(FIT_SIG_OBJS) \
>                         $(obj)crc32.o \
> diff --git a/tools/fdt_host.h b/tools/fdt_host.h
> index c2b23c6..134d965 100644
> --- a/tools/fdt_host.h
> +++ b/tools/fdt_host.h
> @@ -11,4 +11,6 @@
>  #include "../include/libfdt.h"
>  #include "../include/fdt_support.h"
>
> +int fit_check_sign(const void *working_fdt, const void *key);
> +
>  #endif /* __FDT_HOST_H__ */
> diff --git a/tools/fit_check_sign.c b/tools/fit_check_sign.c
> new file mode 100644
> index 0000000..63c7295
> --- /dev/null
> +++ b/tools/fit_check_sign.c
> @@ -0,0 +1,119 @@
> +/*
> + * (C) Copyright 2014
> + * DENX Software Engineering
> + * Heiko Schocher <hs@denx.de>
> + *
> + * Based on:
> + * (C) Copyright 2008 Semihalf
> + *
> + * (C) Copyright 2000-2004
> + * DENX Software Engineering
> + * Wolfgang Denk, wd at denx.de
> + *
> + * Updated-by: Prafulla Wadaskar <prafulla@marvell.com>
> + *             FIT image specific code abstracted from mkimage.c
> + *             some functions added to address abstraction
> + *
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include "mkimage.h"
> +#include "fit_common.h"
> +#include <image.h>
> +#include <u-boot/crc.h>
> +
> +void *key_blob;
> +
> +void usage(char *cmdname)
> +{
> +       fprintf(stderr, "Usage: %s -f fit file -k key file\n"
> +                        "          -f ==> set fit file which should be checked'\n"
> +                        "          -k ==> set key file which contains the key'\n",
> +               cmdname);
> +       exit(EXIT_FAILURE);
> +}
> +
> +void *get_blob(void)
> +{
> +       return key_blob;
> +}
> +
> +int main(int argc, char **argv)
> +{
> +       int ffd = -1;
> +       int kfd = -1;
> +       struct stat fsbuf;
> +       struct stat ksbuf;
> +       void *fit_blob;
> +       char *fdtfile = NULL;
> +       char *keyfile = NULL;
> +       char cmdname[50];
> +       int ret;
> +
> +       strcpy(cmdname, *argv);
> +
> +       while (--argc > 0 && **++argv == '-') {
> +               while (*++*argv) {

If this is a new tool, shouldn't we use getopt()?

> +                       switch (**argv) {
> +                       case 'f':
> +                               if (--argc <= 0)
> +                                       usage(cmdname);
> +                               fdtfile = *++argv;
> +                               goto NXTARG;
> +
> +                       case 'k':
> +                               if (--argc <= 0)
> +                                       usage(cmdname);
> +                               keyfile = *++argv;
> +                               goto NXTARG;
> +
> +                       default:
> +                               usage(cmdname);
> +                       }
> +               }
> +NXTARG:;
> +       }
> +
> +       if (argc != 0)
> +               usage(cmdname);
> +
> +       ffd = mmap_fdt(cmdname, fdtfile, &fit_blob, &fsbuf);
> +       kfd = mmap_fdt(cmdname, keyfile, &key_blob, &ksbuf);
> +
> +       ret = fit_check_sign(fit_blob, key_blob);
> +
> +       if (ret)
> +               ret = EXIT_SUCCESS;
> +       else
> +               ret = EXIT_FAILURE;
> +
> +       (void) munmap((void *)fit_blob, fsbuf.st_size);
> +       (void) munmap((void *)key_blob, ksbuf.st_size);
> +

from here:

> +       /* We're a bit of paranoid */
> +#if defined(_POSIX_SYNCHRONIZED_IO) && \
> +       !defined(__sun__) && \
> +       !defined(__FreeBSD__) && \
> +       !defined(__APPLE__)
> +       (void) fdatasync(ffd);
> +       (void) fdatasync(kfd);
> +#else
> +       (void) fsync(ffd);
> +       (void) fsync(kfd);
> +#endif

I don't think we need this since we are not changing the file.

> +
> +       if (close(ffd)) {
> +               fprintf(stderr, "%s: Write error on %s: %s\n",
> +                       cmdname, fdtfile, strerror(errno));
> +               exit(EXIT_FAILURE);
> +       }
> +       if (close(kfd)) {
> +               fprintf(stderr, "%s: Write error on %s: %s\n",
> +                       cmdname, keyfile, strerror(errno));
> +               exit(EXIT_FAILURE);
> +       }

We are not writing, I think we can ignore errors on close().

> +
> +       exit(ret);
> +}
> diff --git a/tools/image-host.c b/tools/image-host.c
> index 8e185ec..65e3932 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -695,3 +695,16 @@ int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
>
>         return 0;
>  }
> +
> +int fit_check_sign(const void *working_fdt, const void *key)
> +{
> +       int cfg_noffset;
> +       int ret;
> +
> +       cfg_noffset = fit_conf_get_node(working_fdt, NULL);
> +       if (!cfg_noffset)
> +               return -1;
> +
> +       ret = fit_config_verify(working_fdt, cfg_noffset);
> +       return ret;
> +}
> --
> 1.8.3.1
>

Regards,
Simon

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

* [U-Boot] [PATCH v2 3/8] fit: add sha256 support
  2014-02-15 22:47   ` Simon Glass
@ 2014-02-17  6:33     ` Heiko Schocher
  2014-02-17  6:49       ` Heiko Schocher
  0 siblings, 1 reply; 20+ messages in thread
From: Heiko Schocher @ 2014-02-17  6:33 UTC (permalink / raw)
  To: u-boot

Hello Simon,

Am 15.02.2014 23:47, schrieb Simon Glass:
> Hi Heiko,
>
> On 8 February 2014 22:34, Heiko Schocher<hs@denx.de>  wrote:
>> add sha256 support to fit images
>>
>> Signed-off-by: Heiko Schocher<hs@denx.de>
>> Acked-by: Simon Glass<sjg@chromium.org>
>
> Sorry I spotted a few things since.

No problem! Thanks for your review.

>> ---
>> changes for v2:
>> - add Acked-by from Simon Glass
>>
>>   common/image-fit.c | 5 +++++
>>   include/image.h    | 9 +++++++++
>>   lib/sha256.c       | 2 +-
>>   tools/Makefile     | 3 +++
>>   4 files changed, 18 insertions(+), 1 deletion(-)
>>
[...]
>> diff --git a/include/image.h b/include/image.h
>> index 7de2bb2..f001a5f 100644
>> --- a/include/image.h
>> +++ b/include/image.h
>> @@ -57,13 +57,18 @@ struct lmb;
>>   #  ifdef CONFIG_SPL_SHA1_SUPPORT
>>   #   define IMAGE_ENABLE_SHA1   1
>>   #  endif
>> +#  ifdef CONFIG_SPL_SHA256_SUPPORT
>> +#   define IMAGE_ENABLE_SHA256 1
>> +#  endif
>>   # else
>>   #  define CONFIG_CRC32         /* FIT images need CRC32 support */
>>   #  define CONFIG_MD5           /* and MD5 */
>>   #  define CONFIG_SHA1          /* and SHA1 */
>> +#  define CONFIG_SHA256                /* and SHA256 */
>
> Thinking about this again, I wonder if we want to force SHA256 to be
> enabled when FIT is used? Should we just hold the existing
> CONFIG_SHA256 setting in the board file and change:

I can do this, but why are the others fix?

>>   #  define IMAGE_ENABLE_CRC32   1
>>   #  define IMAGE_ENABLE_MD5     1
>>   #  define IMAGE_ENABLE_SHA1    1
>> +#  define IMAGE_ENABLE_SHA256  1
>
> this to:
>
> #ifdef CONFIG_SHA256
>   +#  define IMAGE_ENABLE_SHA256  0
> #endif
>
> ?

Ok, changed, into:

#ifdef CONFIG_SHA256
   #  define IMAGE_ENABLE_SHA256  1
#endif

>>   # endif
>>
>>   #ifndef IMAGE_ENABLE_CRC32
>> @@ -78,6 +83,10 @@ struct lmb;
>>   #define IMAGE_ENABLE_SHA1      0
>>   #endif
>>
>> +#ifndef IMAGE_ENABLE_SHA256
>> +#define IMAGE_ENABLE_SHA256    0
>> +#endif
>> +
>>   #endif /* CONFIG_FIT */
>>
>>   #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
>> diff --git a/lib/sha256.c b/lib/sha256.c
>> index 7348162..5766de2 100644
>> --- a/lib/sha256.c
>> +++ b/lib/sha256.c
>> @@ -258,7 +258,7 @@ void sha256_csum_wd(const unsigned char *input, unsigned int ilen,
>>   {
>>          sha256_context ctx;
>>   #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
>> -       unsigned char *end, *curr;
>> +       const unsigned char *end, *curr;
>
> Why remove the const here?

I add const here ... I remve the "const" for the "curr" pointer.

>>          int chunk;
>>   #endif
>>
>> diff --git a/tools/Makefile b/tools/Makefile
>> index 328cea3..5e36e5e 100644
>> --- a/tools/Makefile
>> +++ b/tools/Makefile
>> @@ -71,6 +71,7 @@ EXT_OBJ_FILES-y += common/image-sig.o
>>   EXT_OBJ_FILES-y += lib/crc32.o
>>   EXT_OBJ_FILES-y += lib/md5.o
>>   EXT_OBJ_FILES-y += lib/sha1.o
>> +EXT_OBJ_FILES-y += lib/sha256.o
>>
>>   # Source files located in the tools directory
>>   NOPED_OBJ_FILES-y += aisimage.o
>> @@ -223,6 +224,7 @@ $(obj)dumpimage$(SFX):      $(obj)aisimage.o \
>>                          $(obj)os_support.o \
>>                          $(obj)pblimage.o \
>>                          $(obj)sha1.o \
>> +                       $(obj)sha256.o \
>>                          $(obj)ublimage.o \
>>                          $(LIBFDT_OBJS) \
>>                          $(RSA_OBJS)
>> @@ -252,6 +254,7 @@ $(obj)mkimage$(SFX):        $(obj)aisimage.o \
>>                          $(obj)os_support.o \
>>                          $(obj)pblimage.o \
>>                          $(obj)sha1.o \
>> +                       $(obj)sha256.o \
>>                          $(obj)ublimage.o \
>>                          $(LIBFDT_OBJS) \
>>                          $(RSA_OBJS)
>> --
>> 1.8.3.1
>>
>> _______________________________________________
>> U-Boot mailing list
>> U-Boot at lists.denx.de
>> http://lists.denx.de/mailman/listinfo/u-boot
>
> Regards,
> Simon
>
>

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

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

* [U-Boot] [PATCH v2 3/8] fit: add sha256 support
  2014-02-17  6:33     ` Heiko Schocher
@ 2014-02-17  6:49       ` Heiko Schocher
  2014-02-17 22:14         ` Simon Glass
  0 siblings, 1 reply; 20+ messages in thread
From: Heiko Schocher @ 2014-02-17  6:49 UTC (permalink / raw)
  To: u-boot

Hello Simon,

I was a little to fast with my answer ...

Am 17.02.2014 07:33, schrieb Heiko Schocher:
> Hello Simon,
>
> Am 15.02.2014 23:47, schrieb Simon Glass:
>> Hi Heiko,
>>
>> On 8 February 2014 22:34, Heiko Schocher<hs@denx.de> wrote:
>>> add sha256 support to fit images
>>>
>>> Signed-off-by: Heiko Schocher<hs@denx.de>
>>> Acked-by: Simon Glass<sjg@chromium.org>
>>
>> Sorry I spotted a few things since.
>
> No problem! Thanks for your review.
>
>>> ---
>>> changes for v2:
>>> - add Acked-by from Simon Glass
>>>
>>> common/image-fit.c | 5 +++++
>>> include/image.h | 9 +++++++++
>>> lib/sha256.c | 2 +-
>>> tools/Makefile | 3 +++
>>> 4 files changed, 18 insertions(+), 1 deletion(-)
>>>
> [...]
>>> diff --git a/include/image.h b/include/image.h
>>> index 7de2bb2..f001a5f 100644
>>> --- a/include/image.h
>>> +++ b/include/image.h
>>> @@ -57,13 +57,18 @@ struct lmb;
>>> # ifdef CONFIG_SPL_SHA1_SUPPORT
>>> # define IMAGE_ENABLE_SHA1 1
>>> # endif
>>> +# ifdef CONFIG_SPL_SHA256_SUPPORT
>>> +# define IMAGE_ENABLE_SHA256 1
>>> +# endif
>>> # else
>>> # define CONFIG_CRC32 /* FIT images need CRC32 support */
>>> # define CONFIG_MD5 /* and MD5 */
>>> # define CONFIG_SHA1 /* and SHA1 */
>>> +# define CONFIG_SHA256 /* and SHA256 */
>>
>> Thinking about this again, I wonder if we want to force SHA256 to be
>> enabled when FIT is used? Should we just hold the existing
>> CONFIG_SHA256 setting in the board file and change:
>
> I can do this, but why are the others fix?

Hmm.. if I do this, mkimage does not work, as missing
this "IMAGE_ENABLE_SHA256" define ... I get the following
error message:

"Unsupported hash algorithm (sha256) for 'hash at 1' hash node in 'U-BOOT at 1' image node
tools/mkimage Can't add hashes to FIT blob"

I think, when compiling mkimage for the host, we have no board config
header availiable, as mkimage is not compiled (and not intent to be)
board specific ...

Seems that this is the reason, why the other algorithms are also
always enabled ...

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

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

* [U-Boot] [PATCH v2 3/8] fit: add sha256 support
  2014-02-17  6:49       ` Heiko Schocher
@ 2014-02-17 22:14         ` Simon Glass
  0 siblings, 0 replies; 20+ messages in thread
From: Simon Glass @ 2014-02-17 22:14 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

On 16 February 2014 23:49, Heiko Schocher <hs@denx.de> wrote:
> Hello Simon,
>
> I was a little to fast with my answer ...
>
> Am 17.02.2014 07:33, schrieb Heiko Schocher:
>
>> Hello Simon,
>>
>> Am 15.02.2014 23:47, schrieb Simon Glass:
>>>
>>> Hi Heiko,
>>>
>>> On 8 February 2014 22:34, Heiko Schocher<hs@denx.de> wrote:
>>>>
>>>> add sha256 support to fit images
>>>>
>>>> Signed-off-by: Heiko Schocher<hs@denx.de>
>>>> Acked-by: Simon Glass<sjg@chromium.org>
>>>
>>>
>>> Sorry I spotted a few things since.
>>
>>
>> No problem! Thanks for your review.
>>
>>>> ---
>>>> changes for v2:
>>>> - add Acked-by from Simon Glass
>>>>
>>>> common/image-fit.c | 5 +++++
>>>> include/image.h | 9 +++++++++
>>>> lib/sha256.c | 2 +-
>>>> tools/Makefile | 3 +++
>>>> 4 files changed, 18 insertions(+), 1 deletion(-)
>>>>
>> [...]
>>>>
>>>> diff --git a/include/image.h b/include/image.h
>>>> index 7de2bb2..f001a5f 100644
>>>> --- a/include/image.h
>>>> +++ b/include/image.h
>>>> @@ -57,13 +57,18 @@ struct lmb;
>>>> # ifdef CONFIG_SPL_SHA1_SUPPORT
>>>> # define IMAGE_ENABLE_SHA1 1
>>>> # endif
>>>> +# ifdef CONFIG_SPL_SHA256_SUPPORT
>>>> +# define IMAGE_ENABLE_SHA256 1
>>>> +# endif
>>>> # else
>>>> # define CONFIG_CRC32 /* FIT images need CRC32 support */
>>>> # define CONFIG_MD5 /* and MD5 */
>>>> # define CONFIG_SHA1 /* and SHA1 */
>>>> +# define CONFIG_SHA256 /* and SHA256 */
>>>
>>>
>>> Thinking about this again, I wonder if we want to force SHA256 to be
>>> enabled when FIT is used? Should we just hold the existing
>>> CONFIG_SHA256 setting in the board file and change:
>>
>>
>> I can do this, but why are the others fix?
>
>
> Hmm.. if I do this, mkimage does not work, as missing
> this "IMAGE_ENABLE_SHA256" define ... I get the following
> error message:
>
> "Unsupported hash algorithm (sha256) for 'hash at 1' hash node in 'U-BOOT at 1'
> image node
> tools/mkimage Can't add hashes to FIT blob"
>
> I think, when compiling mkimage for the host, we have no board config
> header availiable, as mkimage is not compiled (and not intent to be)
> board specific ...
>
> Seems that this is the reason, why the other algorithms are also
> always enabled ...

Ah yes, I remember this problem - I wanted mkimage to support
everything rather than be dependent on what particular board you build
with. In the end I dropped the signing part from this idea.

So yes your code is correct and I'm sorry for the trouble.

Regards,
Simon

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

end of thread, other threads:[~2014-02-17 22:14 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-09  5:34 [U-Boot] [PATCH v2 0/8] common, fit, rsa: enhancements Heiko Schocher
2014-02-09  5:34 ` [U-Boot] [PATCH v2 1/8] tools/image-host: fix sign-images bug Heiko Schocher
2014-02-09  5:34 ` [U-Boot] [PATCH v2 2/8] fdt: add "fdt checksign" command Heiko Schocher
2014-02-14 16:17   ` Simon Glass
2014-02-15 23:00   ` Simon Glass
2014-02-15 23:07     ` Simon Glass
2014-02-09  5:34 ` [U-Boot] [PATCH v2 3/8] fit: add sha256 support Heiko Schocher
2014-02-15 22:47   ` Simon Glass
2014-02-17  6:33     ` Heiko Schocher
2014-02-17  6:49       ` Heiko Schocher
2014-02-17 22:14         ` Simon Glass
2014-02-09  5:34 ` [U-Boot] [PATCH v2 4/8] rsa: add sha256-rsa2048 algorithm Heiko Schocher
2014-02-15 23:11   ` Simon Glass
2014-02-09  5:34 ` [U-Boot] [PATCH v2 5/8] rsa: add sha256,rsa4096 algorithm Heiko Schocher
2014-02-15 23:12   ` Simon Glass
2014-02-09  5:34 ` [U-Boot] [PATCH v2 6/8] gen: Add progressive hash API Heiko Schocher
2014-02-15 23:14   ` Simon Glass
2014-02-09  5:34 ` [U-Boot] [PATCH v2 7/8] tools, fit: add fit_info host command Heiko Schocher
2014-02-09  5:34 ` [U-Boot] [PATCH v2 8/8] tools, fit_check_sign: verify a signed fit image Heiko Schocher
2014-02-15 23:22   ` Simon Glass

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.