aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h59
-rw-r--r--net/mac80211/debugfs_key.c4
-rw-r--r--net/mac80211/ieee80211.c6
-rw-r--r--net/mac80211/ieee80211_i.h8
-rw-r--r--net/mac80211/ieee80211_iface.c21
-rw-r--r--net/mac80211/ieee80211_ioctl.c177
-rw-r--r--net/mac80211/ieee80211_key.h26
-rw-r--r--net/mac80211/key.c243
-rw-r--r--net/mac80211/rx.c7
-rw-r--r--net/mac80211/sta_info.c10
-rw-r--r--net/mac80211/tx.c4
-rw-r--r--net/mac80211/wpa.c30
12 files changed, 366 insertions, 229 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 3437fa16eea..ec8c7393956 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -399,19 +399,34 @@ typedef enum {
399 ALG_CCMP, 399 ALG_CCMP,
400} ieee80211_key_alg; 400} ieee80211_key_alg;
401 401
402/*
403 * This flag indiciates that the station this key is being
404 * configured for may use QoS. If your hardware cannot handle
405 * that situation it should reject that key.
406 */
407#define IEEE80211_KEY_FLAG_WMM_STA (1<<0)
408
402struct ieee80211_key_conf { 409struct ieee80211_key_conf {
403 /* shall be changed by the driver to anything but HW_KEY_IDX_INVALID */ 410 /*
411 * To be set by the driver to the key index it would like to
412 * get in the ieee80211_tx_control.key_idx which defaults
413 * to HW_KEY_IDX_INVALID so that shouldn't be used.
414 */
404 int hw_key_idx; 415 int hw_key_idx;
405 416
417 /* key algorithm, ALG_NONE should never be seen by the driver */
406 ieee80211_key_alg alg; 418 ieee80211_key_alg alg;
407 419
408 int keylen; 420 /* key flags, see above */
421 u8 flags;
422
423 /* key index: 0-3 */
424 s8 keyidx;
409 425
410#define IEEE80211_KEY_FORCE_SW_ENCRYPT (1<<0) /* to be cleared by low-level 426 /* length of key material */
411 driver */ 427 u8 keylen;
412 u32 flags; /* key configuration flags defined above */
413 428
414 s8 keyidx; /* WEP key index */ 429 /* the key material */
415 u8 key[0]; 430 u8 key[0];
416}; 431};
417 432
@@ -419,7 +434,7 @@ struct ieee80211_key_conf {
419#define IEEE80211_SEQ_COUNTER_TX 1 434#define IEEE80211_SEQ_COUNTER_TX 1
420 435
421typedef enum { 436typedef enum {
422 SET_KEY, DISABLE_KEY, REMOVE_ALL_KEYS, 437 SET_KEY, DISABLE_KEY,
423} set_key_cmd; 438} set_key_cmd;
424 439
425/* This is driver-visible part of the per-hw state the stack keeps. */ 440/* This is driver-visible part of the per-hw state the stack keeps. */
@@ -492,8 +507,7 @@ struct ieee80211_hw {
492 507
493/* hole at 6 */ 508/* hole at 6 */
494 509
495 /* Force software encryption for TKIP packets if WMM is enabled. */ 510/* hole at 7 */
496#define IEEE80211_HW_NO_TKIP_WMM_HWACCEL (1<<7)
497 511
498 /* 512 /*
499 * Some devices handle Michael MIC internally and do not include MIC in 513 * Some devices handle Michael MIC internally and do not include MIC in
@@ -627,12 +641,31 @@ struct ieee80211_ops {
627 * 641 *
628 * This is called to enable hardware acceleration of encryption and 642 * This is called to enable hardware acceleration of encryption and
629 * decryption. The address will be the broadcast address for default 643 * decryption. The address will be the broadcast address for default
630 * keys and the other station's hardware address for individual keys. 644 * keys, the other station's hardware address for individual keys or
645 * the zero address for keys that will be used only for transmission.
646 *
647 * The local_address parameter will always be set to our own address,
648 * this is only relevant if you support multiple local addresses.
649 *
631 * When transmitting, the TX control data will use the hw_key_idx 650 * When transmitting, the TX control data will use the hw_key_idx
632 * selected by the low-level driver. 651 * selected by the low-level driver.
652 *
653 * Return 0 if the key is now in use, -EOPNOTSUPP or -ENOSPC if it
654 * couldn't be added; if you return 0 then hw_key_idx must be
655 * assigned to something other than HW_KEY_IDX_INVALID. When the cmd
656 * is DISABLE_KEY then it must succeed.
657 *
658 * This callback can sleep, and is only called between add_interface
659 * and remove_interface calls, i.e. while the interface with the
660 * given local_address is enabled.
661 *
662 * The ieee80211_key_conf structure pointed to by the key parameter
663 * is guaranteed to be valid until another call to set_key removes
664 * it, but it can only be used as a cookie to differentiate keys.
633 */ 665 */
634 int (*set_key)(struct ieee80211_hw *hw, set_key_cmd cmd, 666 int (*set_key)(struct ieee80211_hw *hw, set_key_cmd cmd,
635 u8 *address, struct ieee80211_key_conf *key); 667 const u8 *local_address, const u8 *address,
668 struct ieee80211_key_conf *key);
636 669
637 /* 670 /*
638 * Set TX key index for default/broadcast keys. This is needed in cases 671 * Set TX key index for default/broadcast keys. This is needed in cases
@@ -640,6 +673,10 @@ struct ieee80211_ops {
640 * is not set), in other cases, this function pointer can be set to 673 * is not set), in other cases, this function pointer can be set to
641 * NULL since the IEEE 802.11 module takes care of selecting the key 674 * NULL since the IEEE 802.11 module takes care of selecting the key
642 * index for each TX frame. 675 * index for each TX frame.
676 *
677 * TODO: If you use this callback in your driver tell us if you need
678 * any other information from it to make it easier, like the
679 * key_conf instead.
643 */ 680 */
644 int (*set_key_idx)(struct ieee80211_hw *hw, int idx); 681 int (*set_key_idx)(struct ieee80211_hw *hw, int idx);
645 682
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 246938c32d4..36e7812da55 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -25,6 +25,7 @@ static ssize_t key_##name##_read(struct file *file, \
25 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ 25 return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
26} 26}
27#define KEY_READ_D(name) KEY_READ(name, name, 20, "%d\n") 27#define KEY_READ_D(name) KEY_READ(name, name, 20, "%d\n")
28#define KEY_READ_X(name) KEY_READ(name, name, 20, "0x%x\n")
28 29
29#define KEY_OPS(name) \ 30#define KEY_OPS(name) \
30static const struct file_operations key_ ##name## _ops = { \ 31static const struct file_operations key_ ##name## _ops = { \
@@ -39,7 +40,6 @@ static const struct file_operations key_ ##name## _ops = { \
39#define KEY_CONF_READ(name, buflen, format_string) \ 40#define KEY_CONF_READ(name, buflen, format_string) \
40 KEY_READ(conf_##name, conf.name, buflen, format_string) 41 KEY_READ(conf_##name, conf.name, buflen, format_string)
41#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, 20, "%d\n") 42#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, 20, "%d\n")
42#define KEY_CONF_READ_X(name) KEY_CONF_READ(name, 20, "0x%x\n")
43 43
44#define KEY_CONF_OPS(name) \ 44#define KEY_CONF_OPS(name) \
45static const struct file_operations key_ ##name## _ops = { \ 45static const struct file_operations key_ ##name## _ops = { \
@@ -54,7 +54,7 @@ static const struct file_operations key_ ##name## _ops = { \
54KEY_CONF_FILE(keylen, D); 54KEY_CONF_FILE(keylen, D);
55KEY_CONF_FILE(keyidx, D); 55KEY_CONF_FILE(keyidx, D);
56KEY_CONF_FILE(hw_key_idx, D); 56KEY_CONF_FILE(hw_key_idx, D);
57KEY_CONF_FILE(flags, X); 57KEY_FILE(flags, X);
58KEY_FILE(tx_rx_count, D); 58KEY_FILE(tx_rx_count, D);
59 59
60static ssize_t key_algorithm_read(struct file *file, 60static ssize_t key_algorithm_read(struct file *file,
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 5d5034f36fd..73e314e33de 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -442,6 +442,7 @@ static int ieee80211_open(struct net_device *dev)
442 } else { 442 } else {
443 ieee80211_if_config(dev); 443 ieee80211_if_config(dev);
444 ieee80211_reset_erp_info(dev); 444 ieee80211_reset_erp_info(dev);
445 ieee80211_enable_keys(sdata);
445 } 446 }
446 447
447 if (sdata->type == IEEE80211_IF_TYPE_STA && 448 if (sdata->type == IEEE80211_IF_TYPE_STA &&
@@ -510,6 +511,9 @@ static int ieee80211_stop(struct net_device *dev)
510 local->monitors--; 511 local->monitors--;
511 if (!local->monitors) 512 if (!local->monitors)
512 local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; 513 local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
514 } else {
515 /* disable all keys for as long as this netdev is down */
516 ieee80211_disable_keys(sdata);
513 } 517 }
514 518
515 local->open_count--; 519 local->open_count--;
@@ -908,7 +912,7 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
908 } 912 }
909 913
910 if (skb->len >= mic_len && 914 if (skb->len >= mic_len &&
911 (key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) 915 !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
912 skb_trim(skb, skb->len - mic_len); 916 skb_trim(skb, skb->len - mic_len);
913 if (skb->len >= iv_len && skb->len > hdrlen) { 917 if (skb->len >= iv_len && skb->len > hdrlen) {
914 memmove(skb->data + iv_len, skb->data, hdrlen); 918 memmove(skb->data + iv_len, skb->data, hdrlen);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 7b5cc146c81..0149f905591 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -291,6 +291,9 @@ struct ieee80211_sub_if_data {
291 291
292 struct wireless_dev wdev; 292 struct wireless_dev wdev;
293 293
294 /* keys */
295 struct list_head key_list;
296
294 struct net_device *dev; 297 struct net_device *dev;
295 struct ieee80211_local *local; 298 struct ieee80211_local *local;
296 299
@@ -810,11 +813,6 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
810int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); 813int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
811int ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev); 814int ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev);
812 815
813/* key handling */
814struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata,
815 int idx, size_t key_len, gfp_t flags);
816void ieee80211_key_free(struct ieee80211_key *key);
817
818/* utility functions/constants */ 816/* utility functions/constants */
819extern void *mac80211_wiphy_privid; /* for wiphy privid */ 817extern void *mac80211_wiphy_privid; /* for wiphy privid */
820extern const unsigned char rfc1042_header[6]; 818extern const unsigned char rfc1042_header[6];
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c
index 8bb85f19438..f9c74bb09d3 100644
--- a/net/mac80211/ieee80211_iface.c
+++ b/net/mac80211/ieee80211_iface.c
@@ -25,6 +25,8 @@ void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata)
25 sdata->eapol = 1; 25 sdata->eapol = 1;
26 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) 26 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
27 skb_queue_head_init(&sdata->fragments[i].skb_list); 27 skb_queue_head_init(&sdata->fragments[i].skb_list);
28
29 INIT_LIST_HEAD(&sdata->key_list);
28} 30}
29 31
30static void ieee80211_if_sdata_deinit(struct ieee80211_sub_if_data *sdata) 32static void ieee80211_if_sdata_deinit(struct ieee80211_sub_if_data *sdata)
@@ -210,25 +212,12 @@ void ieee80211_if_reinit(struct net_device *dev)
210 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 212 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
211 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 213 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
212 struct sta_info *sta; 214 struct sta_info *sta;
213 int i;
214 215
215 ASSERT_RTNL(); 216 ASSERT_RTNL();
217
218 ieee80211_free_keys(sdata);
219
216 ieee80211_if_sdata_deinit(sdata); 220 ieee80211_if_sdata_deinit(sdata);
217 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
218 if (!sdata->keys[i])
219 continue;
220#if 0
221 /* The interface is down at the moment, so there is not
222 * really much point in disabling the keys at this point. */
223 memset(addr, 0xff, ETH_ALEN);
224 if (local->ops->set_key)
225 local->ops->set_key(local_to_hw(local), DISABLE_KEY, addr,
226 local->keys[i],
227 local->default_wep_only);
228#endif
229 ieee80211_key_free(sdata->keys[i]);
230 sdata->keys[i] = NULL;
231 }
232 221
233 switch (sdata->type) { 222 switch (sdata->type) {
234 case IEEE80211_IF_TYPE_AP: { 223 case IEEE80211_IF_TYPE_AP: {
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index dc05bc66fbb..8296e7de12c 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -25,28 +25,6 @@
25#include "ieee80211_rate.h" 25#include "ieee80211_rate.h"
26#include "wpa.h" 26#include "wpa.h"
27#include "aes_ccm.h" 27#include "aes_ccm.h"
28#include "debugfs_key.h"
29
30static void ieee80211_set_hw_encryption(struct net_device *dev,
31 struct sta_info *sta, u8 addr[ETH_ALEN],
32 struct ieee80211_key *key)
33{
34 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
35
36 /* default to sw encryption; this will be cleared by low-level
37 * driver if the hw supports requested encryption */
38 if (key)
39 key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
40
41 if (key && local->ops->set_key) {
42 if (local->ops->set_key(local_to_hw(local), SET_KEY, addr,
43 &key->conf)) {
44 key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
45 key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
46 }
47 }
48}
49
50 28
51static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, 29static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
52 int idx, int alg, int set_tx_key, 30 int idx, int alg, int set_tx_key,
@@ -55,8 +33,7 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
55 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 33 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
56 int ret = 0; 34 int ret = 0;
57 struct sta_info *sta; 35 struct sta_info *sta;
58 struct ieee80211_key *key, *old_key; 36 struct ieee80211_key *key;
59 int try_hwaccel = 1;
60 struct ieee80211_sub_if_data *sdata; 37 struct ieee80211_sub_if_data *sdata;
61 38
62 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 39 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -69,16 +46,6 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
69 return -EINVAL; 46 return -EINVAL;
70 } 47 }
71 key = sdata->keys[idx]; 48 key = sdata->keys[idx];
72
73 /* TODO: consider adding hwaccel support for these; at least
74 * Atheros key cache should be able to handle this since AP is
75 * only transmitting frames with default keys. */
76 /* FIX: hw key cache can be used when only one virtual
77 * STA is associated with each AP. If more than one STA
78 * is associated to the same AP, software encryption
79 * must be used. This should be done automatically
80 * based on configured station devices. For the time
81 * being, this can be only set at compile time. */
82 } else { 49 } else {
83 set_tx_key = 0; 50 set_tx_key = 0;
84 if (idx != 0) { 51 if (idx != 0) {
@@ -101,139 +68,28 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
101 key = sta->key; 68 key = sta->key;
102 } 69 }
103 70
104 /* FIX:
105 * Cannot configure default hwaccel keys with WEP algorithm, if
106 * any of the virtual interfaces is using static WEP
107 * configuration because hwaccel would otherwise try to decrypt
108 * these frames.
109 *
110 * For now, just disable WEP hwaccel for broadcast when there is
111 * possibility of conflict with default keys. This can maybe later be
112 * optimized by using non-default keys (at least with Atheros ar521x).
113 */
114 if (!sta && alg == ALG_WEP &&
115 sdata->type != IEEE80211_IF_TYPE_IBSS &&
116 sdata->type != IEEE80211_IF_TYPE_AP) {
117 try_hwaccel = 0;
118 }
119
120 if (local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) {
121 /* Software encryption cannot be used with devices that hide
122 * encryption from the host system, so always try to use
123 * hardware acceleration with such devices. */
124 try_hwaccel = 1;
125 }
126
127 if ((local->hw.flags & IEEE80211_HW_NO_TKIP_WMM_HWACCEL) &&
128 alg == ALG_TKIP) {
129 if (sta && (sta->flags & WLAN_STA_WME)) {
130 /* Hardware does not support hwaccel with TKIP when using WMM.
131 */
132 try_hwaccel = 0;
133 }
134 else if (sdata->type == IEEE80211_IF_TYPE_STA) {
135 sta = sta_info_get(local, sdata->u.sta.bssid);
136 if (sta) {
137 if (sta->flags & WLAN_STA_WME) {
138 try_hwaccel = 0;
139 }
140 sta_info_put(sta);
141 sta = NULL;
142 }
143 }
144 }
145
146 if (alg == ALG_NONE) { 71 if (alg == ALG_NONE) {
147 if (try_hwaccel && key &&
148 key->conf.hw_key_idx != HW_KEY_IDX_INVALID &&
149 local->ops->set_key &&
150 local->ops->set_key(local_to_hw(local), DISABLE_KEY,
151 sta_addr, &key->conf)) {
152 printk(KERN_DEBUG "%s: set_encrypt - low-level disable"
153 " failed\n", dev->name);
154 ret = -EINVAL;
155 }
156
157 if (set_tx_key || sdata->default_key == key) {
158 ieee80211_debugfs_key_remove_default(sdata);
159 sdata->default_key = NULL;
160 }
161 ieee80211_debugfs_key_remove(key);
162 if (sta)
163 sta->key = NULL;
164 else
165 sdata->keys[idx] = NULL;
166 ieee80211_key_free(key); 72 ieee80211_key_free(key);
167 key = NULL; 73 key = NULL;
168 } else { 74 } else {
169 old_key = key; 75 /*
170 key = ieee80211_key_alloc(sta ? NULL : sdata, idx, key_len, 76 * Need to free it before allocating a new one with
171 GFP_KERNEL); 77 * with the same index or the ordering to the driver's
78 * set_key() callback becomes confused.
79 */
80 ieee80211_key_free(key);
81 key = ieee80211_key_alloc(sdata, sta, alg, idx, key_len, _key);
172 if (!key) { 82 if (!key) {
173 ret = -ENOMEM; 83 ret = -ENOMEM;
174 goto err_out; 84 goto err_out;
175 } 85 }
176
177 /* default to sw encryption; low-level driver sets these if the
178 * requested encryption is supported */
179 key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
180 key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
181
182 key->conf.alg = alg;
183 key->conf.keyidx = idx;
184 key->conf.keylen = key_len;
185 memcpy(key->conf.key, _key, key_len);
186
187 if (alg == ALG_CCMP) {
188 /* Initialize AES key state here as an optimization
189 * so that it does not need to be initialized for every
190 * packet. */
191 key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(
192 key->conf.key);
193 if (!key->u.ccmp.tfm) {
194 ret = -ENOMEM;
195 goto err_free;
196 }
197 }
198
199 if (set_tx_key || sdata->default_key == old_key) {
200 ieee80211_debugfs_key_remove_default(sdata);
201 sdata->default_key = NULL;
202 }
203 ieee80211_debugfs_key_remove(old_key);
204 if (sta)
205 sta->key = key;
206 else
207 sdata->keys[idx] = key;
208 ieee80211_key_free(old_key);
209 ieee80211_debugfs_key_add(local, key);
210 if (sta)
211 ieee80211_debugfs_key_sta_link(key, sta);
212
213 if (try_hwaccel &&
214 (alg == ALG_WEP || alg == ALG_TKIP || alg == ALG_CCMP))
215 ieee80211_set_hw_encryption(dev, sta, sta_addr, key);
216 }
217
218 if (set_tx_key || (!sta && !sdata->default_key && key)) {
219 sdata->default_key = key;
220 if (key)
221 ieee80211_debugfs_key_add_default(sdata);
222
223 if (local->ops->set_key_idx &&
224 local->ops->set_key_idx(local_to_hw(local), idx))
225 printk(KERN_DEBUG "%s: failed to set TX key idx for "
226 "low-level driver\n", dev->name);
227 } 86 }
228 87
229 if (sta) 88 if (set_tx_key || (!sta && !sdata->default_key && key))
230 sta_info_put(sta); 89 ieee80211_set_default_key(sdata, idx);
231 90
232 return 0; 91 ret = 0;
233 92 err_out:
234err_free:
235 ieee80211_key_free(key);
236err_out:
237 if (sta) 93 if (sta)
238 sta_info_put(sta); 94 sta_info_put(sta);
239 return ret; 95 return ret;
@@ -1181,12 +1037,7 @@ static int ieee80211_ioctl_siwencode(struct net_device *dev,
1181 alg = ALG_NONE; 1037 alg = ALG_NONE;
1182 else if (erq->length == 0) { 1038 else if (erq->length == 0) {
1183 /* No key data - just set the default TX key index */ 1039 /* No key data - just set the default TX key index */
1184 if (sdata->default_key != sdata->keys[idx]) { 1040 ieee80211_set_default_key(sdata, idx);
1185 ieee80211_debugfs_key_remove_default(sdata);
1186 sdata->default_key = sdata->keys[idx];
1187 if (sdata->default_key)
1188 ieee80211_debugfs_key_add_default(sdata);
1189 }
1190 return 0; 1041 return 0;
1191 } 1042 }
1192 1043
@@ -1232,7 +1083,7 @@ static int ieee80211_ioctl_giwencode(struct net_device *dev,
1232 } 1083 }
1233 1084
1234 memcpy(key, sdata->keys[idx]->conf.key, 1085 memcpy(key, sdata->keys[idx]->conf.key,
1235 min((int)erq->length, sdata->keys[idx]->conf.keylen)); 1086 min_t(int, erq->length, sdata->keys[idx]->conf.keylen));
1236 erq->length = sdata->keys[idx]->conf.keylen; 1087 erq->length = sdata->keys[idx]->conf.keylen;
1237 erq->flags |= IW_ENCODE_ENABLED; 1088 erq->flags |= IW_ENCODE_ENABLED;
1238 1089
diff --git a/net/mac80211/ieee80211_key.h b/net/mac80211/ieee80211_key.h
index 58e19253082..a4e5fbbe045 100644
--- a/net/mac80211/ieee80211_key.h
+++ b/net/mac80211/ieee80211_key.h
@@ -41,7 +41,21 @@
41 41
42#define NUM_RX_DATA_QUEUES 17 42#define NUM_RX_DATA_QUEUES 17
43 43
44struct ieee80211_local;
45struct ieee80211_sub_if_data;
46struct sta_info;
47
48#define KEY_FLAG_UPLOADED_TO_HARDWARE (1<<0)
49
44struct ieee80211_key { 50struct ieee80211_key {
51 struct ieee80211_local *local;
52 struct ieee80211_sub_if_data *sdata;
53 struct sta_info *sta;
54
55 struct list_head list;
56
57 unsigned int flags;
58
45 union { 59 union {
46 struct { 60 struct {
47 /* last used TSC */ 61 /* last used TSC */
@@ -97,4 +111,16 @@ struct ieee80211_key {
97 struct ieee80211_key_conf conf; 111 struct ieee80211_key_conf conf;
98}; 112};
99 113
114struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata,
115 struct sta_info *sta,
116 ieee80211_key_alg alg,
117 int idx,
118 size_t key_len,
119 const u8 *key_data);
120void ieee80211_key_free(struct ieee80211_key *key);
121void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx);
122void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
123void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
124void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata);
125
100#endif /* IEEE80211_KEY_H */ 126#endif /* IEEE80211_KEY_H */
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 843d1577f00..178f00cf61b 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -2,25 +2,198 @@
2 * Copyright 2002-2005, Instant802 Networks, Inc. 2 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005-2006, Devicescape Software, Inc. 3 * Copyright 2005-2006, Devicescape Software, Inc.
4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
5 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
9 */ 10 */
10 11
12#include <linux/if_ether.h>
13#include <linux/etherdevice.h>
14#include <linux/list.h>
11#include <net/mac80211.h> 15#include <net/mac80211.h>
12#include "ieee80211_i.h" 16#include "ieee80211_i.h"
13#include "debugfs_key.h" 17#include "debugfs_key.h"
14#include "aes_ccm.h" 18#include "aes_ccm.h"
15 19
20
21/*
22 * Key handling basics
23 *
24 * Key handling in mac80211 is done based on per-interface (sub_if_data)
25 * keys and per-station keys. Since each station belongs to an interface,
26 * each station key also belongs to that interface.
27 *
28 * Hardware acceleration is done on a best-effort basis, for each key
29 * that is eligible the hardware is asked to enable that key but if
30 * it cannot do that they key is simply kept for software encryption.
31 * There is currently no way of knowing this except by looking into
32 * debugfs.
33 *
34 * All operations here are called under RTNL so no extra locking is
35 * required.
36 */
37
38static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
39static const u8 zero_addr[ETH_ALEN];
40
41static const u8 *get_mac_for_key(struct ieee80211_key *key)
42{
43 const u8 *addr = bcast_addr;
44
45 /*
46 * If we're an AP we won't ever receive frames with a non-WEP
47 * group key so we tell the driver that by using the zero MAC
48 * address to indicate a transmit-only key.
49 */
50 if (key->conf.alg != ALG_WEP &&
51 (key->sdata->type == IEEE80211_IF_TYPE_AP ||
52 key->sdata->type == IEEE80211_IF_TYPE_VLAN))
53 addr = zero_addr;
54
55 if (key->sta)
56 addr = key->sta->addr;
57
58 return addr;
59}
60
61static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
62{
63 const u8 *addr;
64 int ret;
65
66 if (!key->local->ops->set_key)
67 return;
68
69 addr = get_mac_for_key(key);
70
71 ret = key->local->ops->set_key(local_to_hw(key->local), SET_KEY,
72 key->sdata->dev->dev_addr, addr,
73 &key->conf);
74
75 WARN_ON(!ret && (key->conf.hw_key_idx == HW_KEY_IDX_INVALID));
76
77 if (!ret)
78 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
79
80 if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP)
81 printk(KERN_ERR "mac80211-%s: failed to set key "
82 "(%d, " MAC_FMT ") to hardware (%d)\n",
83 wiphy_name(key->local->hw.wiphy),
84 key->conf.keyidx, MAC_ARG(addr), ret);
85}
86
87static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
88{
89 const u8 *addr;
90 int ret;
91
92 if (!key->local->ops->set_key)
93 return;
94
95 if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
96 return;
97
98 addr = get_mac_for_key(key);
99
100 ret = key->local->ops->set_key(local_to_hw(key->local), DISABLE_KEY,
101 key->sdata->dev->dev_addr, addr,
102 &key->conf);
103
104 if (ret)
105 printk(KERN_ERR "mac80211-%s: failed to remove key "
106 "(%d, " MAC_FMT ") from hardware (%d)\n",
107 wiphy_name(key->local->hw.wiphy),
108 key->conf.keyidx, MAC_ARG(addr), ret);
109
110 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
111 key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
112}
113
16struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata, 114struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata,
17 int idx, size_t key_len, gfp_t flags) 115 struct sta_info *sta,
116 ieee80211_key_alg alg,
117 int idx,
118 size_t key_len,
119 const u8 *key_data)
18{ 120{
19 struct ieee80211_key *key; 121 struct ieee80211_key *key;
20 122
21 key = kzalloc(sizeof(struct ieee80211_key) + key_len, flags); 123 BUG_ON(alg == ALG_NONE);
124
125 key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL);
22 if (!key) 126 if (!key)
23 return NULL; 127 return NULL;
128
129 /*
130 * Default to software encryption; we'll later upload the
131 * key to the hardware if possible.
132 */
133 key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
134 key->conf.flags = 0;
135 key->flags = 0;
136
137 key->conf.alg = alg;
138 key->conf.keyidx = idx;
139 key->conf.keylen = key_len;
140 memcpy(key->conf.key, key_data, key_len);
141
142 key->local = sdata->local;
143 key->sdata = sdata;
144 key->sta = sta;
145
146 if (alg == ALG_CCMP) {
147 /*
148 * Initialize AES key state here as an optimization so that
149 * it does not need to be initialized for every packet.
150 */
151 key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data);
152 if (!key->u.ccmp.tfm) {
153 ieee80211_key_free(key);
154 return NULL;
155 }
156 }
157
158 ieee80211_debugfs_key_add(key->local, key);
159
160 if (sta) {
161 ieee80211_debugfs_key_sta_link(key, sta);
162 sta->key = key;
163 /*
164 * some hardware cannot handle TKIP with QoS, so
165 * we indicate whether QoS could be in use.
166 */
167 if (sta->flags & WLAN_STA_WME)
168 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
169 } else {
170 if (sdata->type == IEEE80211_IF_TYPE_STA) {
171 struct sta_info *ap;
172
173 /* same here, the AP could be using QoS */
174 ap = sta_info_get(key->local, key->sdata->u.sta.bssid);
175 if (ap) {
176 if (ap->flags & WLAN_STA_WME)
177 key->conf.flags |=
178 IEEE80211_KEY_FLAG_WMM_STA;
179 sta_info_put(ap);
180 }
181 }
182
183 if (idx >= 0 && idx < NUM_DEFAULT_KEYS) {
184 if (!sdata->keys[idx])
185 sdata->keys[idx] = key;
186 else
187 WARN_ON(1);
188 } else
189 WARN_ON(1);
190 }
191
192 list_add(&key->list, &sdata->key_list);
193
194 if (netif_running(key->sdata->dev))
195 ieee80211_key_enable_hw_accel(key);
196
24 return key; 197 return key;
25} 198}
26 199
@@ -29,8 +202,74 @@ void ieee80211_key_free(struct ieee80211_key *key)
29 if (!key) 202 if (!key)
30 return; 203 return;
31 204
205 ieee80211_key_disable_hw_accel(key);
206
207 if (key->sta) {
208 key->sta->key = NULL;
209 } else {
210 if (key->sdata->default_key == key)
211 ieee80211_set_default_key(key->sdata, -1);
212 if (key->conf.keyidx >= 0 &&
213 key->conf.keyidx < NUM_DEFAULT_KEYS)
214 key->sdata->keys[key->conf.keyidx] = NULL;
215 else
216 WARN_ON(1);
217 }
218
32 if (key->conf.alg == ALG_CCMP) 219 if (key->conf.alg == ALG_CCMP)
33 ieee80211_aes_key_free(key->u.ccmp.tfm); 220 ieee80211_aes_key_free(key->u.ccmp.tfm);
34 ieee80211_debugfs_key_remove(key); 221 ieee80211_debugfs_key_remove(key);
222
223 list_del(&key->list);
224
35 kfree(key); 225 kfree(key);
36} 226}
227
228void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx)
229{
230 struct ieee80211_key *key = NULL;
231
232 if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
233 key = sdata->keys[idx];
234
235 if (sdata->default_key != key) {
236 ieee80211_debugfs_key_remove_default(sdata);
237
238 sdata->default_key = key;
239
240 if (sdata->default_key)
241 ieee80211_debugfs_key_add_default(sdata);
242
243 if (sdata->local->ops->set_key_idx)
244 sdata->local->ops->set_key_idx(
245 local_to_hw(sdata->local), idx);
246 }
247}
248
249void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
250{
251 struct ieee80211_key *key, *tmp;
252
253 list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
254 ieee80211_key_free(key);
255}
256
257void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
258{
259 struct ieee80211_key *key;
260
261 WARN_ON(!netif_running(sdata->dev));
262 if (!netif_running(sdata->dev))
263 return;
264
265 list_for_each_entry(key, &sdata->key_list, list)
266 ieee80211_key_enable_hw_accel(key);
267}
268
269void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata)
270{
271 struct ieee80211_key *key;
272
273 list_for_each_entry(key, &sdata->key_list, list)
274 ieee80211_key_disable_hw_accel(key);
275}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 976b646a40d..ba94f58ba02 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -528,7 +528,7 @@ ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx)
528 528
529 /* Check for weak IVs, if hwaccel did not remove IV from the frame */ 529 /* Check for weak IVs, if hwaccel did not remove IV from the frame */
530 if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) || 530 if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) ||
531 (rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) 531 !(rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
532 if (ieee80211_wep_is_weak_iv(rx->skb, rx->key)) 532 if (ieee80211_wep_is_weak_iv(rx->skb, rx->key))
533 rx->sta->wep_weak_iv_count++; 533 rx->sta->wep_weak_iv_count++;
534 534
@@ -553,7 +553,7 @@ ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx)
553 } 553 }
554 554
555 if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED) || 555 if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED) ||
556 (rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) { 556 !(rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
557 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { 557 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
558 if (net_ratelimit()) 558 if (net_ratelimit())
559 printk(KERN_DEBUG "%s: RX WEP frame, decrypt " 559 printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
@@ -897,8 +897,7 @@ ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx)
897 * uploaded to the hardware. 897 * uploaded to the hardware.
898 */ 898 */
899 if ((rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) && 899 if ((rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) &&
900 (!rx->key || 900 (!rx->key || (rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)))
901 !(rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)))
902 return TXRX_CONTINUE; 901 return TXRX_CONTINUE;
903 902
904 /* Drop unencrypted frames if key is set. */ 903 /* Drop unencrypted frames if key is set. */
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index fba2d79e4d2..c17172abb21 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -19,7 +19,6 @@
19#include "ieee80211_i.h" 19#include "ieee80211_i.h"
20#include "ieee80211_rate.h" 20#include "ieee80211_rate.h"
21#include "sta_info.h" 21#include "sta_info.h"
22#include "debugfs_key.h"
23#include "debugfs_sta.h" 22#include "debugfs_sta.h"
24 23
25/* Caller must hold local->sta_lock */ 24/* Caller must hold local->sta_lock */
@@ -118,8 +117,6 @@ static void sta_info_release(struct kref *kref)
118 } 117 }
119 rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); 118 rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv);
120 rate_control_put(sta->rate_ctrl); 119 rate_control_put(sta->rate_ctrl);
121 if (sta->key)
122 ieee80211_debugfs_key_sta_del(sta->key, sta);
123 kfree(sta); 120 kfree(sta);
124} 121}
125 122
@@ -230,11 +227,8 @@ void sta_info_free(struct sta_info *sta)
230 local->mdev->name, MAC_ARG(sta->addr)); 227 local->mdev->name, MAC_ARG(sta->addr));
231#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 228#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
232 229
233 if (sta->key) { 230 ieee80211_key_free(sta->key);
234 ieee80211_debugfs_key_remove(sta->key); 231 sta->key = NULL;
235 ieee80211_key_free(sta->key);
236 sta->key = NULL;
237 }
238 232
239 rate_control_remove_sta_debugfs(sta); 233 rate_control_remove_sta_debugfs(sta);
240 ieee80211_sta_debugfs_remove(sta); 234 ieee80211_sta_debugfs_remove(sta);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index d70140cbd66..b65ff653624 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -536,7 +536,7 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx)
536 536
537static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb) 537static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
538{ 538{
539 if (tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) { 539 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
540 if (ieee80211_wep_encrypt(tx->local, skb, tx->key)) 540 if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
541 return -1; 541 return -1;
542 } else { 542 } else {
@@ -832,7 +832,7 @@ __ieee80211_parse_tx_radiotap(
832 */ 832 */
833 833
834 control->retry_limit = 1; /* no retry */ 834 control->retry_limit = 1; /* no retry */
835 control->key_idx = -1; /* no encryption key */ 835 control->key_idx = HW_KEY_IDX_INVALID;
836 control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS | 836 control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS |
837 IEEE80211_TXCTL_USE_CTS_PROTECT); 837 IEEE80211_TXCTL_USE_CTS_PROTECT);
838 control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT | 838 control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 4a2a9aa638b..b6cd66e0ee5 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -89,7 +89,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx)
89 if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)) 89 if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len))
90 return TXRX_DROP; 90 return TXRX_DROP;
91 91
92 if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) && 92 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
93 !(tx->flags & IEEE80211_TXRXD_FRAGMENTED) && 93 !(tx->flags & IEEE80211_TXRXD_FRAGMENTED) &&
94 !(tx->local->hw.flags & IEEE80211_HW_TKIP_INCLUDE_MMIC) && 94 !(tx->local->hw.flags & IEEE80211_HW_TKIP_INCLUDE_MMIC) &&
95 !wpa_test) { 95 !wpa_test) {
@@ -146,7 +146,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
146 return TXRX_CONTINUE; 146 return TXRX_CONTINUE;
147 147
148 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && 148 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
149 !(rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) { 149 (rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
150 if (rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) { 150 if (rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) {
151 if (skb->len < MICHAEL_MIC_LEN) 151 if (skb->len < MICHAEL_MIC_LEN)
152 return TXRX_DROP; 152 return TXRX_DROP;
@@ -205,10 +205,10 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
205 hdrlen = ieee80211_get_hdrlen(fc); 205 hdrlen = ieee80211_get_hdrlen(fc);
206 len = skb->len - hdrlen; 206 len = skb->len - hdrlen;
207 207
208 if (tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) 208 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
209 tailneed = TKIP_ICV_LEN;
210 else
211 tailneed = 0; 209 tailneed = 0;
210 else
211 tailneed = TKIP_ICV_LEN;
212 212
213 if ((skb_headroom(skb) < TKIP_IV_LEN || 213 if ((skb_headroom(skb) < TKIP_IV_LEN ||
214 skb_tailroom(skb) < tailneed)) { 214 skb_tailroom(skb) < tailneed)) {
@@ -227,7 +227,7 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
227 if (key->u.tkip.iv16 == 0) 227 if (key->u.tkip.iv16 == 0)
228 key->u.tkip.iv32++; 228 key->u.tkip.iv32++;
229 229
230 if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) { 230 if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
231 u32 flags = tx->local->hw.flags; 231 u32 flags = tx->local->hw.flags;
232 hdr = (struct ieee80211_hdr *)skb->data; 232 hdr = (struct ieee80211_hdr *)skb->data;
233 233
@@ -286,7 +286,7 @@ ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx)
286 tx->u.tx.control->iv_len = TKIP_IV_LEN; 286 tx->u.tx.control->iv_len = TKIP_IV_LEN;
287 ieee80211_tx_set_iswep(tx); 287 ieee80211_tx_set_iswep(tx);
288 288
289 if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) && 289 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
290 !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) && 290 !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) &&
291 !wpa_test) { 291 !wpa_test) {
292 /* hwaccel - with no need for preallocated room for IV/ICV */ 292 /* hwaccel - with no need for preallocated room for IV/ICV */
@@ -331,7 +331,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
331 return TXRX_DROP; 331 return TXRX_DROP;
332 332
333 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && 333 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
334 !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) { 334 (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
335 if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) { 335 if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) {
336 /* Hardware takes care of all processing, including 336 /* Hardware takes care of all processing, including
337 * replay protection, so no need to continue here. */ 337 * replay protection, so no need to continue here. */
@@ -475,10 +475,10 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
475 hdrlen = ieee80211_get_hdrlen(fc); 475 hdrlen = ieee80211_get_hdrlen(fc);
476 len = skb->len - hdrlen; 476 len = skb->len - hdrlen;
477 477
478 if (key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) 478 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
479 tailneed = CCMP_MIC_LEN;
480 else
481 tailneed = 0; 479 tailneed = 0;
480 else
481 tailneed = CCMP_MIC_LEN;
482 482
483 if ((skb_headroom(skb) < CCMP_HDR_LEN || 483 if ((skb_headroom(skb) < CCMP_HDR_LEN ||
484 skb_tailroom(skb) < tailneed)) { 484 skb_tailroom(skb) < tailneed)) {
@@ -504,7 +504,7 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
504 504
505 ccmp_pn2hdr(pos, pn, key->conf.keyidx); 505 ccmp_pn2hdr(pos, pn, key->conf.keyidx);
506 506
507 if (!(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) { 507 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
508 /* hwaccel - with preallocated room for CCMP header */ 508 /* hwaccel - with preallocated room for CCMP header */
509 tx->u.tx.control->key_idx = key->conf.hw_key_idx; 509 tx->u.tx.control->key_idx = key->conf.hw_key_idx;
510 return 0; 510 return 0;
@@ -537,7 +537,7 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx)
537 tx->u.tx.control->iv_len = CCMP_HDR_LEN; 537 tx->u.tx.control->iv_len = CCMP_HDR_LEN;
538 ieee80211_tx_set_iswep(tx); 538 ieee80211_tx_set_iswep(tx);
539 539
540 if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) && 540 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
541 !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) { 541 !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) {
542 /* hwaccel - with no need for preallocated room for CCMP " 542 /* hwaccel - with no need for preallocated room for CCMP "
543 * header or MIC fields */ 543 * header or MIC fields */
@@ -586,7 +586,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
586 return TXRX_DROP; 586 return TXRX_DROP;
587 587
588 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && 588 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
589 !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) && 589 (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
590 !(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) 590 !(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV))
591 return TXRX_CONTINUE; 591 return TXRX_CONTINUE;
592 592
@@ -607,7 +607,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
607 } 607 }
608 608
609 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && 609 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
610 !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) { 610 (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
611 /* hwaccel has already decrypted frame and verified MIC */ 611 /* hwaccel has already decrypted frame and verified MIC */
612 } else { 612 } else {
613 u8 *scratch, *b_0, *aad; 613 u8 *scratch, *b_0, *aad;