diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2016-06-29 07:32:23 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2016-07-01 11:45:19 -0400 |
commit | c0d20d22e0ad20718702ae98cf8b5c200271d6df (patch) | |
tree | f0952e208a147dca7e9e04b2815e24845f194e3a /crypto/rsa-pkcs1pad.c | |
parent | 127827b9c295db35fa7e49d00ac5d14faeda9461 (diff) |
crypto: rsa-pkcs1pad - Require hash to be present
The only user of rsa-pkcs1pad always uses the hash so there is
no reason to support the case of not having a hash.
This patch also changes the digest info lookup so that it is
only done once during template instantiation rather than on each
operation.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/rsa-pkcs1pad.c')
-rw-r--r-- | crypto/rsa-pkcs1pad.c | 83 |
1 files changed, 30 insertions, 53 deletions
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c index ead8dc0d084e..5c1c78e21f84 100644 --- a/crypto/rsa-pkcs1pad.c +++ b/crypto/rsa-pkcs1pad.c | |||
@@ -92,13 +92,12 @@ static const struct rsa_asn1_template *rsa_lookup_asn1(const char *name) | |||
92 | 92 | ||
93 | struct pkcs1pad_ctx { | 93 | struct pkcs1pad_ctx { |
94 | struct crypto_akcipher *child; | 94 | struct crypto_akcipher *child; |
95 | const char *hash_name; | ||
96 | unsigned int key_size; | 95 | unsigned int key_size; |
97 | }; | 96 | }; |
98 | 97 | ||
99 | struct pkcs1pad_inst_ctx { | 98 | struct pkcs1pad_inst_ctx { |
100 | struct crypto_akcipher_spawn spawn; | 99 | struct crypto_akcipher_spawn spawn; |
101 | const char *hash_name; | 100 | const struct rsa_asn1_template *digest_info; |
102 | }; | 101 | }; |
103 | 102 | ||
104 | struct pkcs1pad_request { | 103 | struct pkcs1pad_request { |
@@ -416,20 +415,16 @@ static int pkcs1pad_sign(struct akcipher_request *req) | |||
416 | struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); | 415 | struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); |
417 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); | 416 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); |
418 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); | 417 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); |
419 | const struct rsa_asn1_template *digest_info = NULL; | 418 | struct akcipher_instance *inst = akcipher_alg_instance(tfm); |
419 | struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst); | ||
420 | const struct rsa_asn1_template *digest_info = ictx->digest_info; | ||
420 | int err; | 421 | int err; |
421 | unsigned int ps_end, digest_size = 0; | 422 | unsigned int ps_end, digest_size = 0; |
422 | 423 | ||
423 | if (!ctx->key_size) | 424 | if (!ctx->key_size) |
424 | return -EINVAL; | 425 | return -EINVAL; |
425 | 426 | ||
426 | if (ctx->hash_name) { | 427 | digest_size = digest_info->size; |
427 | digest_info = rsa_lookup_asn1(ctx->hash_name); | ||
428 | if (!digest_info) | ||
429 | return -EINVAL; | ||
430 | |||
431 | digest_size = digest_info->size; | ||
432 | } | ||
433 | 428 | ||
434 | if (req->src_len + digest_size > ctx->key_size - 11) | 429 | if (req->src_len + digest_size > ctx->key_size - 11) |
435 | return -EOVERFLOW; | 430 | return -EOVERFLOW; |
@@ -462,10 +457,8 @@ static int pkcs1pad_sign(struct akcipher_request *req) | |||
462 | memset(req_ctx->in_buf + 1, 0xff, ps_end - 1); | 457 | memset(req_ctx->in_buf + 1, 0xff, ps_end - 1); |
463 | req_ctx->in_buf[ps_end] = 0x00; | 458 | req_ctx->in_buf[ps_end] = 0x00; |
464 | 459 | ||
465 | if (digest_info) { | 460 | memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data, |
466 | memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data, | 461 | digest_info->size); |
467 | digest_info->size); | ||
468 | } | ||
469 | 462 | ||
470 | pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf, | 463 | pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf, |
471 | ctx->key_size - 1 - req->src_len, req->src); | 464 | ctx->key_size - 1 - req->src_len, req->src); |
@@ -499,7 +492,9 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err) | |||
499 | struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); | 492 | struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); |
500 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); | 493 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); |
501 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); | 494 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); |
502 | const struct rsa_asn1_template *digest_info; | 495 | struct akcipher_instance *inst = akcipher_alg_instance(tfm); |
496 | struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst); | ||
497 | const struct rsa_asn1_template *digest_info = ictx->digest_info; | ||
503 | unsigned int pos; | 498 | unsigned int pos; |
504 | 499 | ||
505 | if (err == -EOVERFLOW) | 500 | if (err == -EOVERFLOW) |
@@ -527,17 +522,11 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err) | |||
527 | goto done; | 522 | goto done; |
528 | pos++; | 523 | pos++; |
529 | 524 | ||
530 | if (ctx->hash_name) { | 525 | if (memcmp(req_ctx->out_buf + pos, digest_info->data, |
531 | digest_info = rsa_lookup_asn1(ctx->hash_name); | 526 | digest_info->size)) |
532 | if (!digest_info) | 527 | goto done; |
533 | goto done; | ||
534 | 528 | ||
535 | if (memcmp(req_ctx->out_buf + pos, digest_info->data, | 529 | pos += digest_info->size; |
536 | digest_info->size)) | ||
537 | goto done; | ||
538 | |||
539 | pos += digest_info->size; | ||
540 | } | ||
541 | 530 | ||
542 | err = 0; | 531 | err = 0; |
543 | 532 | ||
@@ -626,12 +615,11 @@ static int pkcs1pad_init_tfm(struct crypto_akcipher *tfm) | |||
626 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); | 615 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); |
627 | struct crypto_akcipher *child_tfm; | 616 | struct crypto_akcipher *child_tfm; |
628 | 617 | ||
629 | child_tfm = crypto_spawn_akcipher(akcipher_instance_ctx(inst)); | 618 | child_tfm = crypto_spawn_akcipher(&ictx->spawn); |
630 | if (IS_ERR(child_tfm)) | 619 | if (IS_ERR(child_tfm)) |
631 | return PTR_ERR(child_tfm); | 620 | return PTR_ERR(child_tfm); |
632 | 621 | ||
633 | ctx->child = child_tfm; | 622 | ctx->child = child_tfm; |
634 | ctx->hash_name = ictx->hash_name; | ||
635 | return 0; | 623 | return 0; |
636 | } | 624 | } |
637 | 625 | ||
@@ -648,12 +636,12 @@ static void pkcs1pad_free(struct akcipher_instance *inst) | |||
648 | struct crypto_akcipher_spawn *spawn = &ctx->spawn; | 636 | struct crypto_akcipher_spawn *spawn = &ctx->spawn; |
649 | 637 | ||
650 | crypto_drop_akcipher(spawn); | 638 | crypto_drop_akcipher(spawn); |
651 | kfree(ctx->hash_name); | ||
652 | kfree(inst); | 639 | kfree(inst); |
653 | } | 640 | } |
654 | 641 | ||
655 | static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) | 642 | static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) |
656 | { | 643 | { |
644 | const struct rsa_asn1_template *digest_info; | ||
657 | struct crypto_attr_type *algt; | 645 | struct crypto_attr_type *algt; |
658 | struct akcipher_instance *inst; | 646 | struct akcipher_instance *inst; |
659 | struct pkcs1pad_inst_ctx *ctx; | 647 | struct pkcs1pad_inst_ctx *ctx; |
@@ -676,7 +664,11 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) | |||
676 | 664 | ||
677 | hash_name = crypto_attr_alg_name(tb[2]); | 665 | hash_name = crypto_attr_alg_name(tb[2]); |
678 | if (IS_ERR(hash_name)) | 666 | if (IS_ERR(hash_name)) |
679 | hash_name = NULL; | 667 | return PTR_ERR(hash_name); |
668 | |||
669 | digest_info = rsa_lookup_asn1(hash_name); | ||
670 | if (!digest_info) | ||
671 | return -EINVAL; | ||
680 | 672 | ||
681 | inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); | 673 | inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); |
682 | if (!inst) | 674 | if (!inst) |
@@ -684,7 +676,7 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) | |||
684 | 676 | ||
685 | ctx = akcipher_instance_ctx(inst); | 677 | ctx = akcipher_instance_ctx(inst); |
686 | spawn = &ctx->spawn; | 678 | spawn = &ctx->spawn; |
687 | ctx->hash_name = hash_name ? kstrdup(hash_name, GFP_KERNEL) : NULL; | 679 | ctx->digest_info = digest_info; |
688 | 680 | ||
689 | crypto_set_spawn(&spawn->base, akcipher_crypto_instance(inst)); | 681 | crypto_set_spawn(&spawn->base, akcipher_crypto_instance(inst)); |
690 | err = crypto_grab_akcipher(spawn, rsa_alg_name, 0, | 682 | err = crypto_grab_akcipher(spawn, rsa_alg_name, 0, |
@@ -696,27 +688,14 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) | |||
696 | 688 | ||
697 | err = -ENAMETOOLONG; | 689 | err = -ENAMETOOLONG; |
698 | 690 | ||
699 | if (!hash_name) { | 691 | if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, |
700 | if (snprintf(inst->alg.base.cra_name, | 692 | "pkcs1pad(%s,%s)", rsa_alg->base.cra_name, hash_name) >= |
701 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)", | 693 | CRYPTO_MAX_ALG_NAME || |
702 | rsa_alg->base.cra_name) >= | 694 | snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, |
703 | CRYPTO_MAX_ALG_NAME || | 695 | "pkcs1pad(%s,%s)", |
704 | snprintf(inst->alg.base.cra_driver_name, | 696 | rsa_alg->base.cra_driver_name, hash_name) >= |
705 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)", | 697 | CRYPTO_MAX_ALG_NAME) |
706 | rsa_alg->base.cra_driver_name) >= | ||
707 | CRYPTO_MAX_ALG_NAME) | ||
708 | goto out_drop_alg; | 698 | goto out_drop_alg; |
709 | } else { | ||
710 | if (snprintf(inst->alg.base.cra_name, | ||
711 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s,%s)", | ||
712 | rsa_alg->base.cra_name, hash_name) >= | ||
713 | CRYPTO_MAX_ALG_NAME || | ||
714 | snprintf(inst->alg.base.cra_driver_name, | ||
715 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s,%s)", | ||
716 | rsa_alg->base.cra_driver_name, hash_name) >= | ||
717 | CRYPTO_MAX_ALG_NAME) | ||
718 | goto out_free_hash; | ||
719 | } | ||
720 | 699 | ||
721 | inst->alg.base.cra_flags = rsa_alg->base.cra_flags & CRYPTO_ALG_ASYNC; | 700 | inst->alg.base.cra_flags = rsa_alg->base.cra_flags & CRYPTO_ALG_ASYNC; |
722 | inst->alg.base.cra_priority = rsa_alg->base.cra_priority; | 701 | inst->alg.base.cra_priority = rsa_alg->base.cra_priority; |
@@ -738,12 +717,10 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) | |||
738 | 717 | ||
739 | err = akcipher_register_instance(tmpl, inst); | 718 | err = akcipher_register_instance(tmpl, inst); |
740 | if (err) | 719 | if (err) |
741 | goto out_free_hash; | 720 | goto out_drop_alg; |
742 | 721 | ||
743 | return 0; | 722 | return 0; |
744 | 723 | ||
745 | out_free_hash: | ||
746 | kfree(ctx->hash_name); | ||
747 | out_drop_alg: | 724 | out_drop_alg: |
748 | crypto_drop_akcipher(spawn); | 725 | crypto_drop_akcipher(spawn); |
749 | out_free_inst: | 726 | out_free_inst: |