aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2008-10-29 11:35:05 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-11-21 11:08:17 -0500
commit274bfb8dc5ffa16cb073801bebe76ab7f4e2e73d (patch)
tree04cd3f6a062496911b56737daa6a0858b769ccd6 /net/ieee80211
parentdfe1bafdbac1c7b48b636fb7ace799e78170e0d6 (diff)
lib80211: absorb crypto bits from net/ieee80211
These bits are shared already between ipw2x00 and hostap, and could probably be shared both more cleanly and with other drivers. This commit simply relocates the code to lib80211 and adjusts the drivers appropriately. Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/ieee80211')
-rw-r--r--net/ieee80211/Kconfig15
-rw-r--r--net/ieee80211/Makefile4
-rw-r--r--net/ieee80211/ieee80211_crypt.c206
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c492
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c782
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c295
-rw-r--r--net/ieee80211/ieee80211_module.c23
-rw-r--r--net/ieee80211/ieee80211_rx.c8
-rw-r--r--net/ieee80211/ieee80211_tx.c7
-rw-r--r--net/ieee80211/ieee80211_wx.c68
10 files changed, 58 insertions, 1842 deletions
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
index d2282bb2e4f1..46f24f4c9dc7 100644
--- a/net/ieee80211/Kconfig
+++ b/net/ieee80211/Kconfig
@@ -8,10 +8,10 @@ config IEEE80211
8 select CRYPTO_MICHAEL_MIC 8 select CRYPTO_MICHAEL_MIC
9 select CRYPTO_ECB 9 select CRYPTO_ECB
10 select CRC32 10 select CRC32
11 select IEEE80211_CRYPT_WEP
12 select IEEE80211_CRYPT_TKIP
13 select IEEE80211_CRYPT_CCMP
14 select LIB80211 11 select LIB80211
12 select LIB80211_CRYPT_WEP
13 select LIB80211_CRYPT_TKIP
14 select LIB80211_CRYPT_CCMP
15 ---help--- 15 ---help---
16 This option enables the hardware independent IEEE 802.11 16 This option enables the hardware independent IEEE 802.11
17 networking stack. This component is deprecated in favor of the 17 networking stack. This component is deprecated in favor of the
@@ -39,12 +39,3 @@ config IEEE80211_DEBUG
39 39
40 If you are not trying to debug or develop the ieee80211 40 If you are not trying to debug or develop the ieee80211
41 subsystem, you most likely want to say N here. 41 subsystem, you most likely want to say N here.
42
43config IEEE80211_CRYPT_WEP
44 tristate
45
46config IEEE80211_CRYPT_CCMP
47 tristate
48
49config IEEE80211_CRYPT_TKIP
50 tristate
diff --git a/net/ieee80211/Makefile b/net/ieee80211/Makefile
index f988417121da..158963ff18d2 100644
--- a/net/ieee80211/Makefile
+++ b/net/ieee80211/Makefile
@@ -1,8 +1,4 @@
1obj-$(CONFIG_IEEE80211) += ieee80211.o 1obj-$(CONFIG_IEEE80211) += ieee80211.o
2obj-$(CONFIG_IEEE80211) += ieee80211_crypt.o
3obj-$(CONFIG_IEEE80211_CRYPT_WEP) += ieee80211_crypt_wep.o
4obj-$(CONFIG_IEEE80211_CRYPT_CCMP) += ieee80211_crypt_ccmp.o
5obj-$(CONFIG_IEEE80211_CRYPT_TKIP) += ieee80211_crypt_tkip.o
6ieee80211-objs := \ 2ieee80211-objs := \
7 ieee80211_module.o \ 3 ieee80211_module.o \
8 ieee80211_tx.o \ 4 ieee80211_tx.o \
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
deleted file mode 100644
index df5592c9339f..000000000000
--- a/net/ieee80211/ieee80211_crypt.c
+++ /dev/null
@@ -1,206 +0,0 @@
1/*
2 * Host AP crypto routines
3 *
4 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
5 * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. See README and COPYING for
10 * more details.
11 *
12 */
13
14#include <linux/errno.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/string.h>
19#include <net/ieee80211.h>
20
21MODULE_AUTHOR("Jouni Malinen");
22MODULE_DESCRIPTION("HostAP crypto");
23MODULE_LICENSE("GPL");
24
25struct ieee80211_crypto_alg {
26 struct list_head list;
27 struct ieee80211_crypto_ops *ops;
28};
29
30static LIST_HEAD(ieee80211_crypto_algs);
31static DEFINE_SPINLOCK(ieee80211_crypto_lock);
32
33void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
34{
35 struct ieee80211_crypt_data *entry, *next;
36 unsigned long flags;
37
38 spin_lock_irqsave(&ieee->lock, flags);
39 list_for_each_entry_safe(entry, next, &ieee->crypt_deinit_list, list) {
40 if (atomic_read(&entry->refcnt) != 0 && !force)
41 continue;
42
43 list_del(&entry->list);
44
45 if (entry->ops) {
46 entry->ops->deinit(entry->priv);
47 module_put(entry->ops->owner);
48 }
49 kfree(entry);
50 }
51 spin_unlock_irqrestore(&ieee->lock, flags);
52}
53
54/* After this, crypt_deinit_list won't accept new members */
55void ieee80211_crypt_quiescing(struct ieee80211_device *ieee)
56{
57 unsigned long flags;
58
59 spin_lock_irqsave(&ieee->lock, flags);
60 ieee->crypt_quiesced = 1;
61 spin_unlock_irqrestore(&ieee->lock, flags);
62}
63
64void ieee80211_crypt_deinit_handler(unsigned long data)
65{
66 struct ieee80211_device *ieee = (struct ieee80211_device *)data;
67 unsigned long flags;
68
69 ieee80211_crypt_deinit_entries(ieee, 0);
70
71 spin_lock_irqsave(&ieee->lock, flags);
72 if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) {
73 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
74 "deletion list\n", ieee->dev->name);
75 ieee->crypt_deinit_timer.expires = jiffies + HZ;
76 add_timer(&ieee->crypt_deinit_timer);
77 }
78 spin_unlock_irqrestore(&ieee->lock, flags);
79}
80
81void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
82 struct ieee80211_crypt_data **crypt)
83{
84 struct ieee80211_crypt_data *tmp;
85 unsigned long flags;
86
87 if (*crypt == NULL)
88 return;
89
90 tmp = *crypt;
91 *crypt = NULL;
92
93 /* must not run ops->deinit() while there may be pending encrypt or
94 * decrypt operations. Use a list of delayed deinits to avoid needing
95 * locking. */
96
97 spin_lock_irqsave(&ieee->lock, flags);
98 if (!ieee->crypt_quiesced) {
99 list_add(&tmp->list, &ieee->crypt_deinit_list);
100 if (!timer_pending(&ieee->crypt_deinit_timer)) {
101 ieee->crypt_deinit_timer.expires = jiffies + HZ;
102 add_timer(&ieee->crypt_deinit_timer);
103 }
104 }
105 spin_unlock_irqrestore(&ieee->lock, flags);
106}
107
108int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
109{
110 unsigned long flags;
111 struct ieee80211_crypto_alg *alg;
112
113 alg = kzalloc(sizeof(*alg), GFP_KERNEL);
114 if (alg == NULL)
115 return -ENOMEM;
116
117 alg->ops = ops;
118
119 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
120 list_add(&alg->list, &ieee80211_crypto_algs);
121 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
122
123 printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
124 ops->name);
125
126 return 0;
127}
128
129int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
130{
131 struct ieee80211_crypto_alg *alg;
132 unsigned long flags;
133
134 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
135 list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
136 if (alg->ops == ops)
137 goto found;
138 }
139 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
140 return -EINVAL;
141
142 found:
143 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
144 "'%s'\n", ops->name);
145 list_del(&alg->list);
146 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
147 kfree(alg);
148 return 0;
149}
150
151struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
152{
153 struct ieee80211_crypto_alg *alg;
154 unsigned long flags;
155
156 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
157 list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
158 if (strcmp(alg->ops->name, name) == 0)
159 goto found;
160 }
161 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
162 return NULL;
163
164 found:
165 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
166 return alg->ops;
167}
168
169static void *ieee80211_crypt_null_init(int keyidx)
170{
171 return (void *)1;
172}
173
174static void ieee80211_crypt_null_deinit(void *priv)
175{
176}
177
178static struct ieee80211_crypto_ops ieee80211_crypt_null = {
179 .name = "NULL",
180 .init = ieee80211_crypt_null_init,
181 .deinit = ieee80211_crypt_null_deinit,
182 .owner = THIS_MODULE,
183};
184
185static int __init ieee80211_crypto_init(void)
186{
187 return ieee80211_register_crypto_ops(&ieee80211_crypt_null);
188}
189
190static void __exit ieee80211_crypto_deinit(void)
191{
192 ieee80211_unregister_crypto_ops(&ieee80211_crypt_null);
193 BUG_ON(!list_empty(&ieee80211_crypto_algs));
194}
195
196EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
197EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
198EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
199EXPORT_SYMBOL(ieee80211_crypt_quiescing);
200
201EXPORT_SYMBOL(ieee80211_register_crypto_ops);
202EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
203EXPORT_SYMBOL(ieee80211_get_crypto_ops);
204
205module_init(ieee80211_crypto_init);
206module_exit(ieee80211_crypto_deinit);
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
deleted file mode 100644
index bea04af0b482..000000000000
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ /dev/null
@@ -1,492 +0,0 @@
1/*
2 * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
5 *
6 * 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 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12#include <linux/kernel.h>
13#include <linux/err.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <linux/netdevice.h>
20#include <linux/if_ether.h>
21#include <linux/if_arp.h>
22#include <asm/string.h>
23#include <linux/wireless.h>
24
25#include <net/ieee80211.h>
26
27#include <linux/crypto.h>
28
29MODULE_AUTHOR("Jouni Malinen");
30MODULE_DESCRIPTION("Host AP crypt: CCMP");
31MODULE_LICENSE("GPL");
32
33#define AES_BLOCK_LEN 16
34#define CCMP_HDR_LEN 8
35#define CCMP_MIC_LEN 8
36#define CCMP_TK_LEN 16
37#define CCMP_PN_LEN 6
38
39struct ieee80211_ccmp_data {
40 u8 key[CCMP_TK_LEN];
41 int key_set;
42
43 u8 tx_pn[CCMP_PN_LEN];
44 u8 rx_pn[CCMP_PN_LEN];
45
46 u32 dot11RSNAStatsCCMPFormatErrors;
47 u32 dot11RSNAStatsCCMPReplays;
48 u32 dot11RSNAStatsCCMPDecryptErrors;
49
50 int key_idx;
51
52 struct crypto_cipher *tfm;
53
54 /* scratch buffers for virt_to_page() (crypto API) */
55 u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
56 tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
57 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
58};
59
60static inline void ieee80211_ccmp_aes_encrypt(struct crypto_cipher *tfm,
61 const u8 pt[16], u8 ct[16])
62{
63 crypto_cipher_encrypt_one(tfm, ct, pt);
64}
65
66static void *ieee80211_ccmp_init(int key_idx)
67{
68 struct ieee80211_ccmp_data *priv;
69
70 priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
71 if (priv == NULL)
72 goto fail;
73 priv->key_idx = key_idx;
74
75 priv->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
76 if (IS_ERR(priv->tfm)) {
77 printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
78 "crypto API aes\n");
79 priv->tfm = NULL;
80 goto fail;
81 }
82
83 return priv;
84
85 fail:
86 if (priv) {
87 if (priv->tfm)
88 crypto_free_cipher(priv->tfm);
89 kfree(priv);
90 }
91
92 return NULL;
93}
94
95static void ieee80211_ccmp_deinit(void *priv)
96{
97 struct ieee80211_ccmp_data *_priv = priv;
98 if (_priv && _priv->tfm)
99 crypto_free_cipher(_priv->tfm);
100 kfree(priv);
101}
102
103static inline void xor_block(u8 * b, u8 * a, size_t len)
104{
105 int i;
106 for (i = 0; i < len; i++)
107 b[i] ^= a[i];
108}
109
110static void ccmp_init_blocks(struct crypto_cipher *tfm,
111 struct ieee80211_hdr_4addr *hdr,
112 u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
113{
114 u8 *pos, qc = 0;
115 size_t aad_len;
116 u16 fc;
117 int a4_included, qc_included;
118 u8 aad[2 * AES_BLOCK_LEN];
119
120 fc = le16_to_cpu(hdr->frame_ctl);
121 a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
122 (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
123 qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
124 (WLAN_FC_GET_STYPE(fc) & IEEE80211_STYPE_QOS_DATA));
125 aad_len = 22;
126 if (a4_included)
127 aad_len += 6;
128 if (qc_included) {
129 pos = (u8 *) & hdr->addr4;
130 if (a4_included)
131 pos += 6;
132 qc = *pos & 0x0f;
133 aad_len += 2;
134 }
135
136 /* CCM Initial Block:
137 * Flag (Include authentication header, M=3 (8-octet MIC),
138 * L=1 (2-octet Dlen))
139 * Nonce: 0x00 | A2 | PN
140 * Dlen */
141 b0[0] = 0x59;
142 b0[1] = qc;
143 memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
144 memcpy(b0 + 8, pn, CCMP_PN_LEN);
145 b0[14] = (dlen >> 8) & 0xff;
146 b0[15] = dlen & 0xff;
147
148 /* AAD:
149 * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
150 * A1 | A2 | A3
151 * SC with bits 4..15 (seq#) masked to zero
152 * A4 (if present)
153 * QC (if present)
154 */
155 pos = (u8 *) hdr;
156 aad[0] = 0; /* aad_len >> 8 */
157 aad[1] = aad_len & 0xff;
158 aad[2] = pos[0] & 0x8f;
159 aad[3] = pos[1] & 0xc7;
160 memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
161 pos = (u8 *) & hdr->seq_ctl;
162 aad[22] = pos[0] & 0x0f;
163 aad[23] = 0; /* all bits masked */
164 memset(aad + 24, 0, 8);
165 if (a4_included)
166 memcpy(aad + 24, hdr->addr4, ETH_ALEN);
167 if (qc_included) {
168 aad[a4_included ? 30 : 24] = qc;
169 /* rest of QC masked */
170 }
171
172 /* Start with the first block and AAD */
173 ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
174 xor_block(auth, aad, AES_BLOCK_LEN);
175 ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
176 xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
177 ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
178 b0[0] &= 0x07;
179 b0[14] = b0[15] = 0;
180 ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
181}
182
183static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len,
184 u8 *aeskey, int keylen, void *priv)
185{
186 struct ieee80211_ccmp_data *key = priv;
187 int i;
188 u8 *pos;
189
190 if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len)
191 return -1;
192
193 if (aeskey != NULL && keylen >= CCMP_TK_LEN)
194 memcpy(aeskey, key->key, CCMP_TK_LEN);
195
196 pos = skb_push(skb, CCMP_HDR_LEN);
197 memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
198 pos += hdr_len;
199
200 i = CCMP_PN_LEN - 1;
201 while (i >= 0) {
202 key->tx_pn[i]++;
203 if (key->tx_pn[i] != 0)
204 break;
205 i--;
206 }
207
208 *pos++ = key->tx_pn[5];
209 *pos++ = key->tx_pn[4];
210 *pos++ = 0;
211 *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
212 *pos++ = key->tx_pn[3];
213 *pos++ = key->tx_pn[2];
214 *pos++ = key->tx_pn[1];
215 *pos++ = key->tx_pn[0];
216
217 return CCMP_HDR_LEN;
218}
219
220static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
221{
222 struct ieee80211_ccmp_data *key = priv;
223 int data_len, i, blocks, last, len;
224 u8 *pos, *mic;
225 struct ieee80211_hdr_4addr *hdr;
226 u8 *b0 = key->tx_b0;
227 u8 *b = key->tx_b;
228 u8 *e = key->tx_e;
229 u8 *s0 = key->tx_s0;
230
231 if (skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
232 return -1;
233
234 data_len = skb->len - hdr_len;
235 len = ieee80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv);
236 if (len < 0)
237 return -1;
238
239 pos = skb->data + hdr_len + CCMP_HDR_LEN;
240 mic = skb_put(skb, CCMP_MIC_LEN);
241 hdr = (struct ieee80211_hdr_4addr *)skb->data;
242 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
243
244 blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
245 last = data_len % AES_BLOCK_LEN;
246
247 for (i = 1; i <= blocks; i++) {
248 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
249 /* Authentication */
250 xor_block(b, pos, len);
251 ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
252 /* Encryption, with counter */
253 b0[14] = (i >> 8) & 0xff;
254 b0[15] = i & 0xff;
255 ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
256 xor_block(pos, e, len);
257 pos += len;
258 }
259
260 for (i = 0; i < CCMP_MIC_LEN; i++)
261 mic[i] = b[i] ^ s0[i];
262
263 return 0;
264}
265
266/*
267 * deal with seq counter wrapping correctly.
268 * refer to timer_after() for jiffies wrapping handling
269 */
270static inline int ccmp_replay_check(u8 *pn_n, u8 *pn_o)
271{
272 u32 iv32_n, iv16_n;
273 u32 iv32_o, iv16_o;
274
275 iv32_n = (pn_n[0] << 24) | (pn_n[1] << 16) | (pn_n[2] << 8) | pn_n[3];
276 iv16_n = (pn_n[4] << 8) | pn_n[5];
277
278 iv32_o = (pn_o[0] << 24) | (pn_o[1] << 16) | (pn_o[2] << 8) | pn_o[3];
279 iv16_o = (pn_o[4] << 8) | pn_o[5];
280
281 if ((s32)iv32_n - (s32)iv32_o < 0 ||
282 (iv32_n == iv32_o && iv16_n <= iv16_o))
283 return 1;
284 return 0;
285}
286
287static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
288{
289 struct ieee80211_ccmp_data *key = priv;
290 u8 keyidx, *pos;
291 struct ieee80211_hdr_4addr *hdr;
292 u8 *b0 = key->rx_b0;
293 u8 *b = key->rx_b;
294 u8 *a = key->rx_a;
295 u8 pn[6];
296 int i, blocks, last, len;
297 size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
298 u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
299
300 if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
301 key->dot11RSNAStatsCCMPFormatErrors++;
302 return -1;
303 }
304
305 hdr = (struct ieee80211_hdr_4addr *)skb->data;
306 pos = skb->data + hdr_len;
307 keyidx = pos[3];
308 if (!(keyidx & (1 << 5))) {
309 if (net_ratelimit()) {
310 printk(KERN_DEBUG "CCMP: received packet without ExtIV"
311 " flag from %pM\n", hdr->addr2);
312 }
313 key->dot11RSNAStatsCCMPFormatErrors++;
314 return -2;
315 }
316 keyidx >>= 6;
317 if (key->key_idx != keyidx) {
318 printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
319 "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
320 return -6;
321 }
322 if (!key->key_set) {
323 if (net_ratelimit()) {
324 printk(KERN_DEBUG "CCMP: received packet from %pM"
325 " with keyid=%d that does not have a configured"
326 " key\n", hdr->addr2, keyidx);
327 }
328 return -3;
329 }
330
331 pn[0] = pos[7];
332 pn[1] = pos[6];
333 pn[2] = pos[5];
334 pn[3] = pos[4];
335 pn[4] = pos[1];
336 pn[5] = pos[0];
337 pos += 8;
338
339 if (ccmp_replay_check(pn, key->rx_pn)) {
340 if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) {
341 IEEE80211_DEBUG_DROP("CCMP: replay detected: STA=%pM "
342 "previous PN %02x%02x%02x%02x%02x%02x "
343 "received PN %02x%02x%02x%02x%02x%02x\n",
344 hdr->addr2,
345 key->rx_pn[0], key->rx_pn[1], key->rx_pn[2],
346 key->rx_pn[3], key->rx_pn[4], key->rx_pn[5],
347 pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]);
348 }
349 key->dot11RSNAStatsCCMPReplays++;
350 return -4;
351 }
352
353 ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
354 xor_block(mic, b, CCMP_MIC_LEN);
355
356 blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
357 last = data_len % AES_BLOCK_LEN;
358
359 for (i = 1; i <= blocks; i++) {
360 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
361 /* Decrypt, with counter */
362 b0[14] = (i >> 8) & 0xff;
363 b0[15] = i & 0xff;
364 ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
365 xor_block(pos, b, len);
366 /* Authentication */
367 xor_block(a, pos, len);
368 ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
369 pos += len;
370 }
371
372 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
373 if (net_ratelimit()) {
374 printk(KERN_DEBUG "CCMP: decrypt failed: STA="
375 "%pM\n", hdr->addr2);
376 }
377 key->dot11RSNAStatsCCMPDecryptErrors++;
378 return -5;
379 }
380
381 memcpy(key->rx_pn, pn, CCMP_PN_LEN);
382
383 /* Remove hdr and MIC */
384 memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
385 skb_pull(skb, CCMP_HDR_LEN);
386 skb_trim(skb, skb->len - CCMP_MIC_LEN);
387
388 return keyidx;
389}
390
391static int ieee80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
392{
393 struct ieee80211_ccmp_data *data = priv;
394 int keyidx;
395 struct crypto_cipher *tfm = data->tfm;
396
397 keyidx = data->key_idx;
398 memset(data, 0, sizeof(*data));
399 data->key_idx = keyidx;
400 data->tfm = tfm;
401 if (len == CCMP_TK_LEN) {
402 memcpy(data->key, key, CCMP_TK_LEN);
403 data->key_set = 1;
404 if (seq) {
405 data->rx_pn[0] = seq[5];
406 data->rx_pn[1] = seq[4];
407 data->rx_pn[2] = seq[3];
408 data->rx_pn[3] = seq[2];
409 data->rx_pn[4] = seq[1];
410 data->rx_pn[5] = seq[0];
411 }
412 crypto_cipher_setkey(data->tfm, data->key, CCMP_TK_LEN);
413 } else if (len == 0)
414 data->key_set = 0;
415 else
416 return -1;
417
418 return 0;
419}
420
421static int ieee80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
422{
423 struct ieee80211_ccmp_data *data = priv;
424
425 if (len < CCMP_TK_LEN)
426 return -1;
427
428 if (!data->key_set)
429 return 0;
430 memcpy(key, data->key, CCMP_TK_LEN);
431
432 if (seq) {
433 seq[0] = data->tx_pn[5];
434 seq[1] = data->tx_pn[4];
435 seq[2] = data->tx_pn[3];
436 seq[3] = data->tx_pn[2];
437 seq[4] = data->tx_pn[1];
438 seq[5] = data->tx_pn[0];
439 }
440
441 return CCMP_TK_LEN;
442}
443
444static char *ieee80211_ccmp_print_stats(char *p, void *priv)
445{
446 struct ieee80211_ccmp_data *ccmp = priv;
447
448 p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
449 "tx_pn=%02x%02x%02x%02x%02x%02x "
450 "rx_pn=%02x%02x%02x%02x%02x%02x "
451 "format_errors=%d replays=%d decrypt_errors=%d\n",
452 ccmp->key_idx, ccmp->key_set,
453 ccmp->tx_pn[0], ccmp->tx_pn[1], ccmp->tx_pn[2],
454 ccmp->tx_pn[3], ccmp->tx_pn[4], ccmp->tx_pn[5],
455 ccmp->rx_pn[0], ccmp->rx_pn[1], ccmp->rx_pn[2],
456 ccmp->rx_pn[3], ccmp->rx_pn[4], ccmp->rx_pn[5],
457 ccmp->dot11RSNAStatsCCMPFormatErrors,
458 ccmp->dot11RSNAStatsCCMPReplays,
459 ccmp->dot11RSNAStatsCCMPDecryptErrors);
460
461 return p;
462}
463
464static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
465 .name = "CCMP",
466 .init = ieee80211_ccmp_init,
467 .deinit = ieee80211_ccmp_deinit,
468 .build_iv = ieee80211_ccmp_hdr,
469 .encrypt_mpdu = ieee80211_ccmp_encrypt,
470 .decrypt_mpdu = ieee80211_ccmp_decrypt,
471 .encrypt_msdu = NULL,
472 .decrypt_msdu = NULL,
473 .set_key = ieee80211_ccmp_set_key,
474 .get_key = ieee80211_ccmp_get_key,
475 .print_stats = ieee80211_ccmp_print_stats,
476 .extra_mpdu_prefix_len = CCMP_HDR_LEN,
477 .extra_mpdu_postfix_len = CCMP_MIC_LEN,
478 .owner = THIS_MODULE,
479};
480
481static int __init ieee80211_crypto_ccmp_init(void)
482{
483 return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
484}
485
486static void __exit ieee80211_crypto_ccmp_exit(void)
487{
488 ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
489}
490
491module_init(ieee80211_crypto_ccmp_init);
492module_exit(ieee80211_crypto_ccmp_exit);
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
deleted file mode 100644
index d12da1da6328..000000000000
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ /dev/null
@@ -1,782 +0,0 @@
1/*
2 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
5 *
6 * 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 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12#include <linux/err.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/slab.h>
16#include <linux/random.h>
17#include <linux/scatterlist.h>
18#include <linux/skbuff.h>
19#include <linux/netdevice.h>
20#include <linux/mm.h>
21#include <linux/if_ether.h>
22#include <linux/if_arp.h>
23#include <asm/string.h>
24
25#include <net/ieee80211.h>
26
27#include <linux/crypto.h>
28#include <linux/crc32.h>
29
30MODULE_AUTHOR("Jouni Malinen");
31MODULE_DESCRIPTION("Host AP crypt: TKIP");
32MODULE_LICENSE("GPL");
33
34struct ieee80211_tkip_data {
35#define TKIP_KEY_LEN 32
36 u8 key[TKIP_KEY_LEN];
37 int key_set;
38
39 u32 tx_iv32;
40 u16 tx_iv16;
41 u16 tx_ttak[5];
42 int tx_phase1_done;
43
44 u32 rx_iv32;
45 u16 rx_iv16;
46 u16 rx_ttak[5];
47 int rx_phase1_done;
48 u32 rx_iv32_new;
49 u16 rx_iv16_new;
50
51 u32 dot11RSNAStatsTKIPReplays;
52 u32 dot11RSNAStatsTKIPICVErrors;
53 u32 dot11RSNAStatsTKIPLocalMICFailures;
54
55 int key_idx;
56
57 struct crypto_blkcipher *rx_tfm_arc4;
58 struct crypto_hash *rx_tfm_michael;
59 struct crypto_blkcipher *tx_tfm_arc4;
60 struct crypto_hash *tx_tfm_michael;
61
62 /* scratch buffers for virt_to_page() (crypto API) */
63 u8 rx_hdr[16], tx_hdr[16];
64
65 unsigned long flags;
66};
67
68static unsigned long ieee80211_tkip_set_flags(unsigned long flags, void *priv)
69{
70 struct ieee80211_tkip_data *_priv = priv;
71 unsigned long old_flags = _priv->flags;
72 _priv->flags = flags;
73 return old_flags;
74}
75
76static unsigned long ieee80211_tkip_get_flags(void *priv)
77{
78 struct ieee80211_tkip_data *_priv = priv;
79 return _priv->flags;
80}
81
82static void *ieee80211_tkip_init(int key_idx)
83{
84 struct ieee80211_tkip_data *priv;
85
86 priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
87 if (priv == NULL)
88 goto fail;
89
90 priv->key_idx = key_idx;
91
92 priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
93 CRYPTO_ALG_ASYNC);
94 if (IS_ERR(priv->tx_tfm_arc4)) {
95 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
96 "crypto API arc4\n");
97 priv->tx_tfm_arc4 = NULL;
98 goto fail;
99 }
100
101 priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
102 CRYPTO_ALG_ASYNC);
103 if (IS_ERR(priv->tx_tfm_michael)) {
104 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
105 "crypto API michael_mic\n");
106 priv->tx_tfm_michael = NULL;
107 goto fail;
108 }
109
110 priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
111 CRYPTO_ALG_ASYNC);
112 if (IS_ERR(priv->rx_tfm_arc4)) {
113 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
114 "crypto API arc4\n");
115 priv->rx_tfm_arc4 = NULL;
116 goto fail;
117 }
118
119 priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
120 CRYPTO_ALG_ASYNC);
121 if (IS_ERR(priv->rx_tfm_michael)) {
122 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
123 "crypto API michael_mic\n");
124 priv->rx_tfm_michael = NULL;
125 goto fail;
126 }
127
128 return priv;
129
130 fail:
131 if (priv) {
132 if (priv->tx_tfm_michael)
133 crypto_free_hash(priv->tx_tfm_michael);
134 if (priv->tx_tfm_arc4)
135 crypto_free_blkcipher(priv->tx_tfm_arc4);
136 if (priv->rx_tfm_michael)
137 crypto_free_hash(priv->rx_tfm_michael);
138 if (priv->rx_tfm_arc4)
139 crypto_free_blkcipher(priv->rx_tfm_arc4);
140 kfree(priv);
141 }
142
143 return NULL;
144}
145
146static void ieee80211_tkip_deinit(void *priv)
147{
148 struct ieee80211_tkip_data *_priv = priv;
149 if (_priv) {
150 if (_priv->tx_tfm_michael)
151 crypto_free_hash(_priv->tx_tfm_michael);
152 if (_priv->tx_tfm_arc4)
153 crypto_free_blkcipher(_priv->tx_tfm_arc4);
154 if (_priv->rx_tfm_michael)
155 crypto_free_hash(_priv->rx_tfm_michael);
156 if (_priv->rx_tfm_arc4)
157 crypto_free_blkcipher(_priv->rx_tfm_arc4);
158 }
159 kfree(priv);
160}
161
162static inline u16 RotR1(u16 val)
163{
164 return (val >> 1) | (val << 15);
165}
166
167static inline u8 Lo8(u16 val)
168{
169 return val & 0xff;
170}
171
172static inline u8 Hi8(u16 val)
173{
174 return val >> 8;
175}
176
177static inline u16 Lo16(u32 val)
178{
179 return val & 0xffff;
180}
181
182static inline u16 Hi16(u32 val)
183{
184 return val >> 16;
185}
186
187static inline u16 Mk16(u8 hi, u8 lo)
188{
189 return lo | (((u16) hi) << 8);
190}
191
192static inline u16 Mk16_le(__le16 * v)
193{
194 return le16_to_cpu(*v);
195}
196
197static const u16 Sbox[256] = {
198 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
199 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
200 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
201 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
202 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
203 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
204 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
205 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
206 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
207 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
208 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
209 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
210 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
211 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
212 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
213 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
214 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
215 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
216 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
217 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
218 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
219 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
220 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
221 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
222 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
223 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
224 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
225 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
226 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
227 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
228 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
229 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
230};
231
232static inline u16 _S_(u16 v)
233{
234 u16 t = Sbox[Hi8(v)];
235 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
236}
237
238#define PHASE1_LOOP_COUNT 8
239
240static void tkip_mixing_phase1(u16 * TTAK, const u8 * TK, const u8 * TA,
241 u32 IV32)
242{
243 int i, j;
244
245 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
246 TTAK[0] = Lo16(IV32);
247 TTAK[1] = Hi16(IV32);
248 TTAK[2] = Mk16(TA[1], TA[0]);
249 TTAK[3] = Mk16(TA[3], TA[2]);
250 TTAK[4] = Mk16(TA[5], TA[4]);
251
252 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
253 j = 2 * (i & 1);
254 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
255 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
256 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
257 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
258 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
259 }
260}
261
262static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
263 u16 IV16)
264{
265 /* Make temporary area overlap WEP seed so that the final copy can be
266 * avoided on little endian hosts. */
267 u16 *PPK = (u16 *) & WEPSeed[4];
268
269 /* Step 1 - make copy of TTAK and bring in TSC */
270 PPK[0] = TTAK[0];
271 PPK[1] = TTAK[1];
272 PPK[2] = TTAK[2];
273 PPK[3] = TTAK[3];
274 PPK[4] = TTAK[4];
275 PPK[5] = TTAK[4] + IV16;
276
277 /* Step 2 - 96-bit bijective mixing using S-box */
278 PPK[0] += _S_(PPK[5] ^ Mk16_le((__le16 *) & TK[0]));
279 PPK[1] += _S_(PPK[0] ^ Mk16_le((__le16 *) & TK[2]));
280 PPK[2] += _S_(PPK[1] ^ Mk16_le((__le16 *) & TK[4]));
281 PPK[3] += _S_(PPK[2] ^ Mk16_le((__le16 *) & TK[6]));
282 PPK[4] += _S_(PPK[3] ^ Mk16_le((__le16 *) & TK[8]));
283 PPK[5] += _S_(PPK[4] ^ Mk16_le((__le16 *) & TK[10]));
284
285 PPK[0] += RotR1(PPK[5] ^ Mk16_le((__le16 *) & TK[12]));
286 PPK[1] += RotR1(PPK[0] ^ Mk16_le((__le16 *) & TK[14]));
287 PPK[2] += RotR1(PPK[1]);
288 PPK[3] += RotR1(PPK[2]);
289 PPK[4] += RotR1(PPK[3]);
290 PPK[5] += RotR1(PPK[4]);
291
292 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
293 * WEPSeed[0..2] is transmitted as WEP IV */
294 WEPSeed[0] = Hi8(IV16);
295 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
296 WEPSeed[2] = Lo8(IV16);
297 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((__le16 *) & TK[0])) >> 1);
298
299#ifdef __BIG_ENDIAN
300 {
301 int i;
302 for (i = 0; i < 6; i++)
303 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
304 }
305#endif
306}
307
308static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
309 u8 * rc4key, int keylen, void *priv)
310{
311 struct ieee80211_tkip_data *tkey = priv;
312 int len;
313 u8 *pos;
314 struct ieee80211_hdr_4addr *hdr;
315
316 hdr = (struct ieee80211_hdr_4addr *)skb->data;
317
318 if (skb_headroom(skb) < 8 || skb->len < hdr_len)
319 return -1;
320
321 if (rc4key == NULL || keylen < 16)
322 return -1;
323
324 if (!tkey->tx_phase1_done) {
325 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
326 tkey->tx_iv32);
327 tkey->tx_phase1_done = 1;
328 }
329 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
330
331 len = skb->len - hdr_len;
332 pos = skb_push(skb, 8);
333 memmove(pos, pos + 8, hdr_len);
334 pos += hdr_len;
335
336 *pos++ = *rc4key;
337 *pos++ = *(rc4key + 1);
338 *pos++ = *(rc4key + 2);
339 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
340 *pos++ = tkey->tx_iv32 & 0xff;
341 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
342 *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
343 *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
344
345 tkey->tx_iv16++;
346 if (tkey->tx_iv16 == 0) {
347 tkey->tx_phase1_done = 0;
348 tkey->tx_iv32++;
349 }
350
351 return 8;
352}
353
354static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
355{
356 struct ieee80211_tkip_data *tkey = priv;
357 struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 };
358 int len;
359 u8 rc4key[16], *pos, *icv;
360 u32 crc;
361 struct scatterlist sg;
362
363 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
364 if (net_ratelimit()) {
365 struct ieee80211_hdr_4addr *hdr =
366 (struct ieee80211_hdr_4addr *)skb->data;
367 printk(KERN_DEBUG ": TKIP countermeasures: dropped "
368 "TX packet to %pM\n", hdr->addr1);
369 }
370 return -1;
371 }
372
373 if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
374 return -1;
375
376 len = skb->len - hdr_len;
377 pos = skb->data + hdr_len;
378
379 if ((ieee80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
380 return -1;
381
382 icv = skb_put(skb, 4);
383
384 crc = ~crc32_le(~0, pos, len);
385 icv[0] = crc;
386 icv[1] = crc >> 8;
387 icv[2] = crc >> 16;
388 icv[3] = crc >> 24;
389
390 crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
391 sg_init_one(&sg, pos, len + 4);
392 return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
393}
394
395/*
396 * deal with seq counter wrapping correctly.
397 * refer to timer_after() for jiffies wrapping handling
398 */
399static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
400 u32 iv32_o, u16 iv16_o)
401{
402 if ((s32)iv32_n - (s32)iv32_o < 0 ||
403 (iv32_n == iv32_o && iv16_n <= iv16_o))
404 return 1;
405 return 0;
406}
407
408static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
409{
410 struct ieee80211_tkip_data *tkey = priv;
411 struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
412 u8 rc4key[16];
413 u8 keyidx, *pos;
414 u32 iv32;
415 u16 iv16;
416 struct ieee80211_hdr_4addr *hdr;
417 u8 icv[4];
418 u32 crc;
419 struct scatterlist sg;
420 int plen;
421
422 hdr = (struct ieee80211_hdr_4addr *)skb->data;
423
424 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
425 if (net_ratelimit()) {
426 printk(KERN_DEBUG ": TKIP countermeasures: dropped "
427 "received packet from %pM\n", hdr->addr2);
428 }
429 return -1;
430 }
431
432 if (skb->len < hdr_len + 8 + 4)
433 return -1;
434
435 pos = skb->data + hdr_len;
436 keyidx = pos[3];
437 if (!(keyidx & (1 << 5))) {
438 if (net_ratelimit()) {
439 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
440 " flag from %pM\n", hdr->addr2);
441 }
442 return -2;
443 }
444 keyidx >>= 6;
445 if (tkey->key_idx != keyidx) {
446 printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
447 "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
448 return -6;
449 }
450 if (!tkey->key_set) {
451 if (net_ratelimit()) {
452 printk(KERN_DEBUG "TKIP: received packet from %pM"
453 " with keyid=%d that does not have a configured"
454 " key\n", hdr->addr2, keyidx);
455 }
456 return -3;
457 }
458 iv16 = (pos[0] << 8) | pos[2];
459 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
460 pos += 8;
461
462 if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
463 if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) {
464 IEEE80211_DEBUG_DROP("TKIP: replay detected: STA=%pM"
465 " previous TSC %08x%04x received TSC "
466 "%08x%04x\n", hdr->addr2,
467 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
468 }
469 tkey->dot11RSNAStatsTKIPReplays++;
470 return -4;
471 }
472
473 if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
474 tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
475 tkey->rx_phase1_done = 1;
476 }
477 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
478
479 plen = skb->len - hdr_len - 12;
480
481 crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
482 sg_init_one(&sg, pos, plen + 4);
483 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
484 if (net_ratelimit()) {
485 printk(KERN_DEBUG ": TKIP: failed to decrypt "
486 "received packet from %pM\n",
487 hdr->addr2);
488 }
489 return -7;
490 }
491
492 crc = ~crc32_le(~0, pos, plen);
493 icv[0] = crc;
494 icv[1] = crc >> 8;
495 icv[2] = crc >> 16;
496 icv[3] = crc >> 24;
497 if (memcmp(icv, pos + plen, 4) != 0) {
498 if (iv32 != tkey->rx_iv32) {
499 /* Previously cached Phase1 result was already lost, so
500 * it needs to be recalculated for the next packet. */
501 tkey->rx_phase1_done = 0;
502 }
503 if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) {
504 IEEE80211_DEBUG_DROP("TKIP: ICV error detected: STA="
505 "%pM\n", hdr->addr2);
506 }
507 tkey->dot11RSNAStatsTKIPICVErrors++;
508 return -5;
509 }
510
511 /* Update real counters only after Michael MIC verification has
512 * completed */
513 tkey->rx_iv32_new = iv32;
514 tkey->rx_iv16_new = iv16;
515
516 /* Remove IV and ICV */
517 memmove(skb->data + 8, skb->data, hdr_len);
518 skb_pull(skb, 8);
519 skb_trim(skb, skb->len - 4);
520
521 return keyidx;
522}
523
524static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
525 u8 * data, size_t data_len, u8 * mic)
526{
527 struct hash_desc desc;
528 struct scatterlist sg[2];
529
530 if (tfm_michael == NULL) {
531 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
532 return -1;
533 }
534 sg_init_table(sg, 2);
535 sg_set_buf(&sg[0], hdr, 16);
536 sg_set_buf(&sg[1], data, data_len);
537
538 if (crypto_hash_setkey(tfm_michael, key, 8))
539 return -1;
540
541 desc.tfm = tfm_michael;
542 desc.flags = 0;
543 return crypto_hash_digest(&desc, sg, data_len + 16, mic);
544}
545
546static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
547{
548 struct ieee80211_hdr_4addr *hdr11;
549 u16 stype;
550
551 hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
552 stype = WLAN_FC_GET_STYPE(le16_to_cpu(hdr11->frame_ctl));
553
554 switch (le16_to_cpu(hdr11->frame_ctl) &
555 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
556 case IEEE80211_FCTL_TODS:
557 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
558 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
559 break;
560 case IEEE80211_FCTL_FROMDS:
561 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
562 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
563 break;
564 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
565 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
566 memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
567 break;
568 case 0:
569 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
570 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
571 break;
572 }
573
574 if (stype & IEEE80211_STYPE_QOS_DATA) {
575 const struct ieee80211_hdr_3addrqos *qoshdr =
576 (struct ieee80211_hdr_3addrqos *)skb->data;
577 hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID;
578 } else
579 hdr[12] = 0; /* priority */
580
581 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
582}
583
584static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
585 void *priv)
586{
587 struct ieee80211_tkip_data *tkey = priv;
588 u8 *pos;
589
590 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
591 printk(KERN_DEBUG "Invalid packet for Michael MIC add "
592 "(tailroom=%d hdr_len=%d skb->len=%d)\n",
593 skb_tailroom(skb), hdr_len, skb->len);
594 return -1;
595 }
596
597 michael_mic_hdr(skb, tkey->tx_hdr);
598 pos = skb_put(skb, 8);
599 if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
600 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
601 return -1;
602
603 return 0;
604}
605
606static void ieee80211_michael_mic_failure(struct net_device *dev,
607 struct ieee80211_hdr_4addr *hdr,
608 int keyidx)
609{
610 union iwreq_data wrqu;
611 struct iw_michaelmicfailure ev;
612
613 /* TODO: needed parameters: count, keyid, key type, TSC */
614 memset(&ev, 0, sizeof(ev));
615 ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
616 if (hdr->addr1[0] & 0x01)
617 ev.flags |= IW_MICFAILURE_GROUP;
618 else
619 ev.flags |= IW_MICFAILURE_PAIRWISE;
620 ev.src_addr.sa_family = ARPHRD_ETHER;
621 memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
622 memset(&wrqu, 0, sizeof(wrqu));
623 wrqu.data.length = sizeof(ev);
624 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
625}
626
627static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
628 int hdr_len, void *priv)
629{
630 struct ieee80211_tkip_data *tkey = priv;
631 u8 mic[8];
632
633 if (!tkey->key_set)
634 return -1;
635
636 michael_mic_hdr(skb, tkey->rx_hdr);
637 if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
638 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
639 return -1;
640 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
641 struct ieee80211_hdr_4addr *hdr;
642 hdr = (struct ieee80211_hdr_4addr *)skb->data;
643 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
644 "MSDU from %pM keyidx=%d\n",
645 skb->dev ? skb->dev->name : "N/A", hdr->addr2,
646 keyidx);
647 if (skb->dev)
648 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
649 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
650 return -1;
651 }
652
653 /* Update TSC counters for RX now that the packet verification has
654 * completed. */
655 tkey->rx_iv32 = tkey->rx_iv32_new;
656 tkey->rx_iv16 = tkey->rx_iv16_new;
657
658 skb_trim(skb, skb->len - 8);
659
660 return 0;
661}
662
663static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
664{
665 struct ieee80211_tkip_data *tkey = priv;
666 int keyidx;
667 struct crypto_hash *tfm = tkey->tx_tfm_michael;
668 struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
669 struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
670 struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
671
672 keyidx = tkey->key_idx;
673 memset(tkey, 0, sizeof(*tkey));
674 tkey->key_idx = keyidx;
675 tkey->tx_tfm_michael = tfm;
676 tkey->tx_tfm_arc4 = tfm2;
677 tkey->rx_tfm_michael = tfm3;
678 tkey->rx_tfm_arc4 = tfm4;
679 if (len == TKIP_KEY_LEN) {
680 memcpy(tkey->key, key, TKIP_KEY_LEN);
681 tkey->key_set = 1;
682 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
683 if (seq) {
684 tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
685 (seq[3] << 8) | seq[2];
686 tkey->rx_iv16 = (seq[1] << 8) | seq[0];
687 }
688 } else if (len == 0)
689 tkey->key_set = 0;
690 else
691 return -1;
692
693 return 0;
694}
695
696static int ieee80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
697{
698 struct ieee80211_tkip_data *tkey = priv;
699
700 if (len < TKIP_KEY_LEN)
701 return -1;
702
703 if (!tkey->key_set)
704 return 0;
705 memcpy(key, tkey->key, TKIP_KEY_LEN);
706
707 if (seq) {
708 /* Return the sequence number of the last transmitted frame. */
709 u16 iv16 = tkey->tx_iv16;
710 u32 iv32 = tkey->tx_iv32;
711 if (iv16 == 0)
712 iv32--;
713 iv16--;
714 seq[0] = tkey->tx_iv16;
715 seq[1] = tkey->tx_iv16 >> 8;
716 seq[2] = tkey->tx_iv32;
717 seq[3] = tkey->tx_iv32 >> 8;
718 seq[4] = tkey->tx_iv32 >> 16;
719 seq[5] = tkey->tx_iv32 >> 24;
720 }
721
722 return TKIP_KEY_LEN;
723}
724
725static char *ieee80211_tkip_print_stats(char *p, void *priv)
726{
727 struct ieee80211_tkip_data *tkip = priv;
728 p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
729 "tx_pn=%02x%02x%02x%02x%02x%02x "
730 "rx_pn=%02x%02x%02x%02x%02x%02x "
731 "replays=%d icv_errors=%d local_mic_failures=%d\n",
732 tkip->key_idx, tkip->key_set,
733 (tkip->tx_iv32 >> 24) & 0xff,
734 (tkip->tx_iv32 >> 16) & 0xff,
735 (tkip->tx_iv32 >> 8) & 0xff,
736 tkip->tx_iv32 & 0xff,
737 (tkip->tx_iv16 >> 8) & 0xff,
738 tkip->tx_iv16 & 0xff,
739 (tkip->rx_iv32 >> 24) & 0xff,
740 (tkip->rx_iv32 >> 16) & 0xff,
741 (tkip->rx_iv32 >> 8) & 0xff,
742 tkip->rx_iv32 & 0xff,
743 (tkip->rx_iv16 >> 8) & 0xff,
744 tkip->rx_iv16 & 0xff,
745 tkip->dot11RSNAStatsTKIPReplays,
746 tkip->dot11RSNAStatsTKIPICVErrors,
747 tkip->dot11RSNAStatsTKIPLocalMICFailures);
748 return p;
749}
750
751static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
752 .name = "TKIP",
753 .init = ieee80211_tkip_init,
754 .deinit = ieee80211_tkip_deinit,
755 .build_iv = ieee80211_tkip_hdr,
756 .encrypt_mpdu = ieee80211_tkip_encrypt,
757 .decrypt_mpdu = ieee80211_tkip_decrypt,
758 .encrypt_msdu = ieee80211_michael_mic_add,
759 .decrypt_msdu = ieee80211_michael_mic_verify,
760 .set_key = ieee80211_tkip_set_key,
761 .get_key = ieee80211_tkip_get_key,
762 .print_stats = ieee80211_tkip_print_stats,
763 .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
764 .extra_mpdu_postfix_len = 4, /* ICV */
765 .extra_msdu_postfix_len = 8, /* MIC */
766 .get_flags = ieee80211_tkip_get_flags,
767 .set_flags = ieee80211_tkip_set_flags,
768 .owner = THIS_MODULE,
769};
770
771static int __init ieee80211_crypto_tkip_init(void)
772{
773 return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
774}
775
776static void __exit ieee80211_crypto_tkip_exit(void)
777{
778 ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
779}
780
781module_init(ieee80211_crypto_tkip_init);
782module_exit(ieee80211_crypto_tkip_exit);
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
deleted file mode 100644
index 3fa30c40779f..000000000000
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ /dev/null
@@ -1,295 +0,0 @@
1/*
2 * Host AP crypt: host-based WEP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2002-2004, Jouni Malinen <j@w1.fi>
5 *
6 * 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 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12#include <linux/err.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/slab.h>
16#include <linux/random.h>
17#include <linux/scatterlist.h>
18#include <linux/skbuff.h>
19#include <linux/mm.h>
20#include <asm/string.h>
21
22#include <net/ieee80211.h>
23
24#include <linux/crypto.h>
25#include <linux/crc32.h>
26
27MODULE_AUTHOR("Jouni Malinen");
28MODULE_DESCRIPTION("Host AP crypt: WEP");
29MODULE_LICENSE("GPL");
30
31struct prism2_wep_data {
32 u32 iv;
33#define WEP_KEY_LEN 13
34 u8 key[WEP_KEY_LEN + 1];
35 u8 key_len;
36 u8 key_idx;
37 struct crypto_blkcipher *tx_tfm;
38 struct crypto_blkcipher *rx_tfm;
39};
40
41static void *prism2_wep_init(int keyidx)
42{
43 struct prism2_wep_data *priv;
44
45 priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
46 if (priv == NULL)
47 goto fail;
48 priv->key_idx = keyidx;
49
50 priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
51 if (IS_ERR(priv->tx_tfm)) {
52 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
53 "crypto API arc4\n");
54 priv->tx_tfm = NULL;
55 goto fail;
56 }
57
58 priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
59 if (IS_ERR(priv->rx_tfm)) {
60 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
61 "crypto API arc4\n");
62 priv->rx_tfm = NULL;
63 goto fail;
64 }
65 /* start WEP IV from a random value */
66 get_random_bytes(&priv->iv, 4);
67
68 return priv;
69
70 fail:
71 if (priv) {
72 if (priv->tx_tfm)
73 crypto_free_blkcipher(priv->tx_tfm);
74 if (priv->rx_tfm)
75 crypto_free_blkcipher(priv->rx_tfm);
76 kfree(priv);
77 }
78 return NULL;
79}
80
81static void prism2_wep_deinit(void *priv)
82{
83 struct prism2_wep_data *_priv = priv;
84 if (_priv) {
85 if (_priv->tx_tfm)
86 crypto_free_blkcipher(_priv->tx_tfm);
87 if (_priv->rx_tfm)
88 crypto_free_blkcipher(_priv->rx_tfm);
89 }
90 kfree(priv);
91}
92
93/* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */
94static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len,
95 u8 *key, int keylen, void *priv)
96{
97 struct prism2_wep_data *wep = priv;
98 u32 klen, len;
99 u8 *pos;
100
101 if (skb_headroom(skb) < 4 || skb->len < hdr_len)
102 return -1;
103
104 len = skb->len - hdr_len;
105 pos = skb_push(skb, 4);
106 memmove(pos, pos + 4, hdr_len);
107 pos += hdr_len;
108
109 klen = 3 + wep->key_len;
110
111 wep->iv++;
112
113 /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
114 * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
115 * can be used to speedup attacks, so avoid using them. */
116 if ((wep->iv & 0xff00) == 0xff00) {
117 u8 B = (wep->iv >> 16) & 0xff;
118 if (B >= 3 && B < klen)
119 wep->iv += 0x0100;
120 }
121
122 /* Prepend 24-bit IV to RC4 key and TX frame */
123 *pos++ = (wep->iv >> 16) & 0xff;
124 *pos++ = (wep->iv >> 8) & 0xff;
125 *pos++ = wep->iv & 0xff;
126 *pos++ = wep->key_idx << 6;
127
128 return 0;
129}
130
131/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
132 * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
133 * so the payload length increases with 8 bytes.
134 *
135 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
136 */
137static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
138{
139 struct prism2_wep_data *wep = priv;
140 struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
141 u32 crc, klen, len;
142 u8 *pos, *icv;
143 struct scatterlist sg;
144 u8 key[WEP_KEY_LEN + 3];
145
146 /* other checks are in prism2_wep_build_iv */
147 if (skb_tailroom(skb) < 4)
148 return -1;
149
150 /* add the IV to the frame */
151 if (prism2_wep_build_iv(skb, hdr_len, NULL, 0, priv))
152 return -1;
153
154 /* Copy the IV into the first 3 bytes of the key */
155 skb_copy_from_linear_data_offset(skb, hdr_len, key, 3);
156
157 /* Copy rest of the WEP key (the secret part) */
158 memcpy(key + 3, wep->key, wep->key_len);
159
160 len = skb->len - hdr_len - 4;
161 pos = skb->data + hdr_len + 4;
162 klen = 3 + wep->key_len;
163
164 /* Append little-endian CRC32 over only the data and encrypt it to produce ICV */
165 crc = ~crc32_le(~0, pos, len);
166 icv = skb_put(skb, 4);
167 icv[0] = crc;
168 icv[1] = crc >> 8;
169 icv[2] = crc >> 16;
170 icv[3] = crc >> 24;
171
172 crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
173 sg_init_one(&sg, pos, len + 4);
174 return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
175}
176
177/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
178 * the frame: IV (4 bytes), encrypted payload (including SNAP header),
179 * ICV (4 bytes). len includes both IV and ICV.
180 *
181 * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
182 * failure. If frame is OK, IV and ICV will be removed.
183 */
184static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
185{
186 struct prism2_wep_data *wep = priv;
187 struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
188 u32 crc, klen, plen;
189 u8 key[WEP_KEY_LEN + 3];
190 u8 keyidx, *pos, icv[4];
191 struct scatterlist sg;
192
193 if (skb->len < hdr_len + 8)
194 return -1;
195
196 pos = skb->data + hdr_len;
197 key[0] = *pos++;
198 key[1] = *pos++;
199 key[2] = *pos++;
200 keyidx = *pos++ >> 6;
201 if (keyidx != wep->key_idx)
202 return -1;
203
204 klen = 3 + wep->key_len;
205
206 /* Copy rest of the WEP key (the secret part) */
207 memcpy(key + 3, wep->key, wep->key_len);
208
209 /* Apply RC4 to data and compute CRC32 over decrypted data */
210 plen = skb->len - hdr_len - 8;
211
212 crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
213 sg_init_one(&sg, pos, plen + 4);
214 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
215 return -7;
216
217 crc = ~crc32_le(~0, pos, plen);
218 icv[0] = crc;
219 icv[1] = crc >> 8;
220 icv[2] = crc >> 16;
221 icv[3] = crc >> 24;
222 if (memcmp(icv, pos + plen, 4) != 0) {
223 /* ICV mismatch - drop frame */
224 return -2;
225 }
226
227 /* Remove IV and ICV */
228 memmove(skb->data + 4, skb->data, hdr_len);
229 skb_pull(skb, 4);
230 skb_trim(skb, skb->len - 4);
231
232 return 0;
233}
234
235static int prism2_wep_set_key(void *key, int len, u8 * seq, void *priv)
236{
237 struct prism2_wep_data *wep = priv;
238
239 if (len < 0 || len > WEP_KEY_LEN)
240 return -1;
241
242 memcpy(wep->key, key, len);
243 wep->key_len = len;
244
245 return 0;
246}
247
248static int prism2_wep_get_key(void *key, int len, u8 * seq, void *priv)
249{
250 struct prism2_wep_data *wep = priv;
251
252 if (len < wep->key_len)
253 return -1;
254
255 memcpy(key, wep->key, wep->key_len);
256
257 return wep->key_len;
258}
259
260static char *prism2_wep_print_stats(char *p, void *priv)
261{
262 struct prism2_wep_data *wep = priv;
263 p += sprintf(p, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
264 return p;
265}
266
267static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
268 .name = "WEP",
269 .init = prism2_wep_init,
270 .deinit = prism2_wep_deinit,
271 .build_iv = prism2_wep_build_iv,
272 .encrypt_mpdu = prism2_wep_encrypt,
273 .decrypt_mpdu = prism2_wep_decrypt,
274 .encrypt_msdu = NULL,
275 .decrypt_msdu = NULL,
276 .set_key = prism2_wep_set_key,
277 .get_key = prism2_wep_get_key,
278 .print_stats = prism2_wep_print_stats,
279 .extra_mpdu_prefix_len = 4, /* IV */
280 .extra_mpdu_postfix_len = 4, /* ICV */
281 .owner = THIS_MODULE,
282};
283
284static int __init ieee80211_crypto_wep_init(void)
285{
286 return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
287}
288
289static void __exit ieee80211_crypto_wep_exit(void)
290{
291 ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
292}
293
294module_init(ieee80211_crypto_wep_init);
295module_exit(ieee80211_crypto_wep_exit);
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
index d34d4e79b6f7..cf21f0bd8569 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -180,13 +180,16 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
180 ieee->host_open_frag = 1; 180 ieee->host_open_frag = 1;
181 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ 181 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
182 182
183 INIT_LIST_HEAD(&ieee->crypt_deinit_list);
184 setup_timer(&ieee->crypt_deinit_timer, ieee80211_crypt_deinit_handler,
185 (unsigned long)ieee);
186 ieee->crypt_quiesced = 0;
187
188 spin_lock_init(&ieee->lock); 183 spin_lock_init(&ieee->lock);
189 184
185 ieee->crypt_info.name = dev->name;
186 ieee->crypt_info.lock = &ieee->lock;
187 INIT_LIST_HEAD(&ieee->crypt_info.crypt_deinit_list);
188 setup_timer(&ieee->crypt_info.crypt_deinit_timer,
189 lib80211_crypt_deinit_handler,
190 (unsigned long)&ieee->crypt_info);
191 ieee->crypt_info.crypt_quiesced = 0;
192
190 ieee->wpa_enabled = 0; 193 ieee->wpa_enabled = 0;
191 ieee->drop_unencrypted = 0; 194 ieee->drop_unencrypted = 0;
192 ieee->privacy_invoked = 0; 195 ieee->privacy_invoked = 0;
@@ -205,19 +208,19 @@ void free_ieee80211(struct net_device *dev)
205 208
206 int i; 209 int i;
207 210
208 ieee80211_crypt_quiescing(ieee); 211 lib80211_crypt_quiescing(&ieee->crypt_info);
209 del_timer_sync(&ieee->crypt_deinit_timer); 212 del_timer_sync(&ieee->crypt_info.crypt_deinit_timer);
210 ieee80211_crypt_deinit_entries(ieee, 1); 213 lib80211_crypt_deinit_entries(&ieee->crypt_info, 1);
211 214
212 for (i = 0; i < WEP_KEYS; i++) { 215 for (i = 0; i < WEP_KEYS; i++) {
213 struct ieee80211_crypt_data *crypt = ieee->crypt[i]; 216 struct lib80211_crypt_data *crypt = ieee->crypt_info.crypt[i];
214 if (crypt) { 217 if (crypt) {
215 if (crypt->ops) { 218 if (crypt->ops) {
216 crypt->ops->deinit(crypt->priv); 219 crypt->ops->deinit(crypt->priv);
217 module_put(crypt->ops->owner); 220 module_put(crypt->ops->owner);
218 } 221 }
219 kfree(crypt); 222 kfree(crypt);
220 ieee->crypt[i] = NULL; 223 ieee->crypt_info.crypt[i] = NULL;
221 } 224 }
222 } 225 }
223 226
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 3dd58b594f6a..9c67dfae4320 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -268,7 +268,7 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
268/* Called only as a tasklet (software IRQ), by ieee80211_rx */ 268/* Called only as a tasklet (software IRQ), by ieee80211_rx */
269static int 269static int
270ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, 270ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
271 struct ieee80211_crypt_data *crypt) 271 struct lib80211_crypt_data *crypt)
272{ 272{
273 struct ieee80211_hdr_3addr *hdr; 273 struct ieee80211_hdr_3addr *hdr;
274 int res, hdrlen; 274 int res, hdrlen;
@@ -300,7 +300,7 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
300static int 300static int
301ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, 301ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
302 struct sk_buff *skb, int keyidx, 302 struct sk_buff *skb, int keyidx,
303 struct ieee80211_crypt_data *crypt) 303 struct lib80211_crypt_data *crypt)
304{ 304{
305 struct ieee80211_hdr_3addr *hdr; 305 struct ieee80211_hdr_3addr *hdr;
306 int res, hdrlen; 306 int res, hdrlen;
@@ -348,7 +348,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
348#endif 348#endif
349 u8 dst[ETH_ALEN]; 349 u8 dst[ETH_ALEN];
350 u8 src[ETH_ALEN]; 350 u8 src[ETH_ALEN];
351 struct ieee80211_crypt_data *crypt = NULL; 351 struct lib80211_crypt_data *crypt = NULL;
352 int keyidx = 0; 352 int keyidx = 0;
353 int can_be_decrypted = 0; 353 int can_be_decrypted = 0;
354 354
@@ -431,7 +431,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
431 * is only allowed 2-bits of storage, no value of keyidx can 431 * is only allowed 2-bits of storage, no value of keyidx can
432 * be provided via above code that would result in keyidx 432 * be provided via above code that would result in keyidx
433 * being out of range */ 433 * being out of range */
434 crypt = ieee->crypt[keyidx]; 434 crypt = ieee->crypt_info.crypt[keyidx];
435 435
436#ifdef NOT_YET 436#ifdef NOT_YET
437 sta = NULL; 437 sta = NULL;
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index d996547f7a62..f78f57e8844a 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -152,7 +152,8 @@ static int ieee80211_copy_snap(u8 * data, __be16 h_proto)
152static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee, 152static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
153 struct sk_buff *frag, int hdr_len) 153 struct sk_buff *frag, int hdr_len)
154{ 154{
155 struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx]; 155 struct lib80211_crypt_data *crypt =
156 ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
156 int res; 157 int res;
157 158
158 if (crypt == NULL) 159 if (crypt == NULL)
@@ -270,7 +271,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
270 .qos_ctl = 0 271 .qos_ctl = 0
271 }; 272 };
272 u8 dest[ETH_ALEN], src[ETH_ALEN]; 273 u8 dest[ETH_ALEN], src[ETH_ALEN];
273 struct ieee80211_crypt_data *crypt; 274 struct lib80211_crypt_data *crypt;
274 int priority = skb->priority; 275 int priority = skb->priority;
275 int snapped = 0; 276 int snapped = 0;
276 277
@@ -294,7 +295,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
294 295
295 ether_type = ((struct ethhdr *)skb->data)->h_proto; 296 ether_type = ((struct ethhdr *)skb->data)->h_proto;
296 297
297 crypt = ieee->crypt[ieee->tx_keyidx]; 298 crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
298 299
299 encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) && 300 encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) &&
300 ieee->sec.encrypt; 301 ieee->sec.encrypt;
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 7cc4e5ee3660..31ea3abfc327 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -307,7 +307,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
307 .flags = 0 307 .flags = 0
308 }; 308 };
309 int i, key, key_provided, len; 309 int i, key, key_provided, len;
310 struct ieee80211_crypt_data **crypt; 310 struct lib80211_crypt_data **crypt;
311 int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv; 311 int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
312 DECLARE_SSID_BUF(ssid); 312 DECLARE_SSID_BUF(ssid);
313 313
@@ -321,30 +321,30 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
321 key_provided = 1; 321 key_provided = 1;
322 } else { 322 } else {
323 key_provided = 0; 323 key_provided = 0;
324 key = ieee->tx_keyidx; 324 key = ieee->crypt_info.tx_keyidx;
325 } 325 }
326 326
327 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ? 327 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
328 "provided" : "default"); 328 "provided" : "default");
329 329
330 crypt = &ieee->crypt[key]; 330 crypt = &ieee->crypt_info.crypt[key];
331 331
332 if (erq->flags & IW_ENCODE_DISABLED) { 332 if (erq->flags & IW_ENCODE_DISABLED) {
333 if (key_provided && *crypt) { 333 if (key_provided && *crypt) {
334 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n", 334 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
335 key); 335 key);
336 ieee80211_crypt_delayed_deinit(ieee, crypt); 336 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
337 } else 337 } else
338 IEEE80211_DEBUG_WX("Disabling encryption.\n"); 338 IEEE80211_DEBUG_WX("Disabling encryption.\n");
339 339
340 /* Check all the keys to see if any are still configured, 340 /* Check all the keys to see if any are still configured,
341 * and if no key index was provided, de-init them all */ 341 * and if no key index was provided, de-init them all */
342 for (i = 0; i < WEP_KEYS; i++) { 342 for (i = 0; i < WEP_KEYS; i++) {
343 if (ieee->crypt[i] != NULL) { 343 if (ieee->crypt_info.crypt[i] != NULL) {
344 if (key_provided) 344 if (key_provided)
345 break; 345 break;
346 ieee80211_crypt_delayed_deinit(ieee, 346 lib80211_crypt_delayed_deinit(&ieee->crypt_info,
347 &ieee->crypt[i]); 347 &ieee->crypt_info.crypt[i]);
348 } 348 }
349 } 349 }
350 350
@@ -366,21 +366,21 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
366 strcmp((*crypt)->ops->name, "WEP") != 0) { 366 strcmp((*crypt)->ops->name, "WEP") != 0) {
367 /* changing to use WEP; deinit previously used algorithm 367 /* changing to use WEP; deinit previously used algorithm
368 * on this key */ 368 * on this key */
369 ieee80211_crypt_delayed_deinit(ieee, crypt); 369 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
370 } 370 }
371 371
372 if (*crypt == NULL && host_crypto) { 372 if (*crypt == NULL && host_crypto) {
373 struct ieee80211_crypt_data *new_crypt; 373 struct lib80211_crypt_data *new_crypt;
374 374
375 /* take WEP into use */ 375 /* take WEP into use */
376 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), 376 new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
377 GFP_KERNEL); 377 GFP_KERNEL);
378 if (new_crypt == NULL) 378 if (new_crypt == NULL)
379 return -ENOMEM; 379 return -ENOMEM;
380 new_crypt->ops = ieee80211_get_crypto_ops("WEP"); 380 new_crypt->ops = lib80211_get_crypto_ops("WEP");
381 if (!new_crypt->ops) { 381 if (!new_crypt->ops) {
382 request_module("ieee80211_crypt_wep"); 382 request_module("lib80211_crypt_wep");
383 new_crypt->ops = ieee80211_get_crypto_ops("WEP"); 383 new_crypt->ops = lib80211_get_crypto_ops("WEP");
384 } 384 }
385 385
386 if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) 386 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
@@ -391,7 +391,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
391 new_crypt = NULL; 391 new_crypt = NULL;
392 392
393 printk(KERN_WARNING "%s: could not initialize WEP: " 393 printk(KERN_WARNING "%s: could not initialize WEP: "
394 "load module ieee80211_crypt_wep\n", dev->name); 394 "load module lib80211_crypt_wep\n", dev->name);
395 return -EOPNOTSUPP; 395 return -EOPNOTSUPP;
396 } 396 }
397 *crypt = new_crypt; 397 *crypt = new_crypt;
@@ -440,7 +440,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
440 if (key_provided) { 440 if (key_provided) {
441 IEEE80211_DEBUG_WX("Setting key %d to default Tx " 441 IEEE80211_DEBUG_WX("Setting key %d to default Tx "
442 "key.\n", key); 442 "key.\n", key);
443 ieee->tx_keyidx = key; 443 ieee->crypt_info.tx_keyidx = key;
444 sec.active_key = key; 444 sec.active_key = key;
445 sec.flags |= SEC_ACTIVE_KEY; 445 sec.flags |= SEC_ACTIVE_KEY;
446 } 446 }
@@ -485,7 +485,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
485{ 485{
486 struct iw_point *erq = &(wrqu->encoding); 486 struct iw_point *erq = &(wrqu->encoding);
487 int len, key; 487 int len, key;
488 struct ieee80211_crypt_data *crypt; 488 struct lib80211_crypt_data *crypt;
489 struct ieee80211_security *sec = &ieee->sec; 489 struct ieee80211_security *sec = &ieee->sec;
490 490
491 IEEE80211_DEBUG_WX("GET_ENCODE\n"); 491 IEEE80211_DEBUG_WX("GET_ENCODE\n");
@@ -496,9 +496,9 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
496 return -EINVAL; 496 return -EINVAL;
497 key--; 497 key--;
498 } else 498 } else
499 key = ieee->tx_keyidx; 499 key = ieee->crypt_info.tx_keyidx;
500 500
501 crypt = ieee->crypt[key]; 501 crypt = ieee->crypt_info.crypt[key];
502 erq->flags = key + 1; 502 erq->flags = key + 1;
503 503
504 if (!sec->enabled) { 504 if (!sec->enabled) {
@@ -531,8 +531,8 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
531 int i, idx, ret = 0; 531 int i, idx, ret = 0;
532 int group_key = 0; 532 int group_key = 0;
533 const char *alg, *module; 533 const char *alg, *module;
534 struct ieee80211_crypto_ops *ops; 534 struct lib80211_crypto_ops *ops;
535 struct ieee80211_crypt_data **crypt; 535 struct lib80211_crypt_data **crypt;
536 536
537 struct ieee80211_security sec = { 537 struct ieee80211_security sec = {
538 .flags = 0, 538 .flags = 0,
@@ -544,17 +544,17 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
544 return -EINVAL; 544 return -EINVAL;
545 idx--; 545 idx--;
546 } else 546 } else
547 idx = ieee->tx_keyidx; 547 idx = ieee->crypt_info.tx_keyidx;
548 548
549 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { 549 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
550 crypt = &ieee->crypt[idx]; 550 crypt = &ieee->crypt_info.crypt[idx];
551 group_key = 1; 551 group_key = 1;
552 } else { 552 } else {
553 /* some Cisco APs use idx>0 for unicast in dynamic WEP */ 553 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
554 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP) 554 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
555 return -EINVAL; 555 return -EINVAL;
556 if (ieee->iw_mode == IW_MODE_INFRA) 556 if (ieee->iw_mode == IW_MODE_INFRA)
557 crypt = &ieee->crypt[idx]; 557 crypt = &ieee->crypt_info.crypt[idx];
558 else 558 else
559 return -EINVAL; 559 return -EINVAL;
560 } 560 }
@@ -563,10 +563,10 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
563 if ((encoding->flags & IW_ENCODE_DISABLED) || 563 if ((encoding->flags & IW_ENCODE_DISABLED) ||
564 ext->alg == IW_ENCODE_ALG_NONE) { 564 ext->alg == IW_ENCODE_ALG_NONE) {
565 if (*crypt) 565 if (*crypt)
566 ieee80211_crypt_delayed_deinit(ieee, crypt); 566 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
567 567
568 for (i = 0; i < WEP_KEYS; i++) 568 for (i = 0; i < WEP_KEYS; i++)
569 if (ieee->crypt[i] != NULL) 569 if (ieee->crypt_info.crypt[i] != NULL)
570 break; 570 break;
571 571
572 if (i == WEP_KEYS) { 572 if (i == WEP_KEYS) {
@@ -589,15 +589,15 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
589 switch (ext->alg) { 589 switch (ext->alg) {
590 case IW_ENCODE_ALG_WEP: 590 case IW_ENCODE_ALG_WEP:
591 alg = "WEP"; 591 alg = "WEP";
592 module = "ieee80211_crypt_wep"; 592 module = "lib80211_crypt_wep";
593 break; 593 break;
594 case IW_ENCODE_ALG_TKIP: 594 case IW_ENCODE_ALG_TKIP:
595 alg = "TKIP"; 595 alg = "TKIP";
596 module = "ieee80211_crypt_tkip"; 596 module = "lib80211_crypt_tkip";
597 break; 597 break;
598 case IW_ENCODE_ALG_CCMP: 598 case IW_ENCODE_ALG_CCMP:
599 alg = "CCMP"; 599 alg = "CCMP";
600 module = "ieee80211_crypt_ccmp"; 600 module = "lib80211_crypt_ccmp";
601 break; 601 break;
602 default: 602 default:
603 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", 603 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -606,10 +606,10 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
606 goto done; 606 goto done;
607 } 607 }
608 608
609 ops = ieee80211_get_crypto_ops(alg); 609 ops = lib80211_get_crypto_ops(alg);
610 if (ops == NULL) { 610 if (ops == NULL) {
611 request_module(module); 611 request_module(module);
612 ops = ieee80211_get_crypto_ops(alg); 612 ops = lib80211_get_crypto_ops(alg);
613 } 613 }
614 if (ops == NULL) { 614 if (ops == NULL) {
615 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", 615 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -619,9 +619,9 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
619 } 619 }
620 620
621 if (*crypt == NULL || (*crypt)->ops != ops) { 621 if (*crypt == NULL || (*crypt)->ops != ops) {
622 struct ieee80211_crypt_data *new_crypt; 622 struct lib80211_crypt_data *new_crypt;
623 623
624 ieee80211_crypt_delayed_deinit(ieee, crypt); 624 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
625 625
626 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); 626 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
627 if (new_crypt == NULL) { 627 if (new_crypt == NULL) {
@@ -649,7 +649,7 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
649 649
650 skip_host_crypt: 650 skip_host_crypt:
651 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { 651 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
652 ieee->tx_keyidx = idx; 652 ieee->crypt_info.tx_keyidx = idx;
653 sec.active_key = idx; 653 sec.active_key = idx;
654 sec.flags |= SEC_ACTIVE_KEY; 654 sec.flags |= SEC_ACTIVE_KEY;
655 } 655 }
@@ -715,7 +715,7 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
715 return -EINVAL; 715 return -EINVAL;
716 idx--; 716 idx--;
717 } else 717 } else
718 idx = ieee->tx_keyidx; 718 idx = ieee->crypt_info.tx_keyidx;
719 719
720 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && 720 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
721 ext->alg != IW_ENCODE_ALG_WEP) 721 ext->alg != IW_ENCODE_ALG_WEP)