summaryrefslogtreecommitdiffstats
path: root/crypto/testmgr.c
diff options
context:
space:
mode:
authorVitaly Chikunov <vt@altlinux.org>2019-04-11 11:51:15 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2019-04-18 10:15:02 -0400
commitc7381b01287240abe942a081729203e26782d981 (patch)
treef70bd59c5b8b110b9116d1660d5fe03033ed3596 /crypto/testmgr.c
parent3ecc97259934489e7e03cbeb1d70f6a23cccb3ae (diff)
crypto: akcipher - new verify API for public key algorithms
Previous akcipher .verify() just `decrypts' (using RSA encrypt which is using public key) signature to uncover message hash, which was then compared in upper level public_key_verify_signature() with the expected hash value, which itself was never passed into verify(). This approach was incompatible with EC-DSA family of algorithms, because, to verify a signature EC-DSA algorithm also needs a hash value as input; then it's used (together with a signature divided into halves `r||s') to produce a witness value, which is then compared with `r' to determine if the signature is correct. Thus, for EC-DSA, nor requirements of .verify() itself, nor its output expectations in public_key_verify_signature() wasn't sufficient. Make improved .verify() call which gets hash value as input and produce complete signature check without any output besides status. Now for the top level verification only crypto_akcipher_verify() needs to be called and its return value inspected. Make sure that `digest' is in kmalloc'd memory (in place of `output`) in {public,tpm}_key_verify_signature() as insisted by Herbert Xu, and will be changed in the following commit. Cc: David Howells <dhowells@redhat.com> Cc: keyrings@vger.kernel.org Signed-off-by: Vitaly Chikunov <vt@altlinux.org> Reviewed-by: Denis Kenzior <denkenz@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r--crypto/testmgr.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 0f6bfb6ce6a4..21b27996508a 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -2595,7 +2595,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
2595 struct crypto_wait wait; 2595 struct crypto_wait wait;
2596 unsigned int out_len_max, out_len = 0; 2596 unsigned int out_len_max, out_len = 0;
2597 int err = -ENOMEM; 2597 int err = -ENOMEM;
2598 struct scatterlist src, dst, src_tab[2]; 2598 struct scatterlist src, dst, src_tab[3];
2599 const char *m, *c; 2599 const char *m, *c;
2600 unsigned int m_size, c_size; 2600 unsigned int m_size, c_size;
2601 const char *op; 2601 const char *op;
@@ -2618,13 +2618,12 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
2618 if (err) 2618 if (err)
2619 goto free_req; 2619 goto free_req;
2620 2620
2621 err = -ENOMEM;
2622 out_len_max = crypto_akcipher_maxsize(tfm);
2623
2624 /* 2621 /*
2625 * First run test which do not require a private key, such as 2622 * First run test which do not require a private key, such as
2626 * encrypt or verify. 2623 * encrypt or verify.
2627 */ 2624 */
2625 err = -ENOMEM;
2626 out_len_max = crypto_akcipher_maxsize(tfm);
2628 outbuf_enc = kzalloc(out_len_max, GFP_KERNEL); 2627 outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
2629 if (!outbuf_enc) 2628 if (!outbuf_enc)
2630 goto free_req; 2629 goto free_req;
@@ -2650,12 +2649,20 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
2650 goto free_all; 2649 goto free_all;
2651 memcpy(xbuf[0], m, m_size); 2650 memcpy(xbuf[0], m, m_size);
2652 2651
2653 sg_init_table(src_tab, 2); 2652 sg_init_table(src_tab, 3);
2654 sg_set_buf(&src_tab[0], xbuf[0], 8); 2653 sg_set_buf(&src_tab[0], xbuf[0], 8);
2655 sg_set_buf(&src_tab[1], xbuf[0] + 8, m_size - 8); 2654 sg_set_buf(&src_tab[1], xbuf[0] + 8, m_size - 8);
2656 sg_init_one(&dst, outbuf_enc, out_len_max); 2655 if (vecs->siggen_sigver_test) {
2657 akcipher_request_set_crypt(req, src_tab, &dst, m_size, 2656 if (WARN_ON(c_size > PAGE_SIZE))
2658 out_len_max); 2657 goto free_all;
2658 memcpy(xbuf[1], c, c_size);
2659 sg_set_buf(&src_tab[2], xbuf[1], c_size);
2660 akcipher_request_set_crypt(req, src_tab, NULL, m_size, c_size);
2661 } else {
2662 sg_init_one(&dst, outbuf_enc, out_len_max);
2663 akcipher_request_set_crypt(req, src_tab, &dst, m_size,
2664 out_len_max);
2665 }
2659 akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 2666 akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
2660 crypto_req_done, &wait); 2667 crypto_req_done, &wait);
2661 2668
@@ -2668,18 +2675,21 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
2668 pr_err("alg: akcipher: %s test failed. err %d\n", op, err); 2675 pr_err("alg: akcipher: %s test failed. err %d\n", op, err);
2669 goto free_all; 2676 goto free_all;
2670 } 2677 }
2671 if (req->dst_len != c_size) { 2678 if (!vecs->siggen_sigver_test) {
2672 pr_err("alg: akcipher: %s test failed. Invalid output len\n", 2679 if (req->dst_len != c_size) {
2673 op); 2680 pr_err("alg: akcipher: %s test failed. Invalid output len\n",
2674 err = -EINVAL; 2681 op);
2675 goto free_all; 2682 err = -EINVAL;
2676 } 2683 goto free_all;
2677 /* verify that encrypted message is equal to expected */ 2684 }
2678 if (memcmp(c, outbuf_enc, c_size)) { 2685 /* verify that encrypted message is equal to expected */
2679 pr_err("alg: akcipher: %s test failed. Invalid output\n", op); 2686 if (memcmp(c, outbuf_enc, c_size) != 0) {
2680 hexdump(outbuf_enc, c_size); 2687 pr_err("alg: akcipher: %s test failed. Invalid output\n",
2681 err = -EINVAL; 2688 op);
2682 goto free_all; 2689 hexdump(outbuf_enc, c_size);
2690 err = -EINVAL;
2691 goto free_all;
2692 }
2683 } 2693 }
2684 2694
2685 /* 2695 /*