mac80211: Add IV-room in the skb for TKIP and WEP
authorJanusz.Dziedzic@tieto.com <Janusz.Dziedzic@tieto.com>
Wed, 9 May 2012 05:11:20 +0000 (08:11 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 16 May 2012 16:46:37 +0000 (12:46 -0400)
Add IV-room in skb also for TKIP and WEP.
Extend patch: "mac80211: support adding IV-room in the skb for CCMP keys"

Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/net/mac80211.h
net/mac80211/wep.c
net/mac80211/wpa.c

index 4d6e6c6818d0adf0e86819af790048819c1f310e..60e3766d37396b2cfd265e3bfb1013037ccf17de 100644 (file)
@@ -939,7 +939,7 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
  *     CCMP key if it requires CCMP encryption of management frames (MFP) to
  *     be done in software.
  * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver
- *     for a CCMP key if space should be prepared for the IV, but the IV
+ *     if space should be prepared for the IV, but the IV
  *     itself should not be generated. Do not set together with
  *     @IEEE80211_KEY_FLAG_GENERATE_IV on the same key.
  */
index 7aa31bbfaa3bf7387df2756bf94877cc15fdda9a..e904401684daf2e9d652489072b9e94bf60202ac 100644 (file)
@@ -92,6 +92,7 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
                                int keylen, int keyidx)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        unsigned int hdrlen;
        u8 *newhdr;
 
@@ -104,6 +105,12 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
        hdrlen = ieee80211_hdrlen(hdr->frame_control);
        newhdr = skb_push(skb, WEP_IV_LEN);
        memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen);
+
+       /* the HW only needs room for the IV, but not the actual IV */
+       if (info->control.hw_key &&
+           (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
+               return newhdr + hdrlen;
+
        ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen);
        return newhdr + hdrlen;
 }
@@ -313,14 +320,15 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
 static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_key_conf *hw_key = info->control.hw_key;
 
-       if (!info->control.hw_key) {
+       if (!hw_key) {
                if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key,
                                          tx->key->conf.keylen,
                                          tx->key->conf.keyidx))
                        return -1;
-       } else if (info->control.hw_key->flags &
-                       IEEE80211_KEY_FLAG_GENERATE_IV) {
+       } else if ((hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
+                  (hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
                if (!ieee80211_wep_add_iv(tx->local, skb,
                                          tx->key->conf.keylen,
                                          tx->key->conf.keyidx))
index 0ae23c60968c0a9e82b214042ee5b01c4f27bb7d..4d05ad9403aeed594d87f5d6eeb70b2b8ac4625b 100644 (file)
@@ -183,7 +183,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
        u8 *pos;
 
        if (info->control.hw_key &&
-           !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
+           !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
+           !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
                /* hwaccel - with no need for software-generated IV */
                return 0;
        }
@@ -204,6 +205,11 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
        memmove(pos, pos + TKIP_IV_LEN, hdrlen);
        pos += hdrlen;
 
+       /* the HW only needs room for the IV, but not the actual IV */
+       if (info->control.hw_key &&
+           (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
+               return 0;
+
        /* Increase IV for the frame */
        spin_lock_irqsave(&key->u.tkip.txlock, flags);
        key->u.tkip.tx.iv16++;