From b3a8c8a5ebb5b4c3eb7b104364e63c453cc85f14 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Tue, 9 Oct 2018 17:47:53 +0100 Subject: crypto: rsa-pkcs1pad: Allow hash to be optional [ver #2] The original pkcs1pad implementation allowed to pad/unpad raw RSA output. However, this has been taken out in commit: commit c0d20d22e0ad ("crypto: rsa-pkcs1pad - Require hash to be present") This patch restored this ability as it is needed by the asymmetric key implementation. Signed-off-by: Denis Kenzior Signed-off-by: David Howells Tested-by: Marcel Holtmann Reviewed-by: Marcel Holtmann Signed-off-by: James Morris --- crypto/rsa-pkcs1pad.c | 59 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 18 deletions(-) (limited to 'crypto') diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c index 812476e46821..cfc04e15fd97 100644 --- a/crypto/rsa-pkcs1pad.c +++ b/crypto/rsa-pkcs1pad.c @@ -392,7 +392,8 @@ static int pkcs1pad_sign(struct akcipher_request *req) if (!ctx->key_size) return -EINVAL; - digest_size = digest_info->size; + if (digest_info) + digest_size = digest_info->size; if (req->src_len + digest_size > ctx->key_size - 11) return -EOVERFLOW; @@ -412,8 +413,9 @@ static int pkcs1pad_sign(struct akcipher_request *req) memset(req_ctx->in_buf + 1, 0xff, ps_end - 1); req_ctx->in_buf[ps_end] = 0x00; - memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data, - digest_info->size); + if (digest_info) + memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data, + digest_info->size); pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf, ctx->key_size - 1 - req->src_len, req->src); @@ -475,10 +477,13 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err) goto done; pos++; - if (crypto_memneq(out_buf + pos, digest_info->data, digest_info->size)) - goto done; + if (digest_info) { + if (crypto_memneq(out_buf + pos, digest_info->data, + digest_info->size)) + goto done; - pos += digest_info->size; + pos += digest_info->size; + } err = 0; @@ -608,11 +613,14 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) hash_name = crypto_attr_alg_name(tb[2]); if (IS_ERR(hash_name)) - return PTR_ERR(hash_name); + hash_name = NULL; - digest_info = rsa_lookup_asn1(hash_name); - if (!digest_info) - return -EINVAL; + if (hash_name) { + digest_info = rsa_lookup_asn1(hash_name); + if (!digest_info) + return -EINVAL; + } else + digest_info = NULL; inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); if (!inst) @@ -632,14 +640,29 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) err = -ENAMETOOLONG; - if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, - "pkcs1pad(%s,%s)", rsa_alg->base.cra_name, hash_name) >= - CRYPTO_MAX_ALG_NAME || - snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, - "pkcs1pad(%s,%s)", - rsa_alg->base.cra_driver_name, hash_name) >= - CRYPTO_MAX_ALG_NAME) - goto out_drop_alg; + if (!hash_name) { + if (snprintf(inst->alg.base.cra_name, + CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)", + rsa_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME) + goto out_drop_alg; + + if (snprintf(inst->alg.base.cra_driver_name, + CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)", + rsa_alg->base.cra_driver_name) >= + CRYPTO_MAX_ALG_NAME) + goto out_drop_alg; + } else { + if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, + "pkcs1pad(%s,%s)", rsa_alg->base.cra_name, + hash_name) >= CRYPTO_MAX_ALG_NAME) + goto out_drop_alg; + + if (snprintf(inst->alg.base.cra_driver_name, + CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s,%s)", + rsa_alg->base.cra_driver_name, + hash_name) >= CRYPTO_MAX_ALG_NAME) + goto out_drop_alg; + } inst->alg.base.cra_flags = rsa_alg->base.cra_flags & CRYPTO_ALG_ASYNC; inst->alg.base.cra_priority = rsa_alg->base.cra_priority; -- cgit