diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/rx.c | 113 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 7 |
2 files changed, 74 insertions, 46 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b0959c249869..08ca066246b9 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -310,52 +310,77 @@ static ieee80211_txrx_result | |||
310 | ieee80211_rx_h_load_key(struct ieee80211_txrx_data *rx) | 310 | ieee80211_rx_h_load_key(struct ieee80211_txrx_data *rx) |
311 | { | 311 | { |
312 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 312 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
313 | int always_sta_key; | 313 | int keyidx; |
314 | int hdrlen; | ||
314 | 315 | ||
315 | if (rx->sdata->type == IEEE80211_IF_TYPE_STA) | 316 | /* |
316 | always_sta_key = 0; | 317 | * Key selection 101 |
317 | else | 318 | * |
318 | always_sta_key = 1; | 319 | * There are three types of keys: |
320 | * - GTK (group keys) | ||
321 | * - PTK (pairwise keys) | ||
322 | * - STK (station-to-station pairwise keys) | ||
323 | * | ||
324 | * When selecting a key, we have to distinguish between multicast | ||
325 | * (including broadcast) and unicast frames, the latter can only | ||
326 | * use PTKs and STKs while the former always use GTKs. Unless, of | ||
327 | * course, actual WEP keys ("pre-RSNA") are used, then unicast | ||
328 | * frames can also use key indizes like GTKs. Hence, if we don't | ||
329 | * have a PTK/STK we check the key index for a WEP key. | ||
330 | * | ||
331 | * There is also a slight problem in IBSS mode: GTKs are negotiated | ||
332 | * with each station, that is something we don't currently handle. | ||
333 | */ | ||
334 | |||
335 | if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) | ||
336 | return TXRX_CONTINUE; | ||
319 | 337 | ||
320 | if (rx->sta && rx->sta->key && always_sta_key) { | 338 | /* |
339 | * No point in finding a key if the frame is neither | ||
340 | * addressed to us nor a multicast frame. | ||
341 | */ | ||
342 | if (!rx->u.rx.ra_match) | ||
343 | return TXRX_CONTINUE; | ||
344 | |||
345 | if (!is_multicast_ether_addr(hdr->addr1) && rx->sta && rx->sta->key) { | ||
321 | rx->key = rx->sta->key; | 346 | rx->key = rx->sta->key; |
322 | } else { | 347 | } else { |
323 | if (rx->sta && rx->sta->key) | 348 | /* |
324 | rx->key = rx->sta->key; | 349 | * The device doesn't give us the IV so we won't be |
325 | else | 350 | * able to look up the key. That's ok though, we |
326 | rx->key = rx->sdata->default_key; | 351 | * don't need to decrypt the frame, we just won't |
352 | * be able to keep statistics accurate. | ||
353 | * Except for key threshold notifications, should | ||
354 | * we somehow allow the driver to tell us which key | ||
355 | * the hardware used if this flag is set? | ||
356 | */ | ||
357 | if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) | ||
358 | return TXRX_CONTINUE; | ||
327 | 359 | ||
328 | if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) && | 360 | hdrlen = ieee80211_get_hdrlen(rx->fc); |
329 | rx->fc & IEEE80211_FCTL_PROTECTED) { | ||
330 | int keyidx = ieee80211_wep_get_keyidx(rx->skb); | ||
331 | 361 | ||
332 | if (keyidx >= 0 && keyidx < NUM_DEFAULT_KEYS && | 362 | if (rx->skb->len < 8 + hdrlen) |
333 | (!rx->sta || !rx->sta->key || keyidx > 0)) | 363 | return TXRX_DROP; /* TODO: count this? */ |
334 | rx->key = rx->sdata->keys[keyidx]; | ||
335 | 364 | ||
336 | if (!rx->key) { | 365 | /* |
337 | if (!rx->u.rx.ra_match) | 366 | * no need to call ieee80211_wep_get_keyidx, |
338 | return TXRX_DROP; | 367 | * it verifies a bunch of things we've done already |
339 | if (net_ratelimit()) | 368 | */ |
340 | printk(KERN_DEBUG "%s: RX WEP frame " | 369 | keyidx = rx->skb->data[hdrlen + 3] >> 6; |
341 | "with unknown keyidx %d " | 370 | |
342 | "(A1=" MAC_FMT | 371 | rx->key = rx->sdata->keys[keyidx]; |
343 | " A2=" MAC_FMT | 372 | |
344 | " A3=" MAC_FMT ")\n", | 373 | /* |
345 | rx->dev->name, keyidx, | 374 | * RSNA-protected unicast frames should always be sent with |
346 | MAC_ARG(hdr->addr1), | 375 | * pairwise or station-to-station keys, but for WEP we allow |
347 | MAC_ARG(hdr->addr2), | 376 | * using a key index as well. |
348 | MAC_ARG(hdr->addr3)); | 377 | */ |
349 | /* | 378 | if (rx->key && rx->key->alg != ALG_WEP && |
350 | * TODO: notify userspace about this | 379 | !is_multicast_ether_addr(hdr->addr1)) |
351 | * via cfg/nl80211 | 380 | rx->key = NULL; |
352 | */ | ||
353 | return TXRX_DROP; | ||
354 | } | ||
355 | } | ||
356 | } | 381 | } |
357 | 382 | ||
358 | if (rx->fc & IEEE80211_FCTL_PROTECTED && rx->key && rx->u.rx.ra_match) { | 383 | if (rx->key) { |
359 | rx->key->tx_rx_count++; | 384 | rx->key->tx_rx_count++; |
360 | if (unlikely(rx->local->key_tx_rx_threshold && | 385 | if (unlikely(rx->local->key_tx_rx_threshold && |
361 | rx->key->tx_rx_count > | 386 | rx->key->tx_rx_count > |
@@ -516,10 +541,6 @@ ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx) | |||
516 | static ieee80211_txrx_result | 541 | static ieee80211_txrx_result |
517 | ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx) | 542 | ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx) |
518 | { | 543 | { |
519 | /* If the device handles decryption totally, skip this test */ | ||
520 | if (rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) | ||
521 | return TXRX_CONTINUE; | ||
522 | |||
523 | if ((rx->key && rx->key->alg != ALG_WEP) || | 544 | if ((rx->key && rx->key->alg != ALG_WEP) || |
524 | !(rx->fc & IEEE80211_FCTL_PROTECTED) || | 545 | !(rx->fc & IEEE80211_FCTL_PROTECTED) || |
525 | ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && | 546 | ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && |
@@ -871,8 +892,14 @@ ieee80211_rx_h_802_1x_pae(struct ieee80211_txrx_data *rx) | |||
871 | static ieee80211_txrx_result | 892 | static ieee80211_txrx_result |
872 | ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx) | 893 | ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx) |
873 | { | 894 | { |
874 | /* If the device handles decryption totally, skip this test */ | 895 | /* |
875 | if (rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) | 896 | * Pass through unencrypted frames if the hardware might have |
897 | * decrypted them already without telling us, but that can only | ||
898 | * be true if we either didn't find a key or the found key is | ||
899 | * uploaded to the hardware. | ||
900 | */ | ||
901 | if ((rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) && | ||
902 | (!rx->key || !rx->key->force_sw_encrypt)) | ||
876 | return TXRX_CONTINUE; | 903 | return TXRX_CONTINUE; |
877 | 904 | ||
878 | /* Drop unencrypted frames if key is set. */ | 905 | /* Drop unencrypted frames if key is set. */ |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 783af32c6911..f5723ea15aae 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -137,9 +137,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) | |||
137 | 137 | ||
138 | fc = rx->fc; | 138 | fc = rx->fc; |
139 | 139 | ||
140 | /* If device handles decryption totally, skip this check */ | 140 | /* |
141 | if ((rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) || | 141 | * No way to verify the MIC if the hardware stripped it |
142 | (rx->local->hw.flags & IEEE80211_HW_DEVICE_STRIPS_MIC)) | 142 | */ |
143 | if (rx->local->hw.flags & IEEE80211_HW_DEVICE_STRIPS_MIC) | ||
143 | return TXRX_CONTINUE; | 144 | return TXRX_CONTINUE; |
144 | 145 | ||
145 | if (!rx->key || rx->key->alg != ALG_TKIP || | 146 | if (!rx->key || rx->key->alg != ALG_TKIP || |