aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-09-26 09:19:40 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:53:13 -0400
commit4f0d18e26f8bc4c6507b69aa0080d0fae807c990 (patch)
treeb9ef529b35cec6a81b8b7868c80088a30aa6bc9d
parentb2e7771e556917cc301a3308561f49b2b2272c07 (diff)
[PATCH] mac80211: consolidate decryption
Currently, we run through all three crypto algorithms for each received frame even though we have previously determined which key we have and as such already know which algorithm will be used. Change it to invoke only the needed function. Also move the WEP decrypt handler to wep.c so that fewer functions need to be non-static. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/rx.c40
-rw-r--r--net/mac80211/wep.c34
-rw-r--r--net/mac80211/wep.h8
-rw-r--r--net/mac80211/wpa.c12
-rw-r--r--net/mac80211/wpa.h4
5 files changed, 55 insertions, 43 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index a0dfafb4f38b..453ccab060a2 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -662,36 +662,32 @@ ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx)
662} 662}
663 663
664static ieee80211_txrx_result 664static ieee80211_txrx_result
665ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx) 665ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx)
666{ 666{
667 if ((rx->key && rx->key->conf.alg != ALG_WEP) || 667 if (!(rx->fc & IEEE80211_FCTL_PROTECTED))
668 !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
669 ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
670 ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
671 (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
672 return TXRX_CONTINUE; 668 return TXRX_CONTINUE;
673 669
674 if (!rx->key) { 670 if (!rx->key) {
675 if (net_ratelimit()) 671 if (net_ratelimit())
676 printk(KERN_DEBUG "%s: RX WEP frame, but no key set\n", 672 printk(KERN_DEBUG "%s: RX protected frame,"
677 rx->dev->name); 673 " but have no key\n", rx->dev->name);
678 return TXRX_DROP; 674 return TXRX_DROP;
679 } 675 }
680 676
681 if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) { 677 switch (rx->key->conf.alg) {
682 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { 678 case ALG_WEP:
683 if (net_ratelimit()) 679 return ieee80211_crypto_wep_decrypt(rx);
684 printk(KERN_DEBUG "%s: RX WEP frame, decrypt " 680 case ALG_TKIP:
685 "failed\n", rx->dev->name); 681 return ieee80211_crypto_tkip_decrypt(rx);
686 return TXRX_DROP; 682 case ALG_CCMP:
687 } 683 return ieee80211_crypto_ccmp_decrypt(rx);
688 } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) { 684 case ALG_NONE:
689 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); 685 return TXRX_CONTINUE;
690 /* remove ICV */
691 skb_trim(rx->skb, rx->skb->len - 4);
692 } 686 }
693 687
694 return TXRX_CONTINUE; 688 /* not reached */
689 WARN_ON(1);
690 return TXRX_DROP;
695} 691}
696 692
697static inline struct ieee80211_fragment_entry * 693static inline struct ieee80211_fragment_entry *
@@ -1371,10 +1367,8 @@ ieee80211_rx_handler ieee80211_rx_handlers[] =
1371 ieee80211_rx_h_check, 1367 ieee80211_rx_h_check,
1372 ieee80211_rx_h_load_key, 1368 ieee80211_rx_h_load_key,
1373 ieee80211_rx_h_sta_process, 1369 ieee80211_rx_h_sta_process,
1374 ieee80211_rx_h_ccmp_decrypt,
1375 ieee80211_rx_h_tkip_decrypt,
1376 ieee80211_rx_h_wep_weak_iv_detection, 1370 ieee80211_rx_h_wep_weak_iv_detection,
1377 ieee80211_rx_h_wep_decrypt, 1371 ieee80211_rx_h_decrypt,
1378 ieee80211_rx_h_defragment, 1372 ieee80211_rx_h_defragment,
1379 ieee80211_rx_h_ps_poll, 1373 ieee80211_rx_h_ps_poll,
1380 ieee80211_rx_h_michael_mic_verify, 1374 ieee80211_rx_h_michael_mic_verify,
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 0b19e89fcf6a..e785fe1f78ed 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -63,8 +63,8 @@ static inline int ieee80211_wep_weak_iv(u32 iv, int keylen)
63} 63}
64 64
65 65
66void ieee80211_wep_get_iv(struct ieee80211_local *local, 66static void ieee80211_wep_get_iv(struct ieee80211_local *local,
67 struct ieee80211_key *key, u8 *iv) 67 struct ieee80211_key *key, u8 *iv)
68{ 68{
69 local->wep_iv++; 69 local->wep_iv++;
70 if (ieee80211_wep_weak_iv(local->wep_iv, key->conf.keylen)) 70 if (ieee80211_wep_weak_iv(local->wep_iv, key->conf.keylen))
@@ -109,9 +109,9 @@ u8 * ieee80211_wep_add_iv(struct ieee80211_local *local,
109} 109}
110 110
111 111
112void ieee80211_wep_remove_iv(struct ieee80211_local *local, 112static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
113 struct sk_buff *skb, 113 struct sk_buff *skb,
114 struct ieee80211_key *key) 114 struct ieee80211_key *key)
115{ 115{
116 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 116 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
117 u16 fc; 117 u16 fc;
@@ -326,3 +326,27 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
326 326
327 return NULL; 327 return NULL;
328} 328}
329
330ieee80211_txrx_result
331ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx)
332{
333 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
334 ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
335 (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH))
336 return TXRX_CONTINUE;
337
338 if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
339 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
340 if (net_ratelimit())
341 printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
342 "failed\n", rx->dev->name);
343 return TXRX_DROP;
344 }
345 } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
346 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
347 /* remove ICV */
348 skb_trim(rx->skb, rx->skb->len - 4);
349 }
350
351 return TXRX_CONTINUE;
352}
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h
index bfe29e8e10aa..dfa5af143386 100644
--- a/net/mac80211/wep.h
+++ b/net/mac80211/wep.h
@@ -18,14 +18,9 @@
18 18
19int ieee80211_wep_init(struct ieee80211_local *local); 19int ieee80211_wep_init(struct ieee80211_local *local);
20void ieee80211_wep_free(struct ieee80211_local *local); 20void ieee80211_wep_free(struct ieee80211_local *local);
21void ieee80211_wep_get_iv(struct ieee80211_local *local,
22 struct ieee80211_key *key, u8 *iv);
23u8 * ieee80211_wep_add_iv(struct ieee80211_local *local, 21u8 * ieee80211_wep_add_iv(struct ieee80211_local *local,
24 struct sk_buff *skb, 22 struct sk_buff *skb,
25 struct ieee80211_key *key); 23 struct ieee80211_key *key);
26void ieee80211_wep_remove_iv(struct ieee80211_local *local,
27 struct sk_buff *skb,
28 struct ieee80211_key *key);
29void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 24void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
30 size_t klen, u8 *data, size_t data_len); 25 size_t klen, u8 *data, size_t data_len);
31int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 26int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
@@ -37,4 +32,7 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
37int ieee80211_wep_get_keyidx(struct sk_buff *skb); 32int ieee80211_wep_get_keyidx(struct sk_buff *skb);
38u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); 33u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
39 34
35ieee80211_txrx_result
36ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx);
37
40#endif /* WEP_H */ 38#endif /* WEP_H */
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 360d11e9de15..108fe3e81e24 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -281,7 +281,7 @@ ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx)
281 281
282 282
283ieee80211_txrx_result 283ieee80211_txrx_result
284ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx) 284ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx)
285{ 285{
286 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; 286 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
287 u16 fc; 287 u16 fc;
@@ -293,9 +293,7 @@ ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx)
293 fc = le16_to_cpu(hdr->frame_control); 293 fc = le16_to_cpu(hdr->frame_control);
294 hdrlen = ieee80211_get_hdrlen(fc); 294 hdrlen = ieee80211_get_hdrlen(fc);
295 295
296 if (!rx->key || rx->key->conf.alg != ALG_TKIP || 296 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
297 !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
298 (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
299 return TXRX_CONTINUE; 297 return TXRX_CONTINUE;
300 298
301 if (!rx->sta || skb->len - hdrlen < 12) 299 if (!rx->sta || skb->len - hdrlen < 12)
@@ -535,7 +533,7 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx)
535 533
536 534
537ieee80211_txrx_result 535ieee80211_txrx_result
538ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx) 536ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx)
539{ 537{
540 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; 538 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
541 u16 fc; 539 u16 fc;
@@ -549,9 +547,7 @@ ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx)
549 fc = le16_to_cpu(hdr->frame_control); 547 fc = le16_to_cpu(hdr->frame_control);
550 hdrlen = ieee80211_get_hdrlen(fc); 548 hdrlen = ieee80211_get_hdrlen(fc);
551 549
552 if (!key || key->conf.alg != ALG_CCMP || 550 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
553 !(rx->fc & IEEE80211_FCTL_PROTECTED) ||
554 (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
555 return TXRX_CONTINUE; 551 return TXRX_CONTINUE;
556 552
557 data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN; 553 data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN;
diff --git a/net/mac80211/wpa.h b/net/mac80211/wpa.h
index da3b9594f9c3..e49946f54623 100644
--- a/net/mac80211/wpa.h
+++ b/net/mac80211/wpa.h
@@ -21,11 +21,11 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx);
21ieee80211_txrx_result 21ieee80211_txrx_result
22ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx); 22ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx);
23ieee80211_txrx_result 23ieee80211_txrx_result
24ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx); 24ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx);
25 25
26ieee80211_txrx_result 26ieee80211_txrx_result
27ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx); 27ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx);
28ieee80211_txrx_result 28ieee80211_txrx_result
29ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx); 29ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx);
30 30
31#endif /* WPA_H */ 31#endif /* WPA_H */