diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2007-09-14 11:10:25 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:49:27 -0400 |
commit | 7848ba7d7a010ccb265617fc2bc053e2bdf06f48 (patch) | |
tree | 844da4a4d796d817b0040b284ddeaa320446eaab /net/mac80211 | |
parent | b708e610622cff07f4374a2b4410884f964b8489 (diff) |
[MAC80211]: rework hardware crypto flags
This patch reworks the various hardware crypto related
flags to make them more local, i.e. put them with each
key or each packet instead of into the hw struct.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: Michael Wu <flamingice@sourmilk.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
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; |