aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-09-14 11:10:25 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:49:27 -0400
commit7848ba7d7a010ccb265617fc2bc053e2bdf06f48 (patch)
tree844da4a4d796d817b0040b284ddeaa320446eaab /net/mac80211
parentb708e610622cff07f4374a2b4410884f964b8489 (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.c24
-rw-r--r--net/mac80211/tx.c5
-rw-r--r--net/mac80211/wpa.c43
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
898ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx) 898ieee80211_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;