From 20031567e12bb312bff95b70767f6275e20f0346 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Wed, 14 Nov 2018 13:51:00 +0100 Subject: rsa: add a structure for the padding The rsa signature use a padding algorithm. By default, we use the padding pkcs-1.5. In order to add some new padding algorithm, we add a padding framework to manage several padding algorithm. The choice of the padding is done in the file .its. Signed-off-by: Philippe Reynes Reviewed-by: Simon Glass --- lib/rsa/rsa-sign.c | 15 +++++++++++--- lib/rsa/rsa-verify.c | 57 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 49 insertions(+), 23 deletions(-) (limited to 'lib/rsa') diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c index 78e348e..6aa0e2a 100644 --- a/lib/rsa/rsa-sign.c +++ b/lib/rsa/rsa-sign.c @@ -387,11 +387,13 @@ static void rsa_engine_remove(ENGINE *e) } } -static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo, +static int rsa_sign_with_key(RSA *rsa, struct padding_algo *padding_algo, + struct checksum_algo *checksum_algo, const struct image_region region[], int region_count, uint8_t **sigp, uint *sig_size) { EVP_PKEY *key; + EVP_PKEY_CTX *ckey; EVP_MD_CTX *context; int ret = 0; size_t size; @@ -422,7 +424,14 @@ static int rsa_sign_with_key(RSA *rsa, struct checksum_algo *checksum_algo, goto err_create; } EVP_MD_CTX_init(context); - if (EVP_DigestSignInit(context, NULL, + + ckey = EVP_PKEY_CTX_new(key, NULL); + if (!ckey) { + ret = rsa_err("EVP key context creation failed"); + goto err_create; + } + + if (EVP_DigestSignInit(context, &ckey, checksum_algo->calculate_sign(), NULL, key) <= 0) { ret = rsa_err("Signer setup failed"); @@ -488,7 +497,7 @@ int rsa_sign(struct image_sign_info *info, ret = rsa_get_priv_key(info->keydir, info->keyname, e, &rsa); if (ret) goto err_priv; - ret = rsa_sign_with_key(rsa, info->checksum, region, + ret = rsa_sign_with_key(rsa, info->padding, info->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 bc83354..279a9ba 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -57,31 +57,57 @@ static int rsa_verify_padding(const uint8_t *msg, const int pad_len, return ret; } +int padding_pkcs_15_verify(struct image_sign_info *info, + uint8_t *msg, int msg_len, + const uint8_t *hash, int hash_len) +{ + struct checksum_algo *checksum = info->checksum; + int ret, pad_len = msg_len - checksum->checksum_len; + + /* Check pkcs1.5 padding bytes. */ + ret = rsa_verify_padding(msg, pad_len, checksum); + if (ret) { + debug("In RSAVerify(): Padding check failed!\n"); + return -EINVAL; + } + + /* Check hash. */ + if (memcmp((uint8_t *)msg + pad_len, hash, msg_len - pad_len)) { + debug("In RSAVerify(): Hash check failed!\n"); + return -EACCES; + } + + return 0; +} + /** * rsa_verify_key() - Verify a signature against some data using RSA Key * * Verify a RSA PKCS1.5 signature against an expected hash using * the RSA Key properties in prop structure. * + * @info: Specifies key and FIT information * @prop: Specifies key * @sig: Signature * @sig_len: Number of bytes in signature * @hash: Pointer to the expected hash * @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, +static int rsa_verify_key(struct image_sign_info *info, + struct key_prop *prop, const uint8_t *sig, const uint32_t sig_len, const uint8_t *hash, - const uint32_t key_len, struct checksum_algo *algo) + const uint32_t key_len) { - int pad_len; int ret; #if !defined(USE_HOSTCC) struct udevice *mod_exp_dev; #endif + struct checksum_algo *checksum = info->checksum; + struct padding_algo *padding = info->padding; + int hash_len = checksum->checksum_len; - if (!prop || !sig || !hash || !algo) + if (!prop || !sig || !hash || !checksum) return -EIO; if (sig_len != (prop->num_bits / 8)) { @@ -89,7 +115,7 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig, return -EINVAL; } - debug("Checksum algorithm: %s", algo->name); + debug("Checksum algorithm: %s", checksum->name); /* Sanity check for stack size */ if (sig_len > RSA_MAX_SIG_BITS / 8) { @@ -116,19 +142,10 @@ static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig, return ret; } - pad_len = key_len - algo->checksum_len; - - /* Check pkcs1.5 padding bytes. */ - ret = rsa_verify_padding(buf, pad_len, algo); + ret = padding->verify(info, buf, key_len, hash, hash_len); if (ret) { - debug("In RSAVerify(): Padding check failed!\n"); - return -EINVAL; - } - - /* Check hash. */ - if (memcmp((uint8_t *)buf + pad_len, hash, sig_len - pad_len)) { - debug("In RSAVerify(): Hash check failed!\n"); - return -EACCES; + debug("In RSAVerify(): padding check failed!\n"); + return ret; } return 0; @@ -182,8 +199,8 @@ static int rsa_verify_with_keynode(struct image_sign_info *info, return -EFAULT; } - ret = rsa_verify_key(&prop, sig, sig_len, hash, - info->crypto->key_len, info->checksum); + ret = rsa_verify_key(info, &prop, sig, sig_len, hash, + info->crypto->key_len); return ret; } -- cgit v1.1