aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/drbg.c
diff options
context:
space:
mode:
authorGilad Ben-Yossef <gilad@benyossef.com>2017-10-18 03:00:41 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2017-11-03 10:11:19 -0400
commit85a2dea4bdbfa7565818ca094d08e838cf62da77 (patch)
tree7dc78fee7b511e9a26664cc3b25d0be9a6d35d97 /crypto/drbg.c
parent0ca2a04ac398a71e49b0b093f365d1188cc13e01 (diff)
crypto: drbg - move to generic async completion
DRBG is starting an async. crypto op and waiting for it complete. Move it over to generic code doing the same. The code now also passes CRYPTO_TFM_REQ_MAY_SLEEP flag indicating crypto request memory allocation may use GFP_KERNEL which should be perfectly fine as the code is obviously sleeping for the completion of the request any way. Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/drbg.c')
-rw-r--r--crypto/drbg.c36
1 files changed, 9 insertions, 27 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 70018397e59a..4faa2781c964 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1651,16 +1651,6 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)
1651 return 0; 1651 return 0;
1652} 1652}
1653 1653
1654static void drbg_skcipher_cb(struct crypto_async_request *req, int error)
1655{
1656 struct drbg_state *drbg = req->data;
1657
1658 if (error == -EINPROGRESS)
1659 return;
1660 drbg->ctr_async_err = error;
1661 complete(&drbg->ctr_completion);
1662}
1663
1664static int drbg_init_sym_kernel(struct drbg_state *drbg) 1654static int drbg_init_sym_kernel(struct drbg_state *drbg)
1665{ 1655{
1666 struct crypto_cipher *tfm; 1656 struct crypto_cipher *tfm;
@@ -1691,7 +1681,7 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
1691 return PTR_ERR(sk_tfm); 1681 return PTR_ERR(sk_tfm);
1692 } 1682 }
1693 drbg->ctr_handle = sk_tfm; 1683 drbg->ctr_handle = sk_tfm;
1694 init_completion(&drbg->ctr_completion); 1684 crypto_init_wait(&drbg->ctr_wait);
1695 1685
1696 req = skcipher_request_alloc(sk_tfm, GFP_KERNEL); 1686 req = skcipher_request_alloc(sk_tfm, GFP_KERNEL);
1697 if (!req) { 1687 if (!req) {
@@ -1700,8 +1690,9 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
1700 return -ENOMEM; 1690 return -ENOMEM;
1701 } 1691 }
1702 drbg->ctr_req = req; 1692 drbg->ctr_req = req;
1703 skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 1693 skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
1704 drbg_skcipher_cb, drbg); 1694 CRYPTO_TFM_REQ_MAY_SLEEP,
1695 crypto_req_done, &drbg->ctr_wait);
1705 1696
1706 alignmask = crypto_skcipher_alignmask(sk_tfm); 1697 alignmask = crypto_skcipher_alignmask(sk_tfm);
1707 drbg->ctr_null_value_buf = kzalloc(DRBG_CTR_NULL_LEN + alignmask, 1698 drbg->ctr_null_value_buf = kzalloc(DRBG_CTR_NULL_LEN + alignmask,
@@ -1762,21 +1753,12 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
1762 /* Output buffer may not be valid for SGL, use scratchpad */ 1753 /* Output buffer may not be valid for SGL, use scratchpad */
1763 skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out, 1754 skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out,
1764 cryptlen, drbg->V); 1755 cryptlen, drbg->V);
1765 ret = crypto_skcipher_encrypt(drbg->ctr_req); 1756 ret = crypto_wait_req(crypto_skcipher_encrypt(drbg->ctr_req),
1766 switch (ret) { 1757 &drbg->ctr_wait);
1767 case 0: 1758 if (ret)
1768 break;
1769 case -EINPROGRESS:
1770 case -EBUSY:
1771 wait_for_completion(&drbg->ctr_completion);
1772 if (!drbg->ctr_async_err) {
1773 reinit_completion(&drbg->ctr_completion);
1774 break;
1775 }
1776 default:
1777 goto out; 1759 goto out;
1778 } 1760
1779 init_completion(&drbg->ctr_completion); 1761 crypto_init_wait(&drbg->ctr_wait);
1780 1762
1781 memcpy(outbuf, drbg->outscratchpad, cryptlen); 1763 memcpy(outbuf, drbg->outscratchpad, cryptlen);
1782 1764