[U-Boot] [PATCH 3/3] fit: rsa: Add support for SHA256 hash

Marek Vasut
2014-02-06T03:47:06Z

Add support for "sha256,rsa2048" signature. This patch utilises the previously
laid groundwork for adding other hashes.

Signed-off-by: Marek Vasut <marex@denx.de>
---
common/image-sig.c | 8 +++++++-
lib/rsa/rsa-sign.c | 5 +++++
lib/rsa/rsa-verify.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/common/image-sig.c b/common/image-sig.c
index 973b06d..c3d63bc 100644
--- a/common/image-sig.c
+++ b/common/image-sig.c
@@ -23,7 +23,13 @@ struct image_sig_algo image_sig_algos[] = {
rsa_sign,
rsa_add_verify_data,
rsa_verify,
- }
+ },
+ {
+ "sha256,rsa2048",
+ rsa_sign,
+ rsa_add_verify_data,
+ rsa_verify,
+ },
};

struct image_sig_algo *image_get_sig_algo(const char *name)
diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index 4e11720..f1167b1 100644
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -17,6 +17,7 @@

enum rsa_hash_type {
RSA_HASH_SHA1,
+ RSA_HASH_SHA256,
RSA_HASH_UNKNOWN,
};

@@ -169,6 +170,8 @@ static const EVP_MD *rsa_sign_get_hash(enum rsa_hash_type hash)
switch (hash) {
case RSA_HASH_SHA1:
return EVP_sha1();
+ case RSA_HASH_SHA256:
+ return EVP_sha256();
default: /* This must never happen. */
rsa_err("Invalid hash type!\n");
exit(1);
@@ -258,6 +261,8 @@ static enum rsa_hash_type rsa_get_sha_type(struct image_sign_info *info)

if (!strncmp(info->algo->name, "sha1", hash_str_len))
return RSA_HASH_SHA1;
+ else if (!strncmp(info->algo->name, "sha256", hash_str_len))
+ return RSA_HASH_SHA256;
else
return RSA_HASH_UNKNOWN;
}
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index 9617f8d..67fb882 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -9,6 +9,7 @@
#include <malloc.h>
#include <rsa.h>
#include <sha1.h>
+#include <sha256.h>
#include <asm/byteorder.h>
#include <asm/errno.h>
#include <asm/unaligned.h>
@@ -70,6 +71,37 @@ static const uint8_t padding_sha1_rsa2048[RSA2048_BYTES - SHA1_SUM_LEN] = {
0x05, 0x00, 0x04, 0x14
};

+static 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,
+};
+
/**
* subtract_modulus() - subtract modulus from the given value
*
@@ -337,6 +369,28 @@ rsa_compute_hash_sha1(const struct image_region region[], int region_count,
return 0;
}

+static int
+rsa_compute_hash_sha256(const struct image_region region[], int region_count,
+ uint8_t **out_hash)
+{
+ sha256_context ctx;
+ int i;
+ uint8_t *hash;
+
+ hash = calloc(1, SHA256_SUM_LEN);
+ if (!hash)
+ return -ENOMEM;
+
+ sha256_starts(&ctx);
+ for (i = 0; i < region_count; i++)
+ sha256_update(&ctx, region[i].data, region[i].size);
+ sha256_finish(&ctx, hash);
+
+ *out_hash = hash;
+
+ return 0;
+}
+
static int rsa_compute_hash(struct image_sign_info *info,
const struct image_region region[], int region_count,
uint8_t **out_hash, const uint8_t **padding,
@@ -349,6 +403,10 @@ static int rsa_compute_hash(struct image_sign_info *info,
pad = padding_sha1_rsa2048;
len = RSA2048_BYTES - SHA1_SUM_LEN;
ret = rsa_compute_hash_sha1(region, region_count, out_hash);
+ } else if (!strcmp(info->algo->name, "sha256,rsa2048")) {
+ pad = padding_sha256_rsa2048;
+ len = RSA2048_BYTES - SHA256_SUM_LEN;
+ ret = rsa_compute_hash_sha256(region, region_count, out_hash);
} else {
ret = -EINVAL;
}
--
1.8.5.3