aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-07-15 10:05:24 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-07-15 10:05:24 -0400
commit95a943c162d74b20d869917bdf5df11293c35b63 (patch)
treec69d5cb97a4d97b6062a276ecdfa8582535193af /net/mac80211
parentecae42d37045ec71831d0e0e493e00b0e0732edd (diff)
parent95acac61ba66c4abd40e038dae8c1ed2e176c7b1 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: net/bluetooth/l2cap_core.c
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/aes_ccm.c37
-rw-r--r--net/mac80211/aes_ccm.h2
-rw-r--r--net/mac80211/aes_cmac.c10
-rw-r--r--net/mac80211/aes_cmac.h2
-rw-r--r--net/mac80211/cfg.c27
-rw-r--r--net/mac80211/debugfs_key.c13
-rw-r--r--net/mac80211/driver-ops.h8
-rw-r--r--net/mac80211/driver-trace.h46
-rw-r--r--net/mac80211/ieee80211_i.h27
-rw-r--r--net/mac80211/iface.c7
-rw-r--r--net/mac80211/key.c75
-rw-r--r--net/mac80211/key.h32
-rw-r--r--net/mac80211/mlme.c58
-rw-r--r--net/mac80211/rx.c36
-rw-r--r--net/mac80211/sta_info.h3
-rw-r--r--net/mac80211/tkip.c108
-rw-r--r--net/mac80211/tkip.h8
-rw-r--r--net/mac80211/tx.c3
-rw-r--r--net/mac80211/util.c67
-rw-r--r--net/mac80211/wpa.c94
20 files changed, 477 insertions, 186 deletions
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c
index b9b595c08112..0785e95c9924 100644
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aes_ccm.c
@@ -11,6 +11,7 @@
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/crypto.h> 12#include <linux/crypto.h>
13#include <linux/err.h> 13#include <linux/err.h>
14#include <crypto/aes.h>
14 15
15#include <net/mac80211.h> 16#include <net/mac80211.h>
16#include "key.h" 17#include "key.h"
@@ -21,21 +22,21 @@ static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a)
21 int i; 22 int i;
22 u8 *b_0, *aad, *b, *s_0; 23 u8 *b_0, *aad, *b, *s_0;
23 24
24 b_0 = scratch + 3 * AES_BLOCK_LEN; 25 b_0 = scratch + 3 * AES_BLOCK_SIZE;
25 aad = scratch + 4 * AES_BLOCK_LEN; 26 aad = scratch + 4 * AES_BLOCK_SIZE;
26 b = scratch; 27 b = scratch;
27 s_0 = scratch + AES_BLOCK_LEN; 28 s_0 = scratch + AES_BLOCK_SIZE;
28 29
29 crypto_cipher_encrypt_one(tfm, b, b_0); 30 crypto_cipher_encrypt_one(tfm, b, b_0);
30 31
31 /* Extra Authenticate-only data (always two AES blocks) */ 32 /* Extra Authenticate-only data (always two AES blocks) */
32 for (i = 0; i < AES_BLOCK_LEN; i++) 33 for (i = 0; i < AES_BLOCK_SIZE; i++)
33 aad[i] ^= b[i]; 34 aad[i] ^= b[i];
34 crypto_cipher_encrypt_one(tfm, b, aad); 35 crypto_cipher_encrypt_one(tfm, b, aad);
35 36
36 aad += AES_BLOCK_LEN; 37 aad += AES_BLOCK_SIZE;
37 38
38 for (i = 0; i < AES_BLOCK_LEN; i++) 39 for (i = 0; i < AES_BLOCK_SIZE; i++)
39 aad[i] ^= b[i]; 40 aad[i] ^= b[i];
40 crypto_cipher_encrypt_one(tfm, a, aad); 41 crypto_cipher_encrypt_one(tfm, a, aad);
41 42
@@ -57,12 +58,12 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
57 u8 *pos, *cpos, *b, *s_0, *e, *b_0; 58 u8 *pos, *cpos, *b, *s_0, *e, *b_0;
58 59
59 b = scratch; 60 b = scratch;
60 s_0 = scratch + AES_BLOCK_LEN; 61 s_0 = scratch + AES_BLOCK_SIZE;
61 e = scratch + 2 * AES_BLOCK_LEN; 62 e = scratch + 2 * AES_BLOCK_SIZE;
62 b_0 = scratch + 3 * AES_BLOCK_LEN; 63 b_0 = scratch + 3 * AES_BLOCK_SIZE;
63 64
64 num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); 65 num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
65 last_len = data_len % AES_BLOCK_LEN; 66 last_len = data_len % AES_BLOCK_SIZE;
66 aes_ccm_prepare(tfm, scratch, b); 67 aes_ccm_prepare(tfm, scratch, b);
67 68
68 /* Process payload blocks */ 69 /* Process payload blocks */
@@ -70,7 +71,7 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
70 cpos = cdata; 71 cpos = cdata;
71 for (j = 1; j <= num_blocks; j++) { 72 for (j = 1; j <= num_blocks; j++) {
72 int blen = (j == num_blocks && last_len) ? 73 int blen = (j == num_blocks && last_len) ?
73 last_len : AES_BLOCK_LEN; 74 last_len : AES_BLOCK_SIZE;
74 75
75 /* Authentication followed by encryption */ 76 /* Authentication followed by encryption */
76 for (i = 0; i < blen; i++) 77 for (i = 0; i < blen; i++)
@@ -96,12 +97,12 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
96 u8 *pos, *cpos, *b, *s_0, *a, *b_0; 97 u8 *pos, *cpos, *b, *s_0, *a, *b_0;
97 98
98 b = scratch; 99 b = scratch;
99 s_0 = scratch + AES_BLOCK_LEN; 100 s_0 = scratch + AES_BLOCK_SIZE;
100 a = scratch + 2 * AES_BLOCK_LEN; 101 a = scratch + 2 * AES_BLOCK_SIZE;
101 b_0 = scratch + 3 * AES_BLOCK_LEN; 102 b_0 = scratch + 3 * AES_BLOCK_SIZE;
102 103
103 num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); 104 num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
104 last_len = data_len % AES_BLOCK_LEN; 105 last_len = data_len % AES_BLOCK_SIZE;
105 aes_ccm_prepare(tfm, scratch, a); 106 aes_ccm_prepare(tfm, scratch, a);
106 107
107 /* Process payload blocks */ 108 /* Process payload blocks */
@@ -109,7 +110,7 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
109 pos = data; 110 pos = data;
110 for (j = 1; j <= num_blocks; j++) { 111 for (j = 1; j <= num_blocks; j++) {
111 int blen = (j == num_blocks && last_len) ? 112 int blen = (j == num_blocks && last_len) ?
112 last_len : AES_BLOCK_LEN; 113 last_len : AES_BLOCK_SIZE;
113 114
114 /* Decryption followed by authentication */ 115 /* Decryption followed by authentication */
115 b_0[14] = (j >> 8) & 0xff; 116 b_0[14] = (j >> 8) & 0xff;
diff --git a/net/mac80211/aes_ccm.h b/net/mac80211/aes_ccm.h
index 6e7820ef3448..5b7d744e2370 100644
--- a/net/mac80211/aes_ccm.h
+++ b/net/mac80211/aes_ccm.h
@@ -12,8 +12,6 @@
12 12
13#include <linux/crypto.h> 13#include <linux/crypto.h>
14 14
15#define AES_BLOCK_LEN 16
16
17struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]); 15struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]);
18void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, 16void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
19 u8 *data, size_t data_len, 17 u8 *data, size_t data_len,
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c
index d502b2684a66..8dfd70d8fcfb 100644
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
@@ -11,12 +11,12 @@
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/crypto.h> 12#include <linux/crypto.h>
13#include <linux/err.h> 13#include <linux/err.h>
14#include <crypto/aes.h>
14 15
15#include <net/mac80211.h> 16#include <net/mac80211.h>
16#include "key.h" 17#include "key.h"
17#include "aes_cmac.h" 18#include "aes_cmac.h"
18 19
19#define AES_BLOCK_SIZE 16
20#define AES_CMAC_KEY_LEN 16 20#define AES_CMAC_KEY_LEN 16
21#define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */ 21#define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */
22#define AAD_LEN 20 22#define AAD_LEN 20
@@ -35,10 +35,10 @@ static void gf_mulx(u8 *pad)
35} 35}
36 36
37 37
38static void aes_128_cmac_vector(struct crypto_cipher *tfm, u8 *scratch, 38static void aes_128_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
39 size_t num_elem,
40 const u8 *addr[], const size_t *len, u8 *mac) 39 const u8 *addr[], const size_t *len, u8 *mac)
41{ 40{
41 u8 scratch[2 * AES_BLOCK_SIZE];
42 u8 *cbc, *pad; 42 u8 *cbc, *pad;
43 const u8 *pos, *end; 43 const u8 *pos, *end;
44 size_t i, e, left, total_len; 44 size_t i, e, left, total_len;
@@ -95,7 +95,7 @@ static void aes_128_cmac_vector(struct crypto_cipher *tfm, u8 *scratch,
95} 95}
96 96
97 97
98void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad, 98void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
99 const u8 *data, size_t data_len, u8 *mic) 99 const u8 *data, size_t data_len, u8 *mic)
100{ 100{
101 const u8 *addr[3]; 101 const u8 *addr[3];
@@ -110,7 +110,7 @@ void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad,
110 addr[2] = zero; 110 addr[2] = zero;
111 len[2] = CMAC_TLEN; 111 len[2] = CMAC_TLEN;
112 112
113 aes_128_cmac_vector(tfm, scratch, 3, addr, len, mic); 113 aes_128_cmac_vector(tfm, 3, addr, len, mic);
114} 114}
115 115
116 116
diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h
index 0eb9a4831508..20785a647254 100644
--- a/net/mac80211/aes_cmac.h
+++ b/net/mac80211/aes_cmac.h
@@ -12,7 +12,7 @@
12#include <linux/crypto.h> 12#include <linux/crypto.h>
13 13
14struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]); 14struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]);
15void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad, 15void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
16 const u8 *data, size_t data_len, u8 *mic); 16 const u8 *data, size_t data_len, u8 *mic);
17void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); 17void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm);
18 18
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 295ab747663f..bfc36e904764 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -209,6 +209,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
209 u8 seq[6] = {0}; 209 u8 seq[6] = {0};
210 struct key_params params; 210 struct key_params params;
211 struct ieee80211_key *key = NULL; 211 struct ieee80211_key *key = NULL;
212 u64 pn64;
212 u32 iv32; 213 u32 iv32;
213 u16 iv16; 214 u16 iv16;
214 int err = -ENOENT; 215 int err = -ENOENT;
@@ -256,22 +257,24 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
256 params.seq_len = 6; 257 params.seq_len = 6;
257 break; 258 break;
258 case WLAN_CIPHER_SUITE_CCMP: 259 case WLAN_CIPHER_SUITE_CCMP:
259 seq[0] = key->u.ccmp.tx_pn[5]; 260 pn64 = atomic64_read(&key->u.ccmp.tx_pn);
260 seq[1] = key->u.ccmp.tx_pn[4]; 261 seq[0] = pn64;
261 seq[2] = key->u.ccmp.tx_pn[3]; 262 seq[1] = pn64 >> 8;
262 seq[3] = key->u.ccmp.tx_pn[2]; 263 seq[2] = pn64 >> 16;
263 seq[4] = key->u.ccmp.tx_pn[1]; 264 seq[3] = pn64 >> 24;
264 seq[5] = key->u.ccmp.tx_pn[0]; 265 seq[4] = pn64 >> 32;
266 seq[5] = pn64 >> 40;
265 params.seq = seq; 267 params.seq = seq;
266 params.seq_len = 6; 268 params.seq_len = 6;
267 break; 269 break;
268 case WLAN_CIPHER_SUITE_AES_CMAC: 270 case WLAN_CIPHER_SUITE_AES_CMAC:
269 seq[0] = key->u.aes_cmac.tx_pn[5]; 271 pn64 = atomic64_read(&key->u.aes_cmac.tx_pn);
270 seq[1] = key->u.aes_cmac.tx_pn[4]; 272 seq[0] = pn64;
271 seq[2] = key->u.aes_cmac.tx_pn[3]; 273 seq[1] = pn64 >> 8;
272 seq[3] = key->u.aes_cmac.tx_pn[2]; 274 seq[2] = pn64 >> 16;
273 seq[4] = key->u.aes_cmac.tx_pn[1]; 275 seq[3] = pn64 >> 24;
274 seq[5] = key->u.aes_cmac.tx_pn[0]; 276 seq[4] = pn64 >> 32;
277 seq[5] = pn64 >> 40;
275 params.seq = seq; 278 params.seq = seq;
276 params.seq_len = 6; 279 params.seq_len = 6;
277 break; 280 break;
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 33c58b85c911..38e6101190d9 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -78,7 +78,7 @@ KEY_OPS(algorithm);
78static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, 78static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
79 size_t count, loff_t *ppos) 79 size_t count, loff_t *ppos)
80{ 80{
81 const u8 *tpn; 81 u64 pn;
82 char buf[20]; 82 char buf[20];
83 int len; 83 int len;
84 struct ieee80211_key *key = file->private_data; 84 struct ieee80211_key *key = file->private_data;
@@ -94,15 +94,16 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
94 key->u.tkip.tx.iv16); 94 key->u.tkip.tx.iv16);
95 break; 95 break;
96 case WLAN_CIPHER_SUITE_CCMP: 96 case WLAN_CIPHER_SUITE_CCMP:
97 tpn = key->u.ccmp.tx_pn; 97 pn = atomic64_read(&key->u.ccmp.tx_pn);
98 len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", 98 len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
99 tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]); 99 (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
100 (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
100 break; 101 break;
101 case WLAN_CIPHER_SUITE_AES_CMAC: 102 case WLAN_CIPHER_SUITE_AES_CMAC:
102 tpn = key->u.aes_cmac.tx_pn; 103 pn = atomic64_read(&key->u.aes_cmac.tx_pn);
103 len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", 104 len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
104 tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], 105 (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
105 tpn[5]); 106 (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
106 break; 107 break;
107 default: 108 default:
108 return 0; 109 return 0;
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index edd2dd79c9be..b2d6bba44054 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -657,4 +657,12 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local,
657 trace_drv_return_void(local); 657 trace_drv_return_void(local);
658} 658}
659 659
660static inline void drv_rssi_callback(struct ieee80211_local *local,
661 const enum ieee80211_rssi_event event)
662{
663 trace_drv_rssi_callback(local, event);
664 if (local->ops->rssi_callback)
665 local->ops->rssi_callback(&local->hw, event);
666 trace_drv_return_void(local);
667}
660#endif /* __MAC80211_DRIVER_OPS */ 668#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 31a9dfa81f65..4470f6e8b845 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -1052,6 +1052,28 @@ TRACE_EVENT(drv_set_rekey_data,
1052 LOCAL_PR_ARG, VIF_PR_ARG) 1052 LOCAL_PR_ARG, VIF_PR_ARG)
1053); 1053);
1054 1054
1055TRACE_EVENT(drv_rssi_callback,
1056 TP_PROTO(struct ieee80211_local *local,
1057 enum ieee80211_rssi_event rssi_event),
1058
1059 TP_ARGS(local, rssi_event),
1060
1061 TP_STRUCT__entry(
1062 LOCAL_ENTRY
1063 __field(u32, rssi_event)
1064 ),
1065
1066 TP_fast_assign(
1067 LOCAL_ASSIGN;
1068 __entry->rssi_event = rssi_event;
1069 ),
1070
1071 TP_printk(
1072 LOCAL_PR_FMT " rssi_event:%d",
1073 LOCAL_PR_ARG, __entry->rssi_event
1074 )
1075);
1076
1055/* 1077/*
1056 * Tracing for API calls that drivers call. 1078 * Tracing for API calls that drivers call.
1057 */ 1079 */
@@ -1342,6 +1364,30 @@ TRACE_EVENT(api_gtk_rekey_notify,
1342 TP_printk(VIF_PR_FMT, VIF_PR_ARG) 1364 TP_printk(VIF_PR_FMT, VIF_PR_ARG)
1343); 1365);
1344 1366
1367TRACE_EVENT(api_enable_rssi_reports,
1368 TP_PROTO(struct ieee80211_sub_if_data *sdata,
1369 int rssi_min_thold, int rssi_max_thold),
1370
1371 TP_ARGS(sdata, rssi_min_thold, rssi_max_thold),
1372
1373 TP_STRUCT__entry(
1374 VIF_ENTRY
1375 __field(int, rssi_min_thold)
1376 __field(int, rssi_max_thold)
1377 ),
1378
1379 TP_fast_assign(
1380 VIF_ASSIGN;
1381 __entry->rssi_min_thold = rssi_min_thold;
1382 __entry->rssi_max_thold = rssi_max_thold;
1383 ),
1384
1385 TP_printk(
1386 VIF_PR_FMT " rssi_min_thold =%d, rssi_max_thold = %d",
1387 VIF_PR_ARG, __entry->rssi_min_thold, __entry->rssi_max_thold
1388 )
1389);
1390
1345/* 1391/*
1346 * Tracing for internal functions 1392 * Tracing for internal functions
1347 * (which may also be called in response to driver calls) 1393 * (which may also be called in response to driver calls)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4f2e424e8b1b..dda0d1ab34f3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -202,7 +202,22 @@ struct ieee80211_rx_data {
202 struct ieee80211_key *key; 202 struct ieee80211_key *key;
203 203
204 unsigned int flags; 204 unsigned int flags;
205 int queue; 205
206 /*
207 * Index into sequence numbers array, 0..16
208 * since the last (16) is used for non-QoS,
209 * will be 16 on non-QoS frames.
210 */
211 int seqno_idx;
212
213 /*
214 * Index into the security IV/PN arrays, 0..16
215 * since the last (16) is used for CCMP-encrypted
216 * management frames, will be set to 16 on mgmt
217 * frames and 0 on non-QoS frames.
218 */
219 int security_idx;
220
206 u32 tkip_iv32; 221 u32 tkip_iv32;
207 u16 tkip_iv16; 222 u16 tkip_iv16;
208}; 223};
@@ -417,6 +432,14 @@ struct ieee80211_if_managed {
417 * generated for the current association. 432 * generated for the current association.
418 */ 433 */
419 int last_cqm_event_signal; 434 int last_cqm_event_signal;
435
436 /*
437 * State variables for keeping track of RSSI of the AP currently
438 * connected to and informing driver when RSSI has gone
439 * below/above a certain threshold.
440 */
441 int rssi_min_thold, rssi_max_thold;
442 int last_ave_beacon_signal;
420}; 443};
421 444
422struct ieee80211_if_ibss { 445struct ieee80211_if_ibss {
@@ -515,12 +538,14 @@ struct ieee80211_if_mesh {
515 * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between 538 * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between
516 * associated stations and deliver multicast frames both 539 * associated stations and deliver multicast frames both
517 * back to wireless media and to the local net stack. 540 * back to wireless media and to the local net stack.
541 * @IEEE80211_SDATA_DISCONNECT_RESUME: Disconnect after resume.
518 */ 542 */
519enum ieee80211_sub_if_data_flags { 543enum ieee80211_sub_if_data_flags {
520 IEEE80211_SDATA_ALLMULTI = BIT(0), 544 IEEE80211_SDATA_ALLMULTI = BIT(0),
521 IEEE80211_SDATA_PROMISC = BIT(1), 545 IEEE80211_SDATA_PROMISC = BIT(1),
522 IEEE80211_SDATA_OPERATING_GMODE = BIT(2), 546 IEEE80211_SDATA_OPERATING_GMODE = BIT(2),
523 IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), 547 IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3),
548 IEEE80211_SDATA_DISCONNECT_RESUME = BIT(4),
524}; 549};
525 550
526/** 551/**
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index dee30aea9ab3..cd5fb40d3fd4 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -363,8 +363,7 @@ static int ieee80211_open(struct net_device *dev)
363 int err; 363 int err;
364 364
365 /* fail early if user set an invalid address */ 365 /* fail early if user set an invalid address */
366 if (!is_zero_ether_addr(dev->dev_addr) && 366 if (!is_valid_ether_addr(dev->dev_addr))
367 !is_valid_ether_addr(dev->dev_addr))
368 return -EADDRNOTAVAIL; 367 return -EADDRNOTAVAIL;
369 368
370 err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type); 369 err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type);
@@ -1130,8 +1129,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1130 1129
1131 ASSERT_RTNL(); 1130 ASSERT_RTNL();
1132 1131
1133 ndev = alloc_netdev_mq(sizeof(*sdata) + local->hw.vif_data_size, 1132 ndev = alloc_netdev_mqs(sizeof(*sdata) + local->hw.vif_data_size,
1134 name, ieee80211_if_setup, local->hw.queues); 1133 name, ieee80211_if_setup, local->hw.queues, 1);
1135 if (!ndev) 1134 if (!ndev)
1136 return -ENOMEM; 1135 return -ENOMEM;
1137 dev_net_set(ndev, wiphy_net(local->hw.wiphy)); 1136 dev_net_set(ndev, wiphy_net(local->hw.wiphy));
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 1208a7878bfd..739bee13e813 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -369,6 +369,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
369 get_unaligned_le16(seq); 369 get_unaligned_le16(seq);
370 } 370 }
371 } 371 }
372 spin_lock_init(&key->u.tkip.txlock);
372 break; 373 break;
373 case WLAN_CIPHER_SUITE_CCMP: 374 case WLAN_CIPHER_SUITE_CCMP:
374 key->conf.iv_len = CCMP_HDR_LEN; 375 key->conf.iv_len = CCMP_HDR_LEN;
@@ -625,3 +626,77 @@ void ieee80211_gtk_rekey_notify(struct ieee80211_vif *vif, const u8 *bssid,
625 cfg80211_gtk_rekey_notify(sdata->dev, bssid, replay_ctr, gfp); 626 cfg80211_gtk_rekey_notify(sdata->dev, bssid, replay_ctr, gfp);
626} 627}
627EXPORT_SYMBOL_GPL(ieee80211_gtk_rekey_notify); 628EXPORT_SYMBOL_GPL(ieee80211_gtk_rekey_notify);
629
630void ieee80211_get_key_tx_seq(struct ieee80211_key_conf *keyconf,
631 struct ieee80211_key_seq *seq)
632{
633 struct ieee80211_key *key;
634 u64 pn64;
635
636 if (WARN_ON(!(keyconf->flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
637 return;
638
639 key = container_of(keyconf, struct ieee80211_key, conf);
640
641 switch (key->conf.cipher) {
642 case WLAN_CIPHER_SUITE_TKIP:
643 seq->tkip.iv32 = key->u.tkip.tx.iv32;
644 seq->tkip.iv16 = key->u.tkip.tx.iv16;
645 break;
646 case WLAN_CIPHER_SUITE_CCMP:
647 pn64 = atomic64_read(&key->u.ccmp.tx_pn);
648 seq->ccmp.pn[5] = pn64;
649 seq->ccmp.pn[4] = pn64 >> 8;
650 seq->ccmp.pn[3] = pn64 >> 16;
651 seq->ccmp.pn[2] = pn64 >> 24;
652 seq->ccmp.pn[1] = pn64 >> 32;
653 seq->ccmp.pn[0] = pn64 >> 40;
654 break;
655 case WLAN_CIPHER_SUITE_AES_CMAC:
656 pn64 = atomic64_read(&key->u.aes_cmac.tx_pn);
657 seq->ccmp.pn[5] = pn64;
658 seq->ccmp.pn[4] = pn64 >> 8;
659 seq->ccmp.pn[3] = pn64 >> 16;
660 seq->ccmp.pn[2] = pn64 >> 24;
661 seq->ccmp.pn[1] = pn64 >> 32;
662 seq->ccmp.pn[0] = pn64 >> 40;
663 break;
664 default:
665 WARN_ON(1);
666 }
667}
668EXPORT_SYMBOL(ieee80211_get_key_tx_seq);
669
670void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf,
671 int tid, struct ieee80211_key_seq *seq)
672{
673 struct ieee80211_key *key;
674 const u8 *pn;
675
676 key = container_of(keyconf, struct ieee80211_key, conf);
677
678 switch (key->conf.cipher) {
679 case WLAN_CIPHER_SUITE_TKIP:
680 if (WARN_ON(tid < 0 || tid >= NUM_RX_DATA_QUEUES))
681 return;
682 seq->tkip.iv32 = key->u.tkip.rx[tid].iv32;
683 seq->tkip.iv16 = key->u.tkip.rx[tid].iv16;
684 break;
685 case WLAN_CIPHER_SUITE_CCMP:
686 if (WARN_ON(tid < -1 || tid >= NUM_RX_DATA_QUEUES))
687 return;
688 if (tid < 0)
689 pn = key->u.ccmp.rx_pn[NUM_RX_DATA_QUEUES];
690 else
691 pn = key->u.ccmp.rx_pn[tid];
692 memcpy(seq->ccmp.pn, pn, CCMP_PN_LEN);
693 break;
694 case WLAN_CIPHER_SUITE_AES_CMAC:
695 if (WARN_ON(tid != 0))
696 return;
697 pn = key->u.aes_cmac.rx_pn;
698 memcpy(seq->aes_cmac.pn, pn, CMAC_PN_LEN);
699 break;
700 }
701}
702EXPORT_SYMBOL(ieee80211_get_key_rx_seq);
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index d801d5351336..7d4e31f037d7 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -28,8 +28,9 @@
28#define CCMP_PN_LEN 6 28#define CCMP_PN_LEN 6
29#define TKIP_IV_LEN 8 29#define TKIP_IV_LEN 8
30#define TKIP_ICV_LEN 4 30#define TKIP_ICV_LEN 4
31#define CMAC_PN_LEN 6
31 32
32#define NUM_RX_DATA_QUEUES 17 33#define NUM_RX_DATA_QUEUES 16
33 34
34struct ieee80211_local; 35struct ieee80211_local;
35struct ieee80211_sub_if_data; 36struct ieee80211_sub_if_data;
@@ -40,9 +41,11 @@ struct sta_info;
40 * 41 *
41 * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present 42 * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present
42 * in the hardware for TX crypto hardware acceleration. 43 * in the hardware for TX crypto hardware acceleration.
44 * @KEY_FLAG_TAINTED: Key is tainted and packets should be dropped.
43 */ 45 */
44enum ieee80211_internal_key_flags { 46enum ieee80211_internal_key_flags {
45 KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0), 47 KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0),
48 KEY_FLAG_TAINTED = BIT(1),
46}; 49};
47 50
48enum ieee80211_internal_tkip_state { 51enum ieee80211_internal_tkip_state {
@@ -52,9 +55,10 @@ enum ieee80211_internal_tkip_state {
52}; 55};
53 56
54struct tkip_ctx { 57struct tkip_ctx {
55 u32 iv32; 58 u32 iv32; /* current iv32 */
56 u16 iv16; 59 u16 iv16; /* current iv16 */
57 u16 p1k[5]; 60 u16 p1k[5]; /* p1k cache */
61 u32 p1k_iv32; /* iv32 for which p1k computed */
58 enum ieee80211_internal_tkip_state state; 62 enum ieee80211_internal_tkip_state state;
59}; 63};
60 64
@@ -71,6 +75,9 @@ struct ieee80211_key {
71 75
72 union { 76 union {
73 struct { 77 struct {
78 /* protects tx context */
79 spinlock_t txlock;
80
74 /* last used TSC */ 81 /* last used TSC */
75 struct tkip_ctx tx; 82 struct tkip_ctx tx;
76 83
@@ -78,32 +85,23 @@ struct ieee80211_key {
78 struct tkip_ctx rx[NUM_RX_DATA_QUEUES]; 85 struct tkip_ctx rx[NUM_RX_DATA_QUEUES];
79 } tkip; 86 } tkip;
80 struct { 87 struct {
81 u8 tx_pn[6]; 88 atomic64_t tx_pn;
82 /* 89 /*
83 * Last received packet number. The first 90 * Last received packet number. The first
84 * NUM_RX_DATA_QUEUES counters are used with Data 91 * NUM_RX_DATA_QUEUES counters are used with Data
85 * frames and the last counter is used with Robust 92 * frames and the last counter is used with Robust
86 * Management frames. 93 * Management frames.
87 */ 94 */
88 u8 rx_pn[NUM_RX_DATA_QUEUES + 1][6]; 95 u8 rx_pn[NUM_RX_DATA_QUEUES + 1][CCMP_PN_LEN];
89 struct crypto_cipher *tfm; 96 struct crypto_cipher *tfm;
90 u32 replays; /* dot11RSNAStatsCCMPReplays */ 97 u32 replays; /* dot11RSNAStatsCCMPReplays */
91 /* scratch buffers for virt_to_page() (crypto API) */
92#ifndef AES_BLOCK_LEN
93#define AES_BLOCK_LEN 16
94#endif
95 u8 tx_crypto_buf[6 * AES_BLOCK_LEN];
96 u8 rx_crypto_buf[6 * AES_BLOCK_LEN];
97 } ccmp; 98 } ccmp;
98 struct { 99 struct {
99 u8 tx_pn[6]; 100 atomic64_t tx_pn;
100 u8 rx_pn[6]; 101 u8 rx_pn[CMAC_PN_LEN];
101 struct crypto_cipher *tfm; 102 struct crypto_cipher *tfm;
102 u32 replays; /* dot11RSNAStatsCMACReplays */ 103 u32 replays; /* dot11RSNAStatsCMACReplays */
103 u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ 104 u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
104 /* scratch buffers for virt_to_page() (crypto API) */
105 u8 tx_crypto_buf[2 * AES_BLOCK_LEN];
106 u8 rx_crypto_buf[2 * AES_BLOCK_LEN];
107 } aes_cmac; 105 } aes_cmac;
108 } u; 106 } u;
109 107
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 182cda66ebef..c99237cd4b98 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1763,6 +1763,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1763 ifmgd->ave_beacon_signal = rx_status->signal * 16; 1763 ifmgd->ave_beacon_signal = rx_status->signal * 16;
1764 ifmgd->last_cqm_event_signal = 0; 1764 ifmgd->last_cqm_event_signal = 0;
1765 ifmgd->count_beacon_signal = 1; 1765 ifmgd->count_beacon_signal = 1;
1766 ifmgd->last_ave_beacon_signal = 0;
1766 } else { 1767 } else {
1767 ifmgd->ave_beacon_signal = 1768 ifmgd->ave_beacon_signal =
1768 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 + 1769 (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
@@ -1770,6 +1771,28 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1770 ifmgd->ave_beacon_signal) / 16; 1771 ifmgd->ave_beacon_signal) / 16;
1771 ifmgd->count_beacon_signal++; 1772 ifmgd->count_beacon_signal++;
1772 } 1773 }
1774
1775 if (ifmgd->rssi_min_thold != ifmgd->rssi_max_thold &&
1776 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
1777 int sig = ifmgd->ave_beacon_signal;
1778 int last_sig = ifmgd->last_ave_beacon_signal;
1779
1780 /*
1781 * if signal crosses either of the boundaries, invoke callback
1782 * with appropriate parameters
1783 */
1784 if (sig > ifmgd->rssi_max_thold &&
1785 (last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) {
1786 ifmgd->last_ave_beacon_signal = sig;
1787 drv_rssi_callback(local, RSSI_EVENT_HIGH);
1788 } else if (sig < ifmgd->rssi_min_thold &&
1789 (last_sig >= ifmgd->rssi_max_thold ||
1790 last_sig == 0)) {
1791 ifmgd->last_ave_beacon_signal = sig;
1792 drv_rssi_callback(local, RSSI_EVENT_LOW);
1793 }
1794 }
1795
1773 if (bss_conf->cqm_rssi_thold && 1796 if (bss_conf->cqm_rssi_thold &&
1774 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT && 1797 ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
1775 !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { 1798 !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
@@ -2029,7 +2052,7 @@ static void ieee80211_sta_timer(unsigned long data)
2029} 2052}
2030 2053
2031static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, 2054static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
2032 u8 *bssid) 2055 u8 *bssid, u8 reason)
2033{ 2056{
2034 struct ieee80211_local *local = sdata->local; 2057 struct ieee80211_local *local = sdata->local;
2035 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2058 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -2047,8 +2070,7 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
2047 * but that's not a problem. 2070 * but that's not a problem.
2048 */ 2071 */
2049 ieee80211_send_deauth_disassoc(sdata, bssid, 2072 ieee80211_send_deauth_disassoc(sdata, bssid,
2050 IEEE80211_STYPE_DEAUTH, 2073 IEEE80211_STYPE_DEAUTH, reason,
2051 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
2052 NULL, true); 2074 NULL, true);
2053 mutex_lock(&ifmgd->mtx); 2075 mutex_lock(&ifmgd->mtx);
2054} 2076}
@@ -2094,7 +2116,8 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2094 " AP %pM, disconnecting.\n", 2116 " AP %pM, disconnecting.\n",
2095 sdata->name, bssid); 2117 sdata->name, bssid);
2096#endif 2118#endif
2097 ieee80211_sta_connection_lost(sdata, bssid); 2119 ieee80211_sta_connection_lost(sdata, bssid,
2120 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
2098 } 2121 }
2099 } else if (time_is_after_jiffies(ifmgd->probe_timeout)) 2122 } else if (time_is_after_jiffies(ifmgd->probe_timeout))
2100 run_again(ifmgd, ifmgd->probe_timeout); 2123 run_again(ifmgd, ifmgd->probe_timeout);
@@ -2106,7 +2129,8 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2106 sdata->name, 2129 sdata->name,
2107 bssid, probe_wait_ms); 2130 bssid, probe_wait_ms);
2108#endif 2131#endif
2109 ieee80211_sta_connection_lost(sdata, bssid); 2132 ieee80211_sta_connection_lost(sdata, bssid,
2133 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
2110 } else if (ifmgd->probe_send_count < max_tries) { 2134 } else if (ifmgd->probe_send_count < max_tries) {
2111#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 2135#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2112 wiphy_debug(local->hw.wiphy, 2136 wiphy_debug(local->hw.wiphy,
@@ -2128,7 +2152,8 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2128 sdata->name, 2152 sdata->name,
2129 bssid, probe_wait_ms); 2153 bssid, probe_wait_ms);
2130 2154
2131 ieee80211_sta_connection_lost(sdata, bssid); 2155 ieee80211_sta_connection_lost(sdata, bssid,
2156 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
2132 } 2157 }
2133 } 2158 }
2134 2159
@@ -2215,6 +2240,27 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
2215{ 2240{
2216 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2241 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2217 2242
2243 if (!ifmgd->associated)
2244 return;
2245
2246 if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) {
2247 sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME;
2248 mutex_lock(&ifmgd->mtx);
2249 if (ifmgd->associated) {
2250#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2251 wiphy_debug(sdata->local->hw.wiphy,
2252 "%s: driver requested disconnect after resume.\n",
2253 sdata->name);
2254#endif
2255 ieee80211_sta_connection_lost(sdata,
2256 ifmgd->associated->bssid,
2257 WLAN_REASON_UNSPECIFIED);
2258 mutex_unlock(&ifmgd->mtx);
2259 return;
2260 }
2261 mutex_unlock(&ifmgd->mtx);
2262 }
2263
2218 if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running)) 2264 if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running))
2219 add_timer(&ifmgd->timer); 2265 add_timer(&ifmgd->timer);
2220 if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) 2266 if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b5493ecd1e93..fe2c2a717793 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -331,7 +331,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
331{ 331{
332 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 332 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
333 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); 333 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
334 int tid; 334 int tid, seqno_idx, security_idx;
335 335
336 /* does the frame have a qos control field? */ 336 /* does the frame have a qos control field? */
337 if (ieee80211_is_data_qos(hdr->frame_control)) { 337 if (ieee80211_is_data_qos(hdr->frame_control)) {
@@ -340,6 +340,9 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
340 tid = *qc & IEEE80211_QOS_CTL_TID_MASK; 340 tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
341 if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT) 341 if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT)
342 status->rx_flags |= IEEE80211_RX_AMSDU; 342 status->rx_flags |= IEEE80211_RX_AMSDU;
343
344 seqno_idx = tid;
345 security_idx = tid;
343 } else { 346 } else {
344 /* 347 /*
345 * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): 348 * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"):
@@ -352,10 +355,15 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
352 * 355 *
353 * We also use that counter for non-QoS STAs. 356 * We also use that counter for non-QoS STAs.
354 */ 357 */
355 tid = NUM_RX_DATA_QUEUES - 1; 358 seqno_idx = NUM_RX_DATA_QUEUES;
359 security_idx = 0;
360 if (ieee80211_is_mgmt(hdr->frame_control))
361 security_idx = NUM_RX_DATA_QUEUES;
362 tid = 0;
356 } 363 }
357 364
358 rx->queue = tid; 365 rx->seqno_idx = seqno_idx;
366 rx->security_idx = security_idx;
359 /* Set skb->priority to 1d tag if highest order bit of TID is not set. 367 /* Set skb->priority to 1d tag if highest order bit of TID is not set.
360 * For now, set skb->priority to 0 for other cases. */ 368 * For now, set skb->priority to 0 for other cases. */
361 rx->skb->priority = (tid > 7) ? 0 : tid; 369 rx->skb->priority = (tid > 7) ? 0 : tid;
@@ -810,7 +818,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
810 /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ 818 /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */
811 if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { 819 if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) {
812 if (unlikely(ieee80211_has_retry(hdr->frame_control) && 820 if (unlikely(ieee80211_has_retry(hdr->frame_control) &&
813 rx->sta->last_seq_ctrl[rx->queue] == 821 rx->sta->last_seq_ctrl[rx->seqno_idx] ==
814 hdr->seq_ctrl)) { 822 hdr->seq_ctrl)) {
815 if (status->rx_flags & IEEE80211_RX_RA_MATCH) { 823 if (status->rx_flags & IEEE80211_RX_RA_MATCH) {
816 rx->local->dot11FrameDuplicateCount++; 824 rx->local->dot11FrameDuplicateCount++;
@@ -818,7 +826,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
818 } 826 }
819 return RX_DROP_UNUSABLE; 827 return RX_DROP_UNUSABLE;
820 } else 828 } else
821 rx->sta->last_seq_ctrl[rx->queue] = hdr->seq_ctrl; 829 rx->sta->last_seq_ctrl[rx->seqno_idx] = hdr->seq_ctrl;
822 } 830 }
823 831
824 if (unlikely(rx->skb->len < 16)) { 832 if (unlikely(rx->skb->len < 16)) {
@@ -1011,6 +1019,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1011 } 1019 }
1012 1020
1013 if (rx->key) { 1021 if (rx->key) {
1022 if (unlikely(rx->key->flags & KEY_FLAG_TAINTED))
1023 return RX_DROP_MONITOR;
1024
1014 rx->key->tx_rx_count++; 1025 rx->key->tx_rx_count++;
1015 /* TODO: add threshold stuff again */ 1026 /* TODO: add threshold stuff again */
1016 } else { 1027 } else {
@@ -1374,11 +1385,10 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1374 if (frag == 0) { 1385 if (frag == 0) {
1375 /* This is the first fragment of a new frame. */ 1386 /* This is the first fragment of a new frame. */
1376 entry = ieee80211_reassemble_add(rx->sdata, frag, seq, 1387 entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
1377 rx->queue, &(rx->skb)); 1388 rx->seqno_idx, &(rx->skb));
1378 if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP && 1389 if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP &&
1379 ieee80211_has_protected(fc)) { 1390 ieee80211_has_protected(fc)) {
1380 int queue = ieee80211_is_mgmt(fc) ? 1391 int queue = rx->security_idx;
1381 NUM_RX_DATA_QUEUES : rx->queue;
1382 /* Store CCMP PN so that we can verify that the next 1392 /* Store CCMP PN so that we can verify that the next
1383 * fragment has a sequential PN value. */ 1393 * fragment has a sequential PN value. */
1384 entry->ccmp = 1; 1394 entry->ccmp = 1;
@@ -1392,7 +1402,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1392 /* This is a fragment for a frame that should already be pending in 1402 /* This is a fragment for a frame that should already be pending in
1393 * fragment cache. Add this fragment to the end of the pending entry. 1403 * fragment cache. Add this fragment to the end of the pending entry.
1394 */ 1404 */
1395 entry = ieee80211_reassemble_find(rx->sdata, frag, seq, rx->queue, hdr); 1405 entry = ieee80211_reassemble_find(rx->sdata, frag, seq,
1406 rx->seqno_idx, hdr);
1396 if (!entry) { 1407 if (!entry) {
1397 I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); 1408 I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag);
1398 return RX_DROP_MONITOR; 1409 return RX_DROP_MONITOR;
@@ -1412,8 +1423,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1412 if (pn[i]) 1423 if (pn[i])
1413 break; 1424 break;
1414 } 1425 }
1415 queue = ieee80211_is_mgmt(fc) ? 1426 queue = rx->security_idx;
1416 NUM_RX_DATA_QUEUES : rx->queue;
1417 rpn = rx->key->u.ccmp.rx_pn[queue]; 1427 rpn = rx->key->u.ccmp.rx_pn[queue];
1418 if (memcmp(pn, rpn, CCMP_PN_LEN)) 1428 if (memcmp(pn, rpn, CCMP_PN_LEN))
1419 return RX_DROP_UNUSABLE; 1429 return RX_DROP_UNUSABLE;
@@ -2590,7 +2600,9 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
2590 .sta = sta, 2600 .sta = sta,
2591 .sdata = sta->sdata, 2601 .sdata = sta->sdata,
2592 .local = sta->local, 2602 .local = sta->local,
2593 .queue = tid, 2603 /* This is OK -- must be QoS data frame */
2604 .security_idx = tid,
2605 .seqno_idx = tid,
2594 .flags = 0, 2606 .flags = 0,
2595 }; 2607 };
2596 struct tid_ampdu_rx *tid_agg_rx; 2608 struct tid_ampdu_rx *tid_agg_rx;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index a06d64ebc177..28beb78e601e 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -287,7 +287,8 @@ struct sta_info {
287 unsigned long rx_dropped; 287 unsigned long rx_dropped;
288 int last_signal; 288 int last_signal;
289 struct ewma avg_signal; 289 struct ewma avg_signal;
290 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; 290 /* Plus 1 for non-QoS frames */
291 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES + 1];
291 292
292 /* Updated from TX status path only, no locking requirements */ 293 /* Updated from TX status path only, no locking requirements */
293 unsigned long tx_filtered_count; 294 unsigned long tx_filtered_count;
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 757e4eb2baf7..cc79e697cdb2 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -101,6 +101,7 @@ static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx,
101 p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; 101 p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i;
102 } 102 }
103 ctx->state = TKIP_STATE_PHASE1_DONE; 103 ctx->state = TKIP_STATE_PHASE1_DONE;
104 ctx->p1k_iv32 = tsc_IV32;
104} 105}
105 106
106static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, 107static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx,
@@ -140,60 +141,69 @@ static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx,
140/* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets 141/* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets
141 * of the IV. Returns pointer to the octet following IVs (i.e., beginning of 142 * of the IV. Returns pointer to the octet following IVs (i.e., beginning of
142 * the packet payload). */ 143 * the packet payload). */
143u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16) 144u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key)
144{ 145{
145 pos = write_tkip_iv(pos, iv16); 146 lockdep_assert_held(&key->u.tkip.txlock);
147
148 pos = write_tkip_iv(pos, key->u.tkip.tx.iv16);
146 *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; 149 *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */;
147 put_unaligned_le32(key->u.tkip.tx.iv32, pos); 150 put_unaligned_le32(key->u.tkip.tx.iv32, pos);
148 return pos + 4; 151 return pos + 4;
149} 152}
150 153
151void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, 154static void ieee80211_compute_tkip_p1k(struct ieee80211_key *key, u32 iv32)
152 struct sk_buff *skb, enum ieee80211_tkip_key_type type,
153 u8 *outkey)
154{ 155{
155 struct ieee80211_key *key = (struct ieee80211_key *) 156 struct ieee80211_sub_if_data *sdata = key->sdata;
156 container_of(keyconf, struct ieee80211_key, conf); 157 struct tkip_ctx *ctx = &key->u.tkip.tx;
157 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 158 const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
158 u8 *data;
159 const u8 *tk;
160 struct tkip_ctx *ctx;
161 u16 iv16;
162 u32 iv32;
163
164 data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
165 iv16 = data[2] | (data[0] << 8);
166 iv32 = get_unaligned_le32(&data[4]);
167
168 tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
169 ctx = &key->u.tkip.tx;
170 159
171#ifdef CONFIG_MAC80211_TKIP_DEBUG 160 lockdep_assert_held(&key->u.tkip.txlock);
172 printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", 161
173 iv16, iv32); 162 /*
174 163 * Update the P1K when the IV32 is different from the value it
175 if (iv32 != ctx->iv32) { 164 * had when we last computed it (or when not initialised yet).
176 printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n", 165 * This might flip-flop back and forth if packets are processed
177 iv32, ctx->iv32); 166 * out-of-order due to the different ACs, but then we have to
178 printk(KERN_DEBUG "Wrap around of iv16 in the middle of a " 167 * just compute the P1K more often.
179 "fragmented packet\n"); 168 */
180 } 169 if (ctx->p1k_iv32 != iv32 || ctx->state == TKIP_STATE_NOT_INIT)
181#endif 170 tkip_mixing_phase1(tk, ctx, sdata->vif.addr, iv32);
171}
182 172
183 /* Update the p1k only when the iv16 in the packet wraps around, this 173void ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *keyconf,
184 * might occur after the wrap around of iv16 in the key in case of 174 u32 iv32, u16 *p1k)
185 * fragmented packets. */ 175{
186 if (iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT) 176 struct ieee80211_key *key = (struct ieee80211_key *)
187 tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32); 177 container_of(keyconf, struct ieee80211_key, conf);
178 struct tkip_ctx *ctx = &key->u.tkip.tx;
179 unsigned long flags;
188 180
189 if (type == IEEE80211_TKIP_P1_KEY) { 181 spin_lock_irqsave(&key->u.tkip.txlock, flags);
190 memcpy(outkey, ctx->p1k, sizeof(u16) * 5); 182 ieee80211_compute_tkip_p1k(key, iv32);
191 return; 183 memcpy(p1k, ctx->p1k, sizeof(ctx->p1k));
192 } 184 spin_unlock_irqrestore(&key->u.tkip.txlock, flags);
185}
186EXPORT_SYMBOL(ieee80211_get_tkip_p1k_iv);
193 187
194 tkip_mixing_phase2(tk, ctx, iv16, outkey); 188void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
189 struct sk_buff *skb, u8 *p2k)
190{
191 struct ieee80211_key *key = (struct ieee80211_key *)
192 container_of(keyconf, struct ieee80211_key, conf);
193 const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
194 struct tkip_ctx *ctx = &key->u.tkip.tx;
195 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
196 const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
197 u32 iv32 = get_unaligned_le32(&data[4]);
198 u16 iv16 = data[2] | (data[0] << 8);
199 unsigned long flags;
200
201 spin_lock_irqsave(&key->u.tkip.txlock, flags);
202 ieee80211_compute_tkip_p1k(key, iv32);
203 tkip_mixing_phase2(tk, ctx, iv16, p2k);
204 spin_unlock_irqrestore(&key->u.tkip.txlock, flags);
195} 205}
196EXPORT_SYMBOL(ieee80211_get_tkip_key); 206EXPORT_SYMBOL(ieee80211_get_tkip_p2k);
197 207
198/* 208/*
199 * Encrypt packet payload with TKIP using @key. @pos is a pointer to the 209 * Encrypt packet payload with TKIP using @key. @pos is a pointer to the
@@ -204,19 +214,15 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key);
204 */ 214 */
205int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, 215int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
206 struct ieee80211_key *key, 216 struct ieee80211_key *key,
207 u8 *pos, size_t payload_len, u8 *ta) 217 struct sk_buff *skb,
218 u8 *payload, size_t payload_len)
208{ 219{
209 u8 rc4key[16]; 220 u8 rc4key[16];
210 struct tkip_ctx *ctx = &key->u.tkip.tx;
211 const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
212
213 /* Calculate per-packet key */
214 if (ctx->iv16 == 0 || ctx->state == TKIP_STATE_NOT_INIT)
215 tkip_mixing_phase1(tk, ctx, ta, ctx->iv32);
216 221
217 tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); 222 ieee80211_get_tkip_p2k(&key->conf, skb, rc4key);
218 223
219 return ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); 224 return ieee80211_wep_encrypt_data(tfm, rc4key, 16,
225 payload, payload_len);
220} 226}
221 227
222/* Decrypt packet payload with TKIP using @key. @pos is a pointer to the 228/* Decrypt packet payload with TKIP using @key. @pos is a pointer to the
diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h
index 1cab9c86978f..e3ecb659b90a 100644
--- a/net/mac80211/tkip.h
+++ b/net/mac80211/tkip.h
@@ -13,11 +13,13 @@
13#include <linux/crypto.h> 13#include <linux/crypto.h>
14#include "key.h" 14#include "key.h"
15 15
16u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16); 16u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key);
17 17
18int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm, 18int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
19 struct ieee80211_key *key, 19 struct ieee80211_key *key,
20 u8 *pos, size_t payload_len, u8 *ta); 20 struct sk_buff *skb,
21 u8 *payload, size_t payload_len);
22
21enum { 23enum {
22 TKIP_DECRYPT_OK = 0, 24 TKIP_DECRYPT_OK = 0,
23 TKIP_DECRYPT_NO_EXT_IV = -1, 25 TKIP_DECRYPT_NO_EXT_IV = -1,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e8d0d2d22665..8cb0d2d0ac69 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -589,6 +589,9 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
589 break; 589 break;
590 } 590 }
591 591
592 if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED))
593 return TX_DROP;
594
592 if (!skip_hw && tx->key && 595 if (!skip_hw && tx->key &&
593 tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) 596 tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
594 info->control.hw_key = &tx->key->conf; 597 info->control.hw_key = &tx->key->conf;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 652e5695225a..5bfb80cba634 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1334,6 +1334,33 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1334 return 0; 1334 return 0;
1335} 1335}
1336 1336
1337void ieee80211_resume_disconnect(struct ieee80211_vif *vif)
1338{
1339 struct ieee80211_sub_if_data *sdata;
1340 struct ieee80211_local *local;
1341 struct ieee80211_key *key;
1342
1343 if (WARN_ON(!vif))
1344 return;
1345
1346 sdata = vif_to_sdata(vif);
1347 local = sdata->local;
1348
1349 if (WARN_ON(!local->resuming))
1350 return;
1351
1352 if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
1353 return;
1354
1355 sdata->flags |= IEEE80211_SDATA_DISCONNECT_RESUME;
1356
1357 mutex_lock(&local->key_mtx);
1358 list_for_each_entry(key, &sdata->key_list, list)
1359 key->flags |= KEY_FLAG_TAINTED;
1360 mutex_unlock(&local->key_mtx);
1361}
1362EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect);
1363
1337static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, 1364static int check_mgd_smps(struct ieee80211_if_managed *ifmgd,
1338 enum ieee80211_smps_mode *smps_mode) 1365 enum ieee80211_smps_mode *smps_mode)
1339{ 1366{
@@ -1450,3 +1477,43 @@ size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)
1450 1477
1451 return pos; 1478 return pos;
1452} 1479}
1480
1481static void _ieee80211_enable_rssi_reports(struct ieee80211_sub_if_data *sdata,
1482 int rssi_min_thold,
1483 int rssi_max_thold)
1484{
1485 trace_api_enable_rssi_reports(sdata, rssi_min_thold, rssi_max_thold);
1486
1487 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
1488 return;
1489
1490 /*
1491 * Scale up threshold values before storing it, as the RSSI averaging
1492 * algorithm uses a scaled up value as well. Change this scaling
1493 * factor if the RSSI averaging algorithm changes.
1494 */
1495 sdata->u.mgd.rssi_min_thold = rssi_min_thold*16;
1496 sdata->u.mgd.rssi_max_thold = rssi_max_thold*16;
1497}
1498
1499void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,
1500 int rssi_min_thold,
1501 int rssi_max_thold)
1502{
1503 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1504
1505 WARN_ON(rssi_min_thold == rssi_max_thold ||
1506 rssi_min_thold > rssi_max_thold);
1507
1508 _ieee80211_enable_rssi_reports(sdata, rssi_min_thold,
1509 rssi_max_thold);
1510}
1511EXPORT_SYMBOL(ieee80211_enable_rssi_reports);
1512
1513void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif)
1514{
1515 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1516
1517 _ieee80211_enable_rssi_reports(sdata, 0, 0);
1518}
1519EXPORT_SYMBOL(ieee80211_disable_rssi_reports);
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 8f6a302d2ac3..7bc8702808fa 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -15,6 +15,7 @@
15#include <linux/gfp.h> 15#include <linux/gfp.h>
16#include <asm/unaligned.h> 16#include <asm/unaligned.h>
17#include <net/mac80211.h> 17#include <net/mac80211.h>
18#include <crypto/aes.h>
18 19
19#include "ieee80211_i.h" 20#include "ieee80211_i.h"
20#include "michael.h" 21#include "michael.h"
@@ -86,11 +87,6 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
86 struct sk_buff *skb = rx->skb; 87 struct sk_buff *skb = rx->skb;
87 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 88 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
88 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 89 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
89 int queue = rx->queue;
90
91 /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */
92 if (rx->queue == NUM_RX_DATA_QUEUES - 1)
93 queue = 0;
94 90
95 /* 91 /*
96 * it makes no sense to check for MIC errors on anything other 92 * it makes no sense to check for MIC errors on anything other
@@ -153,8 +149,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
153 149
154update_iv: 150update_iv:
155 /* update IV in key information to be able to detect replays */ 151 /* update IV in key information to be able to detect replays */
156 rx->key->u.tkip.rx[queue].iv32 = rx->tkip_iv32; 152 rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip_iv32;
157 rx->key->u.tkip.rx[queue].iv16 = rx->tkip_iv16; 153 rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip_iv16;
158 154
159 return RX_CONTINUE; 155 return RX_CONTINUE;
160 156
@@ -176,6 +172,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
176 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 172 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
177 struct ieee80211_key *key = tx->key; 173 struct ieee80211_key *key = tx->key;
178 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 174 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
175 unsigned long flags;
179 unsigned int hdrlen; 176 unsigned int hdrlen;
180 int len, tail; 177 int len, tail;
181 u8 *pos; 178 u8 *pos;
@@ -203,11 +200,12 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
203 pos += hdrlen; 200 pos += hdrlen;
204 201
205 /* Increase IV for the frame */ 202 /* Increase IV for the frame */
203 spin_lock_irqsave(&key->u.tkip.txlock, flags);
206 key->u.tkip.tx.iv16++; 204 key->u.tkip.tx.iv16++;
207 if (key->u.tkip.tx.iv16 == 0) 205 if (key->u.tkip.tx.iv16 == 0)
208 key->u.tkip.tx.iv32++; 206 key->u.tkip.tx.iv32++;
209 207 pos = ieee80211_tkip_add_iv(pos, key);
210 pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); 208 spin_unlock_irqrestore(&key->u.tkip.txlock, flags);
211 209
212 /* hwaccel - with software IV */ 210 /* hwaccel - with software IV */
213 if (info->control.hw_key) 211 if (info->control.hw_key)
@@ -216,9 +214,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
216 /* Add room for ICV */ 214 /* Add room for ICV */
217 skb_put(skb, TKIP_ICV_LEN); 215 skb_put(skb, TKIP_ICV_LEN);
218 216
219 hdr = (struct ieee80211_hdr *) skb->data;
220 return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, 217 return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
221 key, pos, len, hdr->addr2); 218 key, skb, pos, len);
222} 219}
223 220
224 221
@@ -246,11 +243,6 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
246 struct ieee80211_key *key = rx->key; 243 struct ieee80211_key *key = rx->key;
247 struct sk_buff *skb = rx->skb; 244 struct sk_buff *skb = rx->skb;
248 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 245 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
249 int queue = rx->queue;
250
251 /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */
252 if (rx->queue == NUM_RX_DATA_QUEUES - 1)
253 queue = 0;
254 246
255 hdrlen = ieee80211_hdrlen(hdr->frame_control); 247 hdrlen = ieee80211_hdrlen(hdr->frame_control);
256 248
@@ -271,7 +263,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
271 res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, 263 res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
272 key, skb->data + hdrlen, 264 key, skb->data + hdrlen,
273 skb->len - hdrlen, rx->sta->sta.addr, 265 skb->len - hdrlen, rx->sta->sta.addr,
274 hdr->addr1, hwaccel, queue, 266 hdr->addr1, hwaccel, rx->security_idx,
275 &rx->tkip_iv32, 267 &rx->tkip_iv32,
276 &rx->tkip_iv16); 268 &rx->tkip_iv16);
277 if (res != TKIP_DECRYPT_OK) 269 if (res != TKIP_DECRYPT_OK)
@@ -299,8 +291,10 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
299 unsigned int hdrlen; 291 unsigned int hdrlen;
300 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 292 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
301 293
302 b_0 = scratch + 3 * AES_BLOCK_LEN; 294 memset(scratch, 0, 6 * AES_BLOCK_SIZE);
303 aad = scratch + 4 * AES_BLOCK_LEN; 295
296 b_0 = scratch + 3 * AES_BLOCK_SIZE;
297 aad = scratch + 4 * AES_BLOCK_SIZE;
304 298
305 /* 299 /*
306 * Mask FC: zero subtype b4 b5 b6 (if not mgmt) 300 * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
@@ -389,8 +383,10 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
389 struct ieee80211_key *key = tx->key; 383 struct ieee80211_key *key = tx->key;
390 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 384 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
391 int hdrlen, len, tail; 385 int hdrlen, len, tail;
392 u8 *pos, *pn; 386 u8 *pos;
393 int i; 387 u8 pn[6];
388 u64 pn64;
389 u8 scratch[6 * AES_BLOCK_SIZE];
394 390
395 if (info->control.hw_key && 391 if (info->control.hw_key &&
396 !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { 392 !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
@@ -418,14 +414,14 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
418 hdr = (struct ieee80211_hdr *) pos; 414 hdr = (struct ieee80211_hdr *) pos;
419 pos += hdrlen; 415 pos += hdrlen;
420 416
421 /* PN = PN + 1 */ 417 pn64 = atomic64_inc_return(&key->u.ccmp.tx_pn);
422 pn = key->u.ccmp.tx_pn;
423 418
424 for (i = CCMP_PN_LEN - 1; i >= 0; i--) { 419 pn[5] = pn64;
425 pn[i]++; 420 pn[4] = pn64 >> 8;
426 if (pn[i]) 421 pn[3] = pn64 >> 16;
427 break; 422 pn[2] = pn64 >> 24;
428 } 423 pn[1] = pn64 >> 32;
424 pn[0] = pn64 >> 40;
429 425
430 ccmp_pn2hdr(pos, pn, key->conf.keyidx); 426 ccmp_pn2hdr(pos, pn, key->conf.keyidx);
431 427
@@ -434,8 +430,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
434 return 0; 430 return 0;
435 431
436 pos += CCMP_HDR_LEN; 432 pos += CCMP_HDR_LEN;
437 ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0); 433 ccmp_special_blocks(skb, pn, scratch, 0);
438 ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, key->u.ccmp.tx_crypto_buf, pos, len, 434 ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
439 pos, skb_put(skb, CCMP_MIC_LEN)); 435 pos, skb_put(skb, CCMP_MIC_LEN));
440 436
441 return 0; 437 return 0;
@@ -482,8 +478,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
482 478
483 ccmp_hdr2pn(pn, skb->data + hdrlen); 479 ccmp_hdr2pn(pn, skb->data + hdrlen);
484 480
485 queue = ieee80211_is_mgmt(hdr->frame_control) ? 481 queue = rx->security_idx;
486 NUM_RX_DATA_QUEUES : rx->queue;
487 482
488 if (memcmp(pn, key->u.ccmp.rx_pn[queue], CCMP_PN_LEN) <= 0) { 483 if (memcmp(pn, key->u.ccmp.rx_pn[queue], CCMP_PN_LEN) <= 0) {
489 key->u.ccmp.replays++; 484 key->u.ccmp.replays++;
@@ -491,11 +486,12 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
491 } 486 }
492 487
493 if (!(status->flag & RX_FLAG_DECRYPTED)) { 488 if (!(status->flag & RX_FLAG_DECRYPTED)) {
489 u8 scratch[6 * AES_BLOCK_SIZE];
494 /* hardware didn't decrypt/verify MIC */ 490 /* hardware didn't decrypt/verify MIC */
495 ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1); 491 ccmp_special_blocks(skb, pn, scratch, 1);
496 492
497 if (ieee80211_aes_ccm_decrypt( 493 if (ieee80211_aes_ccm_decrypt(
498 key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf, 494 key->u.ccmp.tfm, scratch,
499 skb->data + hdrlen + CCMP_HDR_LEN, data_len, 495 skb->data + hdrlen + CCMP_HDR_LEN, data_len,
500 skb->data + skb->len - CCMP_MIC_LEN, 496 skb->data + skb->len - CCMP_MIC_LEN,
501 skb->data + hdrlen + CCMP_HDR_LEN)) 497 skb->data + hdrlen + CCMP_HDR_LEN))
@@ -526,6 +522,16 @@ static void bip_aad(struct sk_buff *skb, u8 *aad)
526} 522}
527 523
528 524
525static inline void bip_ipn_set64(u8 *d, u64 pn)
526{
527 *d++ = pn;
528 *d++ = pn >> 8;
529 *d++ = pn >> 16;
530 *d++ = pn >> 24;
531 *d++ = pn >> 32;
532 *d = pn >> 40;
533}
534
529static inline void bip_ipn_swap(u8 *d, const u8 *s) 535static inline void bip_ipn_swap(u8 *d, const u8 *s)
530{ 536{
531 *d++ = s[5]; 537 *d++ = s[5];
@@ -544,8 +550,8 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)
544 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 550 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
545 struct ieee80211_key *key = tx->key; 551 struct ieee80211_key *key = tx->key;
546 struct ieee80211_mmie *mmie; 552 struct ieee80211_mmie *mmie;
547 u8 *pn, aad[20]; 553 u8 aad[20];
548 int i; 554 u64 pn64;
549 555
550 if (info->control.hw_key) 556 if (info->control.hw_key)
551 return 0; 557 return 0;
@@ -559,22 +565,17 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)
559 mmie->key_id = cpu_to_le16(key->conf.keyidx); 565 mmie->key_id = cpu_to_le16(key->conf.keyidx);
560 566
561 /* PN = PN + 1 */ 567 /* PN = PN + 1 */
562 pn = key->u.aes_cmac.tx_pn; 568 pn64 = atomic64_inc_return(&key->u.aes_cmac.tx_pn);
563 569
564 for (i = sizeof(key->u.aes_cmac.tx_pn) - 1; i >= 0; i--) { 570 bip_ipn_set64(mmie->sequence_number, pn64);
565 pn[i]++;
566 if (pn[i])
567 break;
568 }
569 bip_ipn_swap(mmie->sequence_number, pn);
570 571
571 bip_aad(skb, aad); 572 bip_aad(skb, aad);
572 573
573 /* 574 /*
574 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) 575 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
575 */ 576 */
576 ieee80211_aes_cmac(key->u.aes_cmac.tfm, key->u.aes_cmac.tx_crypto_buf, 577 ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
577 aad, skb->data + 24, skb->len - 24, mmie->mic); 578 skb->data + 24, skb->len - 24, mmie->mic);
578 579
579 return TX_CONTINUE; 580 return TX_CONTINUE;
580} 581}
@@ -612,8 +613,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
612 if (!(status->flag & RX_FLAG_DECRYPTED)) { 613 if (!(status->flag & RX_FLAG_DECRYPTED)) {
613 /* hardware didn't decrypt/verify MIC */ 614 /* hardware didn't decrypt/verify MIC */
614 bip_aad(skb, aad); 615 bip_aad(skb, aad);
615 ieee80211_aes_cmac(key->u.aes_cmac.tfm, 616 ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
616 key->u.aes_cmac.rx_crypto_buf, aad,
617 skb->data + 24, skb->len - 24, mic); 617 skb->data + 24, skb->len - 24, mic);
618 if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) { 618 if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
619 key->u.aes_cmac.icverrors++; 619 key->u.aes_cmac.icverrors++;