[PATCH] mac80211: consolidate encryption
authorJohannes Berg <johannes@sipsolutions.net>
Wed, 26 Sep 2007 13:19:41 +0000 (15:19 +0200)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 10 Oct 2007 23:53:14 +0000 (16:53 -0700)
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>
net/mac80211/tx.c
net/mac80211/wep.c
net/mac80211/wep.h
net/mac80211/wpa.c
net/mac80211/wpa.h

index 244c80d0c8fb46d3302ab0646d25c6b6ca3c5147..54e05392410d040b3a3112ba8297df0174b46306 100644 (file)
@@ -541,56 +541,26 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx)
        return TXRX_DROP;
 }
 
-static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
-{
-       if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
-               if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
-                       return -1;
-       } else {
-               tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
-               if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
-                       if (!ieee80211_wep_add_iv(tx->local, skb, tx->key))
-                               return -1;
-               }
-       }
-       return 0;
-}
-
 static ieee80211_txrx_result
-ieee80211_tx_h_wep_encrypt(struct ieee80211_txrx_data *tx)
+ieee80211_tx_h_encrypt(struct ieee80211_txrx_data *tx)
 {
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
-       u16 fc;
-
-       fc = le16_to_cpu(hdr->frame_control);
-
-       if (!tx->key || tx->key->conf.alg != ALG_WEP ||
-           ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
-            ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
-             (fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
+       if (!tx->key)
                return TXRX_CONTINUE;
 
-       tx->u.tx.control->iv_len = WEP_IV_LEN;
-       tx->u.tx.control->icv_len = WEP_ICV_LEN;
-       ieee80211_tx_set_iswep(tx);
-
-       if (wep_encrypt_skb(tx, tx->skb) < 0) {
-               I802_DEBUG_INC(tx->local->tx_handlers_drop_wep);
-               return TXRX_DROP;
-       }
-
-       if (tx->u.tx.extra_frag) {
-               int i;
-               for (i = 0; i < tx->u.tx.num_extra_frag; i++) {
-                       if (wep_encrypt_skb(tx, tx->u.tx.extra_frag[i]) < 0) {
-                               I802_DEBUG_INC(tx->local->
-                                              tx_handlers_drop_wep);
-                               return TXRX_DROP;
-                       }
-               }
+       switch (tx->key->conf.alg) {
+       case ALG_WEP:
+               return ieee80211_crypto_wep_encrypt(tx);
+       case ALG_TKIP:
+               return ieee80211_crypto_tkip_encrypt(tx);
+       case ALG_CCMP:
+               return ieee80211_crypto_ccmp_encrypt(tx);
+       case ALG_NONE:
+               return TXRX_CONTINUE;
        }
 
-       return TXRX_CONTINUE;
+       /* not reached */
+       WARN_ON(1);
+       return TXRX_DROP;
 }
 
 static ieee80211_txrx_result
@@ -805,9 +775,7 @@ ieee80211_tx_handler ieee80211_tx_handlers[] =
        ieee80211_tx_h_select_key,
        ieee80211_tx_h_michael_mic_add,
        ieee80211_tx_h_fragment,
-       ieee80211_tx_h_tkip_encrypt,
-       ieee80211_tx_h_ccmp_encrypt,
-       ieee80211_tx_h_wep_encrypt,
+       ieee80211_tx_h_encrypt,
        ieee80211_tx_h_rate_ctrl,
        ieee80211_tx_h_misc,
        ieee80211_tx_h_load_stats,
index e785fe1f78ed5d70f5311d45b9ef9d3ed2b46f63..16fee142f9848d9ec4035aada162b111b4c19d6b 100644 (file)
@@ -80,9 +80,9 @@ static void ieee80211_wep_get_iv(struct ieee80211_local *local,
 }
 
 
-u8 * ieee80211_wep_add_iv(struct ieee80211_local *local,
-                         struct sk_buff *skb,
-                         struct ieee80211_key *key)
+static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
+                               struct sk_buff *skb,
+                               struct ieee80211_key *key)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        u16 fc;
@@ -350,3 +350,54 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx)
 
        return TXRX_CONTINUE;
 }
+
+static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
+{
+       if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
+               if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
+                       return -1;
+       } else {
+               tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx;
+               if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
+                       if (!ieee80211_wep_add_iv(tx->local, skb, tx->key))
+                               return -1;
+               }
+       }
+       return 0;
+}
+
+ieee80211_txrx_result
+ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx)
+{
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
+       u16 fc;
+
+       fc = le16_to_cpu(hdr->frame_control);
+
+       if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
+            ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
+             (fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
+               return TXRX_CONTINUE;
+
+       tx->u.tx.control->iv_len = WEP_IV_LEN;
+       tx->u.tx.control->icv_len = WEP_ICV_LEN;
+       ieee80211_tx_set_iswep(tx);
+
+       if (wep_encrypt_skb(tx, tx->skb) < 0) {
+               I802_DEBUG_INC(tx->local->tx_handlers_drop_wep);
+               return TXRX_DROP;
+       }
+
+       if (tx->u.tx.extra_frag) {
+               int i;
+               for (i = 0; i < tx->u.tx.num_extra_frag; i++) {
+                       if (wep_encrypt_skb(tx, tx->u.tx.extra_frag[i]) < 0) {
+                               I802_DEBUG_INC(tx->local->
+                                              tx_handlers_drop_wep);
+                               return TXRX_DROP;
+                       }
+               }
+       }
+
+       return TXRX_CONTINUE;
+}
index dfa5af1433868a950328f8d142a33efb6d6ea87f..da53190affc08786c045fcdcc06cb5ec892ffd38 100644 (file)
@@ -18,9 +18,6 @@
 
 int ieee80211_wep_init(struct ieee80211_local *local);
 void ieee80211_wep_free(struct ieee80211_local *local);
-u8 * ieee80211_wep_add_iv(struct ieee80211_local *local,
-                         struct sk_buff *skb,
-                         struct ieee80211_key *key);
 void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
                                size_t klen, u8 *data, size_t data_len);
 int 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);
 
 ieee80211_txrx_result
 ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx);
+ieee80211_txrx_result
+ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx);
 
 #endif /* WEP_H */
index 108fe3e81e24f73fb5a56e7ed59d08cdc03da28b..a07fd7484cdfa9bc5c90127fcd8884af6b3a1fa1 100644 (file)
@@ -239,17 +239,16 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
 
 
 ieee80211_txrx_result
-ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx)
+ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
        u16 fc;
-       struct ieee80211_key *key = tx->key;
        struct sk_buff *skb = tx->skb;
        int wpa_test = 0, test = 0;
 
        fc = le16_to_cpu(hdr->frame_control);
 
-       if (!key || key->conf.alg != ALG_TKIP || !WLAN_FC_DATA_PRESENT(fc))
+       if (!WLAN_FC_DATA_PRESENT(fc))
                return TXRX_CONTINUE;
 
        tx->u.tx.control->icv_len = TKIP_ICV_LEN;
@@ -491,17 +490,16 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
 
 
 ieee80211_txrx_result
-ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx)
+ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
-       struct ieee80211_key *key = tx->key;
        u16 fc;
        struct sk_buff *skb = tx->skb;
        int test = 0;
 
        fc = le16_to_cpu(hdr->frame_control);
 
-       if (!key || key->conf.alg != ALG_CCMP || !WLAN_FC_DATA_PRESENT(fc))
+       if (!WLAN_FC_DATA_PRESENT(fc))
                return TXRX_CONTINUE;
 
        tx->u.tx.control->icv_len = CCMP_MIC_LEN;
index e49946f546231ad19e2c0ddb18480a37c7d1925b..49d80cf0cd7569fb5f409121f017b185f0e76bdf 100644 (file)
@@ -19,12 +19,12 @@ ieee80211_txrx_result
 ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx);
 
 ieee80211_txrx_result
-ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx);
+ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx);
 ieee80211_txrx_result
 ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx);
 
 ieee80211_txrx_result
-ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx);
+ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx);
 ieee80211_txrx_result
 ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx);