diff options
Diffstat (limited to 'lib/rsa')
-rw-r--r-- | lib/rsa/rsa-checksum.c | 121 | ||||
-rw-r--r-- | lib/rsa/rsa-sign.c | 4 | ||||
-rw-r--r-- | lib/rsa/rsa-verify.c | 59 |
3 files changed, 49 insertions, 135 deletions
diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c index db183ff2930..2bf28e2dafb 100644 --- a/lib/rsa/rsa-checksum.c +++ b/lib/rsa/rsa-checksum.c @@ -13,130 +13,9 @@ #include <hash.h> #else #include "fdt_host.h" -#include <u-boot/sha1.h> -#include <u-boot/sha256.h> #endif #include <u-boot/rsa.h> -/* 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 -}; - -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 -}; - int hash_calculate(const char *name, const struct image_region region[], int region_count, uint8_t *checksum) diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c index c26f74128f2..9a092800130 100644 --- a/lib/rsa/rsa-sign.c +++ b/lib/rsa/rsa-sign.c @@ -244,7 +244,7 @@ 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, info->algo->checksum, region, + ret = rsa_sign_with_key(rsa, info->checksum, region, region_count, sigp, sig_len); if (ret) goto err_sign; @@ -508,7 +508,7 @@ int rsa_add_verify_data(struct image_sign_info *info, void *keydest) } if (!ret) { ret = fdt_setprop_string(keydest, node, FIT_ALGO_PROP, - info->algo->name); + info->name); } if (!ret && info->require_keys) { ret = fdt_setprop_string(keydest, node, "required", diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 442b7695639..0d548f8b8f9 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -25,6 +25,40 @@ #define RSA_DEFAULT_PUBEXP 65537 /** + * rsa_verify_padding() - Verify RSA message padding is valid + * + * Verify a RSA message's padding is consistent with PKCS1.5 + * padding as described in the RSA PKCS#1 v2.1 standard. + * + * @msg: Padded message + * @pad_len: Number of expected padding bytes + * @algo: Checksum algo structure having information on DER encoding etc. + * @return 0 on success, != 0 on failure + */ +static int rsa_verify_padding(const uint8_t *msg, const int pad_len, + struct checksum_algo *algo) +{ + int ff_len; + int ret; + + /* first byte must be 0x00 */ + ret = *msg++; + /* second byte must be 0x01 */ + ret |= *msg++ ^ 0x01; + /* next ff_len bytes must be 0xff */ + ff_len = pad_len - algo->der_len - 3; + ret |= *msg ^ 0xff; + ret |= memcmp(msg, msg+1, ff_len-1); + msg += ff_len; + /* next byte must be 0x00 */ + ret |= *msg++; + /* next der_len bytes must match der_prefix */ + ret |= memcmp(msg, algo->der_prefix, algo->der_len); + + return ret; +} + +/** * rsa_verify_key() - Verify a signature against some data using RSA Key * * Verify a RSA PKCS1.5 signature against an expected hash using @@ -34,14 +68,14 @@ * @sig: Signature * @sig_len: Number of bytes in signature * @hash: Pointer to the expected hash - * @algo: Checksum algo structure having information on RSA padding etc. + * @key_len: Number of bytes in rsa key + * @algo: Checksum algo structure having information on DER encoding etc. * @return 0 if verified, -ve on error */ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig, const uint32_t sig_len, const uint8_t *hash, - struct checksum_algo *algo) + const uint32_t key_len, struct checksum_algo *algo) { - const uint8_t *padding; int pad_len; int ret; #if !defined(USE_HOSTCC) @@ -83,11 +117,11 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig, return ret; } - padding = algo->rsa_padding; - pad_len = algo->pad_len - algo->checksum_len; + pad_len = key_len - algo->checksum_len; /* Check pkcs1.5 padding bytes. */ - if (memcmp(buf, padding, pad_len)) { + ret = rsa_verify_padding(buf, pad_len, algo); + if (ret) { debug("In RSAVerify(): Padding check failed!\n"); return -EINVAL; } @@ -149,7 +183,8 @@ static int rsa_verify_with_keynode(struct image_sign_info *info, return -EFAULT; } - ret = rsa_verify_key(&prop, sig, sig_len, hash, info->algo->checksum); + ret = rsa_verify_key(&prop, sig, sig_len, hash, + info->crypto->key_len, info->checksum); return ret; } @@ -160,7 +195,7 @@ int rsa_verify(struct image_sign_info *info, { const void *blob = info->fdt_blob; /* Reserve memory for maximum checksum-length */ - uint8_t hash[info->algo->checksum->pad_len]; + uint8_t hash[info->crypto->key_len]; int ndepth, noffset; int sig_node, node; char name[100]; @@ -170,10 +205,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 > - info->algo->checksum->pad_len) { + if (info->checksum->checksum_len > + info->crypto->key_len) { debug("%s: invlaid checksum-algorithm %s for %s\n", - __func__, info->algo->checksum->name, info->algo->name); + __func__, info->checksum->name, info->crypto->name); return -EINVAL; } @@ -184,7 +219,7 @@ int rsa_verify(struct image_sign_info *info, } /* Calculate checksum with checksum-algorithm */ - ret = info->algo->checksum->calculate(info->algo->checksum->name, + ret = info->checksum->calculate(info->checksum->name, region, region_count, hash); if (ret < 0) { debug("%s: Error in checksum calculation\n", __func__); |