diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-05 12:16:10 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-05 12:16:10 -0500 |
commit | ef3263e35e26eb1061260131c4d6d579eea21f85 (patch) | |
tree | 640cf71ae612ea28b5dd91a2a9d6a005f50a7345 | |
parent | 3e5de27e940d00d8d504dfb96625fb654f641509 (diff) | |
parent | 57891633eeef60e732e045731cf20e50ee80acb4 (diff) |
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu:
"This fixes the following issues:
- Intermittent build failure in RSA
- Memory corruption in chelsio crypto driver
- Regression in DRBG due to vmalloced stack"
* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
crypto: rsa - Add Makefile dependencies to fix parallel builds
crypto: chcr - Fix memory corruption
crypto: drbg - prevent invalid SG mappings
-rw-r--r-- | crypto/Makefile | 1 | ||||
-rw-r--r-- | crypto/drbg.c | 29 | ||||
-rw-r--r-- | drivers/crypto/chelsio/chcr_algo.h | 3 | ||||
-rw-r--r-- | include/crypto/drbg.h | 2 |
4 files changed, 29 insertions, 6 deletions
diff --git a/crypto/Makefile b/crypto/Makefile index 99cc64ac70ef..bd6a029094e6 100644 --- a/crypto/Makefile +++ b/crypto/Makefile | |||
@@ -40,6 +40,7 @@ obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o | |||
40 | 40 | ||
41 | $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h | 41 | $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h |
42 | $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h | 42 | $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h |
43 | $(obj)/rsa_helper.o: $(obj)/rsapubkey-asn1.h $(obj)/rsaprivkey-asn1.h | ||
43 | clean-files += rsapubkey-asn1.c rsapubkey-asn1.h | 44 | clean-files += rsapubkey-asn1.c rsapubkey-asn1.h |
44 | clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h | 45 | clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h |
45 | 46 | ||
diff --git a/crypto/drbg.c b/crypto/drbg.c index fb33f7d3b052..053035b5c8f8 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 */ |
267 | static int drbg_ctr_bcc(struct drbg_state *drbg, | 268 | static 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,14 +1775,19 @@ 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 | } | 1785 | } |
1786 | ret = 0; | ||
1770 | 1787 | ||
1771 | return 0; | 1788 | out: |
1789 | memzero_explicit(drbg->outscratchpad, DRBG_OUTSCRATCHLEN); | ||
1790 | return ret; | ||
1772 | } | 1791 | } |
1773 | #endif /* CONFIG_CRYPTO_DRBG_CTR */ | 1792 | #endif /* CONFIG_CRYPTO_DRBG_CTR */ |
1774 | 1793 | ||
diff --git a/drivers/crypto/chelsio/chcr_algo.h b/drivers/crypto/chelsio/chcr_algo.h index ec64fbcdeb49..199b0bb69b89 100644 --- a/drivers/crypto/chelsio/chcr_algo.h +++ b/drivers/crypto/chelsio/chcr_algo.h | |||
@@ -422,7 +422,7 @@ static inline void get_aes_decrypt_key(unsigned char *dec_key, | |||
422 | { | 422 | { |
423 | u32 temp; | 423 | u32 temp; |
424 | u32 w_ring[MAX_NK]; | 424 | u32 w_ring[MAX_NK]; |
425 | int i, j, k = 0; | 425 | int i, j, k; |
426 | u8 nr, nk; | 426 | u8 nr, nk; |
427 | 427 | ||
428 | switch (keylength) { | 428 | switch (keylength) { |
@@ -460,6 +460,7 @@ static inline void get_aes_decrypt_key(unsigned char *dec_key, | |||
460 | temp = w_ring[i % nk]; | 460 | temp = w_ring[i % nk]; |
461 | i++; | 461 | i++; |
462 | } | 462 | } |
463 | i--; | ||
463 | for (k = 0, j = i % nk; k < nk; k++) { | 464 | for (k = 0, j = i % nk; k < nk; k++) { |
464 | *((u32 *)dec_key + k) = htonl(w_ring[j]); | 465 | *((u32 *)dec_key + k) = htonl(w_ring[j]); |
465 | j--; | 466 | j--; |
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h index 61580b19f9f6..22f884c97387 100644 --- a/include/crypto/drbg.h +++ b/include/crypto/drbg.h | |||
@@ -124,6 +124,8 @@ struct drbg_state { | |||
124 | struct skcipher_request *ctr_req; /* CTR mode request handle */ | 124 | struct skcipher_request *ctr_req; /* CTR mode request handle */ |
125 | __u8 *ctr_null_value_buf; /* CTR mode unaligned buffer */ | 125 | __u8 *ctr_null_value_buf; /* CTR mode unaligned buffer */ |
126 | __u8 *ctr_null_value; /* CTR mode aligned zero buf */ | 126 | __u8 *ctr_null_value; /* CTR mode aligned zero buf */ |
127 | __u8 *outscratchpadbuf; /* CTR mode output scratchpad */ | ||
128 | __u8 *outscratchpad; /* CTR mode aligned outbuf */ | ||
127 | struct completion ctr_completion; /* CTR mode async handler */ | 129 | struct completion ctr_completion; /* CTR mode async handler */ |
128 | int ctr_async_err; /* CTR mode async error */ | 130 | int ctr_async_err; /* CTR mode async error */ |
129 | 131 | ||