diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/rx.c | 24 | ||||
-rw-r--r-- | net/mac80211/tx.c | 5 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 43 |
3 files changed, 26 insertions, 46 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 8c6e29089216..28b8b6af4c42 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -363,7 +363,8 @@ ieee80211_rx_h_load_key(struct ieee80211_txrx_data *rx) | |||
363 | * we somehow allow the driver to tell us which key | 363 | * we somehow allow the driver to tell us which key |
364 | * the hardware used if this flag is set? | 364 | * the hardware used if this flag is set? |
365 | */ | 365 | */ |
366 | if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) | 366 | if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && |
367 | (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) | ||
367 | return TXRX_CONTINUE; | 368 | return TXRX_CONTINUE; |
368 | 369 | ||
369 | hdrlen = ieee80211_get_hdrlen(rx->fc); | 370 | hdrlen = ieee80211_get_hdrlen(rx->fc); |
@@ -534,8 +535,8 @@ ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx) | |||
534 | return TXRX_CONTINUE; | 535 | return TXRX_CONTINUE; |
535 | 536 | ||
536 | /* Check for weak IVs, if hwaccel did not remove IV from the frame */ | 537 | /* Check for weak IVs, if hwaccel did not remove IV from the frame */ |
537 | if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) || | 538 | if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED) || |
538 | !(rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | 539 | !(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) |
539 | if (ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | 540 | if (ieee80211_wep_is_weak_iv(rx->skb, rx->key)) |
540 | rx->sta->wep_weak_iv_count++; | 541 | rx->sta->wep_weak_iv_count++; |
541 | 542 | ||
@@ -559,15 +560,14 @@ ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx) | |||
559 | return TXRX_DROP; | 560 | return TXRX_DROP; |
560 | } | 561 | } |
561 | 562 | ||
562 | if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED) || | 563 | if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) { |
563 | !(rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { | ||
564 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { | 564 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { |
565 | if (net_ratelimit()) | 565 | if (net_ratelimit()) |
566 | printk(KERN_DEBUG "%s: RX WEP frame, decrypt " | 566 | printk(KERN_DEBUG "%s: RX WEP frame, decrypt " |
567 | "failed\n", rx->dev->name); | 567 | "failed\n", rx->dev->name); |
568 | return TXRX_DROP; | 568 | return TXRX_DROP; |
569 | } | 569 | } |
570 | } else if (rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) { | 570 | } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) { |
571 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); | 571 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); |
572 | /* remove ICV */ | 572 | /* remove ICV */ |
573 | skb_trim(rx->skb, rx->skb->len - 4); | 573 | skb_trim(rx->skb, rx->skb->len - 4); |
@@ -898,13 +898,10 @@ static ieee80211_txrx_result | |||
898 | ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx) | 898 | ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx) |
899 | { | 899 | { |
900 | /* | 900 | /* |
901 | * Pass through unencrypted frames if the hardware might have | 901 | * Pass through unencrypted frames if the hardware has |
902 | * decrypted them already without telling us, but that can only | 902 | * decrypted them already. |
903 | * be true if we either didn't find a key or the found key is | ||
904 | * uploaded to the hardware. | ||
905 | */ | 903 | */ |
906 | if ((rx->local->hw.flags & IEEE80211_HW_DEVICE_HIDES_WEP) && | 904 | if (rx->u.rx.status->flag & RX_FLAG_DECRYPTED) |
907 | (!rx->key || (rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))) | ||
908 | return TXRX_CONTINUE; | 905 | return TXRX_CONTINUE; |
909 | 906 | ||
910 | /* Drop unencrypted frames if key is set. */ | 907 | /* Drop unencrypted frames if key is set. */ |
@@ -1212,8 +1209,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1212 | goto ignore; | 1209 | goto ignore; |
1213 | } | 1210 | } |
1214 | 1211 | ||
1215 | if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) && | 1212 | if (rx->sdata->type == IEEE80211_IF_TYPE_AP && keyidx) { |
1216 | rx->sdata->type == IEEE80211_IF_TYPE_AP && keyidx) { | ||
1217 | /* AP with Pairwise keys support should never receive Michael | 1213 | /* AP with Pairwise keys support should never receive Michael |
1218 | * MIC errors for non-zero keyidx because these are reserved | 1214 | * MIC errors for non-zero keyidx because these are reserved |
1219 | * for group keys and only the AP is sending real multicast | 1215 | * for group keys and only the AP is sending real multicast |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 08d221674bc0..e2ae1e1fcc7b 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -545,9 +545,8 @@ static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb) | |||
545 | return -1; | 545 | return -1; |
546 | } else { | 546 | } else { |
547 | tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx; | 547 | tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx; |
548 | if (tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) { | 548 | if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) { |
549 | if (ieee80211_wep_add_iv(tx->local, skb, tx->key) == | 549 | if (!ieee80211_wep_add_iv(tx->local, skb, tx->key)) |
550 | NULL) | ||
551 | return -1; | 550 | return -1; |
552 | } | 551 | } |
553 | } | 552 | } |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 775f89e42a43..a23531cef5b0 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -91,7 +91,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx) | |||
91 | 91 | ||
92 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 92 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && |
93 | !(tx->flags & IEEE80211_TXRXD_FRAGMENTED) && | 93 | !(tx->flags & IEEE80211_TXRXD_FRAGMENTED) && |
94 | !(tx->local->hw.flags & IEEE80211_HW_TKIP_INCLUDE_MMIC) && | 94 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && |
95 | !wpa_test) { | 95 | !wpa_test) { |
96 | /* hwaccel - with no need for preallocated room for Michael MIC | 96 | /* hwaccel - with no need for preallocated room for Michael MIC |
97 | */ | 97 | */ |
@@ -138,26 +138,13 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) | |||
138 | /* | 138 | /* |
139 | * No way to verify the MIC if the hardware stripped it | 139 | * No way to verify the MIC if the hardware stripped it |
140 | */ | 140 | */ |
141 | if (rx->local->hw.flags & IEEE80211_HW_DEVICE_STRIPS_MIC) | 141 | if (rx->u.rx.status->flag & RX_FLAG_MMIC_STRIPPED) |
142 | return TXRX_CONTINUE; | 142 | return TXRX_CONTINUE; |
143 | 143 | ||
144 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || | 144 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || |
145 | !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc)) | 145 | !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc)) |
146 | return TXRX_CONTINUE; | 146 | return TXRX_CONTINUE; |
147 | 147 | ||
148 | if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && | ||
149 | (rx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { | ||
150 | if (rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) { | ||
151 | if (skb->len < MICHAEL_MIC_LEN) | ||
152 | return TXRX_DROP; | ||
153 | } | ||
154 | /* Need to verify Michael MIC sometimes in software even when | ||
155 | * hwaccel is used. Atheros ar5212: fragmented frames and QoS | ||
156 | * frames. */ | ||
157 | if (!(rx->flags & IEEE80211_TXRXD_FRAGMENTED) && !wpa_test) | ||
158 | goto remove_mic; | ||
159 | } | ||
160 | |||
161 | if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len) | 148 | if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len) |
162 | || data_len < MICHAEL_MIC_LEN) | 149 | || data_len < MICHAEL_MIC_LEN) |
163 | return TXRX_DROP; | 150 | return TXRX_DROP; |
@@ -184,7 +171,6 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) | |||
184 | return TXRX_DROP; | 171 | return TXRX_DROP; |
185 | } | 172 | } |
186 | 173 | ||
187 | remove_mic: | ||
188 | /* remove Michael MIC from payload */ | 174 | /* remove Michael MIC from payload */ |
189 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); | 175 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); |
190 | 176 | ||
@@ -287,7 +273,7 @@ ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx) | |||
287 | ieee80211_tx_set_iswep(tx); | 273 | ieee80211_tx_set_iswep(tx); |
288 | 274 | ||
289 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 275 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && |
290 | !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) && | 276 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) && |
291 | !wpa_test) { | 277 | !wpa_test) { |
292 | /* hwaccel - with no need for preallocated room for IV/ICV */ | 278 | /* hwaccel - with no need for preallocated room for IV/ICV */ |
293 | tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx; | 279 | tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx; |
@@ -330,11 +316,13 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx) | |||
330 | if (!rx->sta || skb->len - hdrlen < 12) | 316 | if (!rx->sta || skb->len - hdrlen < 12) |
331 | return TXRX_DROP; | 317 | return TXRX_DROP; |
332 | 318 | ||
333 | if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && | 319 | if (rx->u.rx.status->flag & RX_FLAG_DECRYPTED) { |
334 | (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { | 320 | if (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED) { |
335 | if (!(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) { | 321 | /* |
336 | /* Hardware takes care of all processing, including | 322 | * Hardware took care of all processing, including |
337 | * replay protection, so no need to continue here. */ | 323 | * replay protection, and stripped the ICV/IV so |
324 | * we cannot do any checks here. | ||
325 | */ | ||
338 | return TXRX_CONTINUE; | 326 | return TXRX_CONTINUE; |
339 | } | 327 | } |
340 | 328 | ||
@@ -538,7 +526,7 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx) | |||
538 | ieee80211_tx_set_iswep(tx); | 526 | ieee80211_tx_set_iswep(tx); |
539 | 527 | ||
540 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 528 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && |
541 | !(tx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) { | 529 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
542 | /* hwaccel - with no need for preallocated room for CCMP " | 530 | /* hwaccel - with no need for preallocated room for CCMP " |
543 | * header or MIC fields */ | 531 | * header or MIC fields */ |
544 | tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx; | 532 | tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx; |
@@ -585,8 +573,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx) | |||
585 | return TXRX_DROP; | 573 | return TXRX_DROP; |
586 | 574 | ||
587 | if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && | 575 | if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && |
588 | (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 576 | (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) |
589 | !(rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) | ||
590 | return TXRX_CONTINUE; | 577 | return TXRX_CONTINUE; |
591 | 578 | ||
592 | (void) ccmp_hdr2pn(pn, skb->data + hdrlen); | 579 | (void) ccmp_hdr2pn(pn, skb->data + hdrlen); |
@@ -605,10 +592,8 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx) | |||
605 | return TXRX_DROP; | 592 | return TXRX_DROP; |
606 | } | 593 | } |
607 | 594 | ||
608 | if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && | 595 | if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) { |
609 | (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { | 596 | /* hardware didn't decrypt/verify MIC */ |
610 | /* hwaccel has already decrypted frame and verified MIC */ | ||
611 | } else { | ||
612 | u8 *scratch, *b_0, *aad; | 597 | u8 *scratch, *b_0, *aad; |
613 | 598 | ||
614 | scratch = key->u.ccmp.rx_crypto_buf; | 599 | scratch = key->u.ccmp.rx_crypto_buf; |