linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Johannes Berg <johannes@sipsolutions.net>
To: linux-wireless@vger.kernel.org
Cc: Pavel Roskin <proski@gnu.org>
Subject: [RFC/RFT 4/5] mac80211: move control.hw_key assignment
Date: Tue, 15 Dec 2009 21:06:22 +0100	[thread overview]
Message-ID: <20091215200739.661125708@sipsolutions.net> (raw)
In-Reply-To: 20091215200618.253970634@sipsolutions.net

When mac80211 asks a driver to encrypt a frame, it
must assign the control.hw_key pointer for it to
know which key to use etc. Currently, mac80211 does
this whenever it would software-encrypt a frame.

Change the logic of this code to assign the hw_key
pointer when selecting the key, and later check it
when deciding whether to encrypt the frame or let
it be encrypted by the hardware. This allows us to
later simply skip the encryption function since it
no longer modifies the TX control.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/tkip.c |   11 +++++-----
 net/mac80211/tx.c   |    9 ++++++++
 net/mac80211/wep.c  |   18 ++++++++--------
 net/mac80211/wpa.c  |   57 ++++++++++++++++++++--------------------------------
 4 files changed, 46 insertions(+), 49 deletions(-)

--- wireless-testing.orig/net/mac80211/tkip.c	2009-12-15 20:42:43.000000000 +0100
+++ wireless-testing/net/mac80211/tkip.c	2009-12-15 20:45:48.000000000 +0100
@@ -195,11 +195,13 @@ void ieee80211_get_tkip_key(struct ieee8
 }
 EXPORT_SYMBOL(ieee80211_get_tkip_key);
 
-/* Encrypt packet payload with TKIP using @key. @pos is a pointer to the
+/*
+ * Encrypt packet payload with TKIP using @key. @pos is a pointer to the
  * beginning of the buffer containing payload. This payload must include
- * headroom of eight octets for IV and Ext. IV and taildroom of four octets
- * for ICV. @payload_len is the length of payload (_not_ including extra
- * headroom and tailroom). @ta is the transmitter addresses. */
+ * the IV/Ext.IV and space for (taildroom) four octets for ICV.
+ * @payload_len is the length of payload (_not_ including IV/ICV length).
+ * @ta is the transmitter addresses.
+ */
 void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
 				 struct ieee80211_key *key,
 				 u8 *pos, size_t payload_len, u8 *ta)
@@ -214,7 +216,6 @@ void ieee80211_tkip_encrypt_data(struct 
 
 	tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key);
 
-	pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
 	ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len);
 }
 
--- wireless-testing.orig/net/mac80211/wpa.c	2009-12-15 20:42:43.000000000 +0100
+++ wireless-testing/net/mac80211/wpa.c	2009-12-15 20:45:48.000000000 +0100
@@ -31,8 +31,8 @@ ieee80211_tx_h_michael_mic_add(struct ie
 	unsigned int hdrlen;
 	struct ieee80211_hdr *hdr;
 	struct sk_buff *skb = tx->skb;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	int authenticator;
-	int wpa_test = 0;
 	int tail;
 
 	hdr = (struct ieee80211_hdr *)skb->data;
@@ -47,16 +47,15 @@ ieee80211_tx_h_michael_mic_add(struct ie
 	data = skb->data + hdrlen;
 	data_len = skb->len - hdrlen;
 
-	if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
+	if (info->control.hw_key &&
 	    !(tx->flags & IEEE80211_TX_FRAGMENTED) &&
-	    !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) &&
-	    !wpa_test) {
-		/* hwaccel - with no need for preallocated room for MMIC */
+	    !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
+		/* hwaccel - with no need for SW-generated MMIC */
 		return TX_CONTINUE;
 	}
 
 	tail = MICHAEL_MIC_LEN;
-	if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
+	if (!info->control.hw_key)
 		tail += TKIP_ICV_LEN;
 
 	if (WARN_ON(skb_tailroom(skb) < tail ||
@@ -147,17 +146,16 @@ static int tkip_encrypt_skb(struct ieee8
 	int len, tail;
 	u8 *pos;
 
-	if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
-	    !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
-		/* hwaccel - with no need for preallocated room for IV/ICV */
-		info->control.hw_key = &tx->key->conf;
+	if (info->control.hw_key &&
+	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
+		/* hwaccel - with no need for software-generated IV */
 		return 0;
 	}
 
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 	len = skb->len - hdrlen;
 
-	if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
+	if (info->control.hw_key)
 		tail = 0;
 	else
 		tail = TKIP_ICV_LEN;
@@ -175,13 +173,11 @@ static int tkip_encrypt_skb(struct ieee8
 	if (key->u.tkip.tx.iv16 == 0)
 		key->u.tkip.tx.iv32++;
 
-	if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
-		/* hwaccel - with preallocated room for IV */
-		ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
+	pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16);
 
-		info->control.hw_key = &tx->key->conf;
+	/* hwaccel - with software IV */
+	if (info->control.hw_key)
 		return 0;
-	}
 
 	/* Add room for ICV */
 	skb_put(skb, TKIP_ICV_LEN);
@@ -363,24 +359,20 @@ static int ccmp_encrypt_skb(struct ieee8
 	int hdrlen, len, tail;
 	u8 *pos, *pn;
 	int i;
-	bool skip_hw;
-
-	skip_hw = (tx->key->conf.flags & IEEE80211_KEY_FLAG_SW_MGMT) &&
-		ieee80211_is_mgmt(hdr->frame_control);
 
-	if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
-	    !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
-	    !skip_hw) {
-		/* hwaccel - with no need for preallocated room for CCMP
-		 * header or MIC fields */
-		info->control.hw_key = &tx->key->conf;
+	if (info->control.hw_key &&
+	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
+		/*
+		 * hwaccel has no need for preallocated room for CCMP
+		 * header or MIC fields
+		 */
 		return 0;
 	}
 
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 	len = skb->len - hdrlen;
 
-	if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
+	if (info->control.hw_key)
 		tail = 0;
 	else
 		tail = CCMP_MIC_LEN;
@@ -405,11 +397,9 @@ static int ccmp_encrypt_skb(struct ieee8
 
 	ccmp_pn2hdr(pos, pn, key->conf.keyidx);
 
-	if ((key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && !skip_hw) {
-		/* hwaccel - with preallocated room for CCMP header */
-		info->control.hw_key = &tx->key->conf;
+	/* hwaccel - with software CCMP header */
+	if (info->control.hw_key)
 		return 0;
-	}
 
 	pos += CCMP_HDR_LEN;
 	ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0);
@@ -525,11 +515,8 @@ ieee80211_crypto_aes_cmac_encrypt(struct
 	u8 *pn, aad[20];
 	int i;
 
-	if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
-		/* hwaccel */
-		info->control.hw_key = &tx->key->conf;
+	if (info->control.hw_key)
 		return 0;
-	}
 
 	if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
 		return TX_DROP;
--- wireless-testing.orig/net/mac80211/wep.c	2009-12-15 20:42:43.000000000 +0100
+++ wireless-testing/net/mac80211/wep.c	2009-12-15 20:45:48.000000000 +0100
@@ -305,20 +305,20 @@ static int wep_encrypt_skb(struct ieee80
 {
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
-	if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
+	if (!info->control.hw_key) {
 		if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key,
 					  tx->key->conf.keylen,
 					  tx->key->conf.keyidx))
 			return -1;
-	} else {
-		info->control.hw_key = &tx->key->conf;
-		if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
-			if (!ieee80211_wep_add_iv(tx->local, skb,
-						  tx->key->conf.keylen,
-						  tx->key->conf.keyidx))
-				return -1;
-		}
 	}
+
+	if (info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
+		if (!ieee80211_wep_add_iv(tx->local, skb,
+					  tx->key->conf.keylen,
+					  tx->key->conf.keyidx))
+			return -1;
+	}
+
 	return 0;
 }
 
--- wireless-testing.orig/net/mac80211/tx.c	2009-12-15 20:42:56.000000000 +0100
+++ wireless-testing/net/mac80211/tx.c	2009-12-15 20:45:48.000000000 +0100
@@ -463,6 +463,8 @@ ieee80211_tx_h_select_key(struct ieee802
 		tx->key = NULL;
 
 	if (tx->key) {
+		bool skip_hw = false;
+
 		tx->key->tx_rx_count++;
 		/* TODO: add threshold stuff again */
 
@@ -479,12 +481,19 @@ ieee80211_tx_h_select_key(struct ieee802
 			    !ieee80211_use_mfp(hdr->frame_control, tx->sta,
 					       tx->skb))
 				tx->key = NULL;
+			skip_hw = (tx->key->conf.flags &
+						IEEE80211_KEY_FLAG_SW_MGMT) &&
+				   ieee80211_is_mgmt(hdr->frame_control);
 			break;
 		case ALG_AES_CMAC:
 			if (!ieee80211_is_mgmt(hdr->frame_control))
 				tx->key = NULL;
 			break;
 		}
+
+		if (!skip_hw &&
+		    tx->key->conf.flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
+			info->control.hw_key = &tx->key->conf;
 	}
 
 	return TX_CONTINUE;



  parent reply	other threads:[~2009-12-15 20:10 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-15 20:06 [RFC/RFT 0/5] mac80211: re-enable software retry Johannes Berg
2009-12-15 20:06 ` [RFC/RFT 1/5] mac80211: move and rename misc tx handler Johannes Berg
2009-12-15 20:06 ` [RFC/RFT 2/5] mac80211: clear TX control on filtered frames Johannes Berg
2009-12-15 20:06 ` [RFC/RFT 3/5] mac80211: remove useless setting of IEEE80211_TX_INTFL_DONT_ENCRYPT Johannes Berg
2009-12-15 20:06 ` Johannes Berg [this message]
2009-12-15 20:06 ` [RFC/RFT 5/5] mac80211: re-enable re-transmission of filtered frames Johannes Berg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091215200739.661125708@sipsolutions.net \
    --to=johannes@sipsolutions.net \
    --cc=linux-wireless@vger.kernel.org \
    --cc=proski@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).