aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-12-05 09:16:10 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-05 09:16:10 -0800
commitef3263e35e26eb1061260131c4d6d579eea21f85 (patch)
tree640cf71ae612ea28b5dd91a2a9d6a005f50a7345
parentLinux 4.9-rc8 (diff)
parentcrypto: rsa - Add Makefile dependencies to fix parallel builds (diff)
downloadwireguard-linux-ef3263e35e26eb1061260131c4d6d579eea21f85.tar.xz
wireguard-linux-ef3263e35e26eb1061260131c4d6d579eea21f85.zip
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/Makefile1
-rw-r--r--crypto/drbg.c29
-rw-r--r--drivers/crypto/chelsio/chcr_algo.h3
-rw-r--r--include/crypto/drbg.h2
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
$(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
$(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
+$(obj)/rsa_helper.o: $(obj)/rsapubkey-asn1.h $(obj)/rsaprivkey-asn1.h
clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h
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,
u8 *inbuf, u32 inbuflen,
u8 *outbuf, u32 outlen);
#define DRBG_CTR_NULL_LEN 128
+#define DRBG_OUTSCRATCHLEN DRBG_CTR_NULL_LEN
/* BCC function for CTR DRBG as defined in 10.4.3 */
static int drbg_ctr_bcc(struct drbg_state *drbg,
@@ -1644,6 +1645,9 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)
kfree(drbg->ctr_null_value_buf);
drbg->ctr_null_value = NULL;
+ kfree(drbg->outscratchpadbuf);
+ drbg->outscratchpadbuf = NULL;
+
return 0;
}
@@ -1708,6 +1712,15 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
drbg->ctr_null_value = (u8 *)PTR_ALIGN(drbg->ctr_null_value_buf,
alignmask + 1);
+ drbg->outscratchpadbuf = kmalloc(DRBG_OUTSCRATCHLEN + alignmask,
+ GFP_KERNEL);
+ if (!drbg->outscratchpadbuf) {
+ drbg_fini_sym_kernel(drbg);
+ return -ENOMEM;
+ }
+ drbg->outscratchpad = (u8 *)PTR_ALIGN(drbg->outscratchpadbuf,
+ alignmask + 1);
+
return alignmask;
}
@@ -1737,15 +1750,16 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
u8 *outbuf, u32 outlen)
{
struct scatterlist sg_in;
+ int ret;
sg_init_one(&sg_in, inbuf, inlen);
while (outlen) {
- u32 cryptlen = min_t(u32, inlen, outlen);
+ u32 cryptlen = min3(inlen, outlen, (u32)DRBG_OUTSCRATCHLEN);
struct scatterlist sg_out;
- int ret;
- sg_init_one(&sg_out, outbuf, cryptlen);
+ /* Output buffer may not be valid for SGL, use scratchpad */
+ sg_init_one(&sg_out, drbg->outscratchpad, cryptlen);
skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out,
cryptlen, drbg->V);
ret = crypto_skcipher_encrypt(drbg->ctr_req);
@@ -1761,14 +1775,19 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
break;
}
default:
- return ret;
+ goto out;
}
init_completion(&drbg->ctr_completion);
+ memcpy(outbuf, drbg->outscratchpad, cryptlen);
+
outlen -= cryptlen;
}
+ ret = 0;
- return 0;
+out:
+ memzero_explicit(drbg->outscratchpad, DRBG_OUTSCRATCHLEN);
+ return ret;
}
#endif /* CONFIG_CRYPTO_DRBG_CTR */
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,
{
u32 temp;
u32 w_ring[MAX_NK];
- int i, j, k = 0;
+ int i, j, k;
u8 nr, nk;
switch (keylength) {
@@ -460,6 +460,7 @@ static inline void get_aes_decrypt_key(unsigned char *dec_key,
temp = w_ring[i % nk];
i++;
}
+ i--;
for (k = 0, j = i % nk; k < nk; k++) {
*((u32 *)dec_key + k) = htonl(w_ring[j]);
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 {
struct skcipher_request *ctr_req; /* CTR mode request handle */
__u8 *ctr_null_value_buf; /* CTR mode unaligned buffer */
__u8 *ctr_null_value; /* CTR mode aligned zero buf */
+ __u8 *outscratchpadbuf; /* CTR mode output scratchpad */
+ __u8 *outscratchpad; /* CTR mode aligned outbuf */
struct completion ctr_completion; /* CTR mode async handler */
int ctr_async_err; /* CTR mode async error */