diff options
| -rw-r--r-- | common/image-sig.c | 38 | ||||
| -rw-r--r-- | doc/uImage.FIT/signature.txt | 14 | ||||
| -rw-r--r-- | include/image.h | 21 | ||||
| -rw-r--r-- | include/rsa-checksum.h | 23 | ||||
| -rw-r--r-- | include/rsa.h | 14 | ||||
| -rw-r--r-- | lib/rsa/Makefile | 2 | ||||
| -rw-r--r-- | lib/rsa/rsa-checksum.c | 98 | ||||
| -rw-r--r-- | lib/rsa/rsa-sign.c | 10 | ||||
| -rw-r--r-- | lib/rsa/rsa-verify.c | 83 | ||||
| -rw-r--r-- | test/vboot/sign-configs-sha1.its (renamed from test/vboot/sign-configs.its) | 0 | ||||
| -rw-r--r-- | test/vboot/sign-configs-sha256.its | 45 | ||||
| -rw-r--r-- | test/vboot/sign-images-sha1.its (renamed from test/vboot/sign-images.its) | 0 | ||||
| -rw-r--r-- | test/vboot/sign-images-sha256.its | 42 | ||||
| -rwxr-xr-x | test/vboot/vboot_test.sh | 66 | 
14 files changed, 363 insertions, 93 deletions
| diff --git a/common/image-sig.c b/common/image-sig.c index 973b06d505f..8b6f49bb38e 100644 --- a/common/image-sig.c +++ b/common/image-sig.c @@ -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],  	}  }; diff --git a/doc/uImage.FIT/signature.txt b/doc/uImage.FIT/signature.txt index bc9f3fa6e13..71f8b6c06ad 100644 --- a/doc/uImage.FIT/signature.txt +++ b/doc/uImage.FIT/signature.txt @@ -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 diff --git a/include/image.h b/include/image.h index 52969aa653c..44b2b469b0b 100644 --- a/include/image.h +++ b/include/image.h @@ -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 index 00000000000..850b2537537 --- /dev/null +++ b/include/rsa-checksum.h @@ -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 diff --git a/include/rsa.h b/include/rsa.h index add4c789f33..e9ae870622c 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;		/* 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 diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile index 164ab399645..a5a96cb680d 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 00000000000..e520e1ce504 --- /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 549130eda1f..0fe6e9f9cf1 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 02cc4e33530..b3573a87698 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 index db2ed793552..db2ed793552 100644 --- a/test/vboot/sign-configs.its +++ b/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 00000000000..1b3432ec144 --- /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@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.its b/test/vboot/sign-images-sha1.its index f69326a39bc..f69326a39bc 100644 --- a/test/vboot/sign-images.its +++ b/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 00000000000..e6aa9fc4098 --- /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@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"; +		}; +	}; +}; diff --git a/test/vboot/vboot_test.sh b/test/vboot/vboot_test.sh index bb2c6051c8a..3e2856ed1ff 100755 --- a/test/vboot/vboot_test.sh +++ b/test/vboot/vboot_test.sh @@ -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 | 
