diff options
author | Denis Kenzior <denkenz@gmail.com> | 2018-10-09 12:47:53 -0400 |
---|---|---|
committer | James Morris <james.morris@microsoft.com> | 2018-10-26 04:30:46 -0400 |
commit | b3a8c8a5ebb5b4c3eb7b104364e63c453cc85f14 (patch) | |
tree | 2504542402fb696882faa4ef09cc56a9f81be9dc /crypto | |
parent | 3c58b2362ba828ee2970c66c6a6fd7b04fde4413 (diff) |
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 <denkenz@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Marcel Holtmann <marcel@holtmann.org>
Reviewed-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: James Morris <james.morris@microsoft.com>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/rsa-pkcs1pad.c | 59 |
1 files changed, 41 insertions, 18 deletions
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) | |||
392 | if (!ctx->key_size) | 392 | if (!ctx->key_size) |
393 | return -EINVAL; | 393 | return -EINVAL; |
394 | 394 | ||
395 | digest_size = digest_info->size; | 395 | if (digest_info) |
396 | digest_size = digest_info->size; | ||
396 | 397 | ||
397 | if (req->src_len + digest_size > ctx->key_size - 11) | 398 | if (req->src_len + digest_size > ctx->key_size - 11) |
398 | return -EOVERFLOW; | 399 | return -EOVERFLOW; |
@@ -412,8 +413,9 @@ static int pkcs1pad_sign(struct akcipher_request *req) | |||
412 | memset(req_ctx->in_buf + 1, 0xff, ps_end - 1); | 413 | memset(req_ctx->in_buf + 1, 0xff, ps_end - 1); |
413 | req_ctx->in_buf[ps_end] = 0x00; | 414 | req_ctx->in_buf[ps_end] = 0x00; |
414 | 415 | ||
415 | memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data, | 416 | if (digest_info) |
416 | digest_info->size); | 417 | memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data, |
418 | digest_info->size); | ||
417 | 419 | ||
418 | pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf, | 420 | pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf, |
419 | ctx->key_size - 1 - req->src_len, req->src); | 421 | ctx->key_size - 1 - req->src_len, req->src); |
@@ -475,10 +477,13 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err) | |||
475 | goto done; | 477 | goto done; |
476 | pos++; | 478 | pos++; |
477 | 479 | ||
478 | if (crypto_memneq(out_buf + pos, digest_info->data, digest_info->size)) | 480 | if (digest_info) { |
479 | goto done; | 481 | if (crypto_memneq(out_buf + pos, digest_info->data, |
482 | digest_info->size)) | ||
483 | goto done; | ||
480 | 484 | ||
481 | pos += digest_info->size; | 485 | pos += digest_info->size; |
486 | } | ||
482 | 487 | ||
483 | err = 0; | 488 | err = 0; |
484 | 489 | ||
@@ -608,11 +613,14 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) | |||
608 | 613 | ||
609 | hash_name = crypto_attr_alg_name(tb[2]); | 614 | hash_name = crypto_attr_alg_name(tb[2]); |
610 | if (IS_ERR(hash_name)) | 615 | if (IS_ERR(hash_name)) |
611 | return PTR_ERR(hash_name); | 616 | hash_name = NULL; |
612 | 617 | ||
613 | digest_info = rsa_lookup_asn1(hash_name); | 618 | if (hash_name) { |
614 | if (!digest_info) | 619 | digest_info = rsa_lookup_asn1(hash_name); |
615 | return -EINVAL; | 620 | if (!digest_info) |
621 | return -EINVAL; | ||
622 | } else | ||
623 | digest_info = NULL; | ||
616 | 624 | ||
617 | inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); | 625 | inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); |
618 | if (!inst) | 626 | if (!inst) |
@@ -632,14 +640,29 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) | |||
632 | 640 | ||
633 | err = -ENAMETOOLONG; | 641 | err = -ENAMETOOLONG; |
634 | 642 | ||
635 | if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, | 643 | if (!hash_name) { |
636 | "pkcs1pad(%s,%s)", rsa_alg->base.cra_name, hash_name) >= | 644 | if (snprintf(inst->alg.base.cra_name, |
637 | CRYPTO_MAX_ALG_NAME || | 645 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)", |
638 | snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, | 646 | rsa_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME) |
639 | "pkcs1pad(%s,%s)", | 647 | goto out_drop_alg; |
640 | rsa_alg->base.cra_driver_name, hash_name) >= | 648 | |
641 | CRYPTO_MAX_ALG_NAME) | 649 | if (snprintf(inst->alg.base.cra_driver_name, |
642 | goto out_drop_alg; | 650 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)", |
651 | rsa_alg->base.cra_driver_name) >= | ||
652 | CRYPTO_MAX_ALG_NAME) | ||
653 | goto out_drop_alg; | ||
654 | } else { | ||
655 | if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, | ||
656 | "pkcs1pad(%s,%s)", rsa_alg->base.cra_name, | ||
657 | hash_name) >= CRYPTO_MAX_ALG_NAME) | ||
658 | goto out_drop_alg; | ||
659 | |||
660 | if (snprintf(inst->alg.base.cra_driver_name, | ||
661 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s,%s)", | ||
662 | rsa_alg->base.cra_driver_name, | ||
663 | hash_name) >= CRYPTO_MAX_ALG_NAME) | ||
664 | goto out_drop_alg; | ||
665 | } | ||
643 | 666 | ||
644 | inst->alg.base.cra_flags = rsa_alg->base.cra_flags & CRYPTO_ALG_ASYNC; | 667 | inst->alg.base.cra_flags = rsa_alg->base.cra_flags & CRYPTO_ALG_ASYNC; |
645 | inst->alg.base.cra_priority = rsa_alg->base.cra_priority; | 668 | inst->alg.base.cra_priority = rsa_alg->base.cra_priority; |