[U-Boot] [PATCH v3 5/8] rsa: add sha256,rsa4096 algorithm

Heiko Schocher hs at denx.de
Mon Mar 3 12:19:27 CET 2014


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

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

---
changes for v2:
- add comment from Simon Glass:
  - add a commit message
changes for v3:
  add Acked-by from Simon Glass
---
 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 8b6f49b..763960a 100644
--- a/common/image-sig.c
+++ b/common/image-sig.c
@@ -29,6 +29,7 @@ struct checksum_algo checksum_algos[] = {
 	{
 		"sha1",
 		SHA1_SUM_LEN,
+		RSA2048_BYTES,
 #if IMAGE_ENABLE_SIGN
 		EVP_sha1,
 #else
@@ -39,14 +40,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",
@@ -61,7 +76,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 44b2b46..540afaa 100644
--- a/include/image.h
+++ b/include/image.h
@@ -879,6 +879,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 850b253..612db85 100644
--- a/include/rsa-checksum.h
+++ b/include/rsa-checksum.h
@@ -12,6 +12,7 @@
 #include <sha1.h>
 #include <sha256.h>
 
+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 e9ae870..a5680ab 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



More information about the U-Boot mailing list