diff options
Diffstat (limited to 'net/mac80211/wep.c')
-rw-r--r-- | net/mac80211/wep.c | 71 |
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 | ||
286 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | 272 | u8 * 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 | ||
334 | static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | 312 | static 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) | |||
349 | ieee80211_tx_result | 332 | ieee80211_tx_result |
350 | ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) | 333 | ieee80211_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) { |