summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPhilippe Reynes <philippe.reynes@softathome.com>2018-11-14 13:51:00 +0100
committerTom Rini <trini@konsulko.com>2018-12-03 10:44:10 -0500
commit20031567e12bb312bff95b70767f6275e20f0346 (patch)
tree00c9c34581da071f3a87ee01c27370cc524cf223 /lib
parent3b5d6979fcb80ffae3b140be6edc04cbde1a0b72 (diff)
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 <philippe.reynes@softathome.com> Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/rsa/rsa-sign.c15
-rw-r--r--lib/rsa/rsa-verify.c57
2 files changed, 49 insertions, 23 deletions
diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index 78e348eeea..6aa0e2ab5d 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 bc83354378..279a9ba456 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;
}