Re: [PATCH v3] mac80211: move extra crypto data off the stack

2016-10-17 Thread Johannes Berg
[snip]

Sorry, this went out by mistake.

johannes


[PATCH v3] mac80211: move extra crypto data off the stack

2016-10-17 Thread Johannes Berg
From: Johannes Berg 

As the stack can (on x86-64) now be virtually mapped rather than
using "normal" kernel memory, Sergey noticed mac80211 isn't using
the SG APIs correctly by putting on-stack buffers into SG tables.
This leads to kernel crashes.

Fix this by allocating a bit of per-CPU memory for the extra data
that encryption/decryption/verification needs, instead of having
it stored on the stack.

Signed-off-by: Johannes Berg 
---
 net/mac80211/aes_ccm.c |  2 --
 net/mac80211/aes_cmac.c|  5 ++-
 net/mac80211/aes_cmac.h|  2 ++
 net/mac80211/aes_gcm.c |  2 --
 net/mac80211/aes_gmac.c| 10 +++---
 net/mac80211/aes_gmac.h|  5 ++-
 net/mac80211/ieee80211_i.h |  7 
 net/mac80211/main.c|  8 +
 net/mac80211/wpa.c | 86 +-
 9 files changed, 97 insertions(+), 30 deletions(-)

diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c
index 5c9fe00be6cc..8e898a6e8de8 100644
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aes_ccm.c
@@ -34,7 +34,6 @@ int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 
*b_0, u8 *aad,
sg_set_buf([1], data, data_len);
sg_set_buf([2], mic, mic_len);
 
-   aead_request_set_tfm(aead_req, tfm);
aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
aead_request_set_ad(aead_req, sg[0].length);
 
@@ -64,7 +63,6 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 
*b_0, u8 *aad,
sg_set_buf([1], data, data_len);
sg_set_buf([2], mic, mic_len);
 
-   aead_request_set_tfm(aead_req, tfm);
aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
aead_request_set_ad(aead_req, sg[0].length);
 
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c
index bdf0790d89cc..ebb8c2dc9928 100644
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
@@ -20,7 +20,6 @@
 
 #define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */
 #define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */
-#define AAD_LEN 20
 
 
 static void gf_mulx(u8 *pad)
@@ -101,7 +100,7 @@ void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 
*aad,
 
memset(zero, 0, CMAC_TLEN);
addr[0] = aad;
-   len[0] = AAD_LEN;
+   len[0] = CMAC_AAD_LEN;
addr[1] = data;
len[1] = data_len - CMAC_TLEN;
addr[2] = zero;
@@ -119,7 +118,7 @@ void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, 
const u8 *aad,
 
memset(zero, 0, CMAC_TLEN_256);
addr[0] = aad;
-   len[0] = AAD_LEN;
+   len[0] = CMAC_AAD_LEN;
addr[1] = data;
len[1] = data_len - CMAC_TLEN_256;
addr[2] = zero;
diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h
index 3702041f44fd..6645f8963278 100644
--- a/net/mac80211/aes_cmac.h
+++ b/net/mac80211/aes_cmac.h
@@ -11,6 +11,8 @@
 
 #include 
 
+#define CMAC_AAD_LEN 20
+
 struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[],
   size_t key_len);
 void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
diff --git a/net/mac80211/aes_gcm.c b/net/mac80211/aes_gcm.c
index aa8eb2718bc1..831054c6c756 100644
--- a/net/mac80211/aes_gcm.c
+++ b/net/mac80211/aes_gcm.c
@@ -30,7 +30,6 @@ int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 
*j_0, u8 *aad,
sg_set_buf([1], data, data_len);
sg_set_buf([2], mic, IEEE80211_GCMP_MIC_LEN);
 
-   aead_request_set_tfm(aead_req, tfm);
aead_request_set_crypt(aead_req, sg, sg, data_len, j_0);
aead_request_set_ad(aead_req, sg[0].length);
 
@@ -58,7 +57,6 @@ int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 
*j_0, u8 *aad,
sg_set_buf([1], data, data_len);
sg_set_buf([2], mic, IEEE80211_GCMP_MIC_LEN);
 
-   aead_request_set_tfm(aead_req, tfm);
aead_request_set_crypt(aead_req, sg, sg,
   data_len + IEEE80211_GCMP_MIC_LEN, j_0);
aead_request_set_ad(aead_req, sg[0].length);
diff --git a/net/mac80211/aes_gmac.c b/net/mac80211/aes_gmac.c
index 15cfcebf0884..86892e2e3c8c 100644
--- a/net/mac80211/aes_gmac.c
+++ b/net/mac80211/aes_gmac.c
@@ -19,13 +19,12 @@
 
 #define GMAC_MIC_LEN 16
 #define GMAC_NONCE_LEN 12
-#define AAD_LEN 20
 
 int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
-  const u8 *data, size_t data_len, u8 *mic)
+  const u8 *data, size_t data_len, u8 *mic, u8 *zero)
 {
struct scatterlist sg[4];
-   u8 zero[GMAC_MIC_LEN], iv[AES_BLOCK_SIZE];
+   u8 iv[AES_BLOCK_SIZE];
struct aead_request *aead_req;
 
if (data_len < GMAC_MIC_LEN)
@@ -37,7 +36,7 @@ int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 
*aad, u8 *nonce,
 
memset(zero, 0, GMAC_MIC_LEN);
sg_init_table(sg, 4);
-   sg_set_buf([0], aad, AAD_LEN);
+   sg_set_buf([0], aad, GMAC_AAD_LEN);