summaryrefslogtreecommitdiffstats
path: root/crypto/drbg.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2016-11-30 06:53:12 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2016-11-30 06:53:12 -0500
commit479d014de544a0916037fcf77e873f815545cd5e (patch)
tree6752a8184e2f2696c31ab141576e9902410c6c75 /crypto/drbg.c
parent585b5fa63da92b2d46d5c1735a5c46e9a1486bbe (diff)
parent57891633eeef60e732e045731cf20e50ee80acb4 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Merge the crypto tree to pull in chelsio chcr fix.
Diffstat (limited to 'crypto/drbg.c')
-rw-r--r--crypto/drbg.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 9a95b619e19a..8a4d98b4adba 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -262,6 +262,7 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
262 u8 *inbuf, u32 inbuflen, 262 u8 *inbuf, u32 inbuflen,
263 u8 *outbuf, u32 outlen); 263 u8 *outbuf, u32 outlen);
264#define DRBG_CTR_NULL_LEN 128 264#define DRBG_CTR_NULL_LEN 128
265#define DRBG_OUTSCRATCHLEN DRBG_CTR_NULL_LEN
265 266
266/* BCC function for CTR DRBG as defined in 10.4.3 */ 267/* BCC function for CTR DRBG as defined in 10.4.3 */
267static int drbg_ctr_bcc(struct drbg_state *drbg, 268static int drbg_ctr_bcc(struct drbg_state *drbg,
@@ -1644,6 +1645,9 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)
1644 kfree(drbg->ctr_null_value_buf); 1645 kfree(drbg->ctr_null_value_buf);
1645 drbg->ctr_null_value = NULL; 1646 drbg->ctr_null_value = NULL;
1646 1647
1648 kfree(drbg->outscratchpadbuf);
1649 drbg->outscratchpadbuf = NULL;
1650
1647 return 0; 1651 return 0;
1648} 1652}
1649 1653
@@ -1708,6 +1712,15 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
1708 drbg->ctr_null_value = (u8 *)PTR_ALIGN(drbg->ctr_null_value_buf, 1712 drbg->ctr_null_value = (u8 *)PTR_ALIGN(drbg->ctr_null_value_buf,
1709 alignmask + 1); 1713 alignmask + 1);
1710 1714
1715 drbg->outscratchpadbuf = kmalloc(DRBG_OUTSCRATCHLEN + alignmask,
1716 GFP_KERNEL);
1717 if (!drbg->outscratchpadbuf) {
1718 drbg_fini_sym_kernel(drbg);
1719 return -ENOMEM;
1720 }
1721 drbg->outscratchpad = (u8 *)PTR_ALIGN(drbg->outscratchpadbuf,
1722 alignmask + 1);
1723
1711 return alignmask; 1724 return alignmask;
1712} 1725}
1713 1726
@@ -1737,15 +1750,16 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
1737 u8 *outbuf, u32 outlen) 1750 u8 *outbuf, u32 outlen)
1738{ 1751{
1739 struct scatterlist sg_in; 1752 struct scatterlist sg_in;
1753 int ret;
1740 1754
1741 sg_init_one(&sg_in, inbuf, inlen); 1755 sg_init_one(&sg_in, inbuf, inlen);
1742 1756
1743 while (outlen) { 1757 while (outlen) {
1744 u32 cryptlen = min_t(u32, inlen, outlen); 1758 u32 cryptlen = min3(inlen, outlen, (u32)DRBG_OUTSCRATCHLEN);
1745 struct scatterlist sg_out; 1759 struct scatterlist sg_out;
1746 int ret;
1747 1760
1748 sg_init_one(&sg_out, outbuf, cryptlen); 1761 /* Output buffer may not be valid for SGL, use scratchpad */
1762 sg_init_one(&sg_out, drbg->outscratchpad, cryptlen);
1749 skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out, 1763 skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out,
1750 cryptlen, drbg->V); 1764 cryptlen, drbg->V);
1751 ret = crypto_skcipher_encrypt(drbg->ctr_req); 1765 ret = crypto_skcipher_encrypt(drbg->ctr_req);
@@ -1761,15 +1775,20 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
1761 break; 1775 break;
1762 } 1776 }
1763 default: 1777 default:
1764 return ret; 1778 goto out;
1765 } 1779 }
1766 init_completion(&drbg->ctr_completion); 1780 init_completion(&drbg->ctr_completion);
1767 1781
1782 memcpy(outbuf, drbg->outscratchpad, cryptlen);
1783
1768 outlen -= cryptlen; 1784 outlen -= cryptlen;
1769 outbuf += cryptlen; 1785 outbuf += cryptlen;
1770 } 1786 }
1787 ret = 0;
1771 1788
1772 return 0; 1789out:
1790 memzero_explicit(drbg->outscratchpad, DRBG_OUTSCRATCHLEN);
1791 return ret;
1773} 1792}
1774#endif /* CONFIG_CRYPTO_DRBG_CTR */ 1793#endif /* CONFIG_CRYPTO_DRBG_CTR */
1775 1794