diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2007-09-26 09:19:40 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:53:13 -0400 |
commit | 4f0d18e26f8bc4c6507b69aa0080d0fae807c990 (patch) | |
tree | b9ef529b35cec6a81b8b7868c80088a30aa6bc9d | |
parent | b2e7771e556917cc301a3308561f49b2b2272c07 (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.c | 40 | ||||
-rw-r--r-- | net/mac80211/wep.c | 34 | ||||
-rw-r--r-- | net/mac80211/wep.h | 8 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 12 | ||||
-rw-r--r-- | net/mac80211/wpa.h | 4 |
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 | ||
664 | static ieee80211_txrx_result | 664 | static ieee80211_txrx_result |
665 | ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx) | 665 | ieee80211_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 | ||
697 | static inline struct ieee80211_fragment_entry * | 693 | static 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 | ||
66 | void ieee80211_wep_get_iv(struct ieee80211_local *local, | 66 | static 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 | ||
112 | void ieee80211_wep_remove_iv(struct ieee80211_local *local, | 112 | static 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 | |||
330 | ieee80211_txrx_result | ||
331 | ieee80211_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 | ||
19 | int ieee80211_wep_init(struct ieee80211_local *local); | 19 | int ieee80211_wep_init(struct ieee80211_local *local); |
20 | void ieee80211_wep_free(struct ieee80211_local *local); | 20 | void ieee80211_wep_free(struct ieee80211_local *local); |
21 | void ieee80211_wep_get_iv(struct ieee80211_local *local, | ||
22 | struct ieee80211_key *key, u8 *iv); | ||
23 | u8 * ieee80211_wep_add_iv(struct ieee80211_local *local, | 21 | u8 * 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); |
26 | void ieee80211_wep_remove_iv(struct ieee80211_local *local, | ||
27 | struct sk_buff *skb, | ||
28 | struct ieee80211_key *key); | ||
29 | void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, | 24 | void 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); |
31 | int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, | 26 | int 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, | |||
37 | int ieee80211_wep_get_keyidx(struct sk_buff *skb); | 32 | int ieee80211_wep_get_keyidx(struct sk_buff *skb); |
38 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); | 33 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); |
39 | 34 | ||
35 | ieee80211_txrx_result | ||
36 | ieee80211_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 | ||
283 | ieee80211_txrx_result | 283 | ieee80211_txrx_result |
284 | ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx) | 284 | ieee80211_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 | ||
537 | ieee80211_txrx_result | 535 | ieee80211_txrx_result |
538 | ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx) | 536 | ieee80211_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); | |||
21 | ieee80211_txrx_result | 21 | ieee80211_txrx_result |
22 | ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx); | 22 | ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx); |
23 | ieee80211_txrx_result | 23 | ieee80211_txrx_result |
24 | ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx); | 24 | ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx); |
25 | 25 | ||
26 | ieee80211_txrx_result | 26 | ieee80211_txrx_result |
27 | ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx); | 27 | ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx); |
28 | ieee80211_txrx_result | 28 | ieee80211_txrx_result |
29 | ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx); | 29 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx); |
30 | 30 | ||
31 | #endif /* WPA_H */ | 31 | #endif /* WPA_H */ |