aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wep.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-03-16 13:45:25 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-03-16 13:45:25 -0400
commit01a282980937f9ca55a3cb06b9c6ff1cc49ea396 (patch)
tree07a043edc861e245a7a9764751af0898a1f1199a /net/mac80211/wep.c
parentd5ddb4a59ed43b4c569b4efa8b508d50ef140cc6 (diff)
parent377526578f2c343ea281a918b18ece1fca65005c (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/ath/ath9k/hw.c
Diffstat (limited to 'net/mac80211/wep.c')
-rw-r--r--net/mac80211/wep.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 68ad351479df..7aa31bbfaa3b 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -263,16 +263,14 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
263} 263}
264 264
265 265
266bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) 266static bool ieee80211_wep_is_weak_iv(struct sk_buff *skb,
267 struct ieee80211_key *key)
267{ 268{
268 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 269 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
269 unsigned int hdrlen; 270 unsigned int hdrlen;
270 u8 *ivpos; 271 u8 *ivpos;
271 u32 iv; 272 u32 iv;
272 273
273 if (!ieee80211_has_protected(hdr->frame_control))
274 return false;
275
276 hdrlen = ieee80211_hdrlen(hdr->frame_control); 274 hdrlen = ieee80211_hdrlen(hdr->frame_control);
277 ivpos = skb->data + hdrlen; 275 ivpos = skb->data + hdrlen;
278 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; 276 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
@@ -286,18 +284,27 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
286 struct sk_buff *skb = rx->skb; 284 struct sk_buff *skb = rx->skb;
287 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 285 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
288 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 286 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
287 __le16 fc = hdr->frame_control;
289 288
290 if (!ieee80211_is_data(hdr->frame_control) && 289 if (!ieee80211_is_data(fc) && !ieee80211_is_auth(fc))
291 !ieee80211_is_auth(hdr->frame_control))
292 return RX_CONTINUE; 290 return RX_CONTINUE;
293 291
294 if (!(status->flag & RX_FLAG_DECRYPTED)) { 292 if (!(status->flag & RX_FLAG_DECRYPTED)) {
293 if (skb_linearize(rx->skb))
294 return RX_DROP_UNUSABLE;
295 if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
296 rx->sta->wep_weak_iv_count++;
295 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) 297 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key))
296 return RX_DROP_UNUSABLE; 298 return RX_DROP_UNUSABLE;
297 } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { 299 } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
300 if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + WEP_IV_LEN))
301 return RX_DROP_UNUSABLE;
302 if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
303 rx->sta->wep_weak_iv_count++;
298 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); 304 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
299 /* remove ICV */ 305 /* remove ICV */
300 skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN); 306 if (pskb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN))
307 return RX_DROP_UNUSABLE;
301 } 308 }
302 309
303 return RX_CONTINUE; 310 return RX_CONTINUE;