Search Linux Wireless

[PATCH] mac80211: TKIP enable HW encryption for fragmented packets

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Tomas Winkler <tomas.winkler@xxxxxxxxx>

This patch fixes TKIP encryption for fragmented packets.
Each fragmet needs it's own phase2 key.

Signed-off-by: Tomas Winkler <tomas.winkler@xxxxxxxxx>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@xxxxxxxxx>
---
 net/mac80211/ieee80211_i.h |    2 ++
 net/mac80211/tx.c          |   12 ++++++++++++
 net/mac80211/wpa.c         |   18 +++++++++++++-----
 3 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 7f10ff5..5c7b8e2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -156,6 +156,7 @@ struct ieee80211_tx_data {
 	struct sta_info *sta;
 	u16 fc, ethertype;
 	struct ieee80211_key *key;
+	u8 tkip_key[16];
 	unsigned int flags;
 
 	struct ieee80211_tx_control *control;
@@ -170,6 +171,7 @@ struct ieee80211_tx_data {
 	 * in skb) */
 	int num_extra_frag;
 	struct sk_buff **extra_frag;
+	u8 *frag_tkip_key; /* size 16 * num_extra_frag */
 };
 
 
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 80f4343..ee09464 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1078,6 +1078,11 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
 	if (skb) {
 		ieee80211_dump_frame(wiphy_name(local->hw.wiphy),
 				     "TX to low-level driver", skb);
+
+		if (tx->key && (tx->key->conf.flags &
+				IEEE80211_KEY_FLAG_TKIP_REQ_TX_P2_KEY))
+			memcpy(control->tkip_key, tx->tkip_key, 16);
+
 		ret = local->ops->tx(local_to_hw(local), skb, control);
 		if (ret)
 			return IEEE80211_TX_AGAIN;
@@ -1092,6 +1097,11 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
 		for (i = 0; i < tx->num_extra_frag; i++) {
 			if (!tx->extra_frag[i])
 				continue;
+
+			if (tx->frag_tkip_key)
+				memcpy(control->tkip_key,
+					&tx->frag_tkip_key[i * 16], 16);
+
 			if (__ieee80211_queue_stopped(local, control->queue))
 				return IEEE80211_TX_FRAG_AGAIN;
 			if (i == tx->num_extra_frag) {
@@ -1119,6 +1129,8 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
 		}
 		kfree(tx->extra_frag);
 		tx->extra_frag = NULL;
+		kfree(tx->frag_tkip_key);
+		tx->frag_tkip_key = NULL;
 	}
 	return IEEE80211_TX_OK;
 }
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index cc1702e..60f2349 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -228,10 +228,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx,
 					    0x7f),
 				      (u8) key->u.tkip.iv16);
 
-		if (key->conf.flags & IEEE80211_KEY_FLAG_TKIP_REQ_TX_P2_KEY)
-			ieee80211_tkip_gen_rc4key(key, hdr->addr2,
-						tx->control->tkip_key);
 		tx->control->key_idx = tx->key->conf.hw_key_idx;
+
 		return 0;
 	}
 
@@ -249,6 +247,7 @@ ieee80211_tx_result
 ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
 {
 	struct sk_buff *skb = tx->skb;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	int wpa_test = 0, test = 0;
 
 	tx->control->icv_len = TKIP_ICV_LEN;
@@ -266,12 +265,21 @@ ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
 	if (tkip_encrypt_skb(tx, skb, test) < 0)
 		return TX_DROP;
 
+	if (tx->key->conf.flags & IEEE80211_KEY_FLAG_TKIP_REQ_TX_P2_KEY)
+		ieee80211_tkip_gen_rc4key(tx->key, hdr->addr2, tx->tkip_key);
+
+
 	if (tx->extra_frag) {
 		int i;
+		if (tx->key->conf.flags & IEEE80211_KEY_FLAG_TKIP_REQ_TX_P2_KEY)
+			tx->frag_tkip_key =
+				kzalloc(tx->num_extra_frag * 16, GFP_ATOMIC);
 		for (i = 0; i < tx->num_extra_frag; i++) {
-			if (tkip_encrypt_skb(tx, tx->extra_frag[i], test)
-			    < 0)
+			if (tkip_encrypt_skb(tx, tx->extra_frag[i], test) < 0)
 				return TX_DROP;
+			if (tx->key->conf.flags & IEEE80211_KEY_FLAG_TKIP_REQ_TX_P2_KEY)
+				ieee80211_tkip_gen_rc4key(tx->key, hdr->addr2,
+							  &tx->frag_tkip_key[i * 16]);
 		}
 	}
 
-- 
1.5.3.4

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux