aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-09-26 09:19:41 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:53:14 -0400
commit6a22a59d487e7fe509b457b72497593e402911c0 (patch)
treea4bfd02cdea7e1cec690101bc119b515f3dc445c /net/mac80211
parent4f0d18e26f8bc4c6507b69aa0080d0fae807c990 (diff)
[PATCH] mac80211: consolidate encryption
Currently we run through all crypto handlers for each transmitted frame although we already know which one will be used. This changes the code to invoke only the needed handler. It also moves the wep code into wep.c. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/tx.c62
-rw-r--r--net/mac80211/wep.c57
-rw-r--r--net/mac80211/wep.h5
-rw-r--r--net/mac80211/wpa.c10
-rw-r--r--net/mac80211/wpa.h4
5 files changed, 77 insertions, 61 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 244c80d0c8fb..54e05392410d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -541,56 +541,26 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx)
541 return TXRX_DROP; 541 return TXRX_DROP;
542} 542}
543 543
544static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
545{
546 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
547 if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
548 return -1;
549 } else {
550 tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
551 if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
552 if (!ieee80211_wep_add_iv(tx->local, skb, tx->key))
553 return -1;
554 }
555 }
556 return 0;
557}
558
559static ieee80211_txrx_result 544static ieee80211_txrx_result
560ieee80211_tx_h_wep_encrypt(struct ieee80211_txrx_data *tx) 545ieee80211_tx_h_encrypt(struct ieee80211_txrx_data *tx)
561{ 546{
562 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; 547 if (!tx->key)
563 u16 fc;
564
565 fc = le16_to_cpu(hdr->frame_control);
566
567 if (!tx->key || tx->key->conf.alg != ALG_WEP ||
568 ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
569 ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
570 (fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
571 return TXRX_CONTINUE; 548 return TXRX_CONTINUE;
572 549
573 tx->u.tx.control->iv_len = WEP_IV_LEN; 550 switch (tx->key->conf.alg) {
574 tx->u.tx.control->icv_len = WEP_ICV_LEN; 551 case ALG_WEP:
575 ieee80211_tx_set_iswep(tx); 552 return ieee80211_crypto_wep_encrypt(tx);
576 553 case ALG_TKIP:
577 if (wep_encrypt_skb(tx, tx->skb) < 0) { 554 return ieee80211_crypto_tkip_encrypt(tx);
578 I802_DEBUG_INC(tx->local->tx_handlers_drop_wep); 555 case ALG_CCMP:
579 return TXRX_DROP; 556 return ieee80211_crypto_ccmp_encrypt(tx);
580 } 557 case ALG_NONE:
581 558 return TXRX_CONTINUE;
582 if (tx->u.tx.extra_frag) {
583 int i;
584 for (i = 0; i < tx->u.tx.num_extra_frag; i++) {
585 if (wep_encrypt_skb(tx, tx->u.tx.extra_frag[i]) < 0) {
586 I802_DEBUG_INC(tx->local->
587 tx_handlers_drop_wep);
588 return TXRX_DROP;
589 }
590 }
591 } 559 }
592 560
593 return TXRX_CONTINUE; 561 /* not reached */
562 WARN_ON(1);
563 return TXRX_DROP;
594} 564}
595 565
596static ieee80211_txrx_result 566static ieee80211_txrx_result
@@ -805,9 +775,7 @@ ieee80211_tx_handler ieee80211_tx_handlers[] =
805 ieee80211_tx_h_select_key, 775 ieee80211_tx_h_select_key,
806 ieee80211_tx_h_michael_mic_add, 776 ieee80211_tx_h_michael_mic_add,
807 ieee80211_tx_h_fragment, 777 ieee80211_tx_h_fragment,
808 ieee80211_tx_h_tkip_encrypt, 778 ieee80211_tx_h_encrypt,
809 ieee80211_tx_h_ccmp_encrypt,
810 ieee80211_tx_h_wep_encrypt,
811 ieee80211_tx_h_rate_ctrl, 779 ieee80211_tx_h_rate_ctrl,
812 ieee80211_tx_h_misc, 780 ieee80211_tx_h_misc,
813 ieee80211_tx_h_load_stats, 781 ieee80211_tx_h_load_stats,
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index e785fe1f78ed..16fee142f984 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -80,9 +80,9 @@ static void ieee80211_wep_get_iv(struct ieee80211_local *local,
80} 80}
81 81
82 82
83u8 * ieee80211_wep_add_iv(struct ieee80211_local *local, 83static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
84 struct sk_buff *skb, 84 struct sk_buff *skb,
85 struct ieee80211_key *key) 85 struct ieee80211_key *key)
86{ 86{
87 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 87 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
88 u16 fc; 88 u16 fc;
@@ -350,3 +350,54 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx)
350 350
351 return TXRX_CONTINUE; 351 return TXRX_CONTINUE;
352} 352}
353
354static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
355{
356 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
357 if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
358 return -1;
359 } else {
360 tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
361 if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
362 if (!ieee80211_wep_add_iv(tx->local, skb, tx->key))
363 return -1;
364 }
365 }
366 return 0;
367}
368
369ieee80211_txrx_result
370ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx)
371{
372 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
373 u16 fc;
374
375 fc = le16_to_cpu(hdr->frame_control);
376
377 if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
378 ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
379 (fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
380 return TXRX_CONTINUE;
381
382 tx->u.tx.control->iv_len = WEP_IV_LEN;
383 tx->u.tx.control->icv_len = WEP_ICV_LEN;
384 ieee80211_tx_set_iswep(tx);
385
386 if (wep_encrypt_skb(tx, tx->skb) < 0) {
387 I802_DEBUG_INC(tx->local->tx_handlers_drop_wep);
388 return TXRX_DROP;
389 }
390
391 if (tx->u.tx.extra_frag) {
392 int i;
393 for (i = 0; i < tx->u.tx.num_extra_frag; i++) {
394 if (wep_encrypt_skb(tx, tx->u.tx.extra_frag[i]) < 0) {
395 I802_DEBUG_INC(tx->local->
396 tx_handlers_drop_wep);
397 return TXRX_DROP;
398 }
399 }
400 }
401
402 return TXRX_CONTINUE;
403}
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h
index dfa5af143386..da53190affc0 100644
--- a/net/mac80211/wep.h
+++ b/net/mac80211/wep.h
@@ -18,9 +18,6 @@
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);
21u8 * ieee80211_wep_add_iv(struct ieee80211_local *local,
22 struct sk_buff *skb,
23 struct ieee80211_key *key);
24void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 21void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
25 size_t klen, u8 *data, size_t data_len); 22 size_t klen, u8 *data, size_t data_len);
26int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 23int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
@@ -34,5 +31,7 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
34 31
35ieee80211_txrx_result 32ieee80211_txrx_result
36ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx); 33ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx);
34ieee80211_txrx_result
35ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx);
37 36
38#endif /* WEP_H */ 37#endif /* WEP_H */
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 108fe3e81e24..a07fd7484cdf 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -239,17 +239,16 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
239 239
240 240
241ieee80211_txrx_result 241ieee80211_txrx_result
242ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx) 242ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx)
243{ 243{
244 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; 244 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
245 u16 fc; 245 u16 fc;
246 struct ieee80211_key *key = tx->key;
247 struct sk_buff *skb = tx->skb; 246 struct sk_buff *skb = tx->skb;
248 int wpa_test = 0, test = 0; 247 int wpa_test = 0, test = 0;
249 248
250 fc = le16_to_cpu(hdr->frame_control); 249 fc = le16_to_cpu(hdr->frame_control);
251 250
252 if (!key || key->conf.alg != ALG_TKIP || !WLAN_FC_DATA_PRESENT(fc)) 251 if (!WLAN_FC_DATA_PRESENT(fc))
253 return TXRX_CONTINUE; 252 return TXRX_CONTINUE;
254 253
255 tx->u.tx.control->icv_len = TKIP_ICV_LEN; 254 tx->u.tx.control->icv_len = TKIP_ICV_LEN;
@@ -491,17 +490,16 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
491 490
492 491
493ieee80211_txrx_result 492ieee80211_txrx_result
494ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx) 493ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx)
495{ 494{
496 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; 495 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
497 struct ieee80211_key *key = tx->key;
498 u16 fc; 496 u16 fc;
499 struct sk_buff *skb = tx->skb; 497 struct sk_buff *skb = tx->skb;
500 int test = 0; 498 int test = 0;
501 499
502 fc = le16_to_cpu(hdr->frame_control); 500 fc = le16_to_cpu(hdr->frame_control);
503 501
504 if (!key || key->conf.alg != ALG_CCMP || !WLAN_FC_DATA_PRESENT(fc)) 502 if (!WLAN_FC_DATA_PRESENT(fc))
505 return TXRX_CONTINUE; 503 return TXRX_CONTINUE;
506 504
507 tx->u.tx.control->icv_len = CCMP_MIC_LEN; 505 tx->u.tx.control->icv_len = CCMP_MIC_LEN;
diff --git a/net/mac80211/wpa.h b/net/mac80211/wpa.h
index e49946f54623..49d80cf0cd75 100644
--- a/net/mac80211/wpa.h
+++ b/net/mac80211/wpa.h
@@ -19,12 +19,12 @@ ieee80211_txrx_result
19ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx); 19ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx);
20 20
21ieee80211_txrx_result 21ieee80211_txrx_result
22ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx); 22ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx);
23ieee80211_txrx_result 23ieee80211_txrx_result
24ieee80211_crypto_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_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx);
28ieee80211_txrx_result 28ieee80211_txrx_result
29ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx); 29ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx);
30 30