linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection)
@ 2009-01-07 11:23 Jouni Malinen
  2009-01-07 11:23 ` [PATCH 01/14] mac80211: 802.11w - STA flag for MFP Jouni Malinen
                   ` (13 more replies)
  0 siblings, 14 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless

This set of patches adds support for IEEE 802.11w (management frame
protection) into mac80211. It is up-to-date with the latest IEEE 802.11w
draft (D7.0) and I do not expect any major changes to IEEE 802.11w
anymore.

This version is ready to be applied into wireless-testing.

Differences to the last RFC round:
- rebase against current wireless-testing + CSA patch from Sujith (it
  is also allocating a new flag and would have conflicted with the
  previous MFP patches)
- fix ieee80211_is_robust_mgmt_frame() for encrypted (on RX) frames
  (must not check Category field for them since it may be encrypted)
- add a new option for CCMP hwaccel keys to allow the driver to request
  management frame crypto be done in mac80211 if needed
- update ath9k to support MFP

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 01/14] mac80211: 802.11w - STA flag for MFP
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 11:23 ` [PATCH 02/14] mac80211: 802.11w - CCMP for management frames Jouni Malinen
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

Add flags for setting STA entries and struct ieee80211_if_sta to
indicate whether management frame protection (MFP) is used.

Signed-off-by: Jouni Malinen <j@w1.fi>


---
 include/linux/nl80211.h    |    2 ++
 include/net/cfg80211.h     |    2 ++
 net/mac80211/cfg.c         |    4 ++++
 net/mac80211/debugfs_sta.c |    5 +++--
 net/mac80211/ieee80211_i.h |    1 +
 net/mac80211/mlme.c        |    7 +++++--
 net/mac80211/sta_info.h    |    2 ++
 7 files changed, 19 insertions(+), 4 deletions(-)

--- wireless-testing.orig/net/mac80211/mlme.c	2009-01-07 13:07:38.000000000 +0200
+++ wireless-testing/net/mac80211/mlme.c	2009-01-07 13:07:41.000000000 +0200
@@ -1,6 +1,6 @@
 /*
  * BSS client mode implementation
- * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
+ * Copyright 2003-2008, Jouni Malinen <j@w1.fi>
  * Copyright 2004, Instant802 Networks, Inc.
  * Copyright 2005, Devicescape Software, Inc.
  * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
@@ -472,7 +472,7 @@ static void ieee80211_send_deauth_disass
 	/* u.deauth.reason_code == u.disassoc.reason_code */
 	mgmt->u.deauth.reason_code = cpu_to_le16(reason);
 
-	ieee80211_tx_skb(sdata, skb, 0);
+	ieee80211_tx_skb(sdata, skb, ifsta->flags & IEEE80211_STA_MFP_ENABLED);
 }
 
 /* MLME */
@@ -1420,6 +1420,9 @@ static void ieee80211_rx_mgmt_assoc_resp
 
 	rate_control_rate_init(sta);
 
+	if (ifsta->flags & IEEE80211_STA_MFP_ENABLED)
+		set_sta_flags(sta, WLAN_STA_MFP);
+
 	if (elems.wmm_param)
 		set_sta_flags(sta, WLAN_STA_WME);
 
--- wireless-testing.orig/include/linux/nl80211.h	2008-12-31 17:33:38.000000000 +0200
+++ wireless-testing/include/linux/nl80211.h	2009-01-07 13:07:41.000000000 +0200
@@ -412,12 +412,14 @@ enum nl80211_iftype {
  * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
  *	with short barker preamble
  * @NL80211_STA_FLAG_WME: station is WME/QoS capable
+ * @NL80211_STA_FLAG_MFP: station uses management frame protection
  */
 enum nl80211_sta_flags {
 	__NL80211_STA_FLAG_INVALID,
 	NL80211_STA_FLAG_AUTHORIZED,
 	NL80211_STA_FLAG_SHORT_PREAMBLE,
 	NL80211_STA_FLAG_WME,
+	NL80211_STA_FLAG_MFP,
 
 	/* keep last */
 	__NL80211_STA_FLAG_AFTER_LAST,
--- wireless-testing.orig/include/net/cfg80211.h	2008-12-31 17:33:38.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-01-07 13:07:41.000000000 +0200
@@ -112,12 +112,14 @@ struct beacon_parameters {
  * @STATION_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
  *	with short preambles
  * @STATION_FLAG_WME: station is WME/QoS capable
+ * @STATION_FLAG_MFP: station uses management frame protection
  */
 enum station_flags {
 	STATION_FLAG_CHANGED		= 1<<0,
 	STATION_FLAG_AUTHORIZED		= 1<<NL80211_STA_FLAG_AUTHORIZED,
 	STATION_FLAG_SHORT_PREAMBLE	= 1<<NL80211_STA_FLAG_SHORT_PREAMBLE,
 	STATION_FLAG_WME		= 1<<NL80211_STA_FLAG_WME,
+	STATION_FLAG_MFP		= 1<<NL80211_STA_FLAG_MFP,
 };
 
 /**
--- wireless-testing.orig/net/mac80211/cfg.c	2008-12-31 17:33:38.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c	2009-01-07 13:07:41.000000000 +0200
@@ -630,6 +630,10 @@ static void sta_apply_parameters(struct 
 		sta->flags &= ~WLAN_STA_WME;
 		if (params->station_flags & STATION_FLAG_WME)
 			sta->flags |= WLAN_STA_WME;
+
+		sta->flags &= ~WLAN_STA_MFP;
+		if (params->station_flags & STATION_FLAG_MFP)
+			sta->flags |= WLAN_STA_MFP;
 		spin_unlock_bh(&sta->lock);
 	}
 
--- wireless-testing.orig/net/mac80211/debugfs_sta.c	2008-12-31 17:33:38.000000000 +0200
+++ wireless-testing/net/mac80211/debugfs_sta.c	2009-01-07 13:07:41.000000000 +0200
@@ -67,14 +67,15 @@ static ssize_t sta_flags_read(struct fil
 	char buf[100];
 	struct sta_info *sta = file->private_data;
 	u32 staflags = get_sta_flags(sta);
-	int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s",
+	int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s",
 		staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
 		staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
 		staflags & WLAN_STA_PS ? "PS\n" : "",
 		staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
 		staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
 		staflags & WLAN_STA_WME ? "WME\n" : "",
-		staflags & WLAN_STA_WDS ? "WDS\n" : "");
+		staflags & WLAN_STA_WDS ? "WDS\n" : "",
+		staflags & WLAN_STA_MFP ? "MFP\n" : "");
 	return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 }
 STA_OPS(flags);
--- wireless-testing.orig/net/mac80211/sta_info.h	2008-12-31 17:33:39.000000000 +0200
+++ wireless-testing/net/mac80211/sta_info.h	2009-01-07 13:07:41.000000000 +0200
@@ -34,6 +34,7 @@
  * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
  *	IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
  *	frame to this station is transmitted.
+ * @WLAN_STA_MFP: Management frame protection is used with this STA.
  */
 enum ieee80211_sta_info_flags {
 	WLAN_STA_AUTH		= 1<<0,
@@ -46,6 +47,7 @@ enum ieee80211_sta_info_flags {
 	WLAN_STA_WDS		= 1<<7,
 	WLAN_STA_PSPOLL		= 1<<8,
 	WLAN_STA_CLEAR_PS_FILT	= 1<<9,
+	WLAN_STA_MFP		= 1<<10,
 };
 
 #define STA_TID_NUM 16
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-01-07 13:07:38.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-01-07 13:07:41.000000000 +0200
@@ -260,6 +260,7 @@ struct mesh_preq_queue {
 #define IEEE80211_STA_PRIVACY_INVOKED	BIT(13)
 #define IEEE80211_STA_TKIP_WEP_USED	BIT(14)
 #define IEEE80211_STA_CSA_RECEIVED	BIT(15)
+#define IEEE80211_STA_MFP_ENABLED	BIT(16)
 /* flags for MLME request */
 #define IEEE80211_STA_REQ_SCAN 0
 #define IEEE80211_STA_REQ_DIRECT_PROBE 1

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 02/14] mac80211: 802.11w - CCMP for management frames
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
  2009-01-07 11:23 ` [PATCH 01/14] mac80211: 802.11w - STA flag for MFP Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 11:23 ` [PATCH 03/14] mac80211: 802.11w - Add BIP (AES-128-CMAC) Jouni Malinen
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

Extend CCMP to support encryption and decryption of unicast management
frames.

Signed-off-by: Jouni Malinen <j@w1.fi>


---
 include/linux/ieee80211.h |   30 ++++++++++++++++++++++++++++++
 net/mac80211/tx.c         |   23 ++++++++++++++++++++++-
 net/mac80211/wpa.c        |   18 ++++++++++++------
 3 files changed, 64 insertions(+), 7 deletions(-)

--- wireless-testing.orig/net/mac80211/tx.c	2008-12-31 17:33:38.000000000 +0200
+++ wireless-testing/net/mac80211/tx.c	2009-01-07 13:07:44.000000000 +0200
@@ -331,6 +331,22 @@ ieee80211_tx_h_multicast_ps_buf(struct i
 	return TX_CONTINUE;
 }
 
+static int ieee80211_use_mfp(__le16 fc, struct sta_info *sta,
+			     struct sk_buff *skb)
+{
+	if (!ieee80211_is_mgmt(fc))
+		return 0;
+
+	if (sta == NULL || !test_sta_flags(sta, WLAN_STA_MFP))
+		return 0;
+
+	if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *)
+					    skb->data))
+		return 0;
+
+	return 1;
+}
+
 static ieee80211_tx_result
 ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
 {
@@ -430,10 +446,15 @@ ieee80211_tx_h_select_key(struct ieee802
 			if (ieee80211_is_auth(hdr->frame_control))
 				break;
 		case ALG_TKIP:
-		case ALG_CCMP:
 			if (!ieee80211_is_data_present(hdr->frame_control))
 				tx->key = NULL;
 			break;
+		case ALG_CCMP:
+			if (!ieee80211_is_data_present(hdr->frame_control) &&
+			    !ieee80211_use_mfp(hdr->frame_control, tx->sta,
+					       tx->skb))
+				tx->key = NULL;
+			break;
 		}
 	}
 
--- wireless-testing.orig/net/mac80211/wpa.c	2008-12-31 17:33:38.000000000 +0200
+++ wireless-testing/net/mac80211/wpa.c	2009-01-07 13:07:44.000000000 +0200
@@ -268,7 +268,7 @@ static void ccmp_special_blocks(struct s
 				int encrypted)
 {
 	__le16 mask_fc;
-	int a4_included;
+	int a4_included, mgmt;
 	u8 qos_tid;
 	u8 *b_0, *aad;
 	u16 data_len, len_a;
@@ -279,12 +279,15 @@ static void ccmp_special_blocks(struct s
 	aad = scratch + 4 * AES_BLOCK_LEN;
 
 	/*
-	 * Mask FC: zero subtype b4 b5 b6
+	 * Mask FC: zero subtype b4 b5 b6 (if not mgmt)
 	 * Retry, PwrMgt, MoreData; set Protected
 	 */
+	mgmt = ieee80211_is_mgmt(hdr->frame_control);
 	mask_fc = hdr->frame_control;
-	mask_fc &= ~cpu_to_le16(0x0070 | IEEE80211_FCTL_RETRY |
+	mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY |
 				IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA);
+	if (!mgmt)
+		mask_fc &= ~cpu_to_le16(0x0070);
 	mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
 
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -302,8 +305,10 @@ static void ccmp_special_blocks(struct s
 
 	/* First block, b_0 */
 	b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
-	/* Nonce: QoS Priority | A2 | PN */
-	b_0[1] = qos_tid;
+	/* Nonce: Nonce Flags | A2 | PN
+	 * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
+	 */
+	b_0[1] = qos_tid | (mgmt << 4);
 	memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
 	memcpy(&b_0[8], pn, CCMP_PN_LEN);
 	/* l(m) */
@@ -449,7 +454,8 @@ ieee80211_crypto_ccmp_decrypt(struct iee
 
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 
-	if (!ieee80211_is_data(hdr->frame_control))
+	if (!ieee80211_is_data(hdr->frame_control) &&
+	    !ieee80211_is_robust_mgmt_frame(hdr))
 		return RX_CONTINUE;
 
 	data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN;
--- wireless-testing.orig/include/linux/ieee80211.h	2008-12-31 17:33:38.000000000 +0200
+++ wireless-testing/include/linux/ieee80211.h	2009-01-07 13:07:44.000000000 +0200
@@ -1030,6 +1030,7 @@ enum ieee80211_category {
 	WLAN_CATEGORY_QOS = 1,
 	WLAN_CATEGORY_DLS = 2,
 	WLAN_CATEGORY_BACK = 3,
+	WLAN_CATEGORY_PUBLIC = 4,
 	WLAN_CATEGORY_WMM = 17,
 };
 
@@ -1186,6 +1187,35 @@ static inline u8 *ieee80211_get_DA(struc
 }
 
 /**
+ * ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame
+ * @hdr: the frame (buffer must include at least the first octet of payload)
+ */
+static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
+{
+	if (ieee80211_is_disassoc(hdr->frame_control) ||
+	    ieee80211_is_deauth(hdr->frame_control))
+		return true;
+
+	if (ieee80211_is_action(hdr->frame_control)) {
+		u8 *category;
+
+		/*
+		 * Action frames, excluding Public Action frames, are Robust
+		 * Management Frames. However, if we are looking at a Protected
+		 * frame, skip the check since the data may be encrypted and
+		 * the frame has already been found to be a Robust Management
+		 * Frame (by the other end).
+		 */
+		if (ieee80211_has_protected(hdr->frame_control))
+			return true;
+		category = ((u8 *) hdr) + 24;
+		return *category != WLAN_CATEGORY_PUBLIC;
+	}
+
+	return false;
+}
+
+/**
  * ieee80211_fhss_chan_to_freq - get channel frequency
  * @channel: the FHSS channel
  *

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 03/14] mac80211: 802.11w - Add BIP (AES-128-CMAC)
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
  2009-01-07 11:23 ` [PATCH 01/14] mac80211: 802.11w - STA flag for MFP Jouni Malinen
  2009-01-07 11:23 ` [PATCH 02/14] mac80211: 802.11w - CCMP for management frames Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 11:23 ` [PATCH 04/14] mac80211: 802.11w - Use " Jouni Malinen
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

Implement Broadcast/Multicast Integrity Protocol for management frame
protection. This patch adds the needed definitions for the new
information element (MMIE) and implementation for the new "encryption"
type (though, BIP is actually not encrypting data, it provides only
integrity protection). These routines will be used by a follow-on patch
that enables BIP for multicast/broadcast robust management frames.

Signed-off-by: Jouni Malinen <j@w1.fi>


---
 include/linux/ieee80211.h  |   10 +++
 net/mac80211/Makefile      |    1 
 net/mac80211/aes_cmac.c    |  135 +++++++++++++++++++++++++++++++++++++++++++++
 net/mac80211/aes_cmac.h    |   19 ++++++
 net/mac80211/ieee80211_i.h |    2 
 net/mac80211/key.h         |   10 +++
 net/mac80211/wpa.c         |  125 +++++++++++++++++++++++++++++++++++++++++
 net/mac80211/wpa.h         |    5 +
 8 files changed, 306 insertions(+), 1 deletion(-)

--- wireless-testing.orig/include/linux/ieee80211.h	2009-01-07 13:07:44.000000000 +0200
+++ wireless-testing/include/linux/ieee80211.h	2009-01-07 13:07:46.000000000 +0200
@@ -655,6 +655,15 @@ struct ieee80211_mgmt {
 #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u)
 
 
+/* Management MIC information element (IEEE 802.11w) */
+struct ieee80211_mmie {
+	u8 element_id;
+	u8 length;
+	__le16 key_id;
+	u8 sequence_number[6];
+	u8 mic[8];
+} __attribute__ ((packed));
+
 /* Control frames */
 struct ieee80211_rts {
 	__le16 frame_control;
@@ -1018,6 +1027,7 @@ enum ieee80211_eid {
 	WLAN_EID_HT_INFORMATION = 61,
 	/* 802.11i */
 	WLAN_EID_RSN = 48,
+	WLAN_EID_MMIE = 76 /* 802.11w */,
 	WLAN_EID_WPA = 221,
 	WLAN_EID_GENERIC = 221,
 	WLAN_EID_VENDOR_SPECIFIC = 221,
--- wireless-testing.orig/net/mac80211/key.h	2008-12-31 17:33:38.000000000 +0200
+++ wireless-testing/net/mac80211/key.h	2009-01-07 13:07:46.000000000 +0200
@@ -96,6 +96,16 @@ struct ieee80211_key {
 			u8 tx_crypto_buf[6 * AES_BLOCK_LEN];
 			u8 rx_crypto_buf[6 * AES_BLOCK_LEN];
 		} ccmp;
+		struct {
+			u8 tx_pn[6];
+			u8 rx_pn[6];
+			struct crypto_cipher *tfm;
+			u32 replays; /* dot11RSNAStatsCMACReplays */
+			u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
+			/* scratch buffers for virt_to_page() (crypto API) */
+			u8 tx_crypto_buf[2 * AES_BLOCK_LEN];
+			u8 rx_crypto_buf[2 * AES_BLOCK_LEN];
+		} aes_cmac;
 	} u;
 
 	/* number of times this key has been used */
--- wireless-testing.orig/net/mac80211/wpa.c	2009-01-07 13:07:44.000000000 +0200
+++ wireless-testing/net/mac80211/wpa.c	2009-01-07 13:07:46.000000000 +0200
@@ -1,5 +1,6 @@
 /*
  * Copyright 2002-2004, Instant802 Networks, Inc.
+ * Copyright 2008, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -19,6 +20,7 @@
 #include "michael.h"
 #include "tkip.h"
 #include "aes_ccm.h"
+#include "aes_cmac.h"
 #include "wpa.h"
 
 ieee80211_tx_result
@@ -494,3 +496,126 @@ ieee80211_crypto_ccmp_decrypt(struct iee
 
 	return RX_CONTINUE;
 }
+
+
+static void bip_aad(struct sk_buff *skb, u8 *aad)
+{
+	/* BIP AAD: FC(masked) || A1 || A2 || A3 */
+
+	/* FC type/subtype */
+	aad[0] = skb->data[0];
+	/* Mask FC Retry, PwrMgt, MoreData flags to zero */
+	aad[1] = skb->data[1] & ~(BIT(4) | BIT(5) | BIT(6));
+	/* A1 || A2 || A3 */
+	memcpy(aad + 2, skb->data + 4, 3 * ETH_ALEN);
+}
+
+
+static inline void bip_ipn_swap(u8 *d, const u8 *s)
+{
+	*d++ = s[5];
+	*d++ = s[4];
+	*d++ = s[3];
+	*d++ = s[2];
+	*d++ = s[1];
+	*d = s[0];
+}
+
+
+ieee80211_tx_result
+ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)
+{
+	struct sk_buff *skb = tx->skb;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_key *key = tx->key;
+	struct ieee80211_mmie *mmie;
+	u8 *pn, aad[20];
+	int i;
+
+	if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
+		/* hwaccel */
+		info->control.hw_key = &tx->key->conf;
+		return 0;
+	}
+
+	if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
+		return TX_DROP;
+
+	mmie = (struct ieee80211_mmie *) skb_put(skb, sizeof(*mmie));
+	mmie->element_id = WLAN_EID_MMIE;
+	mmie->length = sizeof(*mmie) - 2;
+	mmie->key_id = cpu_to_le16(key->conf.keyidx);
+
+	/* PN = PN + 1 */
+	pn = key->u.aes_cmac.tx_pn;
+
+	for (i = sizeof(key->u.aes_cmac.tx_pn) - 1; i >= 0; i--) {
+		pn[i]++;
+		if (pn[i])
+			break;
+	}
+	bip_ipn_swap(mmie->sequence_number, pn);
+
+	bip_aad(skb, aad);
+
+	/*
+	 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
+	 */
+	ieee80211_aes_cmac(key->u.aes_cmac.tfm, key->u.aes_cmac.tx_crypto_buf,
+			   aad, skb->data + 24, skb->len - 24, mmie->mic);
+
+	return TX_CONTINUE;
+}
+
+
+ieee80211_rx_result
+ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
+{
+	struct sk_buff *skb = rx->skb;
+	struct ieee80211_key *key = rx->key;
+	struct ieee80211_mmie *mmie;
+	u8 aad[20], mic[8], ipn[6];
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+
+	if (!ieee80211_is_mgmt(hdr->frame_control))
+		return RX_CONTINUE;
+
+	if ((rx->status->flag & RX_FLAG_DECRYPTED) &&
+	    (rx->status->flag & RX_FLAG_IV_STRIPPED))
+		return RX_CONTINUE;
+
+	if (skb->len < 24 + sizeof(*mmie))
+		return RX_DROP_UNUSABLE;
+
+	mmie = (struct ieee80211_mmie *)
+		(skb->data + skb->len - sizeof(*mmie));
+	if (mmie->element_id != WLAN_EID_MMIE ||
+	    mmie->length != sizeof(*mmie) - 2)
+		return RX_DROP_UNUSABLE; /* Invalid MMIE */
+
+	bip_ipn_swap(ipn, mmie->sequence_number);
+
+	if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
+		key->u.aes_cmac.replays++;
+		return RX_DROP_UNUSABLE;
+	}
+
+	if (!(rx->status->flag & RX_FLAG_DECRYPTED)) {
+		/* hardware didn't decrypt/verify MIC */
+		bip_aad(skb, aad);
+		ieee80211_aes_cmac(key->u.aes_cmac.tfm,
+				   key->u.aes_cmac.rx_crypto_buf, aad,
+				   skb->data + 24, skb->len - 24, mic);
+		if (memcmp(mic, mmie->mic, sizeof(mmie->mic)) != 0) {
+			key->u.aes_cmac.icverrors++;
+			return RX_DROP_UNUSABLE;
+		}
+	}
+
+	memcpy(key->u.aes_cmac.rx_pn, ipn, 6);
+
+	/* Remove MMIE */
+	skb_trim(skb, skb->len - sizeof(*mmie));
+
+	return RX_CONTINUE;
+}
--- wireless-testing.orig/net/mac80211/wpa.h	2008-12-31 17:33:38.000000000 +0200
+++ wireless-testing/net/mac80211/wpa.h	2009-01-07 13:07:46.000000000 +0200
@@ -28,4 +28,9 @@ ieee80211_crypto_ccmp_encrypt(struct iee
 ieee80211_rx_result
 ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx);
 
+ieee80211_tx_result
+ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx);
+ieee80211_rx_result
+ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx);
+
 #endif /* WPA_H */
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-testing/net/mac80211/aes_cmac.c	2009-01-07 13:07:46.000000000 +0200
@@ -0,0 +1,135 @@
+/*
+ * AES-128-CMAC with TLen 16 for IEEE 802.11w BIP
+ * Copyright 2008, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/crypto.h>
+#include <linux/err.h>
+
+#include <net/mac80211.h>
+#include "key.h"
+#include "aes_cmac.h"
+
+#define AES_BLOCK_SIZE 16
+#define AES_CMAC_KEY_LEN 16
+#define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */
+#define AAD_LEN 20
+
+
+static void gf_mulx(u8 *pad)
+{
+	int i, carry;
+
+	carry = pad[0] & 0x80;
+	for (i = 0; i < AES_BLOCK_SIZE - 1; i++)
+		pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
+	pad[AES_BLOCK_SIZE - 1] <<= 1;
+	if (carry)
+		pad[AES_BLOCK_SIZE - 1] ^= 0x87;
+}
+
+
+static void aes_128_cmac_vector(struct crypto_cipher *tfm, u8 *scratch,
+				size_t num_elem,
+				const u8 *addr[], const size_t *len, u8 *mac)
+{
+	u8 *cbc, *pad;
+	const u8 *pos, *end;
+	size_t i, e, left, total_len;
+
+	cbc = scratch;
+	pad = scratch + AES_BLOCK_SIZE;
+
+	memset(cbc, 0, AES_BLOCK_SIZE);
+
+	total_len = 0;
+	for (e = 0; e < num_elem; e++)
+		total_len += len[e];
+	left = total_len;
+
+	e = 0;
+	pos = addr[0];
+	end = pos + len[0];
+
+	while (left >= AES_BLOCK_SIZE) {
+		for (i = 0; i < AES_BLOCK_SIZE; i++) {
+			cbc[i] ^= *pos++;
+			if (pos >= end) {
+				e++;
+				pos = addr[e];
+				end = pos + len[e];
+			}
+		}
+		if (left > AES_BLOCK_SIZE)
+			crypto_cipher_encrypt_one(tfm, cbc, cbc);
+		left -= AES_BLOCK_SIZE;
+	}
+
+	memset(pad, 0, AES_BLOCK_SIZE);
+	crypto_cipher_encrypt_one(tfm, pad, pad);
+	gf_mulx(pad);
+
+	if (left || total_len == 0) {
+		for (i = 0; i < left; i++) {
+			cbc[i] ^= *pos++;
+			if (pos >= end) {
+				e++;
+				pos = addr[e];
+				end = pos + len[e];
+			}
+		}
+		cbc[left] ^= 0x80;
+		gf_mulx(pad);
+	}
+
+	for (i = 0; i < AES_BLOCK_SIZE; i++)
+		pad[i] ^= cbc[i];
+	crypto_cipher_encrypt_one(tfm, pad, pad);
+	memcpy(mac, pad, CMAC_TLEN);
+}
+
+
+void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad,
+			const u8 *data, size_t data_len, u8 *mic)
+{
+	const u8 *addr[3];
+	size_t len[3];
+	u8 zero[CMAC_TLEN];
+
+	memset(zero, 0, CMAC_TLEN);
+	addr[0] = aad;
+	len[0] = AAD_LEN;
+	addr[1] = data;
+	len[1] = data_len - CMAC_TLEN;
+	addr[2] = zero;
+	len[2] = CMAC_TLEN;
+
+	aes_128_cmac_vector(tfm, scratch, 3, addr, len, mic);
+}
+
+
+struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[])
+{
+	struct crypto_cipher *tfm;
+
+	tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(tfm))
+		return NULL;
+
+	crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN);
+
+	return tfm;
+}
+
+
+void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm)
+{
+	if (tfm)
+		crypto_free_cipher(tfm);
+}
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-testing/net/mac80211/aes_cmac.h	2009-01-07 13:07:46.000000000 +0200
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2008, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef AES_CMAC_H
+#define AES_CMAC_H
+
+#include <linux/crypto.h>
+
+struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]);
+void ieee80211_aes_cmac(struct crypto_cipher *tfm, u8 *scratch, const u8 *aad,
+			const u8 *data, size_t data_len, u8 *mic);
+void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm);
+
+#endif /* AES_CMAC_H */
--- wireless-testing.orig/net/mac80211/Makefile	2008-12-31 17:33:38.000000000 +0200
+++ wireless-testing/net/mac80211/Makefile	2009-01-07 13:07:46.000000000 +0200
@@ -15,6 +15,7 @@ mac80211-y := \
 	michael.o \
 	tkip.o \
 	aes_ccm.o \
+	aes_cmac.o \
 	cfg.o \
 	rx.o \
 	spectmgmt.o \
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-01-07 13:07:41.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-01-07 13:07:46.000000000 +0200
@@ -43,7 +43,7 @@ struct ieee80211_local;
 
 /* Required encryption head and tailroom */
 #define IEEE80211_ENCRYPT_HEADROOM 8
-#define IEEE80211_ENCRYPT_TAILROOM 12
+#define IEEE80211_ENCRYPT_TAILROOM 18
 
 /* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent
  * reception of at least three fragmented frames. This limit can be increased

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 04/14] mac80211: 802.11w - Use BIP (AES-128-CMAC)
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
                   ` (2 preceding siblings ...)
  2009-01-07 11:23 ` [PATCH 03/14] mac80211: 802.11w - Add BIP (AES-128-CMAC) Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 11:23 ` [PATCH 05/14] mac80211: 802.11w - WEXT parameter for setting mgmt cipher Jouni Malinen
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

Add mechanism for managing BIP keys (IGTK) and integrate BIP into the
TX/RX paths.

Signed-off-by: Jouni Malinen <j@w1.fi>


---
 drivers/net/wireless/ath5k/pcu.c |    3 +
 include/linux/ieee80211.h        |    1 
 include/linux/nl80211.h          |    6 +-
 include/net/cfg80211.h           |    5 ++
 include/net/mac80211.h           |    2 
 net/mac80211/cfg.c               |   31 +++++++++++++
 net/mac80211/debugfs_key.c       |   79 +++++++++++++++++++++++++++++++++-
 net/mac80211/debugfs_key.h       |   10 ++++
 net/mac80211/ieee80211_i.h       |    5 +-
 net/mac80211/key.c               |   62 ++++++++++++++++++++++++++
 net/mac80211/key.h               |    6 ++
 net/mac80211/rx.c                |   90 +++++++++++++++++++++++++++++++++++----
 net/mac80211/tx.c                |    9 +++
 net/wireless/nl80211.c           |   29 +++++++++---
 14 files changed, 317 insertions(+), 21 deletions(-)

--- wireless-testing.orig/include/linux/ieee80211.h	2009-01-07 13:07:46.000000000 +0200
+++ wireless-testing/include/linux/ieee80211.h	2009-01-07 13:07:49.000000000 +0200
@@ -1139,6 +1139,7 @@ enum ieee80211_back_parties {
 /* reserved: 				0x000FAC03 */
 #define WLAN_CIPHER_SUITE_CCMP		0x000FAC04
 #define WLAN_CIPHER_SUITE_WEP104	0x000FAC05
+#define WLAN_CIPHER_SUITE_AES_CMAC	0x000FAC06
 
 #define WLAN_MAX_KEY_LEN		32
 
--- wireless-testing.orig/include/net/mac80211.h	2009-01-07 10:39:55.000000000 +0200
+++ wireless-testing/include/net/mac80211.h	2009-01-07 13:07:49.000000000 +0200
@@ -657,11 +657,13 @@ struct ieee80211_if_conf {
  * @ALG_WEP: WEP40 or WEP104
  * @ALG_TKIP: TKIP
  * @ALG_CCMP: CCMP (AES)
+ * @ALG_AES_CMAC: AES-128-CMAC
  */
 enum ieee80211_key_alg {
 	ALG_WEP,
 	ALG_TKIP,
 	ALG_CCMP,
+	ALG_AES_CMAC,
 };
 
 /**
--- wireless-testing.orig/net/mac80211/cfg.c	2009-01-07 13:07:41.000000000 +0200
+++ wireless-testing/net/mac80211/cfg.c	2009-01-07 13:07:49.000000000 +0200
@@ -133,6 +133,9 @@ static int ieee80211_add_key(struct wiph
 	case WLAN_CIPHER_SUITE_CCMP:
 		alg = ALG_CCMP;
 		break;
+	case WLAN_CIPHER_SUITE_AES_CMAC:
+		alg = ALG_AES_CMAC;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -275,6 +278,17 @@ static int ieee80211_get_key(struct wiph
 		else
 			params.cipher = WLAN_CIPHER_SUITE_WEP104;
 		break;
+	case ALG_AES_CMAC:
+		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
+		seq[0] = key->u.aes_cmac.tx_pn[5];
+		seq[1] = key->u.aes_cmac.tx_pn[4];
+		seq[2] = key->u.aes_cmac.tx_pn[3];
+		seq[3] = key->u.aes_cmac.tx_pn[2];
+		seq[4] = key->u.aes_cmac.tx_pn[1];
+		seq[5] = key->u.aes_cmac.tx_pn[0];
+		params.seq = seq;
+		params.seq_len = 6;
+		break;
 	}
 
 	params.key = key->conf.key;
@@ -304,6 +318,22 @@ static int ieee80211_config_default_key(
 	return 0;
 }
 
+static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
+					     struct net_device *dev,
+					     u8 key_idx)
+{
+	struct ieee80211_sub_if_data *sdata;
+
+	rcu_read_lock();
+
+	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	ieee80211_set_default_mgmt_key(sdata, key_idx);
+
+	rcu_read_unlock();
+
+	return 0;
+}
+
 static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 {
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -1153,6 +1183,7 @@ struct cfg80211_ops mac80211_config_ops 
 	.del_key = ieee80211_del_key,
 	.get_key = ieee80211_get_key,
 	.set_default_key = ieee80211_config_default_key,
+	.set_default_mgmt_key = ieee80211_config_default_mgmt_key,
 	.add_beacon = ieee80211_add_beacon,
 	.set_beacon = ieee80211_set_beacon,
 	.del_beacon = ieee80211_del_beacon,
--- wireless-testing.orig/net/mac80211/debugfs_key.c	2008-12-31 17:33:37.000000000 +0200
+++ wireless-testing/net/mac80211/debugfs_key.c	2009-01-07 13:07:49.000000000 +0200
@@ -76,6 +76,9 @@ static ssize_t key_algorithm_read(struct
 	case ALG_CCMP:
 		alg = "CCMP\n";
 		break;
+	case ALG_AES_CMAC:
+		alg = "AES-128-CMAC\n";
+		break;
 	default:
 		return 0;
 	}
@@ -105,6 +108,12 @@ static ssize_t key_tx_spec_read(struct f
 		len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
 				tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]);
 		break;
+	case ALG_AES_CMAC:
+		tpn = key->u.aes_cmac.tx_pn;
+		len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
+				tpn[0], tpn[1], tpn[2], tpn[3], tpn[4],
+				tpn[5]);
+		break;
 	default:
 		return 0;
 	}
@@ -142,6 +151,14 @@ static ssize_t key_rx_spec_read(struct f
 		}
 		len = p - buf;
 		break;
+	case ALG_AES_CMAC:
+		rpn = key->u.aes_cmac.rx_pn;
+		p += scnprintf(p, sizeof(buf)+buf-p,
+			       "%02x%02x%02x%02x%02x%02x\n",
+			       rpn[0], rpn[1], rpn[2],
+			       rpn[3], rpn[4], rpn[5]);
+		len = p - buf;
+		break;
 	default:
 		return 0;
 	}
@@ -156,13 +173,40 @@ static ssize_t key_replays_read(struct f
 	char buf[20];
 	int len;
 
-	if (key->conf.alg != ALG_CCMP)
+	switch (key->conf.alg) {
+	case ALG_CCMP:
+		len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
+		break;
+	case ALG_AES_CMAC:
+		len = scnprintf(buf, sizeof(buf), "%u\n",
+				key->u.aes_cmac.replays);
+		break;
+	default:
 		return 0;
-	len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
+	}
 	return simple_read_from_buffer(userbuf, count, ppos, buf, len);
 }
 KEY_OPS(replays);
 
+static ssize_t key_icverrors_read(struct file *file, char __user *userbuf,
+				  size_t count, loff_t *ppos)
+{
+	struct ieee80211_key *key = file->private_data;
+	char buf[20];
+	int len;
+
+	switch (key->conf.alg) {
+	case ALG_AES_CMAC:
+		len = scnprintf(buf, sizeof(buf), "%u\n",
+				key->u.aes_cmac.icverrors);
+		break;
+	default:
+		return 0;
+	}
+	return simple_read_from_buffer(userbuf, count, ppos, buf, len);
+}
+KEY_OPS(icverrors);
+
 static ssize_t key_key_read(struct file *file, char __user *userbuf,
 			    size_t count, loff_t *ppos)
 {
@@ -224,6 +268,7 @@ void ieee80211_debugfs_key_add(struct ie
 	DEBUGFS_ADD(tx_spec);
 	DEBUGFS_ADD(rx_spec);
 	DEBUGFS_ADD(replays);
+	DEBUGFS_ADD(icverrors);
 	DEBUGFS_ADD(key);
 	DEBUGFS_ADD(ifindex);
 };
@@ -245,6 +290,7 @@ void ieee80211_debugfs_key_remove(struct
 	DEBUGFS_DEL(tx_spec);
 	DEBUGFS_DEL(rx_spec);
 	DEBUGFS_DEL(replays);
+	DEBUGFS_DEL(icverrors);
 	DEBUGFS_DEL(key);
 	DEBUGFS_DEL(ifindex);
 
@@ -282,6 +328,35 @@ void ieee80211_debugfs_key_remove_defaul
 	sdata->common_debugfs.default_key = NULL;
 }
 
+void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
+{
+	char buf[50];
+	struct ieee80211_key *key;
+
+	if (!sdata->debugfsdir)
+		return;
+
+	/* this is running under the key lock */
+
+	key = sdata->default_mgmt_key;
+	if (key) {
+		sprintf(buf, "../keys/%d", key->debugfs.cnt);
+		sdata->common_debugfs.default_mgmt_key =
+			debugfs_create_symlink("default_mgmt_key",
+					       sdata->debugfsdir, buf);
+	} else
+		ieee80211_debugfs_key_remove_mgmt_default(sdata);
+}
+
+void ieee80211_debugfs_key_remove_mgmt_default(struct ieee80211_sub_if_data *sdata)
+{
+	if (!sdata)
+		return;
+
+	debugfs_remove(sdata->common_debugfs.default_mgmt_key);
+	sdata->common_debugfs.default_mgmt_key = NULL;
+}
+
 void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
 				   struct sta_info *sta)
 {
--- wireless-testing.orig/net/mac80211/key.h	2009-01-07 13:07:46.000000000 +0200
+++ wireless-testing/net/mac80211/key.h	2009-01-07 13:07:49.000000000 +0200
@@ -46,6 +46,8 @@ struct sta_info;
  *	acceleration.
  * @KEY_FLAG_TODO_DEFKEY: Key is default key and debugfs needs to be updated.
  * @KEY_FLAG_TODO_ADD_DEBUGFS: Key needs to be added to debugfs.
+ * @KEY_FLAG_TODO_DEFMGMTKEY: Key is default management key and debugfs needs
+ *	to be updated.
  */
 enum ieee80211_internal_key_flags {
 	KEY_FLAG_UPLOADED_TO_HARDWARE	= BIT(0),
@@ -54,6 +56,7 @@ enum ieee80211_internal_key_flags {
 	KEY_FLAG_TODO_HWACCEL_REMOVE	= BIT(3),
 	KEY_FLAG_TODO_DEFKEY		= BIT(4),
 	KEY_FLAG_TODO_ADD_DEBUGFS	= BIT(5),
+	KEY_FLAG_TODO_DEFMGMTKEY	= BIT(6),
 };
 
 struct tkip_ctx {
@@ -124,6 +127,7 @@ struct ieee80211_key {
 		struct dentry *tx_spec;
 		struct dentry *rx_spec;
 		struct dentry *replays;
+		struct dentry *icverrors;
 		struct dentry *key;
 		struct dentry *ifindex;
 		int cnt;
@@ -150,6 +154,8 @@ void ieee80211_key_link(struct ieee80211
 			struct sta_info *sta);
 void ieee80211_key_free(struct ieee80211_key *key);
 void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx);
+void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
+				    int idx);
 void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
 void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
 void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata);
--- wireless-testing.orig/net/mac80211/rx.c	2009-01-07 13:07:38.000000000 +0200
+++ wireless-testing/net/mac80211/rx.c	2009-01-07 13:07:49.000000000 +0200
@@ -435,6 +435,52 @@ ieee80211_rx_h_passive_scan(struct ieee8
 	return RX_CONTINUE;
 }
 
+
+static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+
+	if (skb->len < 24 || is_multicast_ether_addr(hdr->addr1))
+		return 0;
+
+	return ieee80211_is_robust_mgmt_frame(hdr);
+}
+
+
+static int ieee80211_is_multicast_robust_mgmt_frame(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+
+	if (skb->len < 24 || !is_multicast_ether_addr(hdr->addr1))
+		return 0;
+
+	return ieee80211_is_robust_mgmt_frame(hdr);
+}
+
+
+/* Get the BIP key index from MMIE; return -1 if this is not a BIP frame */
+static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
+{
+	struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *) skb->data;
+	struct ieee80211_mmie *mmie;
+
+	if (skb->len < 24 + sizeof(*mmie) ||
+	    !is_multicast_ether_addr(hdr->da))
+		return -1;
+
+	if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *) hdr))
+		return -1; /* not a robust management frame */
+
+	mmie = (struct ieee80211_mmie *)
+		(skb->data + skb->len - sizeof(*mmie));
+	if (mmie->element_id != WLAN_EID_MMIE ||
+	    mmie->length != sizeof(*mmie) - 2)
+		return -1;
+
+	return le16_to_cpu(mmie->key_id);
+}
+
+
 static ieee80211_rx_result
 ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
 {
@@ -550,21 +596,23 @@ ieee80211_rx_h_decrypt(struct ieee80211_
 	int hdrlen;
 	ieee80211_rx_result result = RX_DROP_UNUSABLE;
 	struct ieee80211_key *stakey = NULL;
+	int mmie_keyidx = -1;
 
 	/*
 	 * Key selection 101
 	 *
-	 * There are three types of keys:
+	 * There are four types of keys:
 	 *  - GTK (group keys)
+	 *  - IGTK (group keys for management frames)
 	 *  - PTK (pairwise keys)
 	 *  - STK (station-to-station pairwise keys)
 	 *
 	 * When selecting a key, we have to distinguish between multicast
 	 * (including broadcast) and unicast frames, the latter can only
-	 * use PTKs and STKs while the former always use GTKs. Unless, of
-	 * course, actual WEP keys ("pre-RSNA") are used, then unicast
-	 * frames can also use key indizes like GTKs. Hence, if we don't
-	 * have a PTK/STK we check the key index for a WEP key.
+	 * use PTKs and STKs while the former always use GTKs and IGTKs.
+	 * Unless, of course, actual WEP keys ("pre-RSNA") are used, then
+	 * unicast frames can also use key indices like GTKs. Hence, if we
+	 * don't have a PTK/STK we check the key index for a WEP key.
 	 *
 	 * Note that in a regular BSS, multicast frames are sent by the
 	 * AP only, associated stations unicast the frame to the AP first
@@ -577,8 +625,14 @@ ieee80211_rx_h_decrypt(struct ieee80211_
 	 * possible.
 	 */
 
-	if (!ieee80211_has_protected(hdr->frame_control))
-		return RX_CONTINUE;
+	if (!ieee80211_has_protected(hdr->frame_control)) {
+		if (!ieee80211_is_mgmt(hdr->frame_control) ||
+		    rx->sta == NULL || !test_sta_flags(rx->sta, WLAN_STA_MFP))
+			return RX_CONTINUE;
+		mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
+		if (mmie_keyidx < 0)
+			return RX_CONTINUE;
+	}
 
 	/*
 	 * No point in finding a key and decrypting if the frame is neither
@@ -592,6 +646,16 @@ ieee80211_rx_h_decrypt(struct ieee80211_
 
 	if (!is_multicast_ether_addr(hdr->addr1) && stakey) {
 		rx->key = stakey;
+	} else if (mmie_keyidx >= 0) {
+		/* Broadcast/multicast robust management frame / BIP */
+		if ((rx->status->flag & RX_FLAG_DECRYPTED) &&
+		    (rx->status->flag & RX_FLAG_IV_STRIPPED))
+			return RX_CONTINUE;
+
+		if (mmie_keyidx < NUM_DEFAULT_KEYS ||
+		    mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
+			return RX_DROP_MONITOR; /* unexpected BIP keyidx */
+		rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
 	} else {
 		/*
 		 * The device doesn't give us the IV so we won't be
@@ -654,6 +718,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_
 	case ALG_CCMP:
 		result = ieee80211_crypto_ccmp_decrypt(rx);
 		break;
+	case ALG_AES_CMAC:
+		result = ieee80211_crypto_aes_cmac_decrypt(rx);
+		break;
 	}
 
 	/* either the frame has been decrypted or will be dropped */
@@ -1108,6 +1175,15 @@ ieee80211_drop_unencrypted(struct ieee80
 	/* Drop unencrypted frames if key is set. */
 	if (unlikely(!ieee80211_has_protected(fc) &&
 		     !ieee80211_is_nullfunc(fc) &&
+		     (!ieee80211_is_mgmt(fc) ||
+		      (ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
+		       rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP))) &&
+		     (rx->key || rx->sdata->drop_unencrypted)))
+		return -EACCES;
+	/* BIP does not use Protected field, so need to check MMIE */
+	if (unlikely(rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP) &&
+		     ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
+		     ieee80211_get_mmie_keyidx(rx->skb) < 0 &&
 		     (rx->key || rx->sdata->drop_unencrypted)))
 		return -EACCES;
 
--- wireless-testing.orig/net/mac80211/tx.c	2009-01-07 13:07:44.000000000 +0200
+++ wireless-testing/net/mac80211/tx.c	2009-01-07 13:07:49.000000000 +0200
@@ -427,6 +427,9 @@ ieee80211_tx_h_select_key(struct ieee802
 		tx->key = NULL;
 	else if (tx->sta && (key = rcu_dereference(tx->sta->key)))
 		tx->key = key;
+	else if (ieee80211_is_mgmt(hdr->frame_control) &&
+		 (key = rcu_dereference(tx->sdata->default_mgmt_key)))
+		tx->key = key;
 	else if ((key = rcu_dereference(tx->sdata->default_key)))
 		tx->key = key;
 	else if (tx->sdata->drop_unencrypted &&
@@ -455,6 +458,10 @@ ieee80211_tx_h_select_key(struct ieee802
 					       tx->skb))
 				tx->key = NULL;
 			break;
+		case ALG_AES_CMAC:
+			if (!ieee80211_is_mgmt(hdr->frame_control))
+				tx->key = NULL;
+			break;
 		}
 	}
 
@@ -810,6 +817,8 @@ ieee80211_tx_h_encrypt(struct ieee80211_
 		return ieee80211_crypto_tkip_encrypt(tx);
 	case ALG_CCMP:
 		return ieee80211_crypto_ccmp_encrypt(tx);
+	case ALG_AES_CMAC:
+		return ieee80211_crypto_aes_cmac_encrypt(tx);
 	}
 
 	/* not reached */
--- wireless-testing.orig/net/mac80211/key.c	2009-01-07 10:39:55.000000000 +0200
+++ wireless-testing/net/mac80211/key.c	2009-01-07 13:07:49.000000000 +0200
@@ -18,6 +18,7 @@
 #include "ieee80211_i.h"
 #include "debugfs_key.h"
 #include "aes_ccm.h"
+#include "aes_cmac.h"
 
 
 /**
@@ -219,13 +220,38 @@ void ieee80211_set_default_key(struct ie
 	spin_unlock_irqrestore(&sdata->local->key_lock, flags);
 }
 
+static void
+__ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
+{
+	struct ieee80211_key *key = NULL;
+
+	if (idx >= NUM_DEFAULT_KEYS &&
+	    idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
+		key = sdata->keys[idx];
+
+	rcu_assign_pointer(sdata->default_mgmt_key, key);
+
+	if (key)
+		add_todo(key, KEY_FLAG_TODO_DEFMGMTKEY);
+}
+
+void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
+				    int idx)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&sdata->local->key_lock, flags);
+	__ieee80211_set_default_mgmt_key(sdata, idx);
+	spin_unlock_irqrestore(&sdata->local->key_lock, flags);
+}
+
 
 static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
 				    struct sta_info *sta,
 				    struct ieee80211_key *old,
 				    struct ieee80211_key *new)
 {
-	int idx, defkey;
+	int idx, defkey, defmgmtkey;
 
 	if (new)
 		list_add(&new->list, &sdata->key_list);
@@ -241,13 +267,19 @@ static void __ieee80211_key_replace(stru
 			idx = new->conf.keyidx;
 
 		defkey = old && sdata->default_key == old;
+		defmgmtkey = old && sdata->default_mgmt_key == old;
 
 		if (defkey && !new)
 			__ieee80211_set_default_key(sdata, -1);
+		if (defmgmtkey && !new)
+			__ieee80211_set_default_mgmt_key(sdata, -1);
 
 		rcu_assign_pointer(sdata->keys[idx], new);
 		if (defkey && new)
 			__ieee80211_set_default_key(sdata, new->conf.keyidx);
+		if (defmgmtkey && new)
+			__ieee80211_set_default_mgmt_key(sdata,
+							 new->conf.keyidx);
 	}
 
 	if (old) {
@@ -266,7 +298,7 @@ struct ieee80211_key *ieee80211_key_allo
 {
 	struct ieee80211_key *key;
 
-	BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS);
+	BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
 
 	key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL);
 	if (!key)
@@ -295,6 +327,10 @@ struct ieee80211_key *ieee80211_key_allo
 		key->conf.iv_len = CCMP_HDR_LEN;
 		key->conf.icv_len = CCMP_MIC_LEN;
 		break;
+	case ALG_AES_CMAC:
+		key->conf.iv_len = 0;
+		key->conf.icv_len = sizeof(struct ieee80211_mmie);
+		break;
 	}
 	memcpy(key->conf.key, key_data, key_len);
 	INIT_LIST_HEAD(&key->list);
@@ -312,6 +348,19 @@ struct ieee80211_key *ieee80211_key_allo
 		}
 	}
 
+	if (alg == ALG_AES_CMAC) {
+		/*
+		 * Initialize AES key state here as an optimization so that
+		 * it does not need to be initialized for every packet.
+		 */
+		key->u.aes_cmac.tfm =
+			ieee80211_aes_cmac_key_setup(key_data);
+		if (!key->u.aes_cmac.tfm) {
+			kfree(key);
+			return NULL;
+		}
+	}
+
 	return key;
 }
 
@@ -465,6 +514,8 @@ static void __ieee80211_key_destroy(stru
 
 	if (key->conf.alg == ALG_CCMP)
 		ieee80211_aes_key_free(key->u.ccmp.tfm);
+	if (key->conf.alg == ALG_AES_CMAC)
+		ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
 	ieee80211_debugfs_key_remove(key);
 
 	kfree(key);
@@ -487,6 +538,7 @@ static void __ieee80211_key_todo(void)
 		list_del_init(&key->todo);
 		todoflags = key->flags & (KEY_FLAG_TODO_ADD_DEBUGFS |
 					  KEY_FLAG_TODO_DEFKEY |
+					  KEY_FLAG_TODO_DEFMGMTKEY |
 					  KEY_FLAG_TODO_HWACCEL_ADD |
 					  KEY_FLAG_TODO_HWACCEL_REMOVE |
 					  KEY_FLAG_TODO_DELETE);
@@ -504,6 +556,11 @@ static void __ieee80211_key_todo(void)
 			ieee80211_debugfs_key_add_default(key->sdata);
 			work_done = true;
 		}
+		if (todoflags & KEY_FLAG_TODO_DEFMGMTKEY) {
+			ieee80211_debugfs_key_remove_mgmt_default(key->sdata);
+			ieee80211_debugfs_key_add_mgmt_default(key->sdata);
+			work_done = true;
+		}
 		if (todoflags & KEY_FLAG_TODO_HWACCEL_ADD) {
 			ieee80211_key_enable_hw_accel(key);
 			work_done = true;
@@ -539,6 +596,7 @@ void ieee80211_free_keys(struct ieee8021
 	ieee80211_key_lock();
 
 	ieee80211_debugfs_key_remove_default(sdata);
+	ieee80211_debugfs_key_remove_mgmt_default(sdata);
 
 	spin_lock_irqsave(&sdata->local->key_lock, flags);
 	list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-01-07 13:07:46.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-01-07 13:07:49.000000000 +0200
@@ -409,8 +409,10 @@ struct ieee80211_sub_if_data {
 	unsigned int fragment_next;
 
 #define NUM_DEFAULT_KEYS 4
-	struct ieee80211_key *keys[NUM_DEFAULT_KEYS];
+#define NUM_DEFAULT_MGMT_KEYS 2
+	struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
 	struct ieee80211_key *default_key;
+	struct ieee80211_key *default_mgmt_key;
 
 	u16 sequence_number;
 
@@ -482,6 +484,7 @@ struct ieee80211_sub_if_data {
 	} debugfs;
 	struct {
 		struct dentry *default_key;
+		struct dentry *default_mgmt_key;
 	} common_debugfs;
 
 #ifdef CONFIG_MAC80211_MESH
--- wireless-testing.orig/include/net/cfg80211.h	2009-01-07 13:07:41.000000000 +0200
+++ wireless-testing/include/net/cfg80211.h	2009-01-07 13:07:49.000000000 +0200
@@ -473,6 +473,8 @@ struct ieee80211_channel;
  *
  * @set_default_key: set the default key on an interface
  *
+ * @set_default_mgmt_key: set the default management frame key on an interface
+ *
  * @add_beacon: Add a beacon with given parameters, @head, @interval
  *	and @dtim_period will be valid, @tail is optional.
  * @set_beacon: Change the beacon parameters for an access point mode
@@ -520,6 +522,9 @@ struct cfg80211_ops {
 	int	(*set_default_key)(struct wiphy *wiphy,
 				   struct net_device *netdev,
 				   u8 key_index);
+	int	(*set_default_mgmt_key)(struct wiphy *wiphy,
+					struct net_device *netdev,
+					u8 key_index);
 
 	int	(*add_beacon)(struct wiphy *wiphy, struct net_device *dev,
 			      struct beacon_parameters *info);
--- wireless-testing.orig/net/mac80211/debugfs_key.h	2008-12-31 17:33:37.000000000 +0200
+++ wireless-testing/net/mac80211/debugfs_key.h	2009-01-07 13:07:49.000000000 +0200
@@ -6,6 +6,10 @@ void ieee80211_debugfs_key_add(struct ie
 void ieee80211_debugfs_key_remove(struct ieee80211_key *key);
 void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata);
 void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata);
+void ieee80211_debugfs_key_add_mgmt_default(
+	struct ieee80211_sub_if_data *sdata);
+void ieee80211_debugfs_key_remove_mgmt_default(
+	struct ieee80211_sub_if_data *sdata);
 void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
 				   struct sta_info *sta);
 #else
@@ -19,6 +23,12 @@ static inline void ieee80211_debugfs_key
 static inline void ieee80211_debugfs_key_remove_default(
 	struct ieee80211_sub_if_data *sdata)
 {}
+static inline void ieee80211_debugfs_key_add_mgmt_default(
+	struct ieee80211_sub_if_data *sdata)
+{}
+static inline void ieee80211_debugfs_key_remove_mgmt_default(
+	struct ieee80211_sub_if_data *sdata)
+{}
 static inline void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
 						 struct sta_info *sta)
 {}
--- wireless-testing.orig/net/wireless/nl80211.c	2008-12-31 17:33:37.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c	2009-01-07 13:07:49.000000000 +0200
@@ -738,7 +738,7 @@ static int nl80211_get_key(struct sk_buf
 	if (info->attrs[NL80211_ATTR_KEY_IDX])
 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
 
-	if (key_idx > 3)
+	if (key_idx > 5)
 		return -EINVAL;
 
 	if (info->attrs[NL80211_ATTR_MAC])
@@ -804,30 +804,41 @@ static int nl80211_set_key(struct sk_buf
 	int err;
 	struct net_device *dev;
 	u8 key_idx;
+	int (*func)(struct wiphy *wiphy, struct net_device *netdev,
+		    u8 key_index);
 
 	if (!info->attrs[NL80211_ATTR_KEY_IDX])
 		return -EINVAL;
 
 	key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
 
-	if (key_idx > 3)
+	if (info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]) {
+		if (key_idx < 4 || key_idx > 5)
+			return -EINVAL;
+	} else if (key_idx > 3)
 		return -EINVAL;
 
 	/* currently only support setting default key */
-	if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
+	if (!info->attrs[NL80211_ATTR_KEY_DEFAULT] &&
+	    !info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT])
 		return -EINVAL;
 
 	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
 	if (err)
 		return err;
 
-	if (!drv->ops->set_default_key) {
+	if (info->attrs[NL80211_ATTR_KEY_DEFAULT])
+		func = drv->ops->set_default_key;
+	else
+		func = drv->ops->set_default_mgmt_key;
+
+	if (!func) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
 	rtnl_lock();
-	err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx);
+	err = func(&drv->wiphy, dev, key_idx);
 	rtnl_unlock();
 
  out:
@@ -863,7 +874,7 @@ static int nl80211_new_key(struct sk_buf
 	if (info->attrs[NL80211_ATTR_MAC])
 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
 
-	if (key_idx > 3)
+	if (key_idx > 5)
 		return -EINVAL;
 
 	/*
@@ -894,6 +905,10 @@ static int nl80211_new_key(struct sk_buf
 		if (params.key_len != 13)
 			return -EINVAL;
 		break;
+	case WLAN_CIPHER_SUITE_AES_CMAC:
+		if (params.key_len != 16)
+			return -EINVAL;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -928,7 +943,7 @@ static int nl80211_del_key(struct sk_buf
 	if (info->attrs[NL80211_ATTR_KEY_IDX])
 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
 
-	if (key_idx > 3)
+	if (key_idx > 5)
 		return -EINVAL;
 
 	if (info->attrs[NL80211_ATTR_MAC])
--- wireless-testing.orig/include/linux/nl80211.h	2009-01-07 13:07:41.000000000 +0200
+++ wireless-testing/include/linux/nl80211.h	2009-01-07 13:07:49.000000000 +0200
@@ -72,8 +72,8 @@
  *
  * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified
  *	by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC.
- * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT or
- *	%NL80211_ATTR_KEY_THRESHOLD.
+ * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,
+ *	%NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.
  * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
  *	%NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC and %NL80211_ATTR_KEY_CIPHER
  *	attributes.
@@ -346,6 +346,8 @@ enum nl80211_attrs {
 	NL80211_ATTR_WIPHY_FREQ,
 	NL80211_ATTR_WIPHY_CHANNEL_TYPE,
 
+	NL80211_ATTR_KEY_DEFAULT_MGMT,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
--- wireless-testing.orig/drivers/net/wireless/ath5k/pcu.c	2009-01-07 10:39:55.000000000 +0200
+++ wireless-testing/drivers/net/wireless/ath5k/pcu.c	2009-01-07 13:07:49.000000000 +0200
@@ -1026,6 +1026,9 @@ int ath5k_keycache_type(const struct iee
 			return AR5K_KEYTABLE_TYPE_40;
 		else if (key->keylen == LEN_WEP104)
 			return AR5K_KEYTABLE_TYPE_104;
+		return -EINVAL;
+	default:
+		return -EINVAL;
 	}
 	return -EINVAL;
 }

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 05/14] mac80211: 802.11w - WEXT parameter for setting mgmt cipher
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
                   ` (3 preceding siblings ...)
  2009-01-07 11:23 ` [PATCH 04/14] mac80211: 802.11w - Use " Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 11:23 ` [PATCH 06/14] mac80211: 802.11w - WEXT configuration for IGTK Jouni Malinen
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

Add a new IW_AUTH parameter for setting cipher suite for
multicast/broadcast management frames. This is for full-mac drivers
that take care of RSN IE generation for (re)association request frames.

Signed-off-by: Jouni Malinen <j@w1.fi>


---
 include/linux/wireless.h |    5 ++++-
 net/mac80211/wext.c      |    1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

--- wireless-testing.orig/include/linux/wireless.h	2008-12-31 17:33:37.000000000 +0200
+++ wireless-testing/include/linux/wireless.h	2009-01-07 13:07:51.000000000 +0200
@@ -577,18 +577,21 @@
 #define IW_AUTH_RX_UNENCRYPTED_EAPOL	8
 #define IW_AUTH_ROAMING_CONTROL		9
 #define IW_AUTH_PRIVACY_INVOKED		10
+#define IW_AUTH_CIPHER_GROUP_MGMT	11
 
 /* IW_AUTH_WPA_VERSION values (bit field) */
 #define IW_AUTH_WPA_VERSION_DISABLED	0x00000001
 #define IW_AUTH_WPA_VERSION_WPA		0x00000002
 #define IW_AUTH_WPA_VERSION_WPA2	0x00000004
 
-/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */
+/* IW_AUTH_PAIRWISE_CIPHER, IW_AUTH_GROUP_CIPHER, and IW_AUTH_CIPHER_GROUP_MGMT
+ * values (bit field) */
 #define IW_AUTH_CIPHER_NONE	0x00000001
 #define IW_AUTH_CIPHER_WEP40	0x00000002
 #define IW_AUTH_CIPHER_TKIP	0x00000004
 #define IW_AUTH_CIPHER_CCMP	0x00000008
 #define IW_AUTH_CIPHER_WEP104	0x00000010
+#define IW_AUTH_CIPHER_AES_CMAC	0x00000020
 
 /* IW_AUTH_KEY_MGMT values (bit field) */
 #define IW_AUTH_KEY_MGMT_802_1X	1
--- wireless-testing.orig/net/mac80211/wext.c	2009-01-07 10:39:55.000000000 +0200
+++ wireless-testing/net/mac80211/wext.c	2009-01-07 13:07:51.000000000 +0200
@@ -912,6 +912,7 @@ static int ieee80211_ioctl_siwauth(struc
 	case IW_AUTH_WPA_ENABLED:
 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
 	case IW_AUTH_KEY_MGMT:
+	case IW_AUTH_CIPHER_GROUP_MGMT:
 		break;
 	case IW_AUTH_CIPHER_PAIRWISE:
 		if (sdata->vif.type == NL80211_IFTYPE_STATION) {

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 06/14] mac80211: 802.11w - WEXT configuration for IGTK
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
                   ` (4 preceding siblings ...)
  2009-01-07 11:23 ` [PATCH 05/14] mac80211: 802.11w - WEXT parameter for setting mgmt cipher Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 11:23 ` [PATCH 07/14] mac80211: 802.11w - Configuration of MFP disabled/optional/required Jouni Malinen
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

Added new SIOCSIWENCODEEXT algorithm for configuring BIP (AES-CMAC)
keys (IGTK).

Signed-off-by: Jouni Malinen <j@w1.fi>


---
 include/linux/wireless.h |    1 
 net/mac80211/wext.c      |   62 ++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 49 insertions(+), 14 deletions(-)

--- wireless-testing.orig/include/linux/wireless.h	2009-01-07 13:07:51.000000000 +0200
+++ wireless-testing/include/linux/wireless.h	2009-01-07 13:07:54.000000000 +0200
@@ -615,6 +615,7 @@
 #define IW_ENCODE_ALG_TKIP	2
 #define IW_ENCODE_ALG_CCMP	3
 #define IW_ENCODE_ALG_PMK	4
+#define IW_ENCODE_ALG_AES_CMAC	5
 /* struct iw_encode_ext ->ext_flags */
 #define IW_ENCODE_EXT_TX_SEQ_VALID	0x00000001
 #define IW_ENCODE_EXT_RX_SEQ_VALID	0x00000002
--- wireless-testing.orig/net/mac80211/wext.c	2009-01-07 13:07:51.000000000 +0200
+++ wireless-testing/net/mac80211/wext.c	2009-01-07 13:07:54.000000000 +0200
@@ -37,7 +37,14 @@ static int ieee80211_set_encryption(stru
 	struct ieee80211_key *key;
 	int err;
 
-	if (idx < 0 || idx >= NUM_DEFAULT_KEYS) {
+	if (alg == ALG_AES_CMAC) {
+		if (idx < NUM_DEFAULT_KEYS ||
+		    idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) {
+			printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d "
+			       "(BIP)\n", sdata->dev->name, idx);
+			return -EINVAL;
+		}
+	} else if (idx < 0 || idx >= NUM_DEFAULT_KEYS) {
 		printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n",
 		       sdata->dev->name, idx);
 		return -EINVAL;
@@ -103,6 +110,9 @@ static int ieee80211_set_encryption(stru
 
 		if (set_tx_key || (!sta && !sdata->default_key && key))
 			ieee80211_set_default_key(sdata, idx);
+		if (alg == ALG_AES_CMAC &&
+		    (set_tx_key || (!sta && !sdata->default_mgmt_key && key)))
+			ieee80211_set_default_mgmt_key(sdata, idx);
 	}
 
  out_unlock:
@@ -1033,6 +1043,9 @@ static int ieee80211_ioctl_siwencodeext(
 	case IW_ENCODE_ALG_CCMP:
 		alg = ALG_CCMP;
 		break;
+	case IW_ENCODE_ALG_AES_CMAC:
+		alg = ALG_AES_CMAC;
+		break;
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -1041,20 +1054,41 @@ static int ieee80211_ioctl_siwencodeext(
 		remove = 1;
 
 	idx = erq->flags & IW_ENCODE_INDEX;
-	if (idx < 1 || idx > 4) {
-		idx = -1;
-		if (!sdata->default_key)
-			idx = 0;
-		else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
-			if (sdata->default_key == sdata->keys[i]) {
-				idx = i;
-				break;
+	if (alg == ALG_AES_CMAC) {
+		if (idx < NUM_DEFAULT_KEYS + 1 ||
+		    idx > NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) {
+			idx = -1;
+			if (!sdata->default_mgmt_key)
+				idx = 0;
+			else for (i = NUM_DEFAULT_KEYS;
+				  i < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS;
+				  i++) {
+				if (sdata->default_mgmt_key == sdata->keys[i])
+				{
+					idx = i;
+					break;
+				}
 			}
-		}
-		if (idx < 0)
-			return -EINVAL;
-	} else
-		idx--;
+			if (idx < 0)
+				return -EINVAL;
+		} else
+			idx--;
+	} else {
+		if (idx < 1 || idx > 4) {
+			idx = -1;
+			if (!sdata->default_key)
+				idx = 0;
+			else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
+				if (sdata->default_key == sdata->keys[i]) {
+					idx = i;
+					break;
+				}
+			}
+			if (idx < 0)
+				return -EINVAL;
+		} else
+			idx--;
+	}
 
 	return ieee80211_set_encryption(sdata, ext->addr.sa_data, idx, alg,
 					remove,

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 07/14] mac80211: 802.11w - Configuration of MFP disabled/optional/required
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
                   ` (5 preceding siblings ...)
  2009-01-07 11:23 ` [PATCH 06/14] mac80211: 802.11w - WEXT configuration for IGTK Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 11:23 ` [PATCH 08/14] mac80211: 802.11w - SA Query processing Jouni Malinen
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

Add new WEXT IW_AUTH_* parameter for setting MFP
disabled/optional/required.

Signed-off-by: Jouni Malinen <j@w1.fi>


---
 include/linux/wireless.h   |    6 ++++++
 net/mac80211/ieee80211_i.h |    6 ++++++
 net/mac80211/mlme.c        |    4 ++++
 net/mac80211/wext.c        |    7 +++++++
 4 files changed, 23 insertions(+)

--- wireless-testing.orig/include/linux/wireless.h	2009-01-07 13:07:54.000000000 +0200
+++ wireless-testing/include/linux/wireless.h	2009-01-07 13:07:56.000000000 +0200
@@ -578,6 +578,7 @@
 #define IW_AUTH_ROAMING_CONTROL		9
 #define IW_AUTH_PRIVACY_INVOKED		10
 #define IW_AUTH_CIPHER_GROUP_MGMT	11
+#define IW_AUTH_MFP			12
 
 /* IW_AUTH_WPA_VERSION values (bit field) */
 #define IW_AUTH_WPA_VERSION_DISABLED	0x00000001
@@ -607,6 +608,11 @@
 #define IW_AUTH_ROAMING_DISABLE	1	/* user space program used for roaming
 					 * control */
 
+/* IW_AUTH_MFP (management frame protection) values */
+#define IW_AUTH_MFP_DISABLED	0	/* MFP disabled */
+#define IW_AUTH_MFP_OPTIONAL	1	/* MFP optional */
+#define IW_AUTH_MFP_REQUIRED	2	/* MFP required */
+
 /* SIOCSIWENCODEEXT definitions */
 #define IW_ENCODE_SEQ_MAX_SIZE	8
 /* struct iw_encode_ext ->alg */
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-01-07 13:07:49.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-01-07 13:07:56.000000000 +0200
@@ -320,6 +320,12 @@ struct ieee80211_if_sta {
 	int auth_alg; /* currently used IEEE 802.11 authentication algorithm */
 	int auth_transaction;
 
+	enum {
+		IEEE80211_MFP_DISABLED,
+		IEEE80211_MFP_OPTIONAL,
+		IEEE80211_MFP_REQUIRED
+	} mfp; /* management frame protection */
+
 	unsigned long ibss_join_req;
 	struct sk_buff *probe_resp; /* ProbeResp template for IBSS */
 	u32 supp_rates_bits[IEEE80211_NUM_BANDS];
--- wireless-testing.orig/net/mac80211/wext.c	2009-01-07 13:07:54.000000000 +0200
+++ wireless-testing/net/mac80211/wext.c	2009-01-07 13:07:56.000000000 +0200
@@ -960,6 +960,13 @@ static int ieee80211_ioctl_siwauth(struc
 		else
 			ret = -EOPNOTSUPP;
 		break;
+	case IW_AUTH_MFP:
+		if (sdata->vif.type == NL80211_IFTYPE_STATION ||
+		    sdata->vif.type == NL80211_IFTYPE_ADHOC)
+			sdata->u.sta.mfp = data->value;
+		else
+			ret = -EOPNOTSUPP;
+		break;
 	default:
 		ret = -EOPNOTSUPP;
 		break;
--- wireless-testing.orig/net/mac80211/mlme.c	2009-01-07 13:07:41.000000000 +0200
+++ wireless-testing/net/mac80211/mlme.c	2009-01-07 13:07:56.000000000 +0200
@@ -2341,6 +2341,10 @@ static int ieee80211_sta_config_auth(str
 					       selected->ssid_len);
 		ieee80211_sta_set_bssid(sdata, selected->bssid);
 		ieee80211_sta_def_wmm_params(sdata, selected);
+		if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED)
+			sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED;
+		else
+			sdata->u.sta.flags &= ~IEEE80211_STA_MFP_ENABLED;
 
 		/* Send out direct probe if no probe resp was received or
 		 * the one we have is outdated

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 08/14] mac80211: 802.11w - SA Query processing
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
                   ` (6 preceding siblings ...)
  2009-01-07 11:23 ` [PATCH 07/14] mac80211: 802.11w - Configuration of MFP disabled/optional/required Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 11:23 ` [PATCH 09/14] mac80211: 802.11w - Do not force Action frames to disable encryption Jouni Malinen
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

Process SA Query Requests for client mode in mac80211. AP side
processing of SA Query Response frames is in user space (hostapd).

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


---
 include/linux/ieee80211.h |   14 +++++++++
 net/mac80211/rx.c         |   69 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+)

--- wireless-testing.orig/include/linux/ieee80211.h	2009-01-07 13:07:49.000000000 +0200
+++ wireless-testing/include/linux/ieee80211.h	2009-01-07 13:07:59.000000000 +0200
@@ -527,6 +527,8 @@ struct ieee80211_tim_ie {
 	u8 virtual_map[0];
 } __attribute__ ((packed));
 
+#define WLAN_SA_QUERY_TR_ID_LEN 16
+
 struct ieee80211_mgmt {
 	__le16 frame_control;
 	__le16 duration;
@@ -646,6 +648,10 @@ struct ieee80211_mgmt {
 					u8 action_code;
 					u8 variable[0];
 				} __attribute__((packed)) mesh_action;
+				struct {
+					u8 action;
+					u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
+				} __attribute__ ((packed)) sa_query;
 			} u;
 		} __attribute__ ((packed)) action;
 	} u;
@@ -1041,6 +1047,7 @@ enum ieee80211_category {
 	WLAN_CATEGORY_DLS = 2,
 	WLAN_CATEGORY_BACK = 3,
 	WLAN_CATEGORY_PUBLIC = 4,
+	WLAN_CATEGORY_SA_QUERY = 8,
 	WLAN_CATEGORY_WMM = 17,
 };
 
@@ -1129,6 +1136,13 @@ enum ieee80211_back_parties {
 	WLAN_BACK_TIMER = 2,
 };
 
+/* SA Query action */
+enum ieee80211_sa_query_action {
+	WLAN_ACTION_SA_QUERY_REQUEST = 0,
+	WLAN_ACTION_SA_QUERY_RESPONSE = 1,
+};
+
+
 /* A-MSDU 802.11n */
 #define IEEE80211_QOS_CONTROL_A_MSDU_PRESENT 0x0080
 
--- wireless-testing.orig/net/mac80211/rx.c	2009-01-07 13:07:49.000000000 +0200
+++ wireless-testing/net/mac80211/rx.c	2009-01-07 13:07:59.000000000 +0200
@@ -1635,6 +1635,57 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_
 	return RX_CONTINUE;
 }
 
+void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata,
+				    struct ieee80211_mgmt *mgmt,
+				    size_t len)
+{
+	struct ieee80211_local *local = sdata->local;
+	struct sk_buff *skb;
+	struct ieee80211_mgmt *resp;
+
+	if (compare_ether_addr(mgmt->da, sdata->dev->dev_addr) != 0) {
+		/* Not to own unicast address */
+		return;
+	}
+
+	if (compare_ether_addr(mgmt->sa, sdata->u.sta.bssid) != 0 ||
+	    compare_ether_addr(mgmt->bssid, sdata->u.sta.bssid) != 0) {
+		/* Not from the current AP. */
+		return;
+	}
+
+	if (sdata->u.sta.state == IEEE80211_STA_MLME_ASSOCIATE) {
+		/* Association in progress; ignore SA Query */
+		return;
+	}
+
+	if (len < 24 + 1 + sizeof(resp->u.action.u.sa_query)) {
+		/* Too short SA Query request frame */
+		return;
+	}
+
+	skb = dev_alloc_skb(sizeof(*resp) + local->hw.extra_tx_headroom);
+	if (skb == NULL)
+		return;
+
+	skb_reserve(skb, local->hw.extra_tx_headroom);
+	resp = (struct ieee80211_mgmt *) skb_put(skb, 24);
+	memset(resp, 0, 24);
+	memcpy(resp->da, mgmt->sa, ETH_ALEN);
+	memcpy(resp->sa, sdata->dev->dev_addr, ETH_ALEN);
+	memcpy(resp->bssid, sdata->u.sta.bssid, ETH_ALEN);
+	resp->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+					  IEEE80211_STYPE_ACTION);
+	skb_put(skb, 1 + sizeof(resp->u.action.u.sa_query));
+	resp->u.action.category = WLAN_CATEGORY_SA_QUERY;
+	resp->u.action.u.sa_query.action = WLAN_ACTION_SA_QUERY_RESPONSE;
+	memcpy(resp->u.action.u.sa_query.trans_id,
+	       mgmt->u.action.u.sa_query.trans_id,
+	       WLAN_SA_QUERY_TR_ID_LEN);
+
+	ieee80211_tx_skb(sdata, skb, 1);
+}
+
 static ieee80211_rx_result debug_noinline
 ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
 {
@@ -1708,6 +1759,24 @@ ieee80211_rx_h_action(struct ieee80211_r
 			break;
 		}
 		break;
+	case WLAN_CATEGORY_SA_QUERY:
+		if (len < (IEEE80211_MIN_ACTION_SIZE +
+			   sizeof(mgmt->u.action.u.sa_query)))
+			return RX_DROP_MONITOR;
+		switch (mgmt->u.action.u.sa_query.action) {
+		case WLAN_ACTION_SA_QUERY_REQUEST:
+			if (sdata->vif.type != NL80211_IFTYPE_STATION)
+				return RX_DROP_MONITOR;
+			ieee80211_process_sa_query_req(sdata, mgmt, len);
+			break;
+		case WLAN_ACTION_SA_QUERY_RESPONSE:
+			/*
+			 * SA Query response is currently only used in AP mode
+			 * and it is processed in user space.
+			 */
+			return RX_CONTINUE;
+		}
+		break;
 	default:
 		return RX_CONTINUE;
 	}

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 09/14] mac80211: 802.11w - Do not force Action frames to disable encryption
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
                   ` (7 preceding siblings ...)
  2009-01-07 11:23 ` [PATCH 08/14] mac80211: 802.11w - SA Query processing Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 11:23 ` [PATCH 10/14] mac80211: 802.11w - Drop unprotected robust management frames if MFP is used Jouni Malinen
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

When sending out Action frames, allow ieee80211_tx_skb() to send them
without enforcing do_not_encrypt. These frames will be encrypted if
MFP has been negotiated.

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


---
 net/mac80211/ht.c         |    6 +++---
 net/mac80211/mesh_hwmp.c  |    4 ++--
 net/mac80211/mesh_plink.c |    2 +-
 net/mac80211/spectmgmt.c  |    2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

--- wireless-testing.orig/net/mac80211/ht.c	2009-01-07 10:39:55.000000000 +0200
+++ wireless-testing/net/mac80211/ht.c	2009-01-07 13:08:01.000000000 +0200
@@ -200,7 +200,7 @@ static void ieee80211_send_addba_request
 	mgmt->u.action.u.addba_req.start_seq_num =
 					cpu_to_le16(start_seq_num << 4);
 
-	ieee80211_tx_skb(sdata, skb, 0);
+	ieee80211_tx_skb(sdata, skb, 1);
 }
 
 static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
@@ -246,7 +246,7 @@ static void ieee80211_send_addba_resp(st
 	mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
 	mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
 
-	ieee80211_tx_skb(sdata, skb, 0);
+	ieee80211_tx_skb(sdata, skb, 1);
 }
 
 static void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
@@ -289,7 +289,7 @@ static void ieee80211_send_delba(struct 
 	mgmt->u.action.u.delba.params = cpu_to_le16(params);
 	mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
 
-	ieee80211_tx_skb(sdata, skb, 0);
+	ieee80211_tx_skb(sdata, skb, 1);
 }
 
 void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
--- wireless-testing.orig/net/mac80211/mesh_hwmp.c	2008-12-31 17:33:35.000000000 +0200
+++ wireless-testing/net/mac80211/mesh_hwmp.c	2009-01-07 13:08:01.000000000 +0200
@@ -149,7 +149,7 @@ static int mesh_path_sel_frame_tx(enum m
 	pos += ETH_ALEN;
 	memcpy(pos, &dst_dsn, 4);
 
-	ieee80211_tx_skb(sdata, skb, 0);
+	ieee80211_tx_skb(sdata, skb, 1);
 	return 0;
 }
 
@@ -198,7 +198,7 @@ int mesh_path_error_tx(u8 *dst, __le32 d
 	pos += ETH_ALEN;
 	memcpy(pos, &dst_dsn, 4);
 
-	ieee80211_tx_skb(sdata, skb, 0);
+	ieee80211_tx_skb(sdata, skb, 1);
 	return 0;
 }
 
--- wireless-testing.orig/net/mac80211/mesh_plink.c	2009-01-07 10:39:55.000000000 +0200
+++ wireless-testing/net/mac80211/mesh_plink.c	2009-01-07 13:08:01.000000000 +0200
@@ -218,7 +218,7 @@ static int mesh_plink_frame_tx(struct ie
 		memcpy(pos, &reason, 2);
 	}
 
-	ieee80211_tx_skb(sdata, skb, 0);
+	ieee80211_tx_skb(sdata, skb, 1);
 	return 0;
 }
 
--- wireless-testing.orig/net/mac80211/spectmgmt.c	2009-01-07 13:07:38.000000000 +0200
+++ wireless-testing/net/mac80211/spectmgmt.c	2009-01-07 13:08:01.000000000 +0200
@@ -65,7 +65,7 @@ static void ieee80211_send_refuse_measur
 			IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
 	msr_report->u.action.u.measurement.msr_elem.type = request_ie->type;
 
-	ieee80211_tx_skb(sdata, skb, 0);
+	ieee80211_tx_skb(sdata, skb, 1);
 }
 
 void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 10/14] mac80211: 802.11w - Drop unprotected robust management frames if MFP is used
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
                   ` (8 preceding siblings ...)
  2009-01-07 11:23 ` [PATCH 09/14] mac80211: 802.11w - Do not force Action frames to disable encryption Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 11:23 ` [PATCH 11/14] mac80211: 802.11w - Implement Association Comeback processing Jouni Malinen
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

Use ieee80211_drop_unencrypted() to decide whether a received frame
should be dropped with management frames, too. If MFP is negotiated,
unprotected robust management frames will be dropped.

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


---
 net/mac80211/rx.c |    7 +++++++
 1 file changed, 7 insertions(+)

--- wireless-testing.orig/net/mac80211/rx.c	2009-01-07 13:07:59.000000000 +0200
+++ wireless-testing/net/mac80211/rx.c	2009-01-07 13:08:03.000000000 +0200
@@ -1705,6 +1705,9 @@ ieee80211_rx_h_action(struct ieee80211_r
 	if (!(rx->flags & IEEE80211_RX_RA_MATCH))
 		return RX_DROP_MONITOR;
 
+	if (ieee80211_drop_unencrypted(rx, mgmt->frame_control))
+		return RX_DROP_MONITOR;
+
 	/* all categories we currently handle have action_code */
 	if (len < IEEE80211_MIN_ACTION_SIZE + 1)
 		return RX_DROP_MONITOR;
@@ -1790,10 +1793,14 @@ static ieee80211_rx_result debug_noinlin
 ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
 
 	if (!(rx->flags & IEEE80211_RX_RA_MATCH))
 		return RX_DROP_MONITOR;
 
+	if (ieee80211_drop_unencrypted(rx, mgmt->frame_control))
+		return RX_DROP_MONITOR;
+
 	if (ieee80211_vif_is_mesh(&sdata->vif))
 		return ieee80211_mesh_rx_mgmt(sdata, rx->skb, rx->status);
 

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 11/14] mac80211: 802.11w - Implement Association Comeback processing
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
                   ` (9 preceding siblings ...)
  2009-01-07 11:23 ` [PATCH 10/14] mac80211: 802.11w - Drop unprotected robust management frames if MFP is used Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 11:23 ` [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames Jouni Malinen
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

When MFP is enabled, the AP does not allow a STA to associate if an
existing security association exists without first going through SA
Query process. When this happens, the association request is denied
with a new status code ("temporarily rejected") ans Association
Comeback IE is used to notify when the association may be tried again
(i.e., when the SA Query procedure has timed out).

Use the comeback time to update the mac80211 client MLME timer for
next association attempt to minimize waiting time if association is
temporarily rejected.

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


---
 include/linux/ieee80211.h  |    4 ++++
 net/mac80211/ieee80211_i.h |    2 ++
 net/mac80211/mlme.c        |   20 +++++++++++++++++---
 net/mac80211/util.c        |    4 ++++
 4 files changed, 27 insertions(+), 3 deletions(-)

--- wireless-testing.orig/include/linux/ieee80211.h	2009-01-07 13:07:59.000000000 +0200
+++ wireless-testing/include/linux/ieee80211.h	2009-01-07 13:08:05.000000000 +0200
@@ -914,6 +914,9 @@ enum ieee80211_statuscode {
 	/* 802.11g */
 	WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
 	WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
+	/* 802.11w */
+	WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY = 30,
+	WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION = 31,
 	/* 802.11i */
 	WLAN_STATUS_INVALID_IE = 40,
 	WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
@@ -1034,6 +1037,7 @@ enum ieee80211_eid {
 	/* 802.11i */
 	WLAN_EID_RSN = 48,
 	WLAN_EID_MMIE = 76 /* 802.11w */,
+	WLAN_EID_ASSOC_COMEBACK_TIME = 77,
 	WLAN_EID_WPA = 221,
 	WLAN_EID_GENERIC = 221,
 	WLAN_EID_VENDOR_SPECIFIC = 221,
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-01-07 13:07:56.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-01-07 13:08:05.000000000 +0200
@@ -820,6 +820,7 @@ struct ieee802_11_elems {
 	u8 *country_elem;
 	u8 *pwr_constr_elem;
 	u8 *quiet_elem; 	/* first quite element */
+	u8 *assoc_comeback;
 
 	/* length of them, respectively */
 	u8 ssid_len;
@@ -847,6 +848,7 @@ struct ieee802_11_elems {
 	u8 pwr_constr_elem_len;
 	u8 quiet_elem_len;
 	u8 num_of_quiet_elem;	/* can be more the one */
+	u8 assoc_comeback_len;
 };
 
 static inline struct ieee80211_local *hw_to_local(
--- wireless-testing.orig/net/mac80211/mlme.c	2009-01-07 13:07:56.000000000 +0200
+++ wireless-testing/net/mac80211/mlme.c	2009-01-07 13:08:05.000000000 +0200
@@ -1287,6 +1287,23 @@ static void ieee80211_rx_mgmt_assoc_resp
 	       sdata->dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
 	       capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
 
+	pos = mgmt->u.assoc_resp.variable;
+	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
+
+	if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
+	    elems.assoc_comeback && elems.assoc_comeback_len == 4) {
+		u32 tu, ms;
+		tu = get_unaligned_le32(elems.assoc_comeback);
+		ms = tu * 1024 / 1000;
+		printk(KERN_DEBUG "%s: AP rejected association temporarily; "
+		       "comeback duration %u TU (%u ms)\n",
+		       sdata->dev->name, tu, ms);
+		if (ms > IEEE80211_ASSOC_TIMEOUT)
+			mod_timer(&ifsta->timer,
+				  jiffies + msecs_to_jiffies(ms));
+		return;
+	}
+
 	if (status_code != WLAN_STATUS_SUCCESS) {
 		printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
 		       sdata->dev->name, status_code);
@@ -1302,9 +1319,6 @@ static void ieee80211_rx_mgmt_assoc_resp
 		       "set\n", sdata->dev->name, aid);
 	aid &= ~(BIT(15) | BIT(14));
 
-	pos = mgmt->u.assoc_resp.variable;
-	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
-
 	if (!elems.supp_rates) {
 		printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
 		       sdata->dev->name);
--- wireless-testing.orig/net/mac80211/util.c	2009-01-07 10:39:55.000000000 +0200
+++ wireless-testing/net/mac80211/util.c	2009-01-07 13:08:05.000000000 +0200
@@ -653,6 +653,10 @@ void ieee802_11_parse_elems(u8 *start, s
 			elems->pwr_constr_elem = pos;
 			elems->pwr_constr_elem_len = elen;
 			break;
+		case WLAN_EID_ASSOC_COMEBACK_TIME:
+			elems->assoc_comeback = pos;
+			elems->assoc_comeback_len = elen;
+			break;
 		default:
 			break;
 		}

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
                   ` (10 preceding siblings ...)
  2009-01-07 11:23 ` [PATCH 11/14] mac80211: 802.11w - Implement Association Comeback processing Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 12:08   ` Johannes Berg
  2009-01-07 11:23 ` [PATCH 13/14] ath9k: Fix set_key error codes Jouni Malinen
  2009-01-07 11:24 ` [PATCH 14/14] ath9k: Setup MFP options for CCMP Jouni Malinen
  13 siblings, 1 reply; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

If driver/firmware/hardware does not support CCMP for management
frames, it can now request mac80211 to take care of encryption and
decryption of management frames (when MFP is enabled) in software. The
driver will need to add this new IEEE80211_KEY_FLAG_SW_MGMT flag when a
CCMP key is being configured for TX side and return the encrypted frames
on RX side without RX_FLAG_DECRYPTED flag to use software CCMP for
management frames (but hardware for data frames).

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


---
 include/net/mac80211.h |    4 ++++
 net/mac80211/wpa.c     |    9 +++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

--- wireless-testing.orig/include/net/mac80211.h	2009-01-07 13:07:49.000000000 +0200
+++ wireless-testing/include/net/mac80211.h	2009-01-07 13:08:07.000000000 +0200
@@ -692,12 +692,16 @@ enum ieee80211_key_len {
  *	generation in software.
  * @IEEE80211_KEY_FLAG_PAIRWISE: Set by mac80211, this flag indicates
  *	that the key is pairwise rather then a shared key.
+ * @IEEE80211_KEY_FLAG_SW_MGMT: This flag should be set by the driver for a
+ *	CCMP key if it requires CCMP encryption of management frames (MFP) to
+ *	be done in software.
  */
 enum ieee80211_key_flags {
 	IEEE80211_KEY_FLAG_WMM_STA	= 1<<0,
 	IEEE80211_KEY_FLAG_GENERATE_IV	= 1<<1,
 	IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2,
 	IEEE80211_KEY_FLAG_PAIRWISE	= 1<<3,
+	IEEE80211_KEY_FLAG_SW_MGMT	= 1<<4,
 };
 
 /**
--- wireless-testing.orig/net/mac80211/wpa.c	2009-01-07 13:07:46.000000000 +0200
+++ wireless-testing/net/mac80211/wpa.c	2009-01-07 13:08:07.000000000 +0200
@@ -369,9 +369,14 @@ 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)) {
+	    !(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;
@@ -406,7 +411,7 @@ static int ccmp_encrypt_skb(struct ieee8
 
 	ccmp_pn2hdr(pos, pn, key->conf.keyidx);
 
-	if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
+	if ((key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && !skip_hw) {
 		/* hwaccel - with preallocated room for CCMP header */
 		info->control.hw_key = &tx->key->conf;
 		return 0;

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 13/14] ath9k: Fix set_key error codes
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
                   ` (11 preceding siblings ...)
  2009-01-07 11:23 ` [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames Jouni Malinen
@ 2009-01-07 11:23 ` Jouni Malinen
  2009-01-07 11:24 ` [PATCH 14/14] ath9k: Setup MFP options for CCMP Jouni Malinen
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:23 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

Return -EOPNOTSUPP if the algorithm is not supported and -ENOSPC if
there is no room in the key cache. This avoids KERN_ERR printk in
mac80211 for "errors" that are actually expected to happen in normal
operating conditions.

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


---
 drivers/net/wireless/ath9k/main.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- wireless-testing.orig/drivers/net/wireless/ath9k/main.c	2009-01-07 10:39:55.000000000 +0200
+++ wireless-testing/drivers/net/wireless/ath9k/main.c	2009-01-07 13:08:10.000000000 +0200
@@ -815,7 +815,7 @@ static int ath_key_config(struct ath_sof
 		hk.kv_type = ATH9K_CIPHER_AES_CCM;
 		break;
 	default:
-		return -EINVAL;
+		return -EOPNOTSUPP;
 	}
 
 	hk.kv_len = key->keylen;
@@ -849,7 +849,7 @@ static int ath_key_config(struct ath_sof
 		else
 			idx = ath_reserve_key_cache_slot(sc);
 		if (idx < 0)
-			return -EIO; /* no free key cache entries */
+			return -ENOSPC; /* no free key cache entries */
 	}
 
 	if (key->alg == ALG_TKIP)

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 14/14] ath9k: Setup MFP options for CCMP
  2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
                   ` (12 preceding siblings ...)
  2009-01-07 11:23 ` [PATCH 13/14] ath9k: Fix set_key error codes Jouni Malinen
@ 2009-01-07 11:24 ` Jouni Malinen
  13 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 11:24 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Jouni Malinen

Configure hardware CCMP for management frame protection and use
software crypto when needed.

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


---
 drivers/net/wireless/ath9k/ath9k.h |    2 ++
 drivers/net/wireless/ath9k/hw.c    |   17 +++++++++++++++++
 drivers/net/wireless/ath9k/main.c  |    2 ++
 drivers/net/wireless/ath9k/recv.c  |    6 ++++++
 drivers/net/wireless/ath9k/reg.h   |    6 ++++++
 5 files changed, 33 insertions(+)

--- wireless-testing.orig/drivers/net/wireless/ath9k/hw.c	2009-01-07 10:39:55.000000000 +0200
+++ wireless-testing/drivers/net/wireless/ath9k/hw.c	2009-01-07 13:08:13.000000000 +0200
@@ -2266,6 +2266,23 @@ int ath9k_hw_reset(struct ath_hal *ah, s
 	if (r)
 		return r;
 
+	/* Setup MFP options for CCMP */
+	if (AR_SREV_9280_20_OR_LATER(ah)) {
+		/* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
+		 * frames when constructing CCMP AAD. */
+		REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
+			      0xc7ff);
+		ah->sw_mgmt_crypto = false;
+	} else if (AR_SREV_9160_10_OR_LATER(ah)) {
+		/* Disable hardware crypto for management frames */
+		REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
+			    AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
+		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+			    AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
+		ah->sw_mgmt_crypto = true;
+	} else
+		ah->sw_mgmt_crypto = true;
+
 	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
 		ath9k_hw_set_delta_slope(ah, chan);
 
--- wireless-testing.orig/drivers/net/wireless/ath9k/reg.h	2009-01-07 10:39:55.000000000 +0200
+++ wireless-testing/drivers/net/wireless/ath9k/reg.h	2009-01-07 13:08:13.000000000 +0200
@@ -1243,6 +1243,8 @@ enum {
 
 #define AR_AES_MUTE_MASK1       0x8060
 #define AR_AES_MUTE_MASK1_SEQ   0x0000FFFF
+#define AR_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000
+#define AR_AES_MUTE_MASK1_FC_MGMT_S 16
 
 #define AR_GATED_CLKS       0x8064
 #define AR_GATED_CLKS_TX    0x00000002
@@ -1467,6 +1469,10 @@ enum {
 #define AR_PCU_TXBUF_CTRL_USABLE_SIZE   0x700
 #define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE   0x380
 
+#define AR_PCU_MISC_MODE2               0x8344
+#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE           0x00000002
+#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT   0x00000004
+
 #define AR_KEYTABLE_0           0x8800
 #define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
 #define AR_KEY_CACHE_SIZE       128
--- wireless-testing.orig/drivers/net/wireless/ath9k/main.c	2009-01-07 13:08:10.000000000 +0200
+++ wireless-testing/drivers/net/wireless/ath9k/main.c	2009-01-07 13:08:13.000000000 +0200
@@ -2348,6 +2348,8 @@ static int ath9k_set_key(struct ieee8021
 			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
 			if (key->alg == ALG_TKIP)
 				key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+			if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
+				key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
 			ret = 0;
 		}
 		break;
--- wireless-testing.orig/drivers/net/wireless/ath9k/recv.c	2008-12-18 08:32:48.000000000 +0200
+++ wireless-testing/drivers/net/wireless/ath9k/recv.c	2009-01-07 13:08:13.000000000 +0200
@@ -593,6 +593,12 @@ int ath_rx_tasklet(struct ath_softc *sc,
 			if (test_bit(keyix, sc->sc_keymap))
 				rx_status.flag |= RX_FLAG_DECRYPTED;
 		}
+		if (ah->sw_mgmt_crypto &&
+		    (rx_status.flag & RX_FLAG_DECRYPTED) &&
+		    ieee80211_is_mgmt(hdr->frame_control)) {
+			/* Use software decrypt for management frames. */
+			rx_status.flag &= ~RX_FLAG_DECRYPTED;
+		}
 
 		/* Send the frame to mac80211 */
 		__ieee80211_rx(sc->hw, skb, &rx_status);
--- wireless-testing.orig/drivers/net/wireless/ath9k/ath9k.h	2009-01-07 10:39:55.000000000 +0200
+++ wireless-testing/drivers/net/wireless/ath9k/ath9k.h	2009-01-07 13:08:13.000000000 +0200
@@ -805,6 +805,8 @@ struct ath_hal {
 #ifndef ATH_NF_PER_CHAN
 	struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
 #endif
+
+	bool sw_mgmt_crypto;
 };
 
 struct chan_centers {

-- 

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-07 11:23 ` [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames Jouni Malinen
@ 2009-01-07 12:08   ` Johannes Berg
  2009-01-07 12:24     ` Jouni Malinen
  0 siblings, 1 reply; 31+ messages in thread
From: Johannes Berg @ 2009-01-07 12:08 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: John W. Linville, linux-wireless, Jouni Malinen

[-- Attachment #1: Type: text/plain, Size: 824 bytes --]

On Wed, 2009-01-07 at 13:23 +0200, Jouni Malinen wrote:
> plain text document attachment (ieee80211w-sw-mgmt-ccmp.patch)
> If driver/firmware/hardware does not support CCMP for management
> frames, it can now request mac80211 to take care of encryption and
> decryption of management frames (when MFP is enabled) in software. The
> driver will need to add this new IEEE80211_KEY_FLAG_SW_MGMT flag when a
> CCMP key is being configured for TX side and return the encrypted frames
> on RX side without RX_FLAG_DECRYPTED flag to use software CCMP for
> management frames (but hardware for data frames).

Wouldn't it be better to invert the meaning of the flag so we don't have
to update all drivers now? It's likely that people won't test CCMP hw
encryption and also that it won't work, I'd think, no?

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-07 12:08   ` Johannes Berg
@ 2009-01-07 12:24     ` Jouni Malinen
  2009-01-07 12:47       ` Johannes Berg
  0 siblings, 1 reply; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 12:24 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John W. Linville, linux-wireless, Jouni Malinen

On Wed, Jan 07, 2009 at 01:08:38PM +0100, Johannes Berg wrote:
> On Wed, 2009-01-07 at 13:23 +0200, Jouni Malinen wrote:
> > plain text document attachment (ieee80211w-sw-mgmt-ccmp.patch)
> > If driver/firmware/hardware does not support CCMP for management
> > frames, it can now request mac80211 to take care of encryption and
> > decryption of management frames (when MFP is enabled) in software. The
> > driver will need to add this new IEEE80211_KEY_FLAG_SW_MGMT flag when a
> > CCMP key is being configured for TX side and return the encrypted frames
> > on RX side without RX_FLAG_DECRYPTED flag to use software CCMP for
> > management frames (but hardware for data frames).
> 
> Wouldn't it be better to invert the meaning of the flag so we don't have
> to update all drivers now? It's likely that people won't test CCMP hw
> encryption and also that it won't work, I'd think, no?

I did consider this, but could not convince myself that drivers would be
expected to work without some testing and likely changes.. I do not care
that much which way this is, so if you want this to be inverted, that's
fine, too. I might even go as far as adding an explicit capability flag
that drivers will need to set to claim MFP support and export this to
userspace so that hostapd/wpa_supplicant could refuse the configuration
early. With that kind of flag, inverting this key flag does not get much
since the drivers would need to be changed anyway for MFP to work in
every case.

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-07 12:24     ` Jouni Malinen
@ 2009-01-07 12:47       ` Johannes Berg
  2009-01-07 14:09         ` Jouni Malinen
  0 siblings, 1 reply; 31+ messages in thread
From: Johannes Berg @ 2009-01-07 12:47 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: John W. Linville, linux-wireless, Jouni Malinen

[-- Attachment #1: Type: text/plain, Size: 1538 bytes --]

On Wed, 2009-01-07 at 14:24 +0200, Jouni Malinen wrote:

> I did consider this, but could not convince myself that drivers would be
> expected to work without some testing and likely changes.. 

Ok, I guess in that case it doesn't really matter much, though it'd be
good to not randomly associate to an AP that has MFP enabled when we
don't know the hardware can handle it.
I know, for example, that Broadcom hardware can handle it just fine when
done in software, but I'm pretty sure it cannot handle it in hardware
crypto...

> I do not care
> that much which way this is, so if you want this to be inverted, that's
> fine, too. I might even go as far as adding an explicit capability flag
> that drivers will need to set to claim MFP support and export this to
> userspace so that hostapd/wpa_supplicant could refuse the configuration
> early. With that kind of flag, inverting this key flag does not get much
> since the drivers would need to be changed anyway for MFP to work in
> every case.

You seem to be concerned only about AP mode, while I'm not much
concerned about that, there it's always tested explicitly by the person
setting up the AP, but someone who's just using STA mode would now
suddenly potentially run into problems when using an AP that is
MFP-enabled, no?

Hence, I think adding an explicit flag (whether it needs to be exported
to userspace I don't know) would probably be good so if the driver/hw
really cannot handle MFP at all then we don't associate using it, no?

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-07 12:47       ` Johannes Berg
@ 2009-01-07 14:09         ` Jouni Malinen
  2009-01-07 15:09           ` Johannes Berg
       [not found]           ` <226823.3656.qm@web57008.mail.re3.yahoo.com>
  0 siblings, 2 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 14:09 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John W. Linville, linux-wireless, Jouni Malinen

On Wed, Jan 07, 2009 at 01:47:08PM +0100, Johannes Berg wrote:

> Ok, I guess in that case it doesn't really matter much, though it'd be
> good to not randomly associate to an AP that has MFP enabled when we
> don't know the hardware can handle it.

Yes and that why I was considering of a flag to notify hostapd and
wpa_supplicant about the capability.. But that would mean modifying WEXT
even more ;-).

> I know, for example, that Broadcom hardware can handle it just fine when
> done in software, but I'm pretty sure it cannot handle it in hardware
> crypto...

If that is the case, it would be just a quick test and one-liner to the
driver to fix it. As long as the hardware/firmware does not touch
received management frames that have Protected field set to one it
should be fine (some try to use same rules as for data frames and that
will fail).

> You seem to be concerned only about AP mode, while I'm not much
> concerned about that, there it's always tested explicitly by the person
> setting up the AP, but someone who's just using STA mode would now
> suddenly potentially run into problems when using an AP that is
> MFP-enabled, no?

It is similar for both ends.. For example, wpa_supplicant does not
enable MFP on the client side by default, i.e., both hostapd and
wpa_supplicant behave the same in the sense that MFP needs to be
explicitly enabled.

> Hence, I think adding an explicit flag (whether it needs to be exported
> to userspace I don't know) would probably be good so if the driver/hw
> really cannot handle MFP at all then we don't associate using it, no?

MFP is negotiated in RSN IE and in case of mac80211, it would need to be
going to userspace since wpa_supplicant builds the RSN IE (and well,
hostapd obviously does the same for Authenticator side). We could a new
WEXT capability (e.g., IW_ENC_CAPA_MFP) for this, if desired.. It would
also be possible already with the current patchset to probe for this by
setting IW_AUTH_MFP and see whether the driver returns EOPNOTSUPP, so in
that sense, wpa_supplicant (and hostapd) could already figure this out
before trying to associate.

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-07 14:09         ` Jouni Malinen
@ 2009-01-07 15:09           ` Johannes Berg
  2009-01-07 15:30             ` Jouni Malinen
       [not found]           ` <226823.3656.qm@web57008.mail.re3.yahoo.com>
  1 sibling, 1 reply; 31+ messages in thread
From: Johannes Berg @ 2009-01-07 15:09 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: John W. Linville, linux-wireless, Jouni Malinen

[-- Attachment #1: Type: text/plain, Size: 2163 bytes --]

On Wed, 2009-01-07 at 16:09 +0200, Jouni Malinen wrote:
> On Wed, Jan 07, 2009 at 01:47:08PM +0100, Johannes Berg wrote:
> 
> > Ok, I guess in that case it doesn't really matter much, though it'd be
> > good to not randomly associate to an AP that has MFP enabled when we
> > don't know the hardware can handle it.
> 
> Yes and that why I was considering of a flag to notify hostapd and
> wpa_supplicant about the capability.. But that would mean modifying WEXT
> even more ;-).

Or just adding it to nl80211, are we ever expecting to have pure wext
drivers with MFP capabilities??

> > You seem to be concerned only about AP mode, while I'm not much
> > concerned about that, there it's always tested explicitly by the person
> > setting up the AP, but someone who's just using STA mode would now
> > suddenly potentially run into problems when using an AP that is
> > MFP-enabled, no?
> 
> It is similar for both ends.. For example, wpa_supplicant does not
> enable MFP on the client side by default, i.e., both hostapd and
> wpa_supplicant behave the same in the sense that MFP needs to be
> explicitly enabled.
> 
> > Hence, I think adding an explicit flag (whether it needs to be exported
> > to userspace I don't know) would probably be good so if the driver/hw
> > really cannot handle MFP at all then we don't associate using it, no?
> 
> MFP is negotiated in RSN IE and in case of mac80211, it would need to be
> going to userspace since wpa_supplicant builds the RSN IE (and well,
> hostapd obviously does the same for Authenticator side). We could a new
> WEXT capability (e.g., IW_ENC_CAPA_MFP) for this, if desired.. It would
> also be possible already with the current patchset to probe for this by
> setting IW_AUTH_MFP and see whether the driver returns EOPNOTSUPP, so in
> that sense, wpa_supplicant (and hostapd) could already figure this out
> before trying to associate.

Generally, the thing is that we don't really want to require people to
manually enable MFP, but rather have NM set it to "enable whenever
possible". That seems not workable unless we know which driver/hw
supports it.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-07 15:09           ` Johannes Berg
@ 2009-01-07 15:30             ` Jouni Malinen
  2009-01-07 15:37               ` Johannes Berg
  2009-01-08  9:57               ` Helmut Schaa
  0 siblings, 2 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 15:30 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John W. Linville, linux-wireless, Jouni Malinen

On Wed, Jan 07, 2009 at 04:09:04PM +0100, Johannes Berg wrote:

> Or just adding it to nl80211, are we ever expecting to have pure wext
> drivers with MFP capabilities??

Not that likely, I would assume. However, I would rather not start
extending driver_wext.c in wpa_supplicant with nl80211 functionality and
I don't see Network Manager moving away from hardcoding driver_wext
anytime soon..

> Generally, the thing is that we don't really want to require people to
> manually enable MFP, but rather have NM set it to "enable whenever
> possible". That seems not workable unless we know which driver/hw
> supports it.

Sure. Enabling optional MFP automatically whenever driver/hw supports it
would be nice (there is a separate policy selection of requiring MFP and
that's something that users will need to configure if they want it). For
this feature, I would be fine having the optional-MFP configuration in
wpa_supplicant mean that it will be disabled if driver does not support
it, i.e., NM would not actually need to care and it could just always
set ieee80211w=1 in wpa_supplicant configuration (or well, at this
point, it would need to care a bit since wpa_supplicant would reject the
configuration if it was not built with 802.11w support, but that is
probably fine when done over dbus and not config file).

As far as wpa_supplicant is concerned, I can make it determine this by
trying to enable MFP mode at startup to figure out whether the driver is
capable, so there is no need to add an explicit capability flag for this
if we do not want to modify WEXT. For nl80211, we can add capability
flag for MFP and then driver_nl80211.c can skip this validation step.
However, we would still need to add a driver-mac80211 flag for
indicating whether the driver supports MFP.

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-07 15:30             ` Jouni Malinen
@ 2009-01-07 15:37               ` Johannes Berg
  2009-01-07 16:33                 ` Jouni Malinen
  2009-01-08  9:57               ` Helmut Schaa
  1 sibling, 1 reply; 31+ messages in thread
From: Johannes Berg @ 2009-01-07 15:37 UTC (permalink / raw)
  To: Jouni Malinen
  Cc: John W. Linville, linux-wireless, Jouni Malinen, Dan Williams

[-- Attachment #1: Type: text/plain, Size: 1588 bytes --]

On Wed, 2009-01-07 at 17:30 +0200, Jouni Malinen wrote:

> Sure. Enabling optional MFP automatically whenever driver/hw supports it
> would be nice (there is a separate policy selection of requiring MFP and
> that's something that users will need to configure if they want it).

Indeed

> For
> this feature, I would be fine having the optional-MFP configuration in
> wpa_supplicant mean that it will be disabled if driver does not support
> it, i.e., NM would not actually need to care and it could just always
> set ieee80211w=1 in wpa_supplicant configuration (or well, at this
> point, it would need to care a bit since wpa_supplicant would reject the
> configuration if it was not built with 802.11w support, but that is
> probably fine when done over dbus and not config file).

Right.

> As far as wpa_supplicant is concerned, I can make it determine this by
> trying to enable MFP mode at startup to figure out whether the driver is
> capable, so there is no need to add an explicit capability flag for this
> if we do not want to modify WEXT.

Makes sense, yeah.

> For nl80211, we can add capability
> flag for MFP and then driver_nl80211.c can skip this validation step.

Would be nice to be able to print it out in iw, just for information.

> However, we would still need to add a driver-mac80211 flag for
> indicating whether the driver supports MFP.

Right, and once we have that the polarity of this key flag doesn't
matter at all, though I suspect there are much fewer drivers that will
be able to support it in hardware.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-07 15:37               ` Johannes Berg
@ 2009-01-07 16:33                 ` Jouni Malinen
  2009-01-07 16:37                   ` Johannes Berg
  0 siblings, 1 reply; 31+ messages in thread
From: Jouni Malinen @ 2009-01-07 16:33 UTC (permalink / raw)
  To: Johannes Berg
  Cc: John W. Linville, linux-wireless, Jouni Malinen, Dan Williams

On Wed, Jan 07, 2009 at 04:37:51PM +0100, Johannes Berg wrote:

> > For nl80211, we can add capability
> > flag for MFP and then driver_nl80211.c can skip this validation step.
> 
> Would be nice to be able to print it out in iw, just for information.

OK. I think I'll leave this as a separate step since there does not seem
to be an existing command suitable for this yet, but anyway, the
information will be available once that gets added.. This should be
something that allows the driver to be queried about general
capabilities (encr algorithms, etc., and now also MFP).

> > However, we would still need to add a driver-mac80211 flag for
> > indicating whether the driver supports MFP.
> 
> Right, and once we have that the polarity of this key flag doesn't
> matter at all, though I suspect there are much fewer drivers that will
> be able to support it in hardware.

How about following on top of the MFP patch series (and a small change
to ath9k to set this flag)?


PS.

Actually, NM would probably not need to care about MFP at all (unless
user wants to require it). I think I will change wpa_supplicant default
to MFP-optional once 802.11w gets deployed and is found not to cause
problems.


 ---
 include/net/mac80211.h |    4 ++++
 net/mac80211/wext.c    |    4 ++++
 2 files changed, 8 insertions(+)

--- wireless-testing.orig/include/net/mac80211.h	2009-01-07 18:10:40.000000000 +0200
+++ wireless-testing/include/net/mac80211.h	2009-01-07 18:11:33.000000000 +0200
@@ -866,6 +866,9 @@ enum ieee80211_tkip_key_type {
  *	Hardware which has dynamic power save support, meaning
  *	that power save is enabled in idle periods, and don't need support
  *	from stack.
+ *
+ * @IEEE80211_HW_MFP_CAPABLE:
+ *	Hardware supports management frame protection (MFP, IEEE 802.11w).
  */
 enum ieee80211_hw_flags {
 	IEEE80211_HW_RX_INCLUDES_FCS			= 1<<1,
@@ -879,6 +882,7 @@ enum ieee80211_hw_flags {
 	IEEE80211_HW_SPECTRUM_MGMT			= 1<<9,
 	IEEE80211_HW_AMPDU_AGGREGATION			= 1<<10,
 	IEEE80211_HW_NO_STACK_DYNAMIC_PS		= 1<<11,
+	IEEE80211_HW_MFP_CAPABLE			= 1<<12,
 };
 
 /**
--- wireless-testing.orig/net/mac80211/wext.c	2009-01-07 18:20:30.000000000 +0200
+++ wireless-testing/net/mac80211/wext.c	2009-01-07 18:22:38.000000000 +0200
@@ -961,6 +961,10 @@ static int ieee80211_ioctl_siwauth(struc
 			ret = -EOPNOTSUPP;
 		break;
 	case IW_AUTH_MFP:
+		if (!(sdata->local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) {
+			ret = -EOPNOTSUPP;
+			break;
+		}
 		if (sdata->vif.type == NL80211_IFTYPE_STATION ||
 		    sdata->vif.type == NL80211_IFTYPE_ADHOC)
 			sdata->u.sta.mfp = data->value;


-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-07 16:33                 ` Jouni Malinen
@ 2009-01-07 16:37                   ` Johannes Berg
  0 siblings, 0 replies; 31+ messages in thread
From: Johannes Berg @ 2009-01-07 16:37 UTC (permalink / raw)
  To: Jouni Malinen
  Cc: John W. Linville, linux-wireless, Jouni Malinen, Dan Williams

[-- Attachment #1: Type: text/plain, Size: 2041 bytes --]

On Wed, 2009-01-07 at 18:33 +0200, Jouni Malinen wrote:

> How about following on top of the MFP patch series (and a small change
> to ath9k to set this flag)?

Looks good to me.

> PS.
> 
> Actually, NM would probably not need to care about MFP at all (unless
> user wants to require it). I think I will change wpa_supplicant default
> to MFP-optional once 802.11w gets deployed and is found not to cause
> problems.

True. Except that there probably will be problems unless everybody
implements it perfectly...

>  ---
>  include/net/mac80211.h |    4 ++++
>  net/mac80211/wext.c    |    4 ++++
>  2 files changed, 8 insertions(+)
> 
> --- wireless-testing.orig/include/net/mac80211.h	2009-01-07 18:10:40.000000000 +0200
> +++ wireless-testing/include/net/mac80211.h	2009-01-07 18:11:33.000000000 +0200
> @@ -866,6 +866,9 @@ enum ieee80211_tkip_key_type {
>   *	Hardware which has dynamic power save support, meaning
>   *	that power save is enabled in idle periods, and don't need support
>   *	from stack.
> + *
> + * @IEEE80211_HW_MFP_CAPABLE:
> + *	Hardware supports management frame protection (MFP, IEEE 802.11w).
>   */
>  enum ieee80211_hw_flags {
>  	IEEE80211_HW_RX_INCLUDES_FCS			= 1<<1,
> @@ -879,6 +882,7 @@ enum ieee80211_hw_flags {
>  	IEEE80211_HW_SPECTRUM_MGMT			= 1<<9,
>  	IEEE80211_HW_AMPDU_AGGREGATION			= 1<<10,
>  	IEEE80211_HW_NO_STACK_DYNAMIC_PS		= 1<<11,
> +	IEEE80211_HW_MFP_CAPABLE			= 1<<12,
>  };
>  
>  /**
> --- wireless-testing.orig/net/mac80211/wext.c	2009-01-07 18:20:30.000000000 +0200
> +++ wireless-testing/net/mac80211/wext.c	2009-01-07 18:22:38.000000000 +0200
> @@ -961,6 +961,10 @@ static int ieee80211_ioctl_siwauth(struc
>  			ret = -EOPNOTSUPP;
>  		break;
>  	case IW_AUTH_MFP:
> +		if (!(sdata->local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) {
> +			ret = -EOPNOTSUPP;
> +			break;
> +		}
>  		if (sdata->vif.type == NL80211_IFTYPE_STATION ||
>  		    sdata->vif.type == NL80211_IFTYPE_ADHOC)
>  			sdata->u.sta.mfp = data->value;
> 
> 

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-07 15:30             ` Jouni Malinen
  2009-01-07 15:37               ` Johannes Berg
@ 2009-01-08  9:57               ` Helmut Schaa
  2009-01-08 10:48                 ` Jouni Malinen
  1 sibling, 1 reply; 31+ messages in thread
From: Helmut Schaa @ 2009-01-08  9:57 UTC (permalink / raw)
  To: Jouni Malinen
  Cc: Johannes Berg, John W. Linville, linux-wireless, Jouni Malinen,
	Dan Williams

Am Mittwoch, 7. Januar 2009 schrieb Jouni Malinen:
> On Wed, Jan 07, 2009 at 04:09:04PM +0100, Johannes Berg wrote:
> 
> > Or just adding it to nl80211, are we ever expecting to have pure wext
> > drivers with MFP capabilities??
> 
> Not that likely, I would assume. However, I would rather not start
> extending driver_wext.c in wpa_supplicant with nl80211 functionality and
> I don't see Network Manager moving away from hardcoding driver_wext
> anytime soon..

I guess NetworkManager won't move away from wext unless all drivers
support nl80211.

Jouni, what do you think about extending wpa_supplicant to allow mutliple
drivers to be set on the commandline (-Dnl80211,wext). The supplicant would
then try to register the first driver and only if that fails it takes the next
one (e.g. try nl80211 first and if that fails use wext). That way NM could
use nl80211 for drivers that support nl80211 (mainly mac80211-drivers) and
wext for the other drivers by passing "-Dnl80211,wext" to the supplicant.

That's just a quick thought but I'd like to hear your opinion.

Helmut

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-08  9:57               ` Helmut Schaa
@ 2009-01-08 10:48                 ` Jouni Malinen
  2009-01-08 12:08                   ` Helmut Schaa
  0 siblings, 1 reply; 31+ messages in thread
From: Jouni Malinen @ 2009-01-08 10:48 UTC (permalink / raw)
  To: Helmut Schaa
  Cc: Johannes Berg, John W. Linville, linux-wireless, Jouni Malinen,
	Dan Williams

On Thu, Jan 08, 2009 at 10:57:45AM +0100, Helmut Schaa wrote:

> Jouni, what do you think about extending wpa_supplicant to allow mutliple
> drivers to be set on the commandline (-Dnl80211,wext). The supplicant would
> then try to register the first driver and only if that fails it takes the next
> one (e.g. try nl80211 first and if that fails use wext). That way NM could
> use nl80211 for drivers that support nl80211 (mainly mac80211-drivers) and
> wext for the other drivers by passing "-Dnl80211,wext" to the supplicant.

Well, that could be done inside wpa_supplicant, but more or less the
same effect should already be doable by NM trying to first add the
interface with nl80211 as the driver interface and if that fails, fall
back to wext.

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-08 10:48                 ` Jouni Malinen
@ 2009-01-08 12:08                   ` Helmut Schaa
  2009-01-08 12:18                     ` Jouni Malinen
  0 siblings, 1 reply; 31+ messages in thread
From: Helmut Schaa @ 2009-01-08 12:08 UTC (permalink / raw)
  To: Jouni Malinen
  Cc: Johannes Berg, John W. Linville, linux-wireless, Jouni Malinen,
	Dan Williams

Am Donnerstag, 8. Januar 2009 schrieb Jouni Malinen:
> On Thu, Jan 08, 2009 at 10:57:45AM +0100, Helmut Schaa wrote:
> 
> > Jouni, what do you think about extending wpa_supplicant to allow mutliple
> > drivers to be set on the commandline (-Dnl80211,wext). The supplicant would
> > then try to register the first driver and only if that fails it takes the next
> > one (e.g. try nl80211 first and if that fails use wext). That way NM could
> > use nl80211 for drivers that support nl80211 (mainly mac80211-drivers) and
> > wext for the other drivers by passing "-Dnl80211,wext" to the supplicant.
> 
> Well, that could be done inside wpa_supplicant, but more or less the
> same effect should already be doable by NM trying to first add the
> interface with nl80211 as the driver interface and if that fails, fall
> back to wext.

True. However, other consumers of wpa_supplicant (e.g. Yast in SUSE) could
also benefit from this feature if implemented inside the supplicant. But as
I wrote, this was just a quick thought on how to make the transition from
wext to nl80211 smoother.

Helmut

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-08 12:08                   ` Helmut Schaa
@ 2009-01-08 12:18                     ` Jouni Malinen
  2009-01-08 12:25                       ` Johannes Berg
  2009-01-08 12:29                       ` Helmut Schaa
  0 siblings, 2 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-08 12:18 UTC (permalink / raw)
  To: Helmut Schaa
  Cc: Johannes Berg, John W. Linville, linux-wireless, Jouni Malinen,
	Dan Williams

On Thu, Jan 08, 2009 at 01:08:21PM +0100, Helmut Schaa wrote:

> True. However, other consumers of wpa_supplicant (e.g. Yast in SUSE) could
> also benefit from this feature if implemented inside the supplicant. But as
> I wrote, this was just a quick thought on how to make the transition from
> wext to nl80211 smoother.

Agreed and it should be relatively small change in wpa_supplicant, so
I'm not against doing this. However, at this point I would not yet
recommend trying to use driver_nl80211 as the first option. Once we get
nl80211 bit more complete and at least make sure it does not break
something, adding the automatic driver selection would sound more
reasonable. Though, this would also mean that we depend on drivers never
implementing partial nl80211 support that could trigger wpa_supplicant
into believing that they support nl80211 when they would actually work
much better with wext.

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-08 12:18                     ` Jouni Malinen
@ 2009-01-08 12:25                       ` Johannes Berg
  2009-01-08 12:29                       ` Helmut Schaa
  1 sibling, 0 replies; 31+ messages in thread
From: Johannes Berg @ 2009-01-08 12:25 UTC (permalink / raw)
  To: Jouni Malinen
  Cc: Helmut Schaa, John W. Linville, linux-wireless, Jouni Malinen,
	Dan Williams

[-- Attachment #1: Type: text/plain, Size: 1231 bytes --]

On Thu, 2009-01-08 at 14:18 +0200, Jouni Malinen wrote:

> Agreed and it should be relatively small change in wpa_supplicant, so
> I'm not against doing this. However, at this point I would not yet
> recommend trying to use driver_nl80211 as the first option. Once we get
> nl80211 bit more complete and at least make sure it does not break
> something, adding the automatic driver selection would sound more
> reasonable. Though, this would also mean that we depend on drivers never
> implementing partial nl80211 support that could trigger wpa_supplicant
> into believing that they support nl80211 when they would actually work
> much better with wext.

That's not _much_ of a problem, considering that driver_nl80211 is using
wext, and cfg80211 will continue providing wext calls. Therefore, older
versions of wpa_supplicant will continue working on newer kernel
versions that have more stuff in nl80211 rather than wext, the only
problem could come up when using a "too new" wpa_supplicant on an older
kernel with older nl80211. That's easy to detect though by checking
which commands nl80211 supports, and refusing to work with it unless all
commands that driver_nl80211 needs are implemented.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames
  2009-01-08 12:18                     ` Jouni Malinen
  2009-01-08 12:25                       ` Johannes Berg
@ 2009-01-08 12:29                       ` Helmut Schaa
  1 sibling, 0 replies; 31+ messages in thread
From: Helmut Schaa @ 2009-01-08 12:29 UTC (permalink / raw)
  To: Jouni Malinen
  Cc: Johannes Berg, John W. Linville, linux-wireless, Jouni Malinen,
	Dan Williams

Am Donnerstag, 8. Januar 2009 schrieb Jouni Malinen:
> However, at this point I would not yet
> recommend trying to use driver_nl80211 as the first option. Once we get 
> nl80211 bit more complete and at least make sure it does not break
> something, adding the automatic driver selection would sound more
> reasonable.

Right. Sounds feasible.

> Though, this would also mean that we depend on drivers never 
> implementing partial nl80211 support that could trigger wpa_supplicant
> into believing that they support nl80211 when they would actually work
> much better with wext.

Good point.

Helmut

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [patch] vif_conf.patch failed to patch git wireless-testing (07-01-2009)
       [not found]           ` <226823.3656.qm@web57008.mail.re3.yahoo.com>
@ 2009-01-08 12:44             ` Jouni Malinen
  0 siblings, 0 replies; 31+ messages in thread
From: Jouni Malinen @ 2009-01-08 12:44 UTC (permalink / raw)
  To: Ahmad Ali Tabassam; +Cc: johannes, hostap, linux-wireless

On Wed, Jan 07, 2009 at 07:21:51AM -0800, Ahmad Ali Tabassam wrote:

> I want to enable userspace mlme for my client for wpa_supplicant 0.6.7 with client MLME. . But the http://w1.fi/wireless-testing/vif_conf.patch failed to be applied.  I have the latest wireless-testing git tree (07-01-09). The error is given below............any idea. does there any new pathch?

I updated the patches at http://w1.fi/wireless-testing/ now and the
version there seemed to work in my tests. However, you will now also
need to patch wpa_supplicant with the nl80211.h (see patch below) in
order to get the needed nl80211 command for enabling userspace MLME.


diff --git a/src/common/nl80211_copy.h b/src/common/nl80211_copy.h
index ee742bc..47f9531 100644
--- a/src/common/nl80211_copy.h
+++ b/src/common/nl80211_copy.h
@@ -133,6 +133,9 @@
  * @NL80211_CMD_SET_MESH_PARAMS: Set mesh networking properties for the
  *      interface identified by %NL80211_ATTR_IFINDEX
  *
+ * @NL80211_CMD_SET_VIF: Set virtual interface attributes for vif identified by
+ *	%NL80211_ATTR_IFINDEX.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -178,6 +181,8 @@ enum nl80211_commands {
 	NL80211_CMD_GET_MESH_PARAMS,
 	NL80211_CMD_SET_MESH_PARAMS,
 
+	NL80211_CMD_SET_VIF,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -190,6 +195,7 @@ enum nl80211_commands {
  * here
  */
 #define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS
+#define NL80211_CMD_SET_VIF NL80211_CMD_SET_VIF
 
 /**
  * enum nl80211_attrs - nl80211 netlink attributes
@@ -284,6 +290,11 @@ enum nl80211_commands {
  *	supported interface types, each a flag attribute with the number
  *	of the interface mode.
  *
+ * @NL80211_ATTR_VIF_DROP_UNENCRYPTED: whether unencrypted frames will be
+ *	dropped (u8, 0 or 1)
+ * @NL80211_ATTR_VIF_USERSPACE_MLME: whether userspace MLME is used
+ *	(u8, 0 or 1)
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -348,6 +359,9 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_KEY_DEFAULT_MGMT,
 
+	NL80211_ATTR_VIF_DROP_UNENCRYPTED,
+	NL80211_ATTR_VIF_USERSPACE_MLME,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply related	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2009-01-08 12:45 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-07 11:23 [PATCH 00/14] mac80211: IEEE 802.11w (management frame protection) Jouni Malinen
2009-01-07 11:23 ` [PATCH 01/14] mac80211: 802.11w - STA flag for MFP Jouni Malinen
2009-01-07 11:23 ` [PATCH 02/14] mac80211: 802.11w - CCMP for management frames Jouni Malinen
2009-01-07 11:23 ` [PATCH 03/14] mac80211: 802.11w - Add BIP (AES-128-CMAC) Jouni Malinen
2009-01-07 11:23 ` [PATCH 04/14] mac80211: 802.11w - Use " Jouni Malinen
2009-01-07 11:23 ` [PATCH 05/14] mac80211: 802.11w - WEXT parameter for setting mgmt cipher Jouni Malinen
2009-01-07 11:23 ` [PATCH 06/14] mac80211: 802.11w - WEXT configuration for IGTK Jouni Malinen
2009-01-07 11:23 ` [PATCH 07/14] mac80211: 802.11w - Configuration of MFP disabled/optional/required Jouni Malinen
2009-01-07 11:23 ` [PATCH 08/14] mac80211: 802.11w - SA Query processing Jouni Malinen
2009-01-07 11:23 ` [PATCH 09/14] mac80211: 802.11w - Do not force Action frames to disable encryption Jouni Malinen
2009-01-07 11:23 ` [PATCH 10/14] mac80211: 802.11w - Drop unprotected robust management frames if MFP is used Jouni Malinen
2009-01-07 11:23 ` [PATCH 11/14] mac80211: 802.11w - Implement Association Comeback processing Jouni Malinen
2009-01-07 11:23 ` [PATCH 12/14] mac80211: 802.11w - Optional software CCMP for management frames Jouni Malinen
2009-01-07 12:08   ` Johannes Berg
2009-01-07 12:24     ` Jouni Malinen
2009-01-07 12:47       ` Johannes Berg
2009-01-07 14:09         ` Jouni Malinen
2009-01-07 15:09           ` Johannes Berg
2009-01-07 15:30             ` Jouni Malinen
2009-01-07 15:37               ` Johannes Berg
2009-01-07 16:33                 ` Jouni Malinen
2009-01-07 16:37                   ` Johannes Berg
2009-01-08  9:57               ` Helmut Schaa
2009-01-08 10:48                 ` Jouni Malinen
2009-01-08 12:08                   ` Helmut Schaa
2009-01-08 12:18                     ` Jouni Malinen
2009-01-08 12:25                       ` Johannes Berg
2009-01-08 12:29                       ` Helmut Schaa
     [not found]           ` <226823.3656.qm@web57008.mail.re3.yahoo.com>
2009-01-08 12:44             ` [patch] vif_conf.patch failed to patch git wireless-testing (07-01-2009) Jouni Malinen
2009-01-07 11:23 ` [PATCH 13/14] ath9k: Fix set_key error codes Jouni Malinen
2009-01-07 11:24 ` [PATCH 14/14] ath9k: Setup MFP options for CCMP Jouni Malinen

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).