Search Linux Wireless

[RFC] mac80211: Add an RX flag to skip Michael MIC verification

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

 



mac80211 used to allow drivers to indicate that Michael MIC has already
been verified in received frames to allow the somewhat heavy operation
of validating this in software to be avoided. This disappeared as part
of hardware crypto flag rework (commit
7848ba7d7a010ccb265617fc2bc053e2bdf06f48). The changes below propose a
bit different mechanism for achieving the same benefit for host CPU with
wlan designs that can verify Michael MIC for unfragmented frames in
hardware.

I'm also including a patch to ath9k to start using this new mechanism
and move Michael MIC processing to hardware for both TX and RX whenever
possible. It seems to work based on minimal testing, but I do not want
to submit it to be merged before more thorough testing has taken place.


Some hardware acceleration designs for TKIP take care of Michael MIC
verification in received frames (well, at least for frames that were
not fragmented). Add an RX status flag to allow the expensive software
validation of the Michael MIC to be skipped in cases where it has
already been verified in hardware.

Signed-off-by: Jouni Malinen <jouni.malinen@xxxxxxxxxxx>

---
 include/net/mac80211.h |    3 +++
 net/mac80211/wpa.c     |    4 ++++
 2 files changed, 7 insertions(+)

--- wireless-testing.orig/include/net/mac80211.h	2008-12-18 13:48:45.000000000 +0200
+++ wireless-testing/include/net/mac80211.h	2008-12-18 13:49:08.000000000 +0200
@@ -439,6 +439,8 @@ ieee80211_tx_info_clear_status(struct ie
  * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
  * @RX_FLAG_40MHZ: HT40 (40 MHz) was used
  * @RX_FLAG_SHORT_GI: Short guard interval was used
+ * @RX_FLAG_MMIC_VERIFIED: the hardware has verified the Michael MIC, but the
+ *	MIC has not been stripped off this frame.
  */
 enum mac80211_rx_flags {
 	RX_FLAG_MMIC_ERROR	= 1<<0,
@@ -453,6 +455,7 @@ enum mac80211_rx_flags {
 	RX_FLAG_HT		= 1<<9,
 	RX_FLAG_40MHZ		= 1<<10,
 	RX_FLAG_SHORT_GI	= 1<<11,
+	RX_FLAG_MMIC_VERIFIED	= 1<<12,
 };
 
 /**
--- wireless-testing.orig/net/mac80211/wpa.c	2008-12-18 13:48:45.000000000 +0200
+++ wireless-testing/net/mac80211/wpa.c	2008-12-18 13:49:08.000000000 +0200
@@ -99,6 +99,9 @@ ieee80211_rx_h_michael_mic_verify(struct
 	    !ieee80211_is_data_present(hdr->frame_control))
 		return RX_CONTINUE;
 
+	if (rx->status->flag & RX_FLAG_MMIC_VERIFIED)
+		goto remove_mic;
+
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 	if (skb->len < hdrlen + MICHAEL_MIC_LEN)
 		return RX_DROP_UNUSABLE;
@@ -125,6 +128,7 @@ ieee80211_rx_h_michael_mic_verify(struct
 		return RX_DROP_UNUSABLE;
 	}
 
+remove_mic:
 	/* remove Michael MIC from payload */
 	skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
 



ath9k: Michael MIC in hardware

Remove request for mac80211 to calculate Michael MIC when TKIP is used
since that is not needed with any hardware revisions supported by
ath9k. Only fragmented frames need Michael MIC processing in the stack
and that will be taken care of automatically without driver
request. Mark received frames that that hardware decrypted to have
passed Michael MIC verification if they were not fragmented
(fragmented frames will continue to be verified in mac80211).

Signed-off-by: Jouni Malinen <jouni.malinen@xxxxxxxxxxx>
---
 drivers/net/wireless/ath9k/main.c |    3 ---
 drivers/net/wireless/ath9k/recv.c |   11 +++++++++++
 drivers/net/wireless/ath9k/xmit.c |    8 ++++++++
 3 files changed, 19 insertions(+), 3 deletions(-)

--- wireless-testing.orig/drivers/net/wireless/ath9k/main.c	2008-12-18 14:12:57.000000000 +0200
+++ wireless-testing/drivers/net/wireless/ath9k/main.c	2008-12-18 14:13:01.000000000 +0200
@@ -2366,10 +2366,7 @@ static int ath9k_set_key(struct ieee8021
 		ret = ath_key_config(sc, addr, key);
 		if (ret >= 0) {
 			key->hw_key_idx = ret;
-			/* push IV and Michael MIC generation to stack */
 			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-			if (key->alg == ALG_TKIP)
-				key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
 			ret = 0;
 		}
 		break;
--- wireless-testing.orig/drivers/net/wireless/ath9k/recv.c	2008-12-18 14:12:57.000000000 +0200
+++ wireless-testing/drivers/net/wireless/ath9k/recv.c	2008-12-18 14:13:01.000000000 +0200
@@ -594,6 +594,17 @@ int ath_rx_tasklet(struct ath_softc *sc,
 				rx_status.flag |= RX_FLAG_DECRYPTED;
 		}
 
+		if (rx_status.flag & RX_FLAG_DECRYPTED) {
+			/* Hardware verifies Michael MIC in unfragmented
+			 * frames, so there is no need to do software
+			 * verification for them. */
+			__le16 fc = hdr->frame_control;
+			u16 sc = le16_to_cpu(hdr->seq_ctrl);
+			if (!ieee80211_has_morefrags(fc) &&
+			    (sc & IEEE80211_SCTL_FRAG) == 0)
+				rx_status.flag |= RX_FLAG_MMIC_VERIFIED;
+		}
+
 		/* Send the frame to mac80211 */
 		__ieee80211_rx(sc->hw, skb, &rx_status);
 
--- wireless-testing.orig/drivers/net/wireless/ath9k/xmit.c	2008-12-18 14:13:11.000000000 +0200
+++ wireless-testing/drivers/net/wireless/ath9k/xmit.c	2008-12-18 14:23:23.000000000 +0200
@@ -1711,6 +1711,14 @@ static int ath_tx_setup_buffer(struct at
 
 	if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
 		bf->bf_frmlen += tx_info->control.hw_key->icv_len;
+		if (bf->bf_keytype == ATH9K_KEY_TYPE_TKIP &&
+		    !ieee80211_has_morefrags(fc)) {
+			u16 sc = le16_to_cpu(hdr->seq_ctrl);
+			if ((sc & IEEE80211_SCTL_FRAG) == 0) {
+				 /* Michael MIC in hardware */
+				bf->bf_frmlen += 8;
+			}
+		}
 		bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
 	} else {
 		bf->bf_keyix = ATH9K_TXKEYIX_INVALID;

-- 
Jouni Malinen                                            PGP id EFC895FA
--
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