aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wep.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/wep.c')
-rw-r--r--net/mac80211/wep.c71
1 files changed, 26 insertions, 45 deletions
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index affcecd78c10..872d2fcd1a5b 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -84,24 +84,17 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
84 struct sk_buff *skb, 84 struct sk_buff *skb,
85 struct ieee80211_key *key) 85 struct ieee80211_key *key)
86{ 86{
87 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 87 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
88 u16 fc; 88 unsigned int hdrlen;
89 int hdrlen;
90 u8 *newhdr; 89 u8 *newhdr;
91 90
92 fc = le16_to_cpu(hdr->frame_control); 91 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
93 fc |= IEEE80211_FCTL_PROTECTED;
94 hdr->frame_control = cpu_to_le16(fc);
95 92
96 if ((skb_headroom(skb) < WEP_IV_LEN || 93 if (WARN_ON(skb_tailroom(skb) < WEP_ICV_LEN ||
97 skb_tailroom(skb) < WEP_ICV_LEN)) { 94 skb_headroom(skb) < WEP_IV_LEN))
98 I802_DEBUG_INC(local->tx_expand_skb_head); 95 return NULL;
99 if (unlikely(pskb_expand_head(skb, WEP_IV_LEN, WEP_ICV_LEN,
100 GFP_ATOMIC)))
101 return NULL;
102 }
103 96
104 hdrlen = ieee80211_get_hdrlen(fc); 97 hdrlen = ieee80211_hdrlen(hdr->frame_control);
105 newhdr = skb_push(skb, WEP_IV_LEN); 98 newhdr = skb_push(skb, WEP_IV_LEN);
106 memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); 99 memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen);
107 ieee80211_wep_get_iv(local, key, newhdr + hdrlen); 100 ieee80211_wep_get_iv(local, key, newhdr + hdrlen);
@@ -113,12 +106,10 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
113 struct sk_buff *skb, 106 struct sk_buff *skb,
114 struct ieee80211_key *key) 107 struct ieee80211_key *key)
115{ 108{
116 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 109 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
117 u16 fc; 110 unsigned int hdrlen;
118 int hdrlen;
119 111
120 fc = le16_to_cpu(hdr->frame_control); 112 hdrlen = ieee80211_hdrlen(hdr->frame_control);
121 hdrlen = ieee80211_get_hdrlen(fc);
122 memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); 113 memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen);
123 skb_pull(skb, WEP_IV_LEN); 114 skb_pull(skb, WEP_IV_LEN);
124} 115}
@@ -228,17 +219,15 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
228 u32 klen; 219 u32 klen;
229 u8 *rc4key; 220 u8 *rc4key;
230 u8 keyidx; 221 u8 keyidx;
231 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 222 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
232 u16 fc; 223 unsigned int hdrlen;
233 int hdrlen;
234 size_t len; 224 size_t len;
235 int ret = 0; 225 int ret = 0;
236 226
237 fc = le16_to_cpu(hdr->frame_control); 227 if (!ieee80211_has_protected(hdr->frame_control))
238 if (!(fc & IEEE80211_FCTL_PROTECTED))
239 return -1; 228 return -1;
240 229
241 hdrlen = ieee80211_get_hdrlen(fc); 230 hdrlen = ieee80211_hdrlen(hdr->frame_control);
242 231
243 if (skb->len < 8 + hdrlen) 232 if (skb->len < 8 + hdrlen)
244 return -1; 233 return -1;
@@ -264,11 +253,8 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
264 253
265 if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, 254 if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen,
266 skb->data + hdrlen + WEP_IV_LEN, 255 skb->data + hdrlen + WEP_IV_LEN,
267 len)) { 256 len))
268 if (net_ratelimit())
269 printk(KERN_DEBUG "WEP decrypt failed (ICV)\n");
270 ret = -1; 257 ret = -1;
271 }
272 258
273 kfree(rc4key); 259 kfree(rc4key);
274 260
@@ -285,17 +271,15 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
285 271
286u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) 272u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
287{ 273{
288 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 274 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
289 u16 fc; 275 unsigned int hdrlen;
290 int hdrlen;
291 u8 *ivpos; 276 u8 *ivpos;
292 u32 iv; 277 u32 iv;
293 278
294 fc = le16_to_cpu(hdr->frame_control); 279 if (!ieee80211_has_protected(hdr->frame_control))
295 if (!(fc & IEEE80211_FCTL_PROTECTED))
296 return NULL; 280 return NULL;
297 281
298 hdrlen = ieee80211_get_hdrlen(fc); 282 hdrlen = ieee80211_hdrlen(hdr->frame_control);
299 ivpos = skb->data + hdrlen; 283 ivpos = skb->data + hdrlen;
300 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; 284 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
301 285
@@ -314,14 +298,8 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
314 return RX_CONTINUE; 298 return RX_CONTINUE;
315 299
316 if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { 300 if (!(rx->status->flag & RX_FLAG_DECRYPTED)) {
317 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { 301 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key))
318#ifdef CONFIG_MAC80211_DEBUG
319 if (net_ratelimit())
320 printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
321 "failed\n", rx->dev->name);
322#endif /* CONFIG_MAC80211_DEBUG */
323 return RX_DROP_UNUSABLE; 302 return RX_DROP_UNUSABLE;
324 }
325 } else if (!(rx->status->flag & RX_FLAG_IV_STRIPPED)) { 303 } else if (!(rx->status->flag & RX_FLAG_IV_STRIPPED)) {
326 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); 304 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
327 /* remove ICV */ 305 /* remove ICV */
@@ -333,11 +311,16 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
333 311
334static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) 312static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
335{ 313{
314 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
315
316 info->control.iv_len = WEP_IV_LEN;
317 info->control.icv_len = WEP_ICV_LEN;
318
336 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { 319 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
337 if (ieee80211_wep_encrypt(tx->local, skb, tx->key)) 320 if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
338 return -1; 321 return -1;
339 } else { 322 } else {
340 tx->control->key_idx = tx->key->conf.hw_key_idx; 323 info->control.hw_key = &tx->key->conf;
341 if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) { 324 if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
342 if (!ieee80211_wep_add_iv(tx->local, skb, tx->key)) 325 if (!ieee80211_wep_add_iv(tx->local, skb, tx->key))
343 return -1; 326 return -1;
@@ -349,8 +332,6 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
349ieee80211_tx_result 332ieee80211_tx_result
350ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) 333ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx)
351{ 334{
352 tx->control->iv_len = WEP_IV_LEN;
353 tx->control->icv_len = WEP_ICV_LEN;
354 ieee80211_tx_set_protected(tx); 335 ieee80211_tx_set_protected(tx);
355 336
356 if (wep_encrypt_skb(tx, tx->skb) < 0) { 337 if (wep_encrypt_skb(tx, tx->skb) < 0) {