]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
rsa: add sha256-rsa2048 algorithm
authorHeiko Schocher <hs@denx.de>
Mon, 3 Mar 2014 11:19:26 +0000 (12:19 +0100)
committerTom Rini <trini@ti.com>
Fri, 21 Mar 2014 20:39:34 +0000 (16:39 -0400)
based on patch from andreas@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@oetken.name
Cc: Simon Glass <sjg@chromium.org>
14 files changed:
common/image-sig.c
doc/uImage.FIT/signature.txt
include/image.h
include/rsa-checksum.h [new file with mode: 0644]
include/rsa.h
lib/rsa/Makefile
lib/rsa/rsa-checksum.c [new file with mode: 0644]
lib/rsa/rsa-sign.c
lib/rsa/rsa-verify.c
test/vboot/sign-configs-sha1.its [moved from test/vboot/sign-configs.its with 100% similarity]
test/vboot/sign-configs-sha256.its [new file with mode: 0644]
test/vboot/sign-images-sha1.its [moved from test/vboot/sign-images.its with 100% similarity]
test/vboot/sign-images-sha256.its [new file with mode: 0644]
test/vboot/vboot_test.sh

index 973b06d505f174177c3ea634af38b86c4eddb6d5..8b6f49bb38e55399f20912c65966a07edffeecad 100644 (file)
@@ -14,15 +14,53 @@ DECLARE_GLOBAL_DATA_PTR;
 #endif /* !USE_HOSTCC*/
 #include <image.h>
 #include <rsa.h>
+#include <rsa-checksum.h>
 
 #define IMAGE_MAX_HASHED_NODES         100
 
+#ifdef USE_HOSTCC
+__attribute__((weak)) void *get_blob(void)
+{
+       return NULL;
+}
+#endif
+
+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],
        }
 };
 
index bc9f3fa6e13684d147e23d90b12a432dc053e7fe..71f8b6c06ad46688266cf5808b7bb275e01d5eb7 100644 (file)
@@ -346,7 +346,9 @@ 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
+do sha1 test
 Build FIT with signed images
 Test Verified Boot Run: unsigned signatures:: OK
 Sign images
@@ -355,10 +357,20 @@ 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
+do sha256 test
+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 passed
 
-
 Future Work
 -----------
 - Roll-back protection using a TPM is done using the tpm command. This can
index 52969aa653caf9b7c65686b575cfef45c7bfffd4..44b2b469b0b278f89089a587e97fccfbd47d08ad 100644 (file)
@@ -833,6 +833,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
@@ -872,6 +873,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 */
 
@@ -922,6 +940,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 (file)
index 0000000..850b253
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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>
+
+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
index add4c789f335488f3ed5442365acf9a95dc49d84..e9ae870622c97bee4b02109bdf9a8ddca21ad34d 100644 (file)
 #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;               /* len 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
index 164ab3996455fb58f4a590b032327c57f6b11d61..a5a96cb680d16d1cea1f88375f2ca1ec7bfc1776 100644 (file)
@@ -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 (file)
index 0000000..e520e1c
--- /dev/null
@@ -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);
+}
index 549130eda1f3a41759522c1e2b84798061fcf08c..0fe6e9f9cf1178b084596f83aa2a02ed4ec95b14 100644 (file)
@@ -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;
 
index 02cc4e335309becf02288fff81167cdca6734bab..b3573a87698394147a8e4b3a1c97f000ea9d7473 100644 (file)
@@ -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-sha256.its b/test/vboot/sign-configs-sha256.its
new file mode 100644 (file)
index 0000000..1b3432e
--- /dev/null
@@ -0,0 +1,45 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       hash@1 {
+                               algo = "sha256";
+                       };
+               };
+               fdt@1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       hash@1 {
+                               algo = "sha256";
+                       };
+               };
+       };
+       configurations {
+               default = "conf@1";
+               conf@1 {
+                       kernel = "kernel@1";
+                       fdt = "fdt@1";
+                       signature@1 {
+                               algo = "sha256,rsa2048";
+                               key-name-hint = "dev";
+                               sign-images = "fdt", "kernel";
+                       };
+               };
+       };
+};
diff --git a/test/vboot/sign-images-sha256.its b/test/vboot/sign-images-sha256.its
new file mode 100644 (file)
index 0000000..e6aa9fc
--- /dev/null
@@ -0,0 +1,42 @@
+/dts-v1/;
+
+/ {
+       description = "Chrome OS kernel image with one or more FDT blobs";
+       #address-cells = <1>;
+
+       images {
+               kernel@1 {
+                       data = /incbin/("test-kernel.bin");
+                       type = "kernel_noload";
+                       arch = "sandbox";
+                       os = "linux";
+                       compression = "none";
+                       load = <0x4>;
+                       entry = <0x8>;
+                       kernel-version = <1>;
+                       signature@1 {
+                               algo = "sha256,rsa2048";
+                               key-name-hint = "dev";
+                       };
+               };
+               fdt@1 {
+                       description = "snow";
+                       data = /incbin/("sandbox-kernel.dtb");
+                       type = "flat_dt";
+                       arch = "sandbox";
+                       compression = "none";
+                       fdt-version = <1>;
+                       signature@1 {
+                               algo = "sha256,rsa2048";
+                               key-name-hint = "dev";
+                       };
+               };
+       };
+       configurations {
+               default = "conf@1";
+               conf@1 {
+                       kernel = "kernel@1";
+                       fdt = "fdt@1";
+               };
+       };
+};
index bb2c6051c8a41bb7d82214dad884d27d6c2570f9..3e2856ed1ff92c2198cea4d24ab54e8fcf6853ab 100755 (executable)
@@ -61,47 +61,57 @@ openssl req -batch -new -x509 -key ${keys}/dev.key -out ${keys}/dev.crt
 
 pushd ${dir} >/dev/null
 
-# Compile our device tree files for kernel and U-Boot (CONFIG_OF_CONTROL)
-dtc -p 0x1000 sandbox-kernel.dts -O dtb -o sandbox-kernel.dtb
-dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
+function do_test {
+       echo do $sha test
+       # Compile our device tree files for kernel and U-Boot
+       dtc -p 0x1000 sandbox-kernel.dts -O dtb -o sandbox-kernel.dtb
+       dtc -p 0x1000 sandbox-u-boot.dts -O dtb -o sandbox-u-boot.dtb
 
-# Create a number kernel image with zeroes
-head -c 5000 /dev/zero >test-kernel.bin
+       # Create a number kernel image with zeroes
+       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}
+       # Build the FIT, but don't sign anything yet
+       echo Build FIT with signed images
+       ${mkimage} -D "${dtc}" -f sign-images-$sha.its test.fit >${tmp}
 
-run_uboot "unsigned signatures:" "dev-"
+       run_uboot "unsigned signatures:" "dev-"
 
-# Sign images with our dev keys
-echo Sign images
-${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb -r test.fit >${tmp}
+       # Sign images with our dev keys
+       echo Sign images
+       ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb \
+               -r test.fit >${tmp}
 
-run_uboot "signed images" "dev+"
+       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
+       # Create a fresh .dtb without the public keys
+       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}
+       echo Build FIT with signed configuration
+       ${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
-${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb -r test.fit >${tmp}
+       # Sign images with our dev keys
+       echo Sign images
+       ${mkimage} -D "${dtc}" -F -k dev-keys -K sandbox-u-boot.dtb \
+               -r test.fit >${tmp}
 
-run_uboot "signed config" "dev+"
+       run_uboot "signed config" "dev+"
 
-# Increment the first byte of the signature, which should cause failure
-sig=$(fdtget -t bx test.fit /configurations/conf@1/signature@1 value)
-newbyte=$(printf %x $((0x${sig:0:2} + 1)))
-sig="${newbyte} ${sig:2}"
-fdtput -t bx test.fit /configurations/conf@1/signature@1 value ${sig}
+       # Increment the first byte of the signature, which should cause failure
+       sig=$(fdtget -t bx test.fit /configurations/conf@1/signature@1 value)
+       newbyte=$(printf %x $((0x${sig:0:2} + 1)))
+       sig="${newbyte} ${sig:2}"
+       fdtput -t bx test.fit /configurations/conf@1/signature@1 value ${sig}
 
-run_uboot "signed config with bad hash" "Bad Data Hash"
+       run_uboot "signed config with bad hash" "Bad Data Hash"
+}
+
+sha=sha1
+do_test
+sha=sha256
+do_test
 
 popd >/dev/null