diff options
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r-- | net/mac80211/wpa.c | 43 |
1 files changed, 14 insertions, 29 deletions
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; |