aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-08-28 17:01:54 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:48:51 -0400
commit8f20fc24986a083228823d9b68adca20714b254e (patch)
treeb5d7638b913649c7a181d6703ccd72e35ca06de9 /net/mac80211
parent13262ffd4902805acad2618c12b41fcaa6c50791 (diff)
[MAC80211]: embed key conf in key, fix driver interface
This patch embeds the struct ieee80211_key_conf into struct ieee80211_key and thus avoids allocations and having data present twice. This required some more changes: 1) The removal of the IEEE80211_KEY_DEFAULT_TX_KEY key flag. This flag isn't used by drivers nor should it be since we have a set_key_idx() callback. Maybe that callback needs to be extended to include the key conf, but only a driver that requires it will tell. 2) The removal of the IEEE80211_KEY_DEFAULT_WEP_ONLY key flag. This flag is global, so it shouldn't be passed in the key conf structure. Pass it to the function instead. Also, this patch removes the AID parameter to the set_key() callback because it is currently unused and the hardware currently cannot know about the AID anyway. I suspect this was used with some hardware that actually selected the AID itself, but that functionality was removed. Additionally, I've removed the ALG_NULL key algorithm since we have ALG_NONE. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/debugfs_key.c49
-rw-r--r--net/mac80211/ieee80211.c5
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/ieee80211_iface.c3
-rw-r--r--net/mac80211/ieee80211_ioctl.c79
-rw-r--r--net/mac80211/ieee80211_key.h20
-rw-r--r--net/mac80211/ieee80211_sta.c2
-rw-r--r--net/mac80211/key.c28
-rw-r--r--net/mac80211/rx.c22
-rw-r--r--net/mac80211/sta_info.c17
-rw-r--r--net/mac80211/tkip.c18
-rw-r--r--net/mac80211/tx.c6
-rw-r--r--net/mac80211/wep.c18
-rw-r--r--net/mac80211/wpa.c61
14 files changed, 150 insertions, 181 deletions
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 077f907271cf..246938c32d4d 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -14,17 +14,17 @@
14#include "debugfs.h" 14#include "debugfs.h"
15#include "debugfs_key.h" 15#include "debugfs_key.h"
16 16
17#define KEY_READ(name, buflen, format_string) \ 17#define KEY_READ(name, prop, buflen, format_string) \
18static ssize_t key_##name##_read(struct file *file, \ 18static ssize_t key_##name##_read(struct file *file, \
19 char __user *userbuf, \ 19 char __user *userbuf, \
20 size_t count, loff_t *ppos) \ 20 size_t count, loff_t *ppos) \
21{ \ 21{ \
22 char buf[buflen]; \ 22 char buf[buflen]; \
23 struct ieee80211_key *key = file->private_data; \ 23 struct ieee80211_key *key = file->private_data; \
24 int res = scnprintf(buf, buflen, format_string, key->name); \ 24 int res = scnprintf(buf, buflen, format_string, key->prop); \
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, 20, "%d\n") 27#define KEY_READ_D(name) KEY_READ(name, name, 20, "%d\n")
28 28
29#define KEY_OPS(name) \ 29#define KEY_OPS(name) \
30static const struct file_operations key_ ##name## _ops = { \ 30static const struct file_operations key_ ##name## _ops = { \
@@ -36,10 +36,25 @@ static const struct file_operations key_ ##name## _ops = { \
36 KEY_READ_##format(name) \ 36 KEY_READ_##format(name) \
37 KEY_OPS(name) 37 KEY_OPS(name)
38 38
39KEY_FILE(keylen, D); 39#define KEY_CONF_READ(name, buflen, format_string) \
40KEY_FILE(force_sw_encrypt, D); 40 KEY_READ(conf_##name, conf.name, buflen, format_string)
41KEY_FILE(keyidx, D); 41#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, 20, "%d\n")
42KEY_FILE(hw_key_idx, D); 42#define KEY_CONF_READ_X(name) KEY_CONF_READ(name, 20, "0x%x\n")
43
44#define KEY_CONF_OPS(name) \
45static const struct file_operations key_ ##name## _ops = { \
46 .read = key_conf_##name##_read, \
47 .open = mac80211_open_file_generic, \
48}
49
50#define KEY_CONF_FILE(name, format) \
51 KEY_CONF_READ_##format(name) \
52 KEY_CONF_OPS(name)
53
54KEY_CONF_FILE(keylen, D);
55KEY_CONF_FILE(keyidx, D);
56KEY_CONF_FILE(hw_key_idx, D);
57KEY_CONF_FILE(flags, X);
43KEY_FILE(tx_rx_count, D); 58KEY_FILE(tx_rx_count, D);
44 59
45static ssize_t key_algorithm_read(struct file *file, 60static ssize_t key_algorithm_read(struct file *file,
@@ -49,7 +64,7 @@ static ssize_t key_algorithm_read(struct file *file,
49 char *alg; 64 char *alg;
50 struct ieee80211_key *key = file->private_data; 65 struct ieee80211_key *key = file->private_data;
51 66
52 switch (key->alg) { 67 switch (key->conf.alg) {
53 case ALG_WEP: 68 case ALG_WEP:
54 alg = "WEP\n"; 69 alg = "WEP\n";
55 break; 70 break;
@@ -74,7 +89,7 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
74 int len; 89 int len;
75 struct ieee80211_key *key = file->private_data; 90 struct ieee80211_key *key = file->private_data;
76 91
77 switch (key->alg) { 92 switch (key->conf.alg) {
78 case ALG_WEP: 93 case ALG_WEP:
79 len = scnprintf(buf, sizeof(buf), "\n"); 94 len = scnprintf(buf, sizeof(buf), "\n");
80 break; 95 break;
@@ -103,7 +118,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
103 int i, len; 118 int i, len;
104 const u8 *rpn; 119 const u8 *rpn;
105 120
106 switch (key->alg) { 121 switch (key->conf.alg) {
107 case ALG_WEP: 122 case ALG_WEP:
108 len = scnprintf(buf, sizeof(buf), "\n"); 123 len = scnprintf(buf, sizeof(buf), "\n");
109 break; 124 break;
@@ -139,7 +154,7 @@ static ssize_t key_replays_read(struct file *file, char __user *userbuf,
139 char buf[20]; 154 char buf[20];
140 int len; 155 int len;
141 156
142 if (key->alg != ALG_CCMP) 157 if (key->conf.alg != ALG_CCMP)
143 return 0; 158 return 0;
144 len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays); 159 len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
145 return simple_read_from_buffer(userbuf, count, ppos, buf, len); 160 return simple_read_from_buffer(userbuf, count, ppos, buf, len);
@@ -150,12 +165,12 @@ static ssize_t key_key_read(struct file *file, char __user *userbuf,
150 size_t count, loff_t *ppos) 165 size_t count, loff_t *ppos)
151{ 166{
152 struct ieee80211_key *key = file->private_data; 167 struct ieee80211_key *key = file->private_data;
153 int i, res, bufsize = 2*key->keylen+2; 168 int i, res, bufsize = 2 * key->conf.keylen + 2;
154 char *buf = kmalloc(bufsize, GFP_KERNEL); 169 char *buf = kmalloc(bufsize, GFP_KERNEL);
155 char *p = buf; 170 char *p = buf;
156 171
157 for (i = 0; i < key->keylen; i++) 172 for (i = 0; i < key->conf.keylen; i++)
158 p += scnprintf(p, bufsize+buf-p, "%02x", key->key[i]); 173 p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]);
159 p += scnprintf(p, bufsize+buf-p, "\n"); 174 p += scnprintf(p, bufsize+buf-p, "\n");
160 res = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); 175 res = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
161 kfree(buf); 176 kfree(buf);
@@ -185,7 +200,7 @@ void ieee80211_debugfs_key_add(struct ieee80211_local *local,
185 return; 200 return;
186 201
187 DEBUGFS_ADD(keylen); 202 DEBUGFS_ADD(keylen);
188 DEBUGFS_ADD(force_sw_encrypt); 203 DEBUGFS_ADD(flags);
189 DEBUGFS_ADD(keyidx); 204 DEBUGFS_ADD(keyidx);
190 DEBUGFS_ADD(hw_key_idx); 205 DEBUGFS_ADD(hw_key_idx);
191 DEBUGFS_ADD(tx_rx_count); 206 DEBUGFS_ADD(tx_rx_count);
@@ -205,7 +220,7 @@ void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
205 return; 220 return;
206 221
207 DEBUGFS_DEL(keylen); 222 DEBUGFS_DEL(keylen);
208 DEBUGFS_DEL(force_sw_encrypt); 223 DEBUGFS_DEL(flags);
209 DEBUGFS_DEL(keyidx); 224 DEBUGFS_DEL(keyidx);
210 DEBUGFS_DEL(hw_key_idx); 225 DEBUGFS_DEL(hw_key_idx);
211 DEBUGFS_DEL(tx_rx_count); 226 DEBUGFS_DEL(tx_rx_count);
@@ -227,7 +242,7 @@ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
227 if (!sdata->debugfsdir) 242 if (!sdata->debugfsdir)
228 return; 243 return;
229 244
230 sprintf(buf, "../keys/%d", sdata->default_key->keyidx); 245 sprintf(buf, "../keys/%d", sdata->default_key->conf.keyidx);
231 sdata->debugfs.default_key = 246 sdata->debugfs.default_key =
232 debugfs_create_symlink("default_key", sdata->debugfsdir, buf); 247 debugfs_create_symlink("default_key", sdata->debugfsdir, buf);
233} 248}
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 50d7af3018ea..5d5034f36fde 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -890,7 +890,7 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
890 if (!key) 890 if (!key)
891 goto no_key; 891 goto no_key;
892 892
893 switch (key->alg) { 893 switch (key->conf.alg) {
894 case ALG_WEP: 894 case ALG_WEP:
895 iv_len = WEP_IV_LEN; 895 iv_len = WEP_IV_LEN;
896 mic_len = WEP_ICV_LEN; 896 mic_len = WEP_ICV_LEN;
@@ -907,7 +907,8 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
907 goto no_key; 907 goto no_key;
908 } 908 }
909 909
910 if (skb->len >= mic_len && key->force_sw_encrypt) 910 if (skb->len >= mic_len &&
911 (key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT))
911 skb_trim(skb, skb->len - mic_len); 912 skb_trim(skb, skb->len - mic_len);
912 if (skb->len >= iv_len && skb->len > hdrlen) { 913 if (skb->len >= iv_len && skb->len > hdrlen) {
913 memmove(skb->data + iv_len, skb->data, hdrlen); 914 memmove(skb->data + iv_len, skb->data, hdrlen);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ef633a041dab..cc87e9d988f8 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -816,9 +816,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
816int ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev); 816int ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev);
817 817
818/* key handling */ 818/* key handling */
819struct ieee80211_key_conf *
820ieee80211_key_data2conf(struct ieee80211_local *local,
821 const struct ieee80211_key *data);
822struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata, 819struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata,
823 int idx, size_t key_len, gfp_t flags); 820 int idx, size_t key_len, gfp_t flags);
824void ieee80211_key_free(struct ieee80211_key *key); 821void ieee80211_key_free(struct ieee80211_key *key);
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c
index 61009176d51b..3e59afa23e4e 100644
--- a/net/mac80211/ieee80211_iface.c
+++ b/net/mac80211/ieee80211_iface.c
@@ -227,7 +227,8 @@ void ieee80211_if_reinit(struct net_device *dev)
227 memset(addr, 0xff, ETH_ALEN); 227 memset(addr, 0xff, ETH_ALEN);
228 if (local->ops->set_key) 228 if (local->ops->set_key)
229 local->ops->set_key(local_to_hw(local), DISABLE_KEY, addr, 229 local->ops->set_key(local_to_hw(local), DISABLE_KEY, addr,
230 local->keys[i], 0); 230 local->keys[i],
231 local->default_wep_only);
231#endif 232#endif
232 ieee80211_key_free(sdata->keys[i]); 233 ieee80211_key_free(sdata->keys[i]);
233 sdata->keys[i] = NULL; 234 sdata->keys[i] = NULL;
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index 9964f057bcef..380670c7a0ca 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -31,29 +31,20 @@ static void ieee80211_set_hw_encryption(struct net_device *dev,
31 struct sta_info *sta, u8 addr[ETH_ALEN], 31 struct sta_info *sta, u8 addr[ETH_ALEN],
32 struct ieee80211_key *key) 32 struct ieee80211_key *key)
33{ 33{
34 struct ieee80211_key_conf *keyconf = NULL;
35 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 34 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
36 35
37 /* default to sw encryption; this will be cleared by low-level 36 /* default to sw encryption; this will be cleared by low-level
38 * driver if the hw supports requested encryption */ 37 * driver if the hw supports requested encryption */
39 if (key) 38 if (key)
40 key->force_sw_encrypt = 1; 39 key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
41 40
42 if (key && local->ops->set_key && 41 if (key && local->ops->set_key) {
43 (keyconf = ieee80211_key_data2conf(local, key))) {
44 if (local->ops->set_key(local_to_hw(local), SET_KEY, addr, 42 if (local->ops->set_key(local_to_hw(local), SET_KEY, addr,
45 keyconf, sta ? sta->aid : 0)) { 43 &key->conf, local->default_wep_only)) {
46 key->force_sw_encrypt = 1; 44 key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
47 key->hw_key_idx = HW_KEY_IDX_INVALID; 45 key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
48 } else {
49 key->force_sw_encrypt =
50 !!(keyconf->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT);
51 key->hw_key_idx =
52 keyconf->hw_key_idx;
53
54 } 46 }
55 } 47 }
56 kfree(keyconf);
57} 48}
58 49
59 50
@@ -66,7 +57,6 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
66 struct sta_info *sta; 57 struct sta_info *sta;
67 struct ieee80211_key *key, *old_key; 58 struct ieee80211_key *key, *old_key;
68 int try_hwaccel = 1; 59 int try_hwaccel = 1;
69 struct ieee80211_key_conf *keyconf;
70 struct ieee80211_sub_if_data *sdata; 60 struct ieee80211_sub_if_data *sdata;
71 61
72 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 62 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -154,18 +144,16 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
154 } 144 }
155 145
156 if (alg == ALG_NONE) { 146 if (alg == ALG_NONE) {
157 keyconf = NULL;
158 if (try_hwaccel && key && 147 if (try_hwaccel && key &&
159 key->hw_key_idx != HW_KEY_IDX_INVALID && 148 key->conf.hw_key_idx != HW_KEY_IDX_INVALID &&
160 local->ops->set_key && 149 local->ops->set_key &&
161 (keyconf = ieee80211_key_data2conf(local, key)) != NULL &&
162 local->ops->set_key(local_to_hw(local), DISABLE_KEY, 150 local->ops->set_key(local_to_hw(local), DISABLE_KEY,
163 sta_addr, keyconf, sta ? sta->aid : 0)) { 151 sta_addr, &key->conf,
152 local->default_wep_only)) {
164 printk(KERN_DEBUG "%s: set_encrypt - low-level disable" 153 printk(KERN_DEBUG "%s: set_encrypt - low-level disable"
165 " failed\n", dev->name); 154 " failed\n", dev->name);
166 ret = -EINVAL; 155 ret = -EINVAL;
167 } 156 }
168 kfree(keyconf);
169 157
170 if (set_tx_key || sdata->default_key == key) { 158 if (set_tx_key || sdata->default_key == key) {
171 ieee80211_debugfs_key_remove_default(sdata); 159 ieee80211_debugfs_key_remove_default(sdata);
@@ -189,22 +177,20 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
189 177
190 /* default to sw encryption; low-level driver sets these if the 178 /* default to sw encryption; low-level driver sets these if the
191 * requested encryption is supported */ 179 * requested encryption is supported */
192 key->hw_key_idx = HW_KEY_IDX_INVALID; 180 key->conf.hw_key_idx = HW_KEY_IDX_INVALID;
193 key->force_sw_encrypt = 1; 181 key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
194 182
195 key->alg = alg; 183 key->conf.alg = alg;
196 key->keyidx = idx; 184 key->conf.keyidx = idx;
197 key->keylen = key_len; 185 key->conf.keylen = key_len;
198 memcpy(key->key, _key, key_len); 186 memcpy(key->conf.key, _key, key_len);
199 if (set_tx_key)
200 key->default_tx_key = 1;
201 187
202 if (alg == ALG_CCMP) { 188 if (alg == ALG_CCMP) {
203 /* Initialize AES key state here as an optimization 189 /* Initialize AES key state here as an optimization
204 * so that it does not need to be initialized for every 190 * so that it does not need to be initialized for every
205 * packet. */ 191 * packet. */
206 key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt( 192 key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(
207 key->key); 193 key->conf.key);
208 if (!key->u.ccmp.tfm) { 194 if (!key->u.ccmp.tfm) {
209 ret = -ENOMEM; 195 ret = -ENOMEM;
210 goto err_free; 196 goto err_free;
@@ -941,43 +927,38 @@ static int ieee80211_ioctl_giwretry(struct net_device *dev,
941static void ieee80211_key_enable_hwaccel(struct ieee80211_local *local, 927static void ieee80211_key_enable_hwaccel(struct ieee80211_local *local,
942 struct ieee80211_key *key) 928 struct ieee80211_key *key)
943{ 929{
944 struct ieee80211_key_conf *keyconf;
945 u8 addr[ETH_ALEN]; 930 u8 addr[ETH_ALEN];
946 931
947 if (!key || key->alg != ALG_WEP || !key->force_sw_encrypt || 932 if (!key || key->conf.alg != ALG_WEP ||
933 !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) ||
948 (local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP)) 934 (local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP))
949 return; 935 return;
950 936
951 memset(addr, 0xff, ETH_ALEN); 937 memset(addr, 0xff, ETH_ALEN);
952 keyconf = ieee80211_key_data2conf(local, key); 938
953 if (keyconf && local->ops->set_key && 939 if (local->ops->set_key)
954 local->ops->set_key(local_to_hw(local), 940 local->ops->set_key(local_to_hw(local),
955 SET_KEY, addr, keyconf, 0) == 0) { 941 SET_KEY, addr, &key->conf,
956 key->force_sw_encrypt = 942 local->default_wep_only);
957 !!(keyconf->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT);
958 key->hw_key_idx = keyconf->hw_key_idx;
959 }
960 kfree(keyconf);
961} 943}
962 944
963 945
964static void ieee80211_key_disable_hwaccel(struct ieee80211_local *local, 946static void ieee80211_key_disable_hwaccel(struct ieee80211_local *local,
965 struct ieee80211_key *key) 947 struct ieee80211_key *key)
966{ 948{
967 struct ieee80211_key_conf *keyconf;
968 u8 addr[ETH_ALEN]; 949 u8 addr[ETH_ALEN];
969 950
970 if (!key || key->alg != ALG_WEP || key->force_sw_encrypt || 951 if (!key || key->conf.alg != ALG_WEP ||
952 (key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) ||
971 (local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP)) 953 (local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP))
972 return; 954 return;
973 955
974 memset(addr, 0xff, ETH_ALEN); 956 memset(addr, 0xff, ETH_ALEN);
975 keyconf = ieee80211_key_data2conf(local, key); 957 if (local->ops->set_key)
976 if (keyconf && local->ops->set_key)
977 local->ops->set_key(local_to_hw(local), DISABLE_KEY, 958 local->ops->set_key(local_to_hw(local), DISABLE_KEY,
978 addr, keyconf, 0); 959 addr, &key->conf,
979 kfree(keyconf); 960 local->default_wep_only);
980 key->force_sw_encrypt = 1; 961 key->conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
981} 962}
982 963
983 964
@@ -1341,9 +1322,9 @@ static int ieee80211_ioctl_giwencode(struct net_device *dev,
1341 return 0; 1322 return 0;
1342 } 1323 }
1343 1324
1344 memcpy(key, sdata->keys[idx]->key, 1325 memcpy(key, sdata->keys[idx]->conf.key,
1345 min((int)erq->length, sdata->keys[idx]->keylen)); 1326 min((int)erq->length, sdata->keys[idx]->conf.keylen));
1346 erq->length = sdata->keys[idx]->keylen; 1327 erq->length = sdata->keys[idx]->conf.keylen;
1347 erq->flags |= IW_ENCODE_ENABLED; 1328 erq->flags |= IW_ENCODE_ENABLED;
1348 1329
1349 return 0; 1330 return 0;
diff --git a/net/mac80211/ieee80211_key.h b/net/mac80211/ieee80211_key.h
index c33384912782..1b5e539c678f 100644
--- a/net/mac80211/ieee80211_key.h
+++ b/net/mac80211/ieee80211_key.h
@@ -44,8 +44,6 @@
44struct ieee80211_key { 44struct ieee80211_key {
45 struct kref kref; 45 struct kref kref;
46 46
47 int hw_key_idx; /* filled and used by low-level driver */
48 ieee80211_key_alg alg;
49 union { 47 union {
50 struct { 48 struct {
51 /* last used TSC */ 49 /* last used TSC */
@@ -73,22 +71,16 @@ struct ieee80211_key {
73 u8 rx_crypto_buf[6 * AES_BLOCK_LEN]; 71 u8 rx_crypto_buf[6 * AES_BLOCK_LEN];
74 } ccmp; 72 } ccmp;
75 } u; 73 } u;
76 int tx_rx_count; /* number of times this key has been used */
77 int keylen;
78 74
79 /* if the low level driver can provide hardware acceleration it should 75 /* number of times this key has been used */
80 * clear this flag */ 76 int tx_rx_count;
81 unsigned int force_sw_encrypt:1;
82 unsigned int default_tx_key:1; /* This key is the new default TX key
83 * (used only for broadcast keys). */
84 s8 keyidx; /* WEP key index */
85 77
86#ifdef CONFIG_MAC80211_DEBUGFS 78#ifdef CONFIG_MAC80211_DEBUGFS
87 struct { 79 struct {
88 struct dentry *stalink; 80 struct dentry *stalink;
89 struct dentry *dir; 81 struct dentry *dir;
90 struct dentry *keylen; 82 struct dentry *keylen;
91 struct dentry *force_sw_encrypt; 83 struct dentry *flags;
92 struct dentry *keyidx; 84 struct dentry *keyidx;
93 struct dentry *hw_key_idx; 85 struct dentry *hw_key_idx;
94 struct dentry *tx_rx_count; 86 struct dentry *tx_rx_count;
@@ -100,7 +92,11 @@ struct ieee80211_key {
100 } debugfs; 92 } debugfs;
101#endif 93#endif
102 94
103 u8 key[0]; 95 /*
96 * key config, must be last because it contains key
97 * material as variable length member
98 */
99 struct ieee80211_key_conf conf;
104}; 100};
105 101
106#endif /* IEEE80211_KEY_H */ 102#endif /* IEEE80211_KEY_H */
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index fe94ebfcb157..a2443271629a 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -904,7 +904,7 @@ static int ieee80211_sta_wep_configured(struct net_device *dev)
904{ 904{
905 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 905 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
906 if (!sdata || !sdata->default_key || 906 if (!sdata || !sdata->default_key ||
907 sdata->default_key->alg != ALG_WEP) 907 sdata->default_key->conf.alg != ALG_WEP)
908 return 0; 908 return 0;
909 return 1; 909 return 1;
910} 910}
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index b67558c24639..92d994f090b6 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -13,32 +13,6 @@
13#include "debugfs_key.h" 13#include "debugfs_key.h"
14#include "aes_ccm.h" 14#include "aes_ccm.h"
15 15
16struct ieee80211_key_conf *
17ieee80211_key_data2conf(struct ieee80211_local *local,
18 const struct ieee80211_key *data)
19{
20 struct ieee80211_key_conf *conf;
21
22 conf = kmalloc(sizeof(*conf) + data->keylen, GFP_ATOMIC);
23 if (!conf)
24 return NULL;
25
26 conf->hw_key_idx = data->hw_key_idx;
27 conf->alg = data->alg;
28 conf->keylen = data->keylen;
29 conf->flags = 0;
30 if (data->force_sw_encrypt)
31 conf->flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
32 conf->keyidx = data->keyidx;
33 if (data->default_tx_key)
34 conf->flags |= IEEE80211_KEY_DEFAULT_TX_KEY;
35 if (local->default_wep_only)
36 conf->flags |= IEEE80211_KEY_DEFAULT_WEP_ONLY;
37 memcpy(conf->key, data->key, data->keylen);
38
39 return conf;
40}
41
42struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata, 16struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata,
43 int idx, size_t key_len, gfp_t flags) 17 int idx, size_t key_len, gfp_t flags)
44{ 18{
@@ -56,7 +30,7 @@ static void ieee80211_key_release(struct kref *kref)
56 struct ieee80211_key *key; 30 struct ieee80211_key *key;
57 31
58 key = container_of(kref, struct ieee80211_key, kref); 32 key = container_of(kref, struct ieee80211_key, kref);
59 if (key->alg == ALG_CCMP) 33 if (key->conf.alg == ALG_CCMP)
60 ieee80211_aes_key_free(key->u.ccmp.tfm); 34 ieee80211_aes_key_free(key->u.ccmp.tfm);
61 ieee80211_debugfs_key_remove(key); 35 ieee80211_debugfs_key_remove(key);
62 kfree(key); 36 kfree(key);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b52e3305a8f8..976b646a40de 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -374,7 +374,7 @@ ieee80211_rx_h_load_key(struct ieee80211_txrx_data *rx)
374 * pairwise or station-to-station keys, but for WEP we allow 374 * pairwise or station-to-station keys, but for WEP we allow
375 * using a key index as well. 375 * using a key index as well.
376 */ 376 */
377 if (rx->key && rx->key->alg != ALG_WEP && 377 if (rx->key && rx->key->conf.alg != ALG_WEP &&
378 !is_multicast_ether_addr(hdr->addr1)) 378 !is_multicast_ether_addr(hdr->addr1))
379 rx->key = NULL; 379 rx->key = NULL;
380 } 380 }
@@ -522,18 +522,15 @@ ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx)
522{ 522{
523 if (!rx->sta || !(rx->fc & IEEE80211_FCTL_PROTECTED) || 523 if (!rx->sta || !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
524 (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || 524 (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
525 !rx->key || rx->key->alg != ALG_WEP || 525 !rx->key || rx->key->conf.alg != ALG_WEP ||
526 !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) 526 !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
527 return TXRX_CONTINUE; 527 return TXRX_CONTINUE;
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->force_sw_encrypt) { 531 (rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT))
532 u8 *iv = ieee80211_wep_is_weak_iv(rx->skb, rx->key); 532 if (ieee80211_wep_is_weak_iv(rx->skb, rx->key))
533 if (iv) {
534 rx->sta->wep_weak_iv_count++; 533 rx->sta->wep_weak_iv_count++;
535 }
536 }
537 534
538 return TXRX_CONTINUE; 535 return TXRX_CONTINUE;
539} 536}
@@ -541,7 +538,7 @@ ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx)
541static ieee80211_txrx_result 538static ieee80211_txrx_result
542ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx) 539ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx)
543{ 540{
544 if ((rx->key && rx->key->alg != ALG_WEP) || 541 if ((rx->key && rx->key->conf.alg != ALG_WEP) ||
545 !(rx->fc & IEEE80211_FCTL_PROTECTED) || 542 !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
546 ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && 543 ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
547 ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || 544 ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
@@ -556,7 +553,7 @@ ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx)
556 } 553 }
557 554
558 if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED) || 555 if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED) ||
559 rx->key->force_sw_encrypt) { 556 (rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
560 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { 557 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
561 if (net_ratelimit()) 558 if (net_ratelimit())
562 printk(KERN_DEBUG "%s: RX WEP frame, decrypt " 559 printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
@@ -680,7 +677,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx)
680 /* This is the first fragment of a new frame. */ 677 /* This is the first fragment of a new frame. */
681 entry = ieee80211_reassemble_add(rx->sdata, frag, seq, 678 entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
682 rx->u.rx.queue, &(rx->skb)); 679 rx->u.rx.queue, &(rx->skb));
683 if (rx->key && rx->key->alg == ALG_CCMP && 680 if (rx->key && rx->key->conf.alg == ALG_CCMP &&
684 (rx->fc & IEEE80211_FCTL_PROTECTED)) { 681 (rx->fc & IEEE80211_FCTL_PROTECTED)) {
685 /* Store CCMP PN so that we can verify that the next 682 /* Store CCMP PN so that we can verify that the next
686 * fragment has a sequential PN value. */ 683 * fragment has a sequential PN value. */
@@ -707,7 +704,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx)
707 if (entry->ccmp) { 704 if (entry->ccmp) {
708 int i; 705 int i;
709 u8 pn[CCMP_PN_LEN], *rpn; 706 u8 pn[CCMP_PN_LEN], *rpn;
710 if (!rx->key || rx->key->alg != ALG_CCMP) 707 if (!rx->key || rx->key->conf.alg != ALG_CCMP)
711 return TXRX_DROP; 708 return TXRX_DROP;
712 memcpy(pn, entry->last_pn, CCMP_PN_LEN); 709 memcpy(pn, entry->last_pn, CCMP_PN_LEN);
713 for (i = CCMP_PN_LEN - 1; i >= 0; i--) { 710 for (i = CCMP_PN_LEN - 1; i >= 0; i--) {
@@ -900,7 +897,8 @@ ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx)
900 * uploaded to the hardware. 897 * uploaded to the hardware.
901 */ 898 */
902 if ((rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) && 899 if ((rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) &&
903 (!rx->key || !rx->key->force_sw_encrypt)) 900 (!rx->key ||
901 !(rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)))
904 return TXRX_CONTINUE; 902 return TXRX_CONTINUE;
905 903
906 /* Drop unencrypted frames if key is set. */ 904 /* Drop unencrypted frames if key is set. */
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 34245b882c2b..7e10c692c4ad 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -228,23 +228,20 @@ void sta_info_free(struct sta_info *sta)
228 228
229 if (sta->key) { 229 if (sta->key) {
230 if (local->ops->set_key) { 230 if (local->ops->set_key) {
231 struct ieee80211_key_conf *key; 231 local->ops->set_key(local_to_hw(local),
232 key = ieee80211_key_data2conf(local, sta->key); 232 DISABLE_KEY, sta->addr,
233 if (key) { 233 &sta->key->conf,
234 local->ops->set_key(local_to_hw(local), 234 local->default_wep_only);
235 DISABLE_KEY,
236 sta->addr, key, sta->aid);
237 kfree(key);
238 }
239 } 235 }
240 } else if (sta->key_idx_compression != HW_KEY_IDX_INVALID) { 236 } else if (sta->key_idx_compression != HW_KEY_IDX_INVALID) {
241 struct ieee80211_key_conf conf; 237 struct ieee80211_key_conf conf;
242 memset(&conf, 0, sizeof(conf)); 238 memset(&conf, 0, sizeof(conf));
243 conf.hw_key_idx = sta->key_idx_compression; 239 conf.hw_key_idx = sta->key_idx_compression;
244 conf.alg = ALG_NULL; 240 conf.alg = ALG_NONE;
245 conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT; 241 conf.flags |= IEEE80211_KEY_FORCE_SW_ENCRYPT;
246 local->ops->set_key(local_to_hw(local), DISABLE_KEY, 242 local->ops->set_key(local_to_hw(local), DISABLE_KEY,
247 sta->addr, &conf, sta->aid); 243 sta->addr, &conf,
244 local->default_wep_only);
248 sta->key_idx_compression = HW_KEY_IDX_INVALID; 245 sta->key_idx_compression = HW_KEY_IDX_INVALID;
249 } 246 }
250 247
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 41621720e560..b9c1d5405180 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -182,7 +182,7 @@ u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key,
182 *pos++ = iv0; 182 *pos++ = iv0;
183 *pos++ = iv1; 183 *pos++ = iv1;
184 *pos++ = iv2; 184 *pos++ = iv2;
185 *pos++ = (key->keyidx << 6) | (1 << 5) /* Ext IV */; 185 *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */;
186 *pos++ = key->u.tkip.iv32 & 0xff; 186 *pos++ = key->u.tkip.iv32 & 0xff;
187 *pos++ = (key->u.tkip.iv32 >> 8) & 0xff; 187 *pos++ = (key->u.tkip.iv32 >> 8) & 0xff;
188 *pos++ = (key->u.tkip.iv32 >> 16) & 0xff; 188 *pos++ = (key->u.tkip.iv32 >> 16) & 0xff;
@@ -194,7 +194,7 @@ u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key,
194void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta, 194void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta,
195 u16 *phase1key) 195 u16 *phase1key)
196{ 196{
197 tkip_mixing_phase1(ta, &key->key[ALG_TKIP_TEMP_ENCR_KEY], 197 tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
198 key->u.tkip.iv32, phase1key); 198 key->u.tkip.iv32, phase1key);
199} 199}
200 200
@@ -204,12 +204,13 @@ void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta,
204 /* Calculate per-packet key */ 204 /* Calculate per-packet key */
205 if (key->u.tkip.iv16 == 0 || !key->u.tkip.tx_initialized) { 205 if (key->u.tkip.iv16 == 0 || !key->u.tkip.tx_initialized) {
206 /* IV16 wrapped around - perform TKIP phase 1 */ 206 /* IV16 wrapped around - perform TKIP phase 1 */
207 tkip_mixing_phase1(ta, &key->key[ALG_TKIP_TEMP_ENCR_KEY], 207 tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
208 key->u.tkip.iv32, key->u.tkip.p1k); 208 key->u.tkip.iv32, key->u.tkip.p1k);
209 key->u.tkip.tx_initialized = 1; 209 key->u.tkip.tx_initialized = 1;
210 } 210 }
211 211
212 tkip_mixing_phase2(key->u.tkip.p1k, &key->key[ALG_TKIP_TEMP_ENCR_KEY], 212 tkip_mixing_phase2(key->u.tkip.p1k,
213 &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
213 key->u.tkip.iv16, rc4key); 214 key->u.tkip.iv16, rc4key);
214} 215}
215 216
@@ -266,7 +267,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
266 if (!(keyid & (1 << 5))) 267 if (!(keyid & (1 << 5)))
267 return TKIP_DECRYPT_NO_EXT_IV; 268 return TKIP_DECRYPT_NO_EXT_IV;
268 269
269 if ((keyid >> 6) != key->keyidx) 270 if ((keyid >> 6) != key->conf.keyidx)
270 return TKIP_DECRYPT_INVALID_KEYIDX; 271 return TKIP_DECRYPT_INVALID_KEYIDX;
271 272
272 if (key->u.tkip.rx_initialized[queue] && 273 if (key->u.tkip.rx_initialized[queue] &&
@@ -293,7 +294,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
293 key->u.tkip.iv32_rx[queue] != iv32) { 294 key->u.tkip.iv32_rx[queue] != iv32) {
294 key->u.tkip.rx_initialized[queue] = 1; 295 key->u.tkip.rx_initialized[queue] = 1;
295 /* IV16 wrapped around - perform TKIP phase 1 */ 296 /* IV16 wrapped around - perform TKIP phase 1 */
296 tkip_mixing_phase1(ta, &key->key[ALG_TKIP_TEMP_ENCR_KEY], 297 tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
297 iv32, key->u.tkip.p1k_rx[queue]); 298 iv32, key->u.tkip.p1k_rx[queue]);
298#ifdef CONFIG_TKIP_DEBUG 299#ifdef CONFIG_TKIP_DEBUG
299 { 300 {
@@ -302,7 +303,8 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
302 " TK=", MAC_ARG(ta)); 303 " TK=", MAC_ARG(ta));
303 for (i = 0; i < 16; i++) 304 for (i = 0; i < 16; i++)
304 printk("%02x ", 305 printk("%02x ",
305 key->key[ALG_TKIP_TEMP_ENCR_KEY + i]); 306 key->conf.key[
307 ALG_TKIP_TEMP_ENCR_KEY + i]);
306 printk("\n"); 308 printk("\n");
307 printk(KERN_DEBUG "TKIP decrypt: P1K="); 309 printk(KERN_DEBUG "TKIP decrypt: P1K=");
308 for (i = 0; i < 5; i++) 310 for (i = 0; i < 5; i++)
@@ -313,7 +315,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
313 } 315 }
314 316
315 tkip_mixing_phase2(key->u.tkip.p1k_rx[queue], 317 tkip_mixing_phase2(key->u.tkip.p1k_rx[queue],
316 &key->key[ALG_TKIP_TEMP_ENCR_KEY], 318 &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY],
317 iv16, rc4key); 319 iv16, rc4key);
318#ifdef CONFIG_TKIP_DEBUG 320#ifdef CONFIG_TKIP_DEBUG
319 { 321 {
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ddb104a70161..684f928def93 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -539,11 +539,11 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx)
539 539
540static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb) 540static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
541{ 541{
542 if (tx->key->force_sw_encrypt) { 542 if (tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) {
543 if (ieee80211_wep_encrypt(tx->local, skb, tx->key)) 543 if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
544 return -1; 544 return -1;
545 } else { 545 } else {
546 tx->u.tx.control->key_idx = tx->key->hw_key_idx; 546 tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
547 if (tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) { 547 if (tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) {
548 if (ieee80211_wep_add_iv(tx->local, skb, tx->key) == 548 if (ieee80211_wep_add_iv(tx->local, skb, tx->key) ==
549 NULL) 549 NULL)
@@ -561,7 +561,7 @@ ieee80211_tx_h_wep_encrypt(struct ieee80211_txrx_data *tx)
561 561
562 fc = le16_to_cpu(hdr->frame_control); 562 fc = le16_to_cpu(hdr->frame_control);
563 563
564 if (!tx->key || tx->key->alg != ALG_WEP || 564 if (!tx->key || tx->key->conf.alg != ALG_WEP ||
565 ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && 565 ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
566 ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || 566 ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
567 (fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH))) 567 (fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 1ad3d75281cc..0b19e89fcf6a 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -67,7 +67,7 @@ void ieee80211_wep_get_iv(struct ieee80211_local *local,
67 struct ieee80211_key *key, u8 *iv) 67 struct ieee80211_key *key, u8 *iv)
68{ 68{
69 local->wep_iv++; 69 local->wep_iv++;
70 if (ieee80211_wep_weak_iv(local->wep_iv, key->keylen)) 70 if (ieee80211_wep_weak_iv(local->wep_iv, key->conf.keylen))
71 local->wep_iv += 0x0100; 71 local->wep_iv += 0x0100;
72 72
73 if (!iv) 73 if (!iv)
@@ -76,7 +76,7 @@ void ieee80211_wep_get_iv(struct ieee80211_local *local,
76 *iv++ = (local->wep_iv >> 16) & 0xff; 76 *iv++ = (local->wep_iv >> 16) & 0xff;
77 *iv++ = (local->wep_iv >> 8) & 0xff; 77 *iv++ = (local->wep_iv >> 8) & 0xff;
78 *iv++ = local->wep_iv & 0xff; 78 *iv++ = local->wep_iv & 0xff;
79 *iv++ = key->keyidx << 6; 79 *iv++ = key->conf.keyidx << 6;
80} 80}
81 81
82 82
@@ -159,10 +159,10 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb,
159 u8 *rc4key, *iv; 159 u8 *rc4key, *iv;
160 size_t len; 160 size_t len;
161 161
162 if (!key || key->alg != ALG_WEP) 162 if (!key || key->conf.alg != ALG_WEP)
163 return -1; 163 return -1;
164 164
165 klen = 3 + key->keylen; 165 klen = 3 + key->conf.keylen;
166 rc4key = kmalloc(klen, GFP_ATOMIC); 166 rc4key = kmalloc(klen, GFP_ATOMIC);
167 if (!rc4key) 167 if (!rc4key)
168 return -1; 168 return -1;
@@ -179,7 +179,7 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb,
179 memcpy(rc4key, iv, 3); 179 memcpy(rc4key, iv, 3);
180 180
181 /* Copy rest of the WEP key (the secret part) */ 181 /* Copy rest of the WEP key (the secret part) */
182 memcpy(rc4key + 3, key->key, key->keylen); 182 memcpy(rc4key + 3, key->conf.key, key->conf.keylen);
183 183
184 /* Add room for ICV */ 184 /* Add room for ICV */
185 skb_put(skb, WEP_ICV_LEN); 185 skb_put(skb, WEP_ICV_LEN);
@@ -251,10 +251,10 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
251 251
252 keyidx = skb->data[hdrlen + 3] >> 6; 252 keyidx = skb->data[hdrlen + 3] >> 6;
253 253
254 if (!key || keyidx != key->keyidx || key->alg != ALG_WEP) 254 if (!key || keyidx != key->conf.keyidx || key->conf.alg != ALG_WEP)
255 return -1; 255 return -1;
256 256
257 klen = 3 + key->keylen; 257 klen = 3 + key->conf.keylen;
258 258
259 rc4key = kmalloc(klen, GFP_ATOMIC); 259 rc4key = kmalloc(klen, GFP_ATOMIC);
260 if (!rc4key) 260 if (!rc4key)
@@ -264,7 +264,7 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
264 memcpy(rc4key, skb->data + hdrlen, 3); 264 memcpy(rc4key, skb->data + hdrlen, 3);
265 265
266 /* Copy rest of the WEP key (the secret part) */ 266 /* Copy rest of the WEP key (the secret part) */
267 memcpy(rc4key + 3, key->key, key->keylen); 267 memcpy(rc4key + 3, key->conf.key, key->conf.keylen);
268 268
269 if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, 269 if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen,
270 skb->data + hdrlen + WEP_IV_LEN, 270 skb->data + hdrlen + WEP_IV_LEN,
@@ -321,7 +321,7 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
321 ivpos = skb->data + hdrlen; 321 ivpos = skb->data + hdrlen;
322 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; 322 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
323 323
324 if (ieee80211_wep_weak_iv(iv, key->keylen)) 324 if (ieee80211_wep_weak_iv(iv, key->conf.keylen))
325 return ivpos; 325 return ivpos;
326 326
327 return NULL; 327 return NULL;
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 1142b42b5fe9..4a2a9aa638b3 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -82,14 +82,14 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx)
82 82
83 fc = tx->fc; 83 fc = tx->fc;
84 84
85 if (!tx->key || tx->key->alg != ALG_TKIP || skb->len < 24 || 85 if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 ||
86 !WLAN_FC_DATA_PRESENT(fc)) 86 !WLAN_FC_DATA_PRESENT(fc))
87 return TXRX_CONTINUE; 87 return TXRX_CONTINUE;
88 88
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->force_sw_encrypt && 92 if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
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) {
@@ -114,8 +114,8 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx)
114#else 114#else
115 authenticator = 1; 115 authenticator = 1;
116#endif 116#endif
117 key = &tx->key->key[authenticator ? ALG_TKIP_TEMP_AUTH_TX_MIC_KEY : 117 key = &tx->key->conf.key[authenticator ? ALG_TKIP_TEMP_AUTH_TX_MIC_KEY :
118 ALG_TKIP_TEMP_AUTH_RX_MIC_KEY]; 118 ALG_TKIP_TEMP_AUTH_RX_MIC_KEY];
119 mic = skb_put(skb, MICHAEL_MIC_LEN); 119 mic = skb_put(skb, MICHAEL_MIC_LEN);
120 michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); 120 michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic);
121 121
@@ -141,12 +141,12 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
141 if (rx->local->hw.flags & IEEE80211_HW_DEVICE_STRIPS_MIC) 141 if (rx->local->hw.flags & IEEE80211_HW_DEVICE_STRIPS_MIC)
142 return TXRX_CONTINUE; 142 return TXRX_CONTINUE;
143 143
144 if (!rx->key || rx->key->alg != ALG_TKIP || 144 if (!rx->key || rx->key->conf.alg != ALG_TKIP ||
145 !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc)) 145 !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc))
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->force_sw_encrypt) { 149 !(rx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
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;
@@ -169,8 +169,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
169#else 169#else
170 authenticator = 1; 170 authenticator = 1;
171#endif 171#endif
172 key = &rx->key->key[authenticator ? ALG_TKIP_TEMP_AUTH_RX_MIC_KEY : 172 key = &rx->key->conf.key[authenticator ? ALG_TKIP_TEMP_AUTH_RX_MIC_KEY :
173 ALG_TKIP_TEMP_AUTH_TX_MIC_KEY]; 173 ALG_TKIP_TEMP_AUTH_TX_MIC_KEY];
174 michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); 174 michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic);
175 if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { 175 if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) {
176 if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) 176 if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
@@ -179,7 +179,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx)
179 printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from " 179 printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from "
180 MAC_FMT "\n", rx->dev->name, MAC_ARG(sa)); 180 MAC_FMT "\n", rx->dev->name, MAC_ARG(sa));
181 181
182 mac80211_ev_michael_mic_failure(rx->dev, rx->key->keyidx, 182 mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx,
183 (void *) skb->data); 183 (void *) skb->data);
184 return TXRX_DROP; 184 return TXRX_DROP;
185 } 185 }
@@ -205,7 +205,11 @@ 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 tailneed = !tx->key->force_sw_encrypt ? 0 : TKIP_ICV_LEN; 208 if (tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)
209 tailneed = TKIP_ICV_LEN;
210 else
211 tailneed = 0;
212
209 if ((skb_headroom(skb) < TKIP_IV_LEN || 213 if ((skb_headroom(skb) < TKIP_IV_LEN ||
210 skb_tailroom(skb) < tailneed)) { 214 skb_tailroom(skb) < tailneed)) {
211 I802_DEBUG_INC(tx->local->tx_expand_skb_head); 215 I802_DEBUG_INC(tx->local->tx_expand_skb_head);
@@ -223,7 +227,7 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
223 if (key->u.tkip.iv16 == 0) 227 if (key->u.tkip.iv16 == 0)
224 key->u.tkip.iv32++; 228 key->u.tkip.iv32++;
225 229
226 if (!tx->key->force_sw_encrypt) { 230 if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
227 u32 flags = tx->local->hw.flags; 231 u32 flags = tx->local->hw.flags;
228 hdr = (struct ieee80211_hdr *)skb->data; 232 hdr = (struct ieee80211_hdr *)skb->data;
229 233
@@ -250,7 +254,7 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
250 ~IEEE80211_TXCTL_TKIP_NEW_PHASE1_KEY; 254 ~IEEE80211_TXCTL_TKIP_NEW_PHASE1_KEY;
251 } 255 }
252 256
253 tx->u.tx.control->key_idx = tx->key->hw_key_idx; 257 tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
254 return 0; 258 return 0;
255 } 259 }
256 260
@@ -275,18 +279,18 @@ ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx)
275 279
276 fc = le16_to_cpu(hdr->frame_control); 280 fc = le16_to_cpu(hdr->frame_control);
277 281
278 if (!key || key->alg != ALG_TKIP || !WLAN_FC_DATA_PRESENT(fc)) 282 if (!key || key->conf.alg != ALG_TKIP || !WLAN_FC_DATA_PRESENT(fc))
279 return TXRX_CONTINUE; 283 return TXRX_CONTINUE;
280 284
281 tx->u.tx.control->icv_len = TKIP_ICV_LEN; 285 tx->u.tx.control->icv_len = TKIP_ICV_LEN;
282 tx->u.tx.control->iv_len = TKIP_IV_LEN; 286 tx->u.tx.control->iv_len = TKIP_IV_LEN;
283 ieee80211_tx_set_iswep(tx); 287 ieee80211_tx_set_iswep(tx);
284 288
285 if (!tx->key->force_sw_encrypt && 289 if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
286 !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) && 290 !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) &&
287 !wpa_test) { 291 !wpa_test) {
288 /* hwaccel - with no need for preallocated room for IV/ICV */ 292 /* hwaccel - with no need for preallocated room for IV/ICV */
289 tx->u.tx.control->key_idx = tx->key->hw_key_idx; 293 tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
290 return TXRX_CONTINUE; 294 return TXRX_CONTINUE;
291 } 295 }
292 296
@@ -318,7 +322,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
318 fc = le16_to_cpu(hdr->frame_control); 322 fc = le16_to_cpu(hdr->frame_control);
319 hdrlen = ieee80211_get_hdrlen(fc); 323 hdrlen = ieee80211_get_hdrlen(fc);
320 324
321 if (!rx->key || rx->key->alg != ALG_TKIP || 325 if (!rx->key || rx->key->conf.alg != ALG_TKIP ||
322 !(rx->fc & IEEE80211_FCTL_PROTECTED) || 326 !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
323 (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) 327 (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
324 return TXRX_CONTINUE; 328 return TXRX_CONTINUE;
@@ -327,7 +331,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
327 return TXRX_DROP; 331 return TXRX_DROP;
328 332
329 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && 333 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
330 !rx->key->force_sw_encrypt) { 334 !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
331 if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) { 335 if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) {
332 /* Hardware takes care of all processing, including 336 /* Hardware takes care of all processing, including
333 * replay protection, so no need to continue here. */ 337 * replay protection, so no need to continue here. */
@@ -471,7 +475,10 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
471 hdrlen = ieee80211_get_hdrlen(fc); 475 hdrlen = ieee80211_get_hdrlen(fc);
472 len = skb->len - hdrlen; 476 len = skb->len - hdrlen;
473 477
474 tailneed = !key->force_sw_encrypt ? 0 : CCMP_MIC_LEN; 478 if (key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)
479 tailneed = CCMP_MIC_LEN;
480 else
481 tailneed = 0;
475 482
476 if ((skb_headroom(skb) < CCMP_HDR_LEN || 483 if ((skb_headroom(skb) < CCMP_HDR_LEN ||
477 skb_tailroom(skb) < tailneed)) { 484 skb_tailroom(skb) < tailneed)) {
@@ -495,11 +502,11 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
495 break; 502 break;
496 } 503 }
497 504
498 ccmp_pn2hdr(pos, pn, key->keyidx); 505 ccmp_pn2hdr(pos, pn, key->conf.keyidx);
499 506
500 if (!key->force_sw_encrypt) { 507 if (!(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
501 /* hwaccel - with preallocated room for CCMP header */ 508 /* hwaccel - with preallocated room for CCMP header */
502 tx->u.tx.control->key_idx = key->hw_key_idx; 509 tx->u.tx.control->key_idx = key->conf.hw_key_idx;
503 return 0; 510 return 0;
504 } 511 }
505 512
@@ -523,18 +530,18 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx)
523 530
524 fc = le16_to_cpu(hdr->frame_control); 531 fc = le16_to_cpu(hdr->frame_control);
525 532
526 if (!key || key->alg != ALG_CCMP || !WLAN_FC_DATA_PRESENT(fc)) 533 if (!key || key->conf.alg != ALG_CCMP || !WLAN_FC_DATA_PRESENT(fc))
527 return TXRX_CONTINUE; 534 return TXRX_CONTINUE;
528 535
529 tx->u.tx.control->icv_len = CCMP_MIC_LEN; 536 tx->u.tx.control->icv_len = CCMP_MIC_LEN;
530 tx->u.tx.control->iv_len = CCMP_HDR_LEN; 537 tx->u.tx.control->iv_len = CCMP_HDR_LEN;
531 ieee80211_tx_set_iswep(tx); 538 ieee80211_tx_set_iswep(tx);
532 539
533 if (!tx->key->force_sw_encrypt && 540 if (!(tx->key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
534 !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) { 541 !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) {
535 /* hwaccel - with no need for preallocated room for CCMP " 542 /* hwaccel - with no need for preallocated room for CCMP "
536 * header or MIC fields */ 543 * header or MIC fields */
537 tx->u.tx.control->key_idx = tx->key->hw_key_idx; 544 tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
538 return TXRX_CONTINUE; 545 return TXRX_CONTINUE;
539 } 546 }
540 547
@@ -569,7 +576,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
569 fc = le16_to_cpu(hdr->frame_control); 576 fc = le16_to_cpu(hdr->frame_control);
570 hdrlen = ieee80211_get_hdrlen(fc); 577 hdrlen = ieee80211_get_hdrlen(fc);
571 578
572 if (!key || key->alg != ALG_CCMP || 579 if (!key || key->conf.alg != ALG_CCMP ||
573 !(rx->fc & IEEE80211_FCTL_PROTECTED) || 580 !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
574 (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) 581 (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
575 return TXRX_CONTINUE; 582 return TXRX_CONTINUE;
@@ -579,7 +586,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
579 return TXRX_DROP; 586 return TXRX_DROP;
580 587
581 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && 588 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
582 !key->force_sw_encrypt && 589 !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) &&
583 !(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) 590 !(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV))
584 return TXRX_CONTINUE; 591 return TXRX_CONTINUE;
585 592
@@ -600,7 +607,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
600 } 607 }
601 608
602 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && 609 if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) &&
603 !key->force_sw_encrypt) { 610 !(key->conf.flags & IEEE80211_KEY_FORCE_SW_ENCRYPT)) {
604 /* hwaccel has already decrypted frame and verified MIC */ 611 /* hwaccel has already decrypted frame and verified MIC */
605 } else { 612 } else {
606 u8 *scratch, *b_0, *aad; 613 u8 *scratch, *b_0, *aad;