[PATCH 1/5] cfg80211: Parsing of Multiple BSSID information in scanning

2018-12-07 Thread Jouni Malinen
From: Peng Xu 

This extends cfg80211 BSS table processing to be able to parse Multiple
BSSID element from Beacon and Probe Response frames and to update the
BSS profiles in internal database for non-transmitted BSSs.

Signed-off-by: Peng Xu 
Signed-off-by: Sara Sharon 
Signed-off-by: Johannes Berg 
Signed-off-by: Jouni Malinen 
---
 net/wireless/core.h |   1 +
 net/wireless/scan.c | 504 
 2 files changed, 466 insertions(+), 39 deletions(-)

diff --git a/net/wireless/core.h b/net/wireless/core.h
index c5d6f34..d58c56a 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -152,6 +152,7 @@ extern int cfg80211_rdev_list_generation;
 struct cfg80211_internal_bss {
struct list_head list;
struct list_head hidden_list;
+   struct list_head nontrans_list;
struct rb_node rbn;
u64 ts_boottime;
unsigned long ts;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index d0e7472..559f56d 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -4,7 +4,7 @@
  *
  * Copyright 2008 Johannes Berg 
  * Copyright 2013-2014  Intel Mobile Communications GmbH
- * Copyright 2016  Intel Deutschland GmbH
+ * Copyright 2016-2017 Intel Deutschland GmbH
  */
 #include 
 #include 
@@ -150,6 +150,7 @@ static bool __cfg80211_unlink_bss(struct 
cfg80211_registered_device *rdev,
}
 
list_del_init(>list);
+   list_del_init(>nontrans_list);
rb_erase(>rbn, >bss_tree);
rdev->bss_entries--;
WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(>bss_list),
@@ -159,6 +160,170 @@ static bool __cfg80211_unlink_bss(struct 
cfg80211_registered_device *rdev,
return true;
 }
 
+static void cfg80211_gen_new_bssid(const u8 *bssid, u8 max_bssid,
+  u8 mbssid_index, u8 *new_bssid_addr)
+{
+   u64 bssid_tmp, new_bssid = 0;
+   u64 lsb_n;
+
+   bssid_tmp = ether_addr_to_u64(bssid);
+
+   lsb_n = bssid_tmp & ((1 << max_bssid) - 1);
+   new_bssid = bssid_tmp;
+   new_bssid &= ~((1 << max_bssid) - 1);
+   new_bssid |= (lsb_n + mbssid_index) % (1 << max_bssid);
+
+   u64_to_ether_addr(new_bssid, new_bssid_addr);
+}
+
+static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
+ const u8 *subelement, size_t subie_len,
+ u8 *new_ie, gfp_t gfp)
+{
+   u8 *pos, *tmp;
+   const u8 *tmp_old, *tmp_new;
+   u8 *sub_copy;
+
+   /* copy subelement as we need to change its content to
+* mark an ie after it is processed.
+*/
+   sub_copy = kmalloc(subie_len, gfp);
+   if (!sub_copy)
+   return 0;
+   memcpy(sub_copy, subelement, subie_len);
+
+   pos = _ie[0];
+
+   /* set new ssid */
+   tmp_new = cfg80211_find_ie(WLAN_EID_SSID, sub_copy, subie_len);
+   if (tmp_new) {
+   memcpy(pos, tmp_new, tmp_new[1] + 2);
+   pos += (tmp_new[1] + 2);
+   }
+
+   /* go through IEs in ie (skip SSID) and subelement,
+* merge them into new_ie
+*/
+   tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
+   tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
+
+   while (tmp_old + tmp_old[1] + 2 - ie <= ielen) {
+   if (tmp_old[0] == 0) {
+   tmp_old++;
+   continue;
+   }
+
+   tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy, subie_len);
+   if (!tmp) {
+   /* ie in old ie but not in subelement */
+   if (tmp_old[0] != WLAN_EID_MULTIPLE_BSSID) {
+   memcpy(pos, tmp_old, tmp_old[1] + 2);
+   pos += tmp_old[1] + 2;
+   }
+   } else {
+   /* ie in transmitting ie also in subelement,
+* copy from subelement and flag the ie in subelement
+* as copied (by setting eid field to 0xff). For
+* vendor ie, compare OUI + type + subType to
+* determine if they are the same ie.
+*/
+   if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
+   if (!memcmp(tmp_old + 2, tmp + 2, 5)) {
+   /* same vendor ie, copy from
+* subelement
+*/
+   memcpy(pos, tmp, tmp[1] + 2);
+   pos += tmp[1] + 2;
+   tmp[0] = 0xff;
+   } else {
+   memcpy(pos, tmp_old, tmp_old[1] + 2);
+   pos += tmp_old[1] + 2;
+ 

[PATCH 2/5] cfg80211: Properly track transmitting and non-transmitting BSS

2018-12-07 Thread Jouni Malinen
From: Sara Sharon 

When holding data of the non-transmitting BSS, we need to keep the
transmitting BSS data on. Otherwise it will be released, and release
the non-transmitting BSS with it.

Signed-off-by: Sara Sharon 
Signed-off-by: Johannes Berg 
Signed-off-by: Jouni Malinen 
---
 net/wireless/core.h |  9 +
 net/wireless/scan.c | 36 ++--
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/net/wireless/core.h b/net/wireless/core.h
index d58c56a..b1afc4b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -153,6 +153,7 @@ struct cfg80211_internal_bss {
struct list_head list;
struct list_head hidden_list;
struct list_head nontrans_list;
+   struct cfg80211_bss *transmitted_bss;
struct rb_node rbn;
u64 ts_boottime;
unsigned long ts;
@@ -183,12 +184,20 @@ static inline struct cfg80211_internal_bss 
*bss_from_pub(struct cfg80211_bss *pu
 static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
 {
atomic_inc(>hold);
+   if (bss->transmitted_bss)
+   cfg80211_hold_bss(container_of(bss->transmitted_bss,
+  struct cfg80211_internal_bss,
+  pub));
 }
 
 static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
 {
int r = atomic_dec_return(>hold);
WARN_ON(r < 0);
+   if (bss->transmitted_bss)
+   cfg80211_unhold_bss(container_of(bss->transmitted_bss,
+struct cfg80211_internal_bss,
+pub));
 }
 
 
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 559f56d..6f2fed2 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -109,6 +109,12 @@ static inline void bss_ref_get(struct 
cfg80211_registered_device *rdev,
   pub);
bss->refcount++;
}
+   if (bss->transmitted_bss) {
+   bss = container_of(bss->transmitted_bss,
+  struct cfg80211_internal_bss,
+  pub);
+   bss->refcount++;
+   }
 }
 
 static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
@@ -125,6 +131,18 @@ static inline void bss_ref_put(struct 
cfg80211_registered_device *rdev,
if (hbss->refcount == 0)
bss_free(hbss);
}
+
+   if (bss->transmitted_bss) {
+   struct cfg80211_internal_bss *tbss;
+
+   tbss = container_of(bss->transmitted_bss,
+   struct cfg80211_internal_bss,
+   pub);
+   tbss->refcount--;
+   if (tbss->refcount == 0)
+   bss_free(tbss);
+   }
+
bss->refcount--;
if (bss->refcount == 0)
bss_free(bss);
@@ -1028,6 +1046,7 @@ static bool cfg80211_combine_bsses(struct 
cfg80211_registered_device *rdev,
 static struct cfg80211_internal_bss *
 cfg80211_bss_update(struct cfg80211_registered_device *rdev,
struct cfg80211_internal_bss *tmp,
+   struct cfg80211_bss *trans_bss,
bool signal_valid)
 {
struct cfg80211_internal_bss *found = NULL;
@@ -1184,6 +1203,17 @@ cfg80211_bss_update(struct cfg80211_registered_device 
*rdev,
goto drop;
}
 
+   /* This must be before the call to bss_ref_get */
+   if (trans_bss) {
+   struct cfg80211_internal_bss *pbss =
+   container_of(trans_bss,
+struct cfg80211_internal_bss,
+pub);
+
+   new->transmitted_bss = trans_bss;
+   bss_ref_get(rdev, pbss);
+   }
+
list_add_tail(>list, >bss_list);
rdev->bss_entries++;
rb_insert_bss(rdev, new);
@@ -1339,7 +1369,8 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
 
signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
wiphy->max_adj_channel_rssi_comp;
-   res = cfg80211_bss_update(wiphy_to_rdev(wiphy), , signal_valid);
+   res = cfg80211_bss_update(wiphy_to_rdev(wiphy), , trans_bss,
+ signal_valid);
if (!res)
return NULL;
 
@@ -1657,7 +1688,8 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
 
signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
wiphy->max_adj_channel_rssi_comp;
-   res = cfg80211_bss_update(wiphy_to_rdev(wiphy), , signal_valid);
+   res = cfg80211_bss_update(wiph

[PATCH 4/5] mac80211: Declare support for Multi-BSSID if driver supports it

2018-12-07 Thread Jouni Malinen
From: Sara Sharon 

Define bits and flags for indicating support of Multi-BSSID feature and
indicate support for this if the driver supports it.

Signed-off-by: Sara Sharon 
Signed-off-by: Johannes Berg 
Signed-off-by: Jouni Malinen 
---
 include/linux/ieee80211.h | 6 ++
 include/net/mac80211.h| 3 +++
 net/mac80211/debugfs.c| 1 +
 net/mac80211/main.c   | 4 
 4 files changed, 14 insertions(+)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 407d6fd..0a84f4e 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2656,6 +2656,12 @@ enum ieee80211_tdls_actioncode {
  */
 #define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING   BIT(2)
 
+/* Multiple BSSID capability is set in the 6th bit of the 3rd byte of the
+ * @WLAN_EID_EXT_CAPABILITY information element
+ */
+#define WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT BIT(6)
+
+
 /* TDLS capabilities in the the 4th byte of @WLAN_EID_EXT_CAPABILITY */
 #define WLAN_EXT_CAPA4_TDLS_BUFFER_STA BIT(4)
 #define WLAN_EXT_CAPA4_TDLS_PEER_PSM   BIT(5)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9386cf9..e7c4e11 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2181,6 +2181,8 @@ struct ieee80211_txq {
  * MMPDUs on station interfaces. This of course requires the driver to use
  * TXQs to start with.
  *
+ * @IEEE80211_HW_SUPPORTS_MULTI_BSSID: Hardware supports multi BSSID
+ *
  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
  */
 enum ieee80211_hw_flags {
@@ -2229,6 +2231,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_BUFF_MMPDU_TXQ,
IEEE80211_HW_SUPPORTS_VHT_EXT_NSS_BW,
IEEE80211_HW_STA_MMPDU_TXQ,
+   IEEE80211_HW_SUPPORTS_MULTI_BSSID,
 
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 3fe541e..28a7e60 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -218,6 +218,7 @@ static const char *hw_flag_names[] = {
FLAG(BUFF_MMPDU_TXQ),
FLAG(SUPPORTS_VHT_EXT_NSS_BW),
FLAG(STA_MMPDU_TXQ),
+   FLAG(SUPPORTS_MULTI_BSSID),
 #undef FLAG
 };
 
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 83e71e6..6ad4288 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1104,6 +1104,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if (ieee80211_hw_check(>hw, CHANCTX_STA_CSA))
local->ext_capa[0] |= WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING;
 
+   /* mac80211 supports multi BSSID, if the driver supports it */
+   if (ieee80211_hw_check(>hw, SUPPORTS_MULTI_BSSID))
+   local->ext_capa[2] |= WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT;
+
local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM;
 
result = wiphy_register(local->hw.wiphy);
-- 
2.7.4



[PATCH 5/5] mac80211_hwsim: Declare support for Multi-BSSID

2018-12-07 Thread Jouni Malinen
This can be used to test cfg80211 support for Multi-BSSID scan result
parsing.

Signed-off-by: Jouni Malinen 
---
 drivers/net/wireless/mac80211_hwsim.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/mac80211_hwsim.c 
b/drivers/net/wireless/mac80211_hwsim.c
index 0540834..d5024ad 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2766,6 +2766,7 @@ static int mac80211_hwsim_new_radio(struct genl_info 
*info,
ieee80211_hw_set(hw, TDLS_WIDER_BW);
if (rctbl)
ieee80211_hw_set(hw, SUPPORTS_RC_TABLE);
+   ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
 
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
-- 
2.7.4



[PATCH 3/5] cfg80211: Move Multiple BSS info to struct cfg80211_bss to be visible

2018-12-07 Thread Jouni Malinen
From: Sara Sharon 

Previously the transmitted BSS and the non-trasmitted BSS list were
defined in struct cfg80211_internal_bss. Move them to struct cfg80211_bss
since mac80211 needs this info.

Signed-off-by: Sara Sharon 
Signed-off-by: Johannes Berg 
Signed-off-by: Jouni Malinen 
---
 include/net/cfg80211.h |  2 ++
 net/wireless/core.h| 10 +++
 net/wireless/scan.c| 79 +-
 3 files changed, 45 insertions(+), 46 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ede7fcd..839f717 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2019,6 +2019,8 @@ struct cfg80211_bss {
const struct cfg80211_bss_ies __rcu *proberesp_ies;
 
struct cfg80211_bss *hidden_beacon_bss;
+   struct cfg80211_bss *transmitted_bss;
+   struct list_head nontrans_list;
 
s32 signal;
 
diff --git a/net/wireless/core.h b/net/wireless/core.h
index b1afc4b..40c01b6 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -152,8 +152,6 @@ extern int cfg80211_rdev_list_generation;
 struct cfg80211_internal_bss {
struct list_head list;
struct list_head hidden_list;
-   struct list_head nontrans_list;
-   struct cfg80211_bss *transmitted_bss;
struct rb_node rbn;
u64 ts_boottime;
unsigned long ts;
@@ -184,8 +182,8 @@ static inline struct cfg80211_internal_bss 
*bss_from_pub(struct cfg80211_bss *pu
 static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
 {
atomic_inc(>hold);
-   if (bss->transmitted_bss)
-   cfg80211_hold_bss(container_of(bss->transmitted_bss,
+   if (bss->pub.transmitted_bss)
+   cfg80211_hold_bss(container_of(bss->pub.transmitted_bss,
   struct cfg80211_internal_bss,
   pub));
 }
@@ -194,8 +192,8 @@ static inline void cfg80211_unhold_bss(struct 
cfg80211_internal_bss *bss)
 {
int r = atomic_dec_return(>hold);
WARN_ON(r < 0);
-   if (bss->transmitted_bss)
-   cfg80211_unhold_bss(container_of(bss->transmitted_bss,
+   if (bss->pub.transmitted_bss)
+   cfg80211_unhold_bss(container_of(bss->pub.transmitted_bss,
 struct cfg80211_internal_bss,
 pub));
 }
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 6f2fed2..25ce73d 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -109,8 +109,8 @@ static inline void bss_ref_get(struct 
cfg80211_registered_device *rdev,
   pub);
bss->refcount++;
}
-   if (bss->transmitted_bss) {
-   bss = container_of(bss->transmitted_bss,
+   if (bss->pub.transmitted_bss) {
+   bss = container_of(bss->pub.transmitted_bss,
   struct cfg80211_internal_bss,
   pub);
bss->refcount++;
@@ -132,10 +132,10 @@ static inline void bss_ref_put(struct 
cfg80211_registered_device *rdev,
bss_free(hbss);
}
 
-   if (bss->transmitted_bss) {
+   if (bss->pub.transmitted_bss) {
struct cfg80211_internal_bss *tbss;
 
-   tbss = container_of(bss->transmitted_bss,
+   tbss = container_of(bss->pub.transmitted_bss,
struct cfg80211_internal_bss,
pub);
tbss->refcount--;
@@ -168,7 +168,7 @@ static bool __cfg80211_unlink_bss(struct 
cfg80211_registered_device *rdev,
}
 
list_del_init(>list);
-   list_del_init(>nontrans_list);
+   list_del_init(>pub.nontrans_list);
rb_erase(>rbn, >bss_tree);
rdev->bss_entries--;
WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(>bss_list),
@@ -316,15 +316,15 @@ static bool is_bss(struct cfg80211_bss *a, const u8 
*bssid,
 }
 
 static int
-cfg80211_add_nontrans_list(struct cfg80211_internal_bss *trans_bss,
-  struct cfg80211_internal_bss *nontrans_bss)
+cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss,
+  struct cfg80211_bss *nontrans_bss)
 {
const u8 *ssid;
size_t ssid_len;
-   struct cfg80211_internal_bss *bss = NULL;
+   struct cfg80211_bss *bss = NULL;
 
rcu_read_lock();
-   ssid = ieee80211_bss_get_ie(_bss->pub, WLAN_EID_SSID);
+   ssid = ieee80211_bss_get_ie(nontrans_bss, WLAN_EID_SSID);
if (!ssid)
return -EINVAL;
ssid_len = ssid[1];
@@ -333,7 +333,7 @@ cfg80211_add_nontrans_list(struct cfg80211_internal_bss 
*trans_bss,
 
/* check if nontrans_bss is in the list */
list_for_each_entry(bss, _bss-&g

Re: [RFC PATCH v2 0/2] Extended Key ID support for linux

2018-12-07 Thread Jouni Malinen
On Wed, Dec 05, 2018 at 08:06:33PM +0100, Alexander Wetzel wrote:
> >On Sun, 2018-11-11 at 12:02 +0100, Alexander Wetzel wrote:
> >>IEEE 802.11-2012 added support for Extended Key ID, allowing pairwise
> >>keys to also use keyID 1 and moving group keys to IDs 2 and 3.
> >
> >Where do you read this? I've always been under the impression that
> >individually and group addressed frames use key IDs from different
> >"namespaces", so to speak, where PTK/STK can use 0 (0 or 1 with
> >"Extended Key ID" support) and GTK can use 0-3.

There is no such requirement to change group key IDs in the IEEE 802.11
standard when taking Extended Key ID mechanism into use.

> >In fact, the per-frame pseudocode in 802.11-2016 12.9.2.6 clearly
> >states:
> >
> >if MPDU has individual RA then
> > lookup pairwise key using Key ID from MPDU
> >else
> > lookup group key using Key ID from MPDU
> >endif
> >
> >If it weren't different namespaces, you'd not have to differentiate
> >here.
> >
> 
> I was indeed struggling to understand what the intend of the standard is
> here. I may well be wrong, but the note in "12.6.1.1.10 Mesh GTKSA" tipped
> the scales to assume keyIDs are within one namespace only.
> 
> "Since Key ID 0 is reserved for individually addressed frame transmission,
> there are at most three available Key IDs (only two if extended Key IDs for
> individually addressed frames are in use), and the different MGTKs would
> contend for the single remaining Key ID upon rollover."

Please note that this is is an informative note and not normative part
of the standard. IMHO, that note is not accurate and it looks likely
that it was added without full understanding on how the keys are used in
the standard..

> I got the impression Extended Key IDs were  added without updating all
> sections which should get updates. But the pattern is suspect, even the igtk
> numbers fit into the pattern:
> 
>  PTK 0 & 1
>  GTK 1 & 2 & 3
> iGTK 4 & 5

An AP is allowed to do this, but there is no requirement for doing so.
The pairwise key (TK, not PTK) is required to use Key ID 0 unless the
optional Extended Key ID for Individually Addressed Frames capability is
negotiated (and 0 or 1 if that capability is negotiated). Group keys
(GTK) are allowed to use Key IDs 0..4. IGTKs are allowed to use Key ID
values 4 and 5.

There is a long history behind this and some de facto constraints due to
that history and possible implementation constraints. However, as far as
the protocol itself is concerned, there would be no real need for having
IGTK use 4..5; it could have as well been 0..1 or 1..2 or whatever
combination the AP would like to use.

These three cases have completely independent namespaces for Key IDs as
far as RSN is concerned with one exception: "Use group cipher suite"
that was added as an option for some AP implementation that did not
support individual key mapping. That special case would end up using GTK
for both group-addressed and individually-addressed frames. That said,
I'm not aware of there having ever been an actually deployed device with
this constraint and even if there were, this mode is highly discouraged
and should not be used for anything today. Anyway, this exception and
similar implementation constraints are likely behind the expectations of
TK and GTK having to use different Key ID values.

As far as the kernel changes are concerned, cfg80211 and mac80211 should
support everything that's allowed by the standard, i.e., use of Key IDs
0..3 for GTK. It is up to the user space implementation on the AP side
(e.g., hostapd) to select which Key IDs are actually taken into use.

-- 
Jouni MalinenPGP id EFC895FA


[PATCH] cfg80211: Fix busy loop regression in ieee80211_ie_split_ric()

2018-12-05 Thread Jouni Malinen
This function was modified to support the information element extension
case (WLAN_EID_EXTENSION) in a manner that would result in an infinite
loop when going through set of IEs that include WLAN_EID_RIC_DATA and
contain an IE that is in the after_ric array. The only place where this
can currently happen is in mac80211 ieee80211_send_assoc() where
ieee80211_ie_split_ric() is called with after_ric[].

This can be triggered by valid data from user space nl80211
association/connect request (i.e., requiring GENL_UNS_ADMIN_PERM). The
only known application having an option to include WLAN_EID_RIC_DATA in
these requests is wpa_supplicant and it had a bug that prevented this
specific contents from being used (and because of that, not triggering
this kernel bug in an automated test case ap_ft_ric) and now that this
bug is fixed, it has a workaround to avoid this kernel issue.
WLAN_EID_RIC_DATA is currently used only for testing purposes, so this
does not cause significant harm for production use cases.

Fixes: 2512b1b18d07 ("mac80211: extend ieee80211_ie_split to support EXTENSION")
Signed-off-by: Jouni Malinen 
---
 net/wireless/util.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/wireless/util.c b/net/wireless/util.c
index ef14d80..d473bd1 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1421,6 +1421,8 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
  ies[pos + ext],
  ext == 2))
pos = skip_ie(ies, ielen, pos);
+   else
+   break;
}
} else {
pos = skip_ie(ies, ielen, pos);
-- 
2.7.4



[PATCH 3/3] mac80211: Extend SAE authentication in infra BSS STA mode

2018-10-10 Thread Jouni Malinen
Previous implementation of SAE authentication in infrastructure BSS was
somewhat restricting and not exactly clean way of handling the two
auth() operations. This ended up removing and re-adding the STA entry
for the AP in the middle of authentication and also messing up
authentication state tracking through the sequence of four
Authentication frames. Furthermore, this did not work if the AP ended up
sending out SAE Confirm (auth trans #2) immediately after SAE Commit
(auth trans #1) before the station had time to transmit its SAE Confirm.

Clean up authentication state handling for the SAE case to allow two
rounds of auth() calls without dropping all state between those
operations. Track peer Confirmed status and mark authentication
completed only once both ends have confirmed.

ieee80211_mgd_auth() check for EBUSY cases is now handling only the
pending association (ifmgd->assoc_data) while all pending authentication
(ifmgd->auth_data) cases are allowed to proceed to allow user space to
start a new connection attempt from scratch even if the previously
requested authentication is still waiting completion. This is needed to
avoid making SAE error cases with retries take excessive amount of time
with no means for the user space to stop that (apart from setting the
netdev down).

As an extra bonus, the end of ieee80211_rx_mgmt_auth() can be cleaned up
to avoid the extra copy of the cfg80211_rx_mlme_mgmt() call for ongoing
SAE authentication since the new ieee80211_mark_sta_auth() helper
function can handle both completion of authentication and updates to the
STA entry under the same condition and there is no need to return from
the function between those operations.

Signed-off-by: Jouni Malinen 
---
 net/mac80211/ieee80211_i.h |  1 +
 net/mac80211/mlme.c| 70 +++---
 2 files changed, 48 insertions(+), 23 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f40a216..10a0506 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -377,6 +377,7 @@ struct ieee80211_mgd_auth_data {
u8 key[WLAN_KEY_LEN_WEP104];
u8 key_len, key_idx;
bool done;
+   bool peer_confirmed;
bool timeout_started;
 
u16 sae_trans, sae_status;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1818dbc..d2bc8d5 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2764,8 +2764,15 @@ static void ieee80211_auth_challenge(struct 
ieee80211_sub_if_data *sdata,
 static bool ieee80211_mark_sta_auth(struct ieee80211_sub_if_data *sdata,
const u8 *bssid)
 {
+   struct ieee80211_if_managed *ifmgd = >u.mgd;
struct sta_info *sta;
 
+   sdata_info(sdata, "authenticated\n");
+   ifmgd->auth_data->done = true;
+   ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
+   ifmgd->auth_data->timeout_started = true;
+   run_again(sdata, ifmgd->auth_data->timeout);
+
/* move station state to auth */
mutex_lock(>local->sta_mtx);
sta = sta_info_get(sdata, bssid);
@@ -2811,7 +2818,11 @@ static void ieee80211_rx_mgmt_auth(struct 
ieee80211_sub_if_data *sdata,
status_code = le16_to_cpu(mgmt->u.auth.status_code);
 
if (auth_alg != ifmgd->auth_data->algorithm ||
-   auth_transaction != ifmgd->auth_data->expected_transaction) {
+   (auth_alg != WLAN_AUTH_SAE &&
+auth_transaction != ifmgd->auth_data->expected_transaction) ||
+   (auth_alg == WLAN_AUTH_SAE &&
+(auth_transaction < ifmgd->auth_data->expected_transaction ||
+ auth_transaction > 2))) {
sdata_info(sdata, "%pM unexpected authentication state: alg %d 
(expected %d) transact %d (expected %d)\n",
   mgmt->sa, auth_alg, ifmgd->auth_data->algorithm,
   auth_transaction,
@@ -2854,25 +2865,17 @@ static void ieee80211_rx_mgmt_auth(struct 
ieee80211_sub_if_data *sdata,
 
event.u.mlme.status = MLME_SUCCESS;
drv_event_callback(sdata->local, sdata, );
-   sdata_info(sdata, "authenticated\n");
-   ifmgd->auth_data->done = true;
-   ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
-   ifmgd->auth_data->timeout_started = true;
-   run_again(sdata, ifmgd->auth_data->timeout);
-
-   if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE &&
-   ifmgd->auth_data->expected_transaction != 2) {
-   /*
-* Report auth frame to user space for processing since another
-* round of Authentication frames is still needed.
-*/
-   cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
-   return;
+   if (ifmgd->auth

[PATCH 1/3] mac80211: Helper function for marking STA authenticated

2018-10-10 Thread Jouni Malinen
Authentication exchange can be completed in both TX and RX paths for
SAE, so move this common functionality into a helper function to avoid
having to implement practically the same operations in two places when
extending SAE implementation in the following commits.

Signed-off-by: Jouni Malinen 
---
 net/mac80211/mlme.c | 34 ++
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 89dac79..2d3ec01 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2761,13 +2761,33 @@ static void ieee80211_auth_challenge(struct 
ieee80211_sub_if_data *sdata,
auth_data->key_idx, tx_flags);
 }
 
+static bool ieee80211_mark_sta_auth(struct ieee80211_sub_if_data *sdata,
+   const u8 *bssid)
+{
+   struct sta_info *sta;
+
+   /* move station state to auth */
+   mutex_lock(>local->sta_mtx);
+   sta = sta_info_get(sdata, bssid);
+   if (!sta) {
+   WARN_ONCE(1, "%s: STA %pM not found", sdata->name, bssid);
+   return false;
+   }
+   if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) {
+   sdata_info(sdata, "failed moving %pM to auth\n", bssid);
+   return false;
+   }
+   mutex_unlock(>local->sta_mtx);
+
+   return true;
+}
+
 static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
   struct ieee80211_mgmt *mgmt, size_t len)
 {
struct ieee80211_if_managed *ifmgd = >u.mgd;
u8 bssid[ETH_ALEN];
u16 auth_alg, auth_transaction, status_code;
-   struct sta_info *sta;
struct ieee80211_event event = {
.type = MLME_EVENT,
.u.mlme.data = AUTH_EVENT,
@@ -2850,18 +2870,8 @@ static void ieee80211_rx_mgmt_auth(struct 
ieee80211_sub_if_data *sdata,
return;
}
 
-   /* move station state to auth */
-   mutex_lock(>local->sta_mtx);
-   sta = sta_info_get(sdata, bssid);
-   if (!sta) {
-   WARN_ONCE(1, "%s: STA %pM not found", sdata->name, bssid);
+   if (!ieee80211_mark_sta_auth(sdata, bssid))
goto out_err;
-   }
-   if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) {
-   sdata_info(sdata, "failed moving %pM to auth\n", bssid);
-   goto out_err;
-   }
-   mutex_unlock(>local->sta_mtx);
 
cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
return;
-- 
2.7.4



[PATCH 2/3] mac80211: Move ieee80211_mgd_auth() EBUSY check to be before allocation

2018-10-10 Thread Jouni Malinen
This makes it easier to conditionally replace full allocation of
auth_data to use reallocation for the case of continuing SAE
authentication. Furthermore, there was not really any point in having
this check done so late in the function after having already completed
number of steps that cannot be used anyway in the error case.

Signed-off-by: Jouni Malinen 
---
 net/mac80211/mlme.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 2d3ec01..1818dbc 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4922,6 +4922,10 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data 
*sdata,
return -EOPNOTSUPP;
}
 
+   if ((ifmgd->auth_data && !ifmgd->auth_data->done) ||
+   ifmgd->assoc_data)
+   return -EBUSY;
+
auth_data = kzalloc(sizeof(*auth_data) + req->auth_data_len +
req->ie_len, GFP_KERNEL);
if (!auth_data)
@@ -4957,12 +4961,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data 
*sdata,
 
/* try to authenticate/probe */
 
-   if ((ifmgd->auth_data && !ifmgd->auth_data->done) ||
-   ifmgd->assoc_data) {
-   err = -EBUSY;
-   goto err_free;
-   }
-
if (ifmgd->auth_data)
ieee80211_destroy_auth_data(sdata, false);
 
@@ -5007,7 +5005,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data 
*sdata,
mutex_lock(>local->mtx);
ieee80211_vif_release_channel(sdata);
mutex_unlock(>local->mtx);
- err_free:
kfree(auth_data);
return err;
 }
-- 
2.7.4



[PATCH] nl80211: Add per peer statistics to compute FCS error rate

2018-09-27 Thread Jouni Malinen
From: Ankita Bajaj 

Add support for drivers to report the total number of MPDUs received
and the number of MPDUs received with an FCS error from a specific
peer. These counters will be incremented only when the TA of the
frame matches the MAC address of the peer irrespective of FCS
error.

It should be noted that the TA field in the frame might be corrupted
when there is an FCS error and TA matching logic would fail in such
cases. Hence, FCS error counter might not be fully accurate, but it can
provide help in detecting bad RX links in significant number of cases.
This FCS error counter without full accuracy can be used, e.g., to
trigger a kick-out of a connected client with a bad link in AP mode to
force such a client to roam to another AP.

Signed-off-by: Ankita Bajaj 
Signed-off-by: Jouni Malinen 
---
 include/net/cfg80211.h   | 7 +++
 include/uapi/linux/nl80211.h | 8 
 net/wireless/nl80211.c   | 2 ++
 3 files changed, 17 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9f3ed79..1fbb2d9 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1292,6 +1292,10 @@ struct cfg80211_tid_stats {
  * @ack_signal: signal strength (in dBm) of the last ACK frame.
  * @avg_ack_signal: average rssi value of ack packet for the no of msdu's has
  * been sent.
+ * @rx_mpdu_count: number of MPDUs received from this station
+ * @fcs_err_count: number of packets (MPDUs) received from this station with
+ * an FCS error. This counter should be incremented only when TA of the
+ * received packet with an FCS error matches the peer MAC address.
  */
 struct station_info {
u64 filled;
@@ -1338,6 +1342,9 @@ struct station_info {
struct cfg80211_tid_stats *pertid;
s8 ack_signal;
s8 avg_ack_signal;
+
+   u32 rx_mpdu_count;
+   u32 fcs_err_count;
 };
 
 #if IS_ENABLED(CONFIG_CFG80211)
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index cfc9417..172f312 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3051,6 +3051,12 @@ enum nl80211_sta_bss_param {
  * @NL80211_STA_INFO_PAD: attribute used for padding for 64-bit alignment
  * @NL80211_STA_INFO_ACK_SIGNAL: signal strength of the last ACK frame(u8, dBm)
  * @NL80211_STA_INFO_ACK_SIGNAL_AVG: avg signal strength of ACK frames (s8, 
dBm)
+ * @NL80211_STA_INFO_RX_MPDUS: total number of received packets (MPDUs)
+ * (u32, from this station)
+ * @NL80211_STA_INFO_FCS_ERROR_COUNT: total number of packets (MPDUs) received
+ * with an FCS error (u32, from this station). This count may not include
+ * some packets with an FCS error due to TA corruption. Hence this counter
+ * might not be fully accurate.
  * @__NL80211_STA_INFO_AFTER_LAST: internal
  * @NL80211_STA_INFO_MAX: highest possible station info attribute
  */
@@ -3091,6 +3097,8 @@ enum nl80211_sta_info {
NL80211_STA_INFO_PAD,
NL80211_STA_INFO_ACK_SIGNAL,
NL80211_STA_INFO_ACK_SIGNAL_AVG,
+   NL80211_STA_INFO_RX_MPDUS,
+   NL80211_STA_INFO_FCS_ERROR_COUNT,
 
/* keep last */
__NL80211_STA_INFO_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0827cbd..3151171 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4719,6 +4719,8 @@ static int nl80211_send_station(struct sk_buff *msg, u32 
cmd, u32 portid,
PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
PUT_SINFO_U64(BEACON_RX, rx_beacon);
PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
+   PUT_SINFO(RX_MPDUS, rx_mpdu_count, u32);
+   PUT_SINFO(FCS_ERROR_COUNT, fcs_err_count, u32);
if (wiphy_ext_feature_isset(>wiphy,
NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) {
PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
-- 
2.7.4



Re: SAE authentication frames in client mode

2018-09-20 Thread Jouni Malinen
On Thu, Sep 20, 2018 at 12:55:10AM +0200, Mathy Vanhoef wrote:
> That figure only appears to be an example. It doesn't say an exchange
> must ("shall") follow that order. So I don't see where the standard
> puts a constraint on how the authentication frames are exchanged.

I know this figure is not a normative requirement, but it is a
convenient location to point to for showing that specific sequence. I
did discuss this in the IEEE 802.11 working group when working on the
SAE implementation for infrastructure BSS case and the conclusion from
that discussion was that it is better to follow the common sequence of
STA->AP->STA round trips for the Authentication frames and have the STA
be the one taking care of retransmissions, if needed. I thought we ended
up clarifying that in the standard text somewhere as well, but that was
years ago and I do not remember how exactly this got documented. It is
possible that there would be benefit from adding a more explicit
requirement in REVmd. In any case, this sequence is the one that is
being implemented and enforced for implementations of WPA3.

> A related observation is that retransmissions of the Confirm message
> are done by the kernel? Unfortunately this means the Send-Confirm
> field is not being incremented (as per 12.4.8.6.5). In practice we
> indeed see that this field is not being incremented for retransmitted
> Confirm frames (when using wpa_supplicant). This means that if the
> first Confirm frame sent by the AP is lost, the handshake will fail,
> since the AP will not accept retransmissions with the same
> Send-Confirm counter (and hence won't retransmit its own Confirm
> frame).

For mac80111-based drivers, there is indeed retransmission cases in the
kernel implementation for authentication and association frames. SAE is
not the only case where those are somewhat pointless; similar issue
applies at least for FILS authentication where the timeout is too short
and the retry incorrect anyway. I have some local patches in mac80211
for testing purposes, but I have not yet found time to clean those up
for contribution.

For SAE, wpa_supplicant should really try to send out another Confirm if
no response from the AP is received. The mac80211 retries could be
removed as useless both for SAE and FILS. For now, the recovery from
this by starting authentication exchange from scratch which is likely
sufficient for covering robustness needs with all the link layer retries
making it sufficiently unlikely for the Authentication frames to be lost
completely.

-- 
Jouni MalinenPGP id EFC895FA


Re: SAE authentication frames in client mode

2018-09-19 Thread Jouni Malinen
On Wed, Sep 19, 2018 at 02:36:20PM +0200, Mathy Vanhoef wrote:
> It seems that in client mode, the Linux kernel only accepts an
> authentication frame after sending one itself. Is this interpretation
> correct?

For infrastructure station case, yes.

> If that is the case, this would conflict with the SAE handshake as
> defined in the 802.11-2016 standard. That's because when the AP
> receives a Commit frame, the AP is allowed to send both a Commit and
> Confirm frame (see 12.4.8.6.3). So according to the standard, the
> client must accept a SAE Confirm authentication frame, even if it
> hasn't yet transmitted its own Confirm frame. So this appears to be a
> bug. Thoughts?

While the SAE authentication exchange itself has such flexibility in the
sequence of Commit/Confirm messages, there is a constraint in IEEE
802.11 on how the Authentication frames are exchanged in an
infrastructure BSS between a non-AP STA and an AP. For SAE, this is
explicitly requiring the exchange proceed in the sequence shown in
Figure 4-29 (Example using SAE authentication), i.e., with the Commit
messages exchanged first and the first Confirm message coming from STA
to AP and the exchange concluded with the Confirm message from AP to
STA. This matches the Linux kernel implementation.

For mesh BSS cases, the SAE Confirm message can be sent out immediately
after having processed the Commit message, so the sequence there may end
up being different. That's also supported in the Linux implementation,
but this flexibility is not extended to the infrastructure case on
purpose.

-- 
Jouni MalinenPGP id EFC895FA


[PATCH] cfg80211: Address some corner cases in scan result channel updating

2018-09-05 Thread Jouni Malinen
cfg80211_get_bss_channel() is used to update the RX channel based on the
available frame payload information (channel number from DSSS Parameter
Set element or HT Operation element). This is needed on 2.4 GHz channels
where frames may be received on neighboring channels due to overlapping
frequency range.

This might of some use on the 5 GHz band in some corner cases, but
things are more complex there since there is no n:1 or 1:n mapping
between channel numbers and frequencies due to multiple different
starting frequencies in different operating classes. This could result
in ieee80211_channel_to_frequency() returning incorrect frequency and
ieee80211_get_channel() returning incorrect channel information (or
indication of no match). In the previous implementation, this could
result in some scan results being dropped completely, e.g., for the 4.9
GHz channels. That prevented connection to such BSSs.

Fix this by using the driver-provided channel pointer if
ieee80211_get_channel() does not find matching channel data for the
channel number in the frame payload and if the scan is done with 5 MHz
or 10 MHz channel bandwidth. While doing this, also add comments
describing what the function is trying to achieve to make it easier to
understand what happens here and why.

Signed-off-by: Jouni Malinen 
---
 net/wireless/scan.c | 58 -
 1 file changed, 49 insertions(+), 9 deletions(-)

diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index d36c3eb..d0e7472 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1058,13 +1058,23 @@ cfg80211_bss_update(struct cfg80211_registered_device 
*rdev,
return NULL;
 }
 
+/*
+ * Update RX channel information based on the available frame payload
+ * information. This is mainly for the 2.4 GHz band where frames can be 
received
+ * from neighboring channels and the Beacon frames use the DSSS Parameter Set
+ * element to indicate the current (transmitting) channel, but this might also
+ * be needed on other bands if RX frequency does not match with the actual
+ * operating channel of a BSS.
+ */
 static struct ieee80211_channel *
 cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
-struct ieee80211_channel *channel)
+struct ieee80211_channel *channel,
+enum nl80211_bss_scan_width scan_width)
 {
const u8 *tmp;
u32 freq;
int channel_number = -1;
+   struct ieee80211_channel *alt_channel;
 
tmp = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ie, ielen);
if (tmp && tmp[1] == 1) {
@@ -1078,16 +1088,45 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 
*ie, size_t ielen,
}
}
 
-   if (channel_number < 0)
+   if (channel_number < 0) {
+   /* No channel information in frame payload */
return channel;
+   }
 
freq = ieee80211_channel_to_frequency(channel_number, channel->band);
-   channel = ieee80211_get_channel(wiphy, freq);
-   if (!channel)
-   return NULL;
-   if (channel->flags & IEEE80211_CHAN_DISABLED)
+   alt_channel = ieee80211_get_channel(wiphy, freq);
+   if (!alt_channel) {
+   if (channel->band == NL80211_BAND_2GHZ) {
+   /*
+* Better not allow unexpected channels when that could
+* be going beyond the 1-11 range (e.g., discovering
+* BSS on channel 12 when radio is configured for
+* channel 11.
+*/
+   return NULL;
+   }
+
+   /* No match for the payload channel number - ignore it */
+   return channel;
+   }
+
+   if (scan_width == NL80211_BSS_CHAN_WIDTH_10 ||
+   scan_width == NL80211_BSS_CHAN_WIDTH_5) {
+   /*
+* Ignore channel number in 5 and 10 MHz channels where there
+* may not be an n:1 or 1:n mapping between frequencies and
+* channel numbers.
+*/
+   return channel;
+   }
+
+   /*
+* Use the channel determined through the payload channel number
+* instead of the RX channel reported by the driver.
+*/
+   if (alt_channel->flags & IEEE80211_CHAN_DISABLED)
return NULL;
-   return channel;
+   return alt_channel;
 }
 
 /* Returned bss is reference counted and must be cleaned up appropriately. */
@@ -1112,7 +1151,8 @@ cfg80211_inform_bss_data(struct wiphy *wiphy,
(data->signal < 0 || data->signal > 100)))
return NULL;
 
-   channel = cfg80211_get_bss_channel(wiphy, ie, ielen, data->chan);
+   channel = cfg80211_get_bss_channel(wiphy, ie, ielen, data->chan,
+ 

[PATCH] cfg80211: nl80211_update_ft_ies() to validate NL80211_ATTR_IE

2018-08-29 Thread Jouni Malinen
From: Arunk Khandavalli 

nl80211_update_ft_ies() tried to validate NL80211_ATTR_IE with
is_valid_ie_attr() before dereferencing it, but that helper function
returns true in case of NULL pointer (i.e., attribute not included).
This can result to dereferencing a NULL pointer. Fix that by explicitly
checking that NL80211_ATTR_IE is included.

Fixes: 355199e02b83 ("cfg80211: Extend support for IEEE 802.11r Fast BSS 
Transition")
Signed-off-by: Arunk Khandavalli 
Signed-off-by: Jouni Malinen 
---
 net/wireless/nl80211.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 62e6679..65ec49d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -12206,6 +12206,7 @@ static int nl80211_update_ft_ies(struct sk_buff *skb, 
struct genl_info *info)
return -EOPNOTSUPP;
 
if (!info->attrs[NL80211_ATTR_MDID] ||
+   !info->attrs[NL80211_ATTR_IE] ||
!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
return -EINVAL;
 
-- 
2.7.4



[PATCHv2] cfg80211: Call reg_notifier for self managed hints conditionally

2018-04-26 Thread Jouni Malinen
From: Amar Singhal <asing...@codeaurora.org>

Currently the regulatory core does not call the regulatory callback
reg_notifier for self managed wiphys, but regulatory_hint_user() call is
independent of wiphy and is meant for all wiphys in the system. Even a
self managed wiphy may be interested in regulatory_hint_user() to know
the country code from a trusted regulatory domain change like a cellular
base station. Therefore, for the regulatory source
NL80211_REGDOM_SET_BY_USER and the user hint type
NL80211_USER_REG_HINT_CELL_BASE, call the regulatory notifier.

No current wlan driver uses the REGULATORY_WIPHY_SELF_MANAGED flag while
also registering the reg_notifier regulatory callback, therefore there
will be no impact on existing drivers without them being explicitly
modified to take advantage of this new possibility.

Signed-off-by: Amar Singhal <asing...@codeaurora.org>
Signed-off-by: Jouni Malinen <jo...@codeaurora.org>
---
 net/wireless/reg.c | 33 +
 1 file changed, 29 insertions(+), 4 deletions(-)
 
v2
- merge the two patches into a single one
- instead of modifying reg_only_self_managed_wiphys() use a new helper
  function notify_self_managed_wiphys() to clean up the implementation
- update commit message and comments to describe the desired use case
  more clearly and note that this does not change behavior with existing
  drivers without an explicit driver change

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index ecfee5f..25bce79 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2768,6 +2768,21 @@ static void reg_process_hint(struct regulatory_request 
*reg_request)
reg_free_request(reg_request);
 }
 
+static void notify_self_managed_wiphys(struct regulatory_request *request)
+{
+   struct cfg80211_registered_device *rdev;
+   struct wiphy *wiphy;
+
+   list_for_each_entry(rdev, _rdev_list, list) {
+   wiphy = >wiphy;
+   if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
+   request->initiator == NL80211_REGDOM_SET_BY_USER &&
+   request->user_reg_hint_type ==
+   NL80211_USER_REG_HINT_CELL_BASE)
+   reg_call_notifier(wiphy, request);
+   }
+}
+
 static bool reg_only_self_managed_wiphys(void)
 {
struct cfg80211_registered_device *rdev;
@@ -2819,6 +2834,7 @@ static void reg_process_pending_hints(void)
 
spin_unlock(_requests_lock);
 
+   notify_self_managed_wiphys(reg_request);
if (reg_only_self_managed_wiphys()) {
reg_free_request(reg_request);
return;
@@ -3698,17 +3714,26 @@ EXPORT_SYMBOL(regulatory_set_wiphy_regd_sync_rtnl);
 
 void wiphy_regulatory_register(struct wiphy *wiphy)
 {
-   struct regulatory_request *lr;
+   struct regulatory_request *lr = get_last_request();
 
-   /* self-managed devices ignore external hints */
-   if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
+   /* self-managed devices ignore beacon hints and country IE */
+   if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS |
   REGULATORY_COUNTRY_IE_IGNORE;
 
+   /*
+* The last request may have been received before this
+* registration call. Call the driver notifier if
+* initiator is USER and user type is CELL_BASE.
+*/
+   if (lr->initiator == NL80211_REGDOM_SET_BY_USER &&
+   lr->user_reg_hint_type == NL80211_USER_REG_HINT_CELL_BASE)
+   reg_call_notifier(wiphy, lr);
+   }
+
if (!reg_dev_ignore_cell_hint(wiphy))
reg_num_devs_support_basehint++;
 
-   lr = get_last_request();
wiphy_update_regulatory(wiphy, lr->initiator);
wiphy_all_share_dfs_chan_state(wiphy);
 }
-- 
2.7.4



Re: Wi-Fi Disconnection on Suspend for no wowlan triggers

2018-04-05 Thread Jouni Malinen
On Thu, Apr 05, 2018 at 10:07:04AM +0200, Arend van Spriel wrote:
> On 4/5/2018 9:59 AM, Johannes Berg wrote:
> >There's the "any" trigger that might be appropriate for that, or a
> >"disconnect" trigger.
> >
> >But I'm basically thinking the same as Steve - if you're never going to
> >wake up the host, there's not really much point in keeping the
> >connection, and if you only suspend briefly like e.g. on Android then
> >you probably *do* want to wake up the host for pretty much everything
> >that's going on (hence the "any" trigger).
> 
> Agree, which is why I suggested to look at wowlan triggers. If we already
> have an appropriate "any" trigger even better ;-)

The "any" trigger sounds like a reasonable thing to use, so the question
really is on what the default behavior should be if the driver has
capability of doing this and there is no explicit configuration in user
space. Currently, the default behavior seems to be to force
disconnection. Would it make sense to allow drivers to indicate that
they rather use "any" trigger by default? Or make that the default
behavior is the driver supports "any"?

For example, wpa_supplicant does not currently set any trigger
configuration unless explicitly asked to do so. This in combination with
the kernel default (disconnect) does not seem to result in desired
behavior in number of Android cases.

And if the default behavior should be changed, should that behavior
change be done in the kernel or user space (wpa_supplicant)?

-- 
Jouni MalinenPGP id EFC895FA

Re: [PATCH v4 1/3] mac80211_hwsim: add permanent mac address option for new radios

2018-03-19 Thread Jouni Malinen
On Mon, Jan 22, 2018 at 06:04:35PM +0100, Benjamin Beichler wrote:
> If simulation needs predictable permanent mac addresses of hwsim wireless
> phy, this patch add the ability to create a new radio with a user defined
> permanent mac address. Allowed mac addresses needs to be locally
> administrated mac addresses (as also the former fixed 42:* and 02:* were).
> 
> To do not break the operation with legacy software using hwsim, the new
> address is set twice. The problem here is, the netlink call backs use
> wiphy->addresses[1] as identification of a radio and not the proposed
> permanent address (wiphy->addresses[0]). This design decision is not
> documented in the kernel repo, therefore this patch simply reproduces this,
> but with the same address.

But this patch does break operation with legacy software.. Namely, some
mac80211_hwsim test cases in hostap.git. However, that seems to be due
to a strange swapping of operations here:

> diff --git a/drivers/net/wireless/mac80211_hwsim.c 
> b/drivers/net/wireless/mac80211_hwsim.c
> @@ -2571,15 +2573,25 @@ static int mac80211_hwsim_new_radio(struct genl_info 
> *info,

> - eth_zero_addr(addr);
> - addr[0] = 0x02;
> - addr[3] = idx >> 8;
> - addr[4] = idx;
> - memcpy(data->addresses[0].addr, addr, ETH_ALEN);
> - memcpy(data->addresses[1].addr, addr, ETH_ALEN);
> - data->addresses[1].addr[0] |= 0x40;
> - hw->wiphy->n_addresses = 2;
> - hw->wiphy->addresses = data->addresses;
> + if (!param->perm_addr) {
> + eth_zero_addr(addr);
> + addr[0] = 0x02;
> + addr[3] = idx >> 8;
> + addr[4] = idx;
> + memcpy(data->addresses[0].addr, addr, ETH_ALEN);
> + /* Why need here second address ? */
> + data->addresses[1].addr[0] |= 0x40;
> + memcpy(data->addresses[1].addr, addr, ETH_ALEN);
> + hw->wiphy->n_addresses = 2;
> + hw->wiphy->addresses = data->addresses;

Why did that ORing of 0x40 got moved to be before the memcpy()?
Effectively, that removes the OR operation completely since the
following memcpy() overrides the first octets of
data->addresses[1].addr. Restoring the order of those two lines seems to
fix the behavior.

-- 
Jouni MalinenPGP id EFC895FA


[PATCH 2/2] cfg80211: Modify wiphy registration semantics for self managed hints

2018-03-03 Thread Jouni Malinen
From: Amar Singhal <asing...@codeaurora.org>

Call regulatory notifier conditionally for self managed hints during
wiphy registration. Call when regulatory hint source is
NL80211_REGDOM_SET_BY_USER and sub-type is
NL80211_USER_REG_HINT_CELL_BASE. Call the notifier with last
reg-domain request. This is needed to allow trusted regulatory domain
changes to be processed by the driver.

Signed-off-by: Amar Singhal <asing...@codeaurora.org>
Signed-off-by: Kiran Kumar Lokere <klok...@codeaurora.org>
Signed-off-by: Jouni Malinen <jo...@codeaurora.org>
---
 net/wireless/reg.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 4f25a11b..48eaa8d 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -3518,15 +3518,21 @@ void wiphy_regulatory_register(struct wiphy *wiphy)
 {
struct regulatory_request *lr;
 
-   /* self-managed devices ignore external hints */
-   if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
+   lr = get_last_request();
+
+   /* self-managed devices ignore beacon hints and 11d IE */
+   if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS |
   REGULATORY_COUNTRY_IE_IGNORE;
 
+   if (lr->initiator == NL80211_REGDOM_SET_BY_USER &&
+   lr->user_reg_hint_type == NL80211_USER_REG_HINT_CELL_BASE)
+   reg_call_notifier(wiphy, lr);
+   }
+
if (!reg_dev_ignore_cell_hint(wiphy))
reg_num_devs_support_basehint++;
 
-   lr = get_last_request();
wiphy_update_regulatory(wiphy, lr->initiator);
wiphy_all_share_dfs_chan_state(wiphy);
 }
-- 
2.7.4



[PATCH 1/2] cfg80211: Enhance semantics for self-managed hints

2018-03-03 Thread Jouni Malinen
From: Amar Singhal <asing...@codeaurora.org>

Currently, kernel ignores regulatory_hint_user for a wiphy
with flag REGULATORY_WIPHY_SELF_MANAGED set. Wiphy with
REGULATORY_WIPHY_SELF_MANAGED set would ignore beacon hints and country
IE hints and updates from other wiphys in the system, but it may want
to know regulatory setting originating from user-space
(NL80211_REGDOM_SET_BY_USER) that can be trusted
(NL80211_USER_REG_HINT_CELL_BASE). Therefore, conditionally call the
regulatory notifier for a self managed wiphy.

Signed-off-by: Amar Singhal <asing...@codeaurora.org>
Signed-off-by: Kiran Kumar Lokere <klok...@codeaurora.org>
Signed-off-by: Jouni Malinen <jo...@codeaurora.org>
---
 include/net/regulatory.h |  7 ---
 net/wireless/reg.c   | 14 ++
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/include/net/regulatory.h b/include/net/regulatory.h
index f83cacc..25241c7 100644
--- a/include/net/regulatory.h
+++ b/include/net/regulatory.h
@@ -156,9 +156,10 @@ struct regulatory_request {
  * system. Conversely, a self-managed wiphy does not share its regulatory
  * hints with other devices in the system. If a system contains several
  * devices, one or more of which are self-managed, there might be
- * contradictory regulatory settings between them. Usage of flag is
- * generally discouraged. Only use it if the FW/driver is incompatible
- * with non-locally originated hints.
+ * contradictory regulatory settings between them. Regulatory information
+ * from trusted user space sources can still be passed to self-managed
+ * wiphy. Usage of this flag is generally discouraged. Only use it if the
+ * FW/driver is incompatible with non-locally originated hints.
  * This flag is incompatible with the flags: %REGULATORY_CUSTOM_REG,
  * %REGULATORY_STRICT_REG, %REGULATORY_COUNTRY_IE_FOLLOW_POWER,
  * %REGULATORY_COUNTRY_IE_IGNORE and %REGULATORY_DISABLE_BEACON_HINTS.
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 7b42f0b..4f25a11b 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2580,7 +2580,7 @@ static void reg_process_hint(struct regulatory_request 
*reg_request)
reg_free_request(reg_request);
 }
 
-static bool reg_only_self_managed_wiphys(void)
+static bool reg_only_self_managed_wiphys(struct regulatory_request 
*reg_request)
 {
struct cfg80211_registered_device *rdev;
struct wiphy *wiphy;
@@ -2590,10 +2590,16 @@ static bool reg_only_self_managed_wiphys(void)
 
list_for_each_entry(rdev, _rdev_list, list) {
wiphy = >wiphy;
-   if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
+   if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
self_managed_found = true;
-   else
+   if (reg_request->initiator ==
+   NL80211_REGDOM_SET_BY_USER &&
+   reg_request->user_reg_hint_type ==
+   NL80211_USER_REG_HINT_CELL_BASE)
+   reg_call_notifier(wiphy, reg_request);
+   } else {
return false;
+   }
}
 
/* make sure at least one self-managed wiphy exists */
@@ -2631,7 +2637,7 @@ static void reg_process_pending_hints(void)
 
spin_unlock(_requests_lock);
 
-   if (reg_only_self_managed_wiphys()) {
+   if (reg_only_self_managed_wiphys(reg_request)) {
reg_free_request(reg_request);
return;
}
-- 
2.7.4



Re: [PATCH v2] ieee80211: Increase the PMK maximum length to 64 bytes

2018-02-10 Thread Jouni Malinen
On Wed, Feb 07, 2018 at 09:21:34PM +0100, Johannes Berg wrote:
> On Wed, 2018-02-07 at 20:35 +0100, Arend van Spriel wrote:
> > On 2/7/2018 5:20 PM, Srinivas Dasari wrote:
> > > This is needed to cover the case of DPP with the NIST P-521 and
> > > brainpoolP512r1 curves which derive a PMK that is longer than the
> > > previously used limit.
> > 
> > So how are driver supposed to deal with this longer PMK. Maybe if you 
> > could elaborate on what DPP stands for in this context it would become 
> > more clear. 
> 
> device provisioning protocol, I guess? But longer curves and longer PMK
> is kinda obvious, whichever way that ends up getting used.

Yes, that's what DPP stands for here. With those two curves, the PMK
will be 64 octets.

> > Can we stick with PMK_MAX_LEN or does it need to be more 
> > fine-grained per use-case? If existing drivers only support 48 bytes PMK 
> > and trust nl80211 code to check that limit it may screw them up. Not?
> 
> Yeah I'm concerned about this too - and regardless of that issue, we
> probably need those drivers that do support it to advertise support for
> the new curves, and then allow the longer PMK length only for those that do?

Please note that some drivers may not support even the current
PMK_MAX_LEN (48) value. In fact, most of the cfg80211 cases using
NL80211_ATTR_PMK are separately enforcing shorter lengths (32 or that
48), so this change in PMK_MAX_LEN definition does not actually have any
impact for many of the existing cases. The only place where it does make
a difference is NL80211_CMD_SET_PMKSA and NL80211_ATTR_PMK was added for
that command with FILS authentication in mind in the first place (and
that would not get a 64 octet value from wpa_supplicant at least).

It turns out that there are no known use of PMK with DPP authentication
at the moment in any driver, so for now, I think I'll just make
wpa_supplicant skip addition of the NL80211_ATTR_PMK if the PMK is
longer than 48 octets. This should take care of the most immediate need,
but it would be good to prepare for the possibility of there being a
driver/firmware that would like to offload roaming and 4-way handshake
with DPP APs and do that using this PMK value from DPP network
introduction rather than offloading network introduction. For that to
work, PMK_MAX_LEN needs to be increased.

So DPP works just fine with most drivers even with the 64 octet PMK (as
long as that wpa_supplicant change goes in) when there is no requirement
of offloading 4-way handshake.

As far as driver support for various PMK lengths is concerned, how
should that be advertised? The limits can be different for each
particular use of NL80211_ATTR_PMK (NL80211_CMD_CONNECT,
NL80211_CMD_ASSOCIATE, NL80211_START_AP, NL80211_CMD_SET_PMKSA (for
FILS), NL80211_CMD_SET_PMKSA (for DPP), NL80211_CMD_SET_PMKSA (for
something else), NL80211_CMD_SET_PMK).

-- 
Jouni MalinenPGP id EFC895FA


[PATCH] nl80211: Fix external_auth check for offloaded authentication

2018-02-02 Thread Jouni Malinen
From: Srinivas Dasari <dasa...@codeaurora.org>

Unfortunately removal of the ext_feature flag in the last revision of
the patch ended up negating the comparison and prevented the command
from being processed (either nl80211_external_auth() or
rdev_external_auth() returns -EOPNOTSUPP). Fix this by adding back the
lost '!'.

Fixes: 40cbfa90218b ("cfg80211/nl80211: Optional authentication offload to 
userspace")
Signed-off-by: Srinivas Dasari <dasa...@codeaurora.org>
Signed-off-by: Jouni Malinen <jo...@codeaurora.org>
---
 net/wireless/nl80211.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index cc6ec5b..3b6dbc1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -12486,7 +12486,7 @@ static int nl80211_external_auth(struct sk_buff *skb, 
struct genl_info *info)
struct net_device *dev = info->user_ptr[1];
struct cfg80211_external_auth_params params;
 
-   if (rdev->ops->external_auth)
+   if (!rdev->ops->external_auth)
return -EOPNOTSUPP;
 
if (!info->attrs[NL80211_ATTR_SSID])
-- 
2.7.4



[PATCH v3 2/3] cfg80211/nl80211: Optional authentication offload to userspace

2018-01-25 Thread Jouni Malinen
From: Srinivas Dasari <dasa...@qti.qualcomm.com>

This interface allows the host driver to offload the authentication to
user space. This is exclusively defined for host drivers that do not
define separate commands for authentication and association, but rely on
userspace SME (e.g., in wpa_supplicant for the ~WPA_DRIVER_FLAGS_SME
case) for the authentication to happen. This can be used to implement
SAE without full implementation in the kernel/firmware while still being
able to use NL80211_CMD_CONNECT with driver-based BSS selection.

Host driver sends NL80211_CMD_EXTERNAL_AUTH event to start/abort
authentication to the port on which connect is triggered and status
of authentication is further indicated by user space to host
driver through the same command response interface.

User space entities advertise this capability through the
NL80211_ATTR_EXTERNAL_AUTH_SUPP flag in the NL80211_CMD_CONNECT request.
Host drivers shall look at this capability to offload the authentication.

Signed-off-by: Srinivas Dasari <dasa...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 54 +--
 include/uapi/linux/nl80211.h | 48 
 net/wireless/nl80211.c   | 88 
 net/wireless/rdev-ops.h  | 15 
 net/wireless/trace.h | 23 
 5 files changed, 225 insertions(+), 3 deletions(-)

v3:
- rename CONNECT_REQ_EXTERNAL_AUTH_SUPP to
  CONNECT_REQ_EXTERNAL_AUTH_SUPPORT
- rename NL80211_ATTR_EXTERNAL_AUTH_SUPP to
  NL80211_ATTR_EXTERNAL_AUTH_SUPPORT
- remove NL80211_EXT_FEATURE_EXTERNAL_AUTH
- unicast netlink events to the port used for the connect command

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ab30a22..1aebcf1 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1903,11 +1903,16 @@ struct cfg80211_auth_request {
  * @ASSOC_REQ_DISABLE_HT:  Disable HT (802.11n)
  * @ASSOC_REQ_DISABLE_VHT:  Disable VHT
  * @ASSOC_REQ_USE_RRM: Declare RRM capability in this association
+ * @CONNECT_REQ_EXTERNAL_AUTH_SUPPORT: User space indicates external
+ *  authentication capability. Drivers can offload authentication to
+ *  userspace if this flag is set. Only applicable for cfg80211_connect()
+ *  request (connect callback).
  */
 enum cfg80211_assoc_req_flags {
-   ASSOC_REQ_DISABLE_HT= BIT(0),
-   ASSOC_REQ_DISABLE_VHT   = BIT(1),
-   ASSOC_REQ_USE_RRM   = BIT(2),
+   ASSOC_REQ_DISABLE_HT= BIT(0),
+   ASSOC_REQ_DISABLE_VHT   = BIT(1),
+   ASSOC_REQ_USE_RRM   = BIT(2),
+   CONNECT_REQ_EXTERNAL_AUTH_SUPPORT   = BIT(3),
 };
 
 /**
@@ -2599,6 +2604,33 @@ struct cfg80211_pmk_conf {
 };
 
 /**
+ * struct cfg80211_external_auth_params - Trigger External authentication.
+ *
+ * Commonly used across the external auth request and event interfaces.
+ *
+ * @action: action type / trigger for external authentication. Only significant
+ * for the authentication request event interface (driver to user space).
+ * @bssid: BSSID of the peer with which the authentication has
+ * to happen. Used by both the authentication request event and
+ * authentication response command interface.
+ * @ssid: SSID of the AP.  Used by both the authentication request event and
+ * authentication response command interface.
+ * @key_mgmt_suite: AKM suite of the respective authentication. Used by the
+ * authentication request event interface.
+ * @status: status code, %WLAN_STATUS_SUCCESS for successful authentication,
+ * use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
+ * the real status code for failures. Used only for the authentication
+ * response command interface (user space to driver).
+ */
+struct cfg80211_external_auth_params {
+   enum nl80211_external_auth_action action;
+   u8 bssid[ETH_ALEN] __aligned(2);
+   struct cfg80211_ssid ssid;
+   unsigned int key_mgmt_suite;
+   u16 status;
+};
+
+/**
  * struct cfg80211_ops - backend description for wireless configuration
  *
  * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2921,6 +2953,9 @@ struct cfg80211_pmk_conf {
  * (invoked with the wireless_dev mutex held)
  * @del_pmk: delete the previously configured PMK for the given authenticator.
  * (invoked with the wireless_dev mutex held)
+ *
+ * @external_auth: indicates result of offloaded authentication processing from
+ * user space
  */
 struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3214,6 +3249,8 @@ struct cfg80211_ops {
   const struct cfg80211_pmk_conf *conf);
int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
   const u8 *aa);
+   int (*external_auth)(struct wi

[PATCH v3 1/3] nl80211: Introduce scan flags to emphasize requested scan behavior

2018-01-25 Thread Jouni Malinen
From: Sunil Dutt <usd...@qti.qualcomm.com>

This commit defines new scan flags (LOW_SPAN, LOW_POWER, HIGH_LATENCY)
to emphasize the requested scan behavior for the driver. These flags
are optional and are mutually exclusive. The implementation of the
respective functionality can be driver/hardware specific.

These flags can be used to control the compromise between how long
a scan takes, how much power it uses, and high accurate/complete
the scan is in finding the BSSs.

Signed-off-by: Sunil Dutt <usd...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/uapi/linux/nl80211.h | 28 +++-
 net/wireless/nl80211.c   | 13 +++--
 2 files changed, 38 insertions(+), 3 deletions(-)

v3:
- rebased (moved this scan related change to the top of the series)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index c587a61..6f60503 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4945,6 +4945,9 @@ enum nl80211_feature_flags {
  * probe request tx deferral and suppression
  * @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL
  * value in %NL80211_ATTR_USE_MFP.
+ * @NL80211_EXT_FEATURE_LOW_SPAN_SCAN: Driver supports low span scan.
+ * @NL80211_EXT_FEATURE_LOW_POWER_SCAN: Driver supports low power scan.
+ * @NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN: Driver supports high accuracy scan.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4972,6 +4975,9 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE,
NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
NL80211_EXT_FEATURE_MFP_OPTIONAL,
+   NL80211_EXT_FEATURE_LOW_SPAN_SCAN,
+   NL80211_EXT_FEATURE_LOW_POWER_SCAN,
+   NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
 
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
@@ -5032,6 +5038,10 @@ enum nl80211_timeout_reason {
  * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN
  * requests.
  *
+ * NL80211_SCAN_FLAG_LOW_SPAN, NL80211_SCAN_FLAG_LOW_POWER, and
+ * NL80211_SCAN_FLAG_HIGH_ACCURACY flags are exclusive of each other, i.e., 
only
+ * one of them can be used in the request.
+ *
  * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority
  * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning
  * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured
@@ -5059,7 +5069,20 @@ enum nl80211_timeout_reason {
  * and suppression (if it has received a broadcast Probe Response frame,
  * Beacon frame or FILS Discovery frame from an AP that the STA considers
  * a suitable candidate for (re-)association - suitable in terms of
- * SSID and/or RSSI
+ * SSID and/or RSSI.
+ * @NL80211_SCAN_FLAG_LOW_SPAN: Span corresponds to the total time taken to
+ * accomplish the scan. Thus, this flag intends the driver to perform the
+ * scan request with lesser span/duration. It is specific to the driver
+ * implementations on how this is accomplished. Scan accuracy may get
+ * impacted with this flag.
+ * @NL80211_SCAN_FLAG_LOW_POWER: This flag intends the scan attempts to consume
+ * optimal possible power. Drivers can resort to their specific means to
+ * optimize the power. Scan accuracy may get impacted with this flag.
+ * @NL80211_SCAN_FLAG_HIGH_ACCURACY: Accuracy here intends to the extent of 
scan
+ * results obtained. Thus HIGH_ACCURACY scan flag aims to get maximum
+ * possible scan results. This flag hints the driver to use the best
+ * possible scan configuration to improve the accuracy in scanning.
+ * Latency and power use may get impacted with this flag.
  */
 enum nl80211_scan_flags {
NL80211_SCAN_FLAG_LOW_PRIORITY  = 1<<0,
@@ -5070,6 +5093,9 @@ enum nl80211_scan_flags {
NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP   = 1<<5,
NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE= 1<<6,
NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION= 1<<7,
+   NL80211_SCAN_FLAG_LOW_SPAN  = 1<<8,
+   NL80211_SCAN_FLAG_LOW_POWER = 1<<9,
+   NL80211_SCAN_FLAG_HIGH_ACCURACY = 1<<10,
 };
 
 /**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c084dd2..a83e758 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6712,8 +6712,17 @@ nl80211_check_scan_flags(struct wiphy *wiphy, struct 
wireless_dev *wdev,
 
*flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
 
-   if ((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
-   !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN))
+   if (((*flags & NL80211_SCAN_FLAG_

[PATCH v3 3/3] nl80211: Allow SAE Authentication for NL80211_CMD_CONNECT

2018-01-25 Thread Jouni Malinen
From: Srinivas Dasari <dasa...@qti.qualcomm.com>

This commit allows SAE Authentication for NL80211_CMD_CONNECT
interface, provided host driver advertises the support.

Host drivers offload the SAE authentication to user space
through NL80211_CMD_EXTERNAL_AUTH interface and thus expect
the user space to advertise support to handle offload through
NL80211_ATTR_EXTERNAL_AUTH_SUPPORT in NL80211_CMD_CONNECT
request. Such drivers should reject the connect request on no
offload support from user space.

Signed-off-by: Srinivas Dasari <dasa...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/wireless/nl80211.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

v3:
- clarified commit message to cover NL80211_ATTR_EXTERNAL_AUTH_SUPPORT
  in NL80211_CMD_CONNECT and potential need to reject the command with
  missing support

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8b10598..7478a6d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3918,9 +3918,10 @@ static bool nl80211_valid_auth_type(struct 
cfg80211_registered_device *rdev,
return false;
return true;
case NL80211_CMD_CONNECT:
-   /* SAE not supported yet */
-   if (auth_type == NL80211_AUTHTYPE_SAE)
+   if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
+   auth_type == NL80211_AUTHTYPE_SAE)
return false;
+
/* FILS with SK PFS or PK not supported yet */
if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
auth_type == NL80211_AUTHTYPE_FILS_PK)
-- 
2.7.4



[PATCH v2 3/3] nl80211: Introduce scan flags to emphasize requested scan behavior

2017-12-22 Thread Jouni Malinen
From: Sunil Dutt <usd...@qti.qualcomm.com>

This commit defines new scan flags (LOW_SPAN, LOW_POWER, HIGH_LATENCY)
to emphasize the requested scan behavior for the driver. These flags are
optional and are mutually exclusive. The implementation of the
respective functionality can be driver/hardware specific.

These flags can be used to control the compromise between how long a
scan takes, how much power it uses, and high accurate/complete the scan
is in finding the BSSs.

Signed-off-by: Sunil Dutt <usd...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/uapi/linux/nl80211.h | 28 +++-
 net/wireless/nl80211.c   | 13 +++--
 2 files changed, 38 insertions(+), 3 deletions(-)

v2:
- added driver capability flags to indicate which of the options are
  supported
- added to this patch series due to a new dependency in one of the
  header files

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 083c6c1..56e6bc0 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4979,6 +4979,9 @@ enum nl80211_feature_flags {
  * @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL
  * value in %NL80211_ATTR_USE_MFP.
  * @NL80211_EXT_FEATURE_EXTERNAL_AUTH: Driver supports external authentication
+ * @NL80211_EXT_FEATURE_LOW_SPAN_SCAN: Driver supports low span scan.
+ * @NL80211_EXT_FEATURE_LOW_POWER_SCAN: Driver supports low power scan.
+ * @NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN: Driver supports high accuracy scan.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -5007,6 +5010,9 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
NL80211_EXT_FEATURE_MFP_OPTIONAL,
NL80211_EXT_FEATURE_EXTERNAL_AUTH,
+   NL80211_EXT_FEATURE_LOW_SPAN_SCAN,
+   NL80211_EXT_FEATURE_LOW_POWER_SCAN,
+   NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
 
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
@@ -5067,6 +5073,10 @@ enum nl80211_timeout_reason {
  * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN
  * requests.
  *
+ * NL80211_SCAN_FLAG_LOW_SPAN, NL80211_SCAN_FLAG_LOW_POWER, and
+ * NL80211_SCAN_FLAG_HIGH_ACCURACY flags are exclusive of each other, i.e., 
only
+ * one of them can be used in the request.
+ *
  * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority
  * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning
  * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured
@@ -5094,7 +5104,20 @@ enum nl80211_timeout_reason {
  * and suppression (if it has received a broadcast Probe Response frame,
  * Beacon frame or FILS Discovery frame from an AP that the STA considers
  * a suitable candidate for (re-)association - suitable in terms of
- * SSID and/or RSSI
+ * SSID and/or RSSI.
+ * @NL80211_SCAN_FLAG_LOW_SPAN: Span corresponds to the total time taken to
+ * accomplish the scan. Thus, this flag intends the driver to perform the
+ * scan request with lesser span/duration. It is specific to the driver
+ * implementations on how this is accomplished. Scan accuracy may get
+ * impacted with this flag.
+ * @NL80211_SCAN_FLAG_LOW_POWER: This flag intends the scan attempts to consume
+ * optimal possible power. Drivers can resort to their specific means to
+ * optimize the power. Scan accuracy may get impacted with this flag.
+ * @NL80211_SCAN_FLAG_HIGH_ACCURACY: Accuracy here intends to the extent of 
scan
+ * results obtained. Thus HIGH_ACCURACY scan flag aims to get maximum
+ * possible scan results. This flag hints the driver to use the best
+ * possible scan configuration to improve the accuracy in scanning.
+ * Latency and power use may get impacted with this flag.
  */
 enum nl80211_scan_flags {
NL80211_SCAN_FLAG_LOW_PRIORITY  = 1<<0,
@@ -5105,6 +5128,9 @@ enum nl80211_scan_flags {
NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP   = 1<<5,
NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE= 1<<6,
NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION= 1<<7,
+   NL80211_SCAN_FLAG_LOW_SPAN  = 1<<8,
+   NL80211_SCAN_FLAG_LOW_POWER = 1<<9,
+   NL80211_SCAN_FLAG_HIGH_ACCURACY = 1<<10,
 };
 
 /**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ea36514..8a53e6e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6712,8 +6712,17 @@ nl80211_check_scan_flags(struct wiphy *wiphy, struct 
wireless_dev *wdev,
 
*flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
 
-   if ((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
-   !(wi

[PATCH v2 2/3] nl80211: Allow SAE Authentication for NL80211_CMD_CONNECT

2017-12-22 Thread Jouni Malinen
From: Srinivas Dasari <dasa...@qti.qualcomm.com>

This commit allows SAE Authentication for NL80211_CMD_CONNECT
interface, provided this is supported by the host driver.

Signed-off-by: Srinivas Dasari <dasa...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/wireless/nl80211.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

v2:
- no changes; just rebased and included in the full patch series

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 41a0373..ea36514 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3917,7 +3917,8 @@ static bool nl80211_valid_auth_type(struct 
cfg80211_registered_device *rdev,
return true;
case NL80211_CMD_CONNECT:
/* SAE not supported yet */
-   if (auth_type == NL80211_AUTHTYPE_SAE)
+   if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
+   auth_type == NL80211_AUTHTYPE_SAE)
return false;
/* FILS with SK PFS or PK not supported yet */
if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
-- 
2.7.4



[PATCH v2 1/3] cfg80211/nl80211: Optional authentication offload to userspace

2017-12-22 Thread Jouni Malinen
From: Srinivas Dasari <dasa...@qti.qualcomm.com>

This interface allows the host driver to offload the authentication to
user space. This is exclusively defined for host drivers that do not
define separate commands for authentication and association, but rely on
userspace SME (e.g., in wpa_supplicant for the ~WPA_DRIVER_FLAGS_SME
case) for the authentication to happen. This can be used to implement
SAE without full implementation in the kernel/firmware while still being
able to use NL80211_CMD_CONNECT with driver-based BSS selection.

The host driver sends the NL80211_CMD_EXTERNAL_AUTH event to start/abort
the authentication to userspace and status of authentication is further
indicated by user space to host driver through the same command
interface. Such drivers advertise the capability through
NL80211_EXT_FEATURE_EXTERNAL_AUTH. User space entities advertise this
capability through the NL80211_ATTR_EXTERNAL_AUTH_SUPP flag in the
NL80211_CMD_CONNECT request.

Signed-off-by: Srinivas Dasari <dasa...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 44 
 include/uapi/linux/nl80211.h | 46 +
 net/wireless/nl80211.c   | 98 
 net/wireless/rdev-ops.h  | 15 +++
 net/wireless/trace.h | 22 ++
 5 files changed, 225 insertions(+)

v2:
- add NL80211_ATTR_EXTERNAL_AUTH_SUPPORTED flag for user space to
  indicate support for offload capability in the NL80211_CMD_CONNECT
  command

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 3a4a1a9..582a7e7 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1903,11 +1903,15 @@ struct cfg80211_auth_request {
  * @ASSOC_REQ_DISABLE_HT:  Disable HT (802.11n)
  * @ASSOC_REQ_DISABLE_VHT:  Disable VHT
  * @ASSOC_REQ_USE_RRM: Declare RRM capability in this association
+ * @CONNECT_REQ_EXTERNAL_AUTH_SUPP: User space indicates external 
authentication
+ * capability. Drivers can offload authentication to userspace if this flag is
+ * set. Only applicable for cfg80211_connect() request (connect callback).
  */
 enum cfg80211_assoc_req_flags {
ASSOC_REQ_DISABLE_HT= BIT(0),
ASSOC_REQ_DISABLE_VHT   = BIT(1),
ASSOC_REQ_USE_RRM   = BIT(2),
+   CONNECT_REQ_EXTERNAL_AUTH_SUPP  = BIT(3),
 };
 
 /**
@@ -2599,6 +2603,30 @@ struct cfg80211_pmk_conf {
 };
 
 /**
+ * struct cfg80211_external_auth_params - External authentication
+ * trigger parameters. Commonly used across the external auth request and
+ * event interfaces.
+ * @action: action type / trigger for external authentication. Only significant
+ * for the event interface (from driver to user space).
+ * @bssid: BSSID of the peer with which the authentication has
+ *  to happen. Used by both the request and event interface.
+ * @ssid: SSID of the AP. Used by both the request and event interface.
+ * @key_mgmt_suite: AKM suite of the respective authentication. Optional for
+ * the request interface.
+ * @status: status code, %WLAN_STATUS_SUCCESS for successful authentication,
+ * use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
+ * the real status code for failures. Used only for the request
+ * interface from user space to the driver.
+ */
+struct cfg80211_external_auth_params {
+   enum nl80211_external_auth_action action;
+   u8 bssid[ETH_ALEN] __aligned(2);
+   struct cfg80211_ssid ssid;
+   unsigned int key_mgmt_suite;
+   u16 status;
+};
+
+/**
  * struct cfg80211_ops - backend description for wireless configuration
  *
  * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2921,6 +2949,9 @@ struct cfg80211_pmk_conf {
  * (invoked with the wireless_dev mutex held)
  * @del_pmk: delete the previously configured PMK for the given authenticator.
  * (invoked with the wireless_dev mutex held)
+ *
+ * @external_auth: indicates result of offloaded authentication processing from
+ * user space
  */
 struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3214,6 +3245,8 @@ struct cfg80211_ops {
   const struct cfg80211_pmk_conf *conf);
int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
   const u8 *aa);
+   int (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
+struct cfg80211_external_auth_params *params);
 };
 
 /*
@@ -6201,6 +6234,17 @@ void cfg80211_nan_func_terminated(struct wireless_dev 
*wdev,
 /* ethtool helper */
 void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo 
*info);
 
+/**
+ * cfg80211_external_auth_request - userspace request for authentication
+ * @netdev: network device
+ * @params: External authentication parameters
+ * @gfp: allocation flags
+ * Returns: 0 on suc

[PATCH] nl80211: Introduce scan flags to emphasize requested scan behavior

2017-12-13 Thread Jouni Malinen
From: Sunil Dutt <usd...@qti.qualcomm.com>

This commit defines new scan flags (LOW_SPAN, LOW_POWER, HIGH_LATENCY)
to emphasize the requested scan behavior for the driver. These flags are
optional and are mutually exclusive. Driver shall resort to default
behavior if a respective flag is not supported. The implementation of
the respective functionality can be driver/hardware specific.

These flags can be used to control the compromise between how long a
scan takes, how much power it uses, and high accurate/complete the scan
is in finding the BSSs.

Signed-off-by: Sunil Dutt <usd...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/uapi/linux/nl80211.h | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 6dd6939..68fdb95 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -5059,6 +5059,11 @@ enum nl80211_timeout_reason {
  * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN
  * requests.
  *
+ * NL80211_SCAN_FLAG_LOW_SPAN, NL80211_SCAN_FLAG_LOW_POWER, and
+ * NL80211_SCAN_FLAG_HIGH_ACCURACY flags are exclusive of each other, i.e., 
only
+ * one of them can be used in the request. If the driver does not support the
+ * requested behavior, default scan behavior will be used instead.
+ *
  * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority
  * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning
  * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured
@@ -5086,7 +5091,20 @@ enum nl80211_timeout_reason {
  * and suppression (if it has received a broadcast Probe Response frame,
  * Beacon frame or FILS Discovery frame from an AP that the STA considers
  * a suitable candidate for (re-)association - suitable in terms of
- * SSID and/or RSSI
+ * SSID and/or RSSI.
+ * @NL80211_SCAN_FLAG_LOW_SPAN: Span corresponds to the total time taken to
+ * accomplish the scan. Thus, this flag intends the driver to perform the
+ * scan request with lesser span/duration. It is specific to the driver
+ * implementations on how this is accomplished. Scan accuracy may get
+ * impacted with this flag. This flag cannot be used with
+ * @NL80211_SCAN_FLAG_LOW_POWER: This flag intends the scan attempts to consume
+ * optimal possible power. Drivers can resort to their specific means to
+ * optimize the power. Scan accuracy may get impacted with this flag.
+ * @NL80211_SCAN_FLAG_HIGH_ACCURACY: Accuracy here intends to the extent of 
scan
+ * results obtained. Thus HIGH_ACCURACY scan flag aims to get maximum
+ * possible scan results. This flag hints the driver to use the best
+ * possible scan configuration to improve the accuracy in scanning.
+ * Latency and power use may get impacted with this flag.
  */
 enum nl80211_scan_flags {
NL80211_SCAN_FLAG_LOW_PRIORITY  = 1<<0,
@@ -5097,6 +5115,9 @@ enum nl80211_scan_flags {
NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP   = 1<<5,
NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE= 1<<6,
NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION= 1<<7,
+   NL80211_SCAN_FLAG_LOW_SPAN  = 1<<8,
+   NL80211_SCAN_FLAG_LOW_POWER = 1<<9,
+   NL80211_SCAN_FLAG_HIGH_ACCURACY = 1<<10,
 };
 
 /**
-- 
2.7.4



[PATCH] cfg80211: Scan results to also report the per chain signal strength

2017-12-13 Thread Jouni Malinen
From: Sunil Dutt <usd...@qti.qualcomm.com>

This commit enhances the scan results to report the per chain signal
strength based on the latest BSS update. This provides similar
information to what is already available through STA information.

Signed-off-by: Sunil Dutt <usd...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 8 
 include/uapi/linux/nl80211.h | 3 +++
 net/wireless/nl80211.c   | 5 +
 net/wireless/scan.c  | 5 +
 4 files changed, 21 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fa1f575..c2b26a5 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1773,6 +1773,8 @@ enum cfg80211_signal_type {
  * by %parent_bssid.
  * @parent_bssid: the BSS according to which %parent_tsf is set. This is set to
  * the BSS that requested the scan in which the beacon/probe was received.
+ * @chains: bitmask for filled values in @chain_signal.
+ * @chain_signal: per-chain signal strength of last received BSS in dBm.
  */
 struct cfg80211_inform_bss {
struct ieee80211_channel *chan;
@@ -1781,6 +1783,8 @@ struct cfg80211_inform_bss {
u64 boottime_ns;
u64 parent_tsf;
u8 parent_bssid[ETH_ALEN] __aligned(2);
+   u8 chains;
+   s8 chain_signal[IEEE80211_MAX_CHAINS];
 };
 
 /**
@@ -1824,6 +1828,8 @@ struct cfg80211_bss_ies {
  * that holds the beacon data. @beacon_ies is still valid, of course, and
  * points to the same data as hidden_beacon_bss->beacon_ies in that case.
  * @signal: signal strength value (type depends on the wiphy's signal_type)
+ * @chains: bitmask for filled values in @chain_signal.
+ * @chain_signal: per-chain signal strength of last received BSS in dBm.
  * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
  */
 struct cfg80211_bss {
@@ -1842,6 +1848,8 @@ struct cfg80211_bss {
u16 capability;
 
u8 bssid[ETH_ALEN];
+   u8 chains;
+   s8 chain_signal[IEEE80211_MAX_CHAINS];
 
u8 priv[0] __aligned(sizeof(void *));
 };
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index e86edf0..6dd6939 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3888,6 +3888,8 @@ enum nl80211_bss_scan_width {
  * @NL80211_BSS_PARENT_BSSID. (u64).
  * @NL80211_BSS_PARENT_BSSID: the BSS according to which 
@NL80211_BSS_PARENT_TSF
  * is set.
+ * @NL80211_BSS_CHAIN_SIGNAL: per-chain signal strength of last BSS update.
+ * Contains a nested array of signal strength attributes (u8, dBm).
  * @__NL80211_BSS_AFTER_LAST: internal
  * @NL80211_BSS_MAX: highest BSS attribute
  */
@@ -3911,6 +3913,7 @@ enum nl80211_bss {
NL80211_BSS_PAD,
NL80211_BSS_PARENT_TSF,
NL80211_BSS_PARENT_BSSID,
+   NL80211_BSS_CHAIN_SIGNAL,
 
/* keep last */
__NL80211_BSS_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e920c3a..d9953bd 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7840,6 +7840,11 @@ static int nl80211_send_bss(struct sk_buff *msg, struct 
netlink_callback *cb,
  intbss->ts_boottime, NL80211_BSS_PAD))
goto nla_put_failure;
 
+   if (!nl80211_put_signal(msg, intbss->pub.chains,
+   intbss->pub.chain_signal,
+   NL80211_BSS_CHAIN_SIGNAL))
+   goto nla_put_failure;
+
switch (rdev->wiphy.signal_type) {
case CFG80211_SIGNAL_TYPE_MBM:
if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index f6c5fe48..d36c3eb 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -981,6 +981,9 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
found->ts = tmp->ts;
found->ts_boottime = tmp->ts_boottime;
found->parent_tsf = tmp->parent_tsf;
+   found->pub.chains = tmp->pub.chains;
+   memcpy(found->pub.chain_signal, tmp->pub.chain_signal,
+  IEEE80211_MAX_CHAINS);
ether_addr_copy(found->parent_bssid, tmp->parent_bssid);
} else {
struct cfg80211_internal_bss *new;
@@ -1233,6 +1236,8 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
tmp.ts_boottime = data->boottime_ns;
tmp.parent_tsf = data->parent_tsf;
+   tmp.pub.chains = data->chains;
+   memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS);
ether_addr_copy(tmp.parent_bssid, data->parent_bssid);
 
signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
-- 
2.7.4



[PATCH 2/2] nl80211: Allow SAE Authentication for NL80211_CMD_CONNECT

2017-12-13 Thread Jouni Malinen
From: Srinivas Dasari <dasa...@qti.qualcomm.com>

This commit allows SAE Authentication for NL80211_CMD_CONNECT
interface, provided this is supported by the host driver.

Signed-off-by: Srinivas Dasari <dasa...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/wireless/nl80211.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 72ec615..e920c3a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3916,7 +3916,8 @@ static bool nl80211_valid_auth_type(struct 
cfg80211_registered_device *rdev,
return true;
case NL80211_CMD_CONNECT:
/* SAE not supported yet */
-   if (auth_type == NL80211_AUTHTYPE_SAE)
+   if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
+   auth_type == NL80211_AUTHTYPE_SAE)
return false;
/* FILS with SK PFS or PK not supported yet */
if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
-- 
2.7.4



[PATCH 1/2] cfg80211/nl80211: Optional authentication offload to userspace

2017-12-13 Thread Jouni Malinen
From: Srinivas Dasari <dasa...@qti.qualcomm.com>

This interface allows the host driver to offload the authentication to
user space. This is exclusively defined for host drivers that do not
define separate commands for authentication and association, but rely on
userspace SME (e.g., in wpa_supplicant for the ~WPA_DRIVER_FLAGS_SME
case) for the authentication to happen. This can be used to implement
SAE without full implementation in the kernel/firmware while still being
able to use NL80211_CMD_CONNECT with driver-based BSS selection.

The host driver sends the NL80211_CMD_EXTERNAL_AUTH event to start/abort
the authentication to userspace and status of authentication is further
indicated by user space to host driver through the same command
interface. Such drivers advertise the capability through
NL80211_EXT_FEATURE_EXTERNAL_AUTH.

Signed-off-by: Srinivas Dasari <dasa...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 40 
 include/uapi/linux/nl80211.h | 39 
 net/wireless/nl80211.c   | 87 
 net/wireless/rdev-ops.h  | 15 
 net/wireless/trace.h | 25 +
 5 files changed, 206 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d7f8e7b..fa1f575 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2591,6 +2591,30 @@ struct cfg80211_pmk_conf {
 };
 
 /**
+ * struct cfg80211_external_auth_params - External authentication
+ * trigger parameters. Commonly used across the external auth request and
+ * event interfaces.
+ * @action: action type / trigger for external authentication. Only significant
+ * for the event interface (from driver to user space).
+ * @bssid: BSSID of the peer with which the authentication has
+ *  to happen. Used by both the request and event interface.
+ * @ssid: SSID of the AP. Used by both the request and event interface.
+ * @key_mgmt_suite: AKM suite of the respective authentication. Optional for
+ * the request interface.
+ * @status: status code, %WLAN_STATUS_SUCCESS for successful authentication,
+ * use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
+ * the real status code for failures. Used only for the request
+ * interface from user space to the driver.
+ */
+struct cfg80211_external_auth_params {
+   enum nl80211_external_auth_action action;
+   u8 bssid[ETH_ALEN] __aligned(2);
+   struct cfg80211_ssid ssid;
+   unsigned int key_mgmt_suite;
+   u16 status;
+};
+
+/**
  * struct cfg80211_ops - backend description for wireless configuration
  *
  * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2913,6 +2937,9 @@ struct cfg80211_pmk_conf {
  * (invoked with the wireless_dev mutex held)
  * @del_pmk: delete the previously configured PMK for the given authenticator.
  * (invoked with the wireless_dev mutex held)
+ *
+ * @external_auth: indicates result of offloaded authentication processing from
+ * user space
  */
 struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3206,6 +3233,8 @@ struct cfg80211_ops {
   const struct cfg80211_pmk_conf *conf);
int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
   const u8 *aa);
+   int (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
+struct cfg80211_external_auth_params *params);
 };
 
 /*
@@ -6193,6 +6222,17 @@ void cfg80211_nan_func_terminated(struct wireless_dev 
*wdev,
 /* ethtool helper */
 void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo 
*info);
 
+/**
+ * cfg80211_external_auth_request - userspace request for authentication
+ * @netdev: network device
+ * @params: External authentication parameters
+ * @gfp: allocation flags
+ * Returns: 0 on success, < 0 on error
+ */
+int cfg80211_external_auth_request(struct net_device *netdev,
+  struct cfg80211_external_auth_params *params,
+  gfp_t gfp);
+
 /* Logging, debugging and troubleshooting/diagnostic helpers. */
 
 /* wiphy_printk helpers, similar to dev_printk */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f882fe1..e86edf0 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -992,6 +992,23 @@
  *
  * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
  *
+ * @NL80211_CMD_EXTERNAL_AUTH: This command/event interface is exclusively
+ * defined for host drivers that do not define separate commands for
+ * authentication and association, bute rely on user space SME (e.g., in
+ * wpa_supplicant for the ~WPA_DRIVER_FLAGS_SME case) for the
+ * authentication to happen.
+ *
+ * User space uses the

[RFC v2] cfg80211: Implement Multiple BSSID capability in scanning

2017-11-28 Thread Jouni Malinen
From: Peng Xu <p...@qti.qualcomm.com>

This extends cfg80211 BSS table processing to be able to parse Multiple
BSSID element from Beacon and Probe Response frames and to update the
BSS profiles in internal database for non-transmitted BSSs.

Signed-off-by: Peng Xu <p...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/wireless/core.h |   1 +
 net/wireless/scan.c | 450 ++--
 2 files changed, 437 insertions(+), 14 deletions(-)

v2:
- address number of comments from Johannes on the first version
- fix number of issues that came up during additional testing
- some additional cleanup on the implementation

diff --git a/net/wireless/core.h b/net/wireless/core.h
index 35165f4..3b4a566 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -139,6 +139,7 @@ extern int cfg80211_rdev_list_generation;
 struct cfg80211_internal_bss {
struct list_head list;
struct list_head hidden_list;
+   struct list_head nontrans_list;
struct rb_node rbn;
u64 ts_boottime;
unsigned long ts;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 9f0901f..4be56b1 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -149,6 +149,7 @@ static bool __cfg80211_unlink_bss(struct 
cfg80211_registered_device *rdev,
}
 
list_del_init(>list);
+   list_del_init(>nontrans_list);
rb_erase(>rbn, >bss_tree);
rdev->bss_entries--;
WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(>bss_list),
@@ -1005,6 +1006,7 @@ cfg80211_bss_update(struct cfg80211_registered_device 
*rdev,
memcpy(new, tmp, sizeof(*new));
new->refcount = 1;
INIT_LIST_HEAD(>hidden_list);
+   INIT_LIST_HEAD(>nontrans_list);
 
if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
@@ -1086,18 +1088,157 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 
*ie, size_t ielen,
return channel;
 }
 
+static void gen_new_bssid(const u8 *bssid, u8 max_bssid, u8 mbssid_index,
+ u8 *new_bssid_addr)
+{
+   u64 bssid_tmp, new_bssid = 0;
+   u64 lsb_n;
+
+   bssid_tmp = ether_addr_to_u64(bssid);
+
+   lsb_n = bssid_tmp & ((1 << max_bssid) - 1);
+   new_bssid = bssid_tmp;
+   new_bssid &= ~((1 << max_bssid) - 1);
+   new_bssid |= (lsb_n + mbssid_index) % (1 << max_bssid);
+
+   u64_to_ether_addr(new_bssid, new_bssid_addr);
+}
+
+static size_t gen_new_ie(const u8 *ie, size_t ielen, const u8 *subelement,
+size_t subie_len, u8 *new_ie, gfp_t gfp)
+{
+   u8 *pos, *tmp;
+   const u8 *tmp_old, *tmp_new;
+   u8 *sub_copy;
+
+   /* copy subelement as we need to change its content to
+* mark an ie after it is processed.
+*/
+   sub_copy = kmalloc(subie_len, gfp);
+   if (!sub_copy)
+   return 0;
+   memcpy(sub_copy, subelement, subie_len);
+
+   pos = _ie[0];
+
+   /* set new ssid */
+   tmp_new = cfg80211_find_ie(WLAN_EID_SSID, sub_copy, subie_len);
+   if (tmp_new) {
+   memcpy(pos, tmp_new, tmp_new[1] + 2);
+   pos += (tmp_new[1] + 2);
+   }
+
+   /* go through IEs in ie (skip SSID) and subelement,
+* merge them into new_ie
+*/
+   tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
+   tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
+
+   while (tmp_old + tmp_old[1] + 2 - ie <= ielen) {
+   if (tmp_old[0] == 0) {
+   tmp_old++;
+   continue;
+   }
+
+   tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy, subie_len);
+   if (!tmp) {
+   /* ie in old ie but not in subelement */
+   if (tmp_old[0] != WLAN_EID_MULTIPLE_BSSID) {
+   memcpy(pos, tmp_old, tmp_old[1] + 2);
+   pos += tmp_old[1] + 2;
+   }
+   } else {
+   /* ie in transmitting ie also in subelement,
+* copy from subelement and flag the ie in subelement
+* as copied (by setting eid field to 0xff). For
+* vendor ie, compare OUI + type + subType to
+* determine if they are the same ie.
+*/
+   if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
+   if (!memcmp(tmp_old + 2, tmp + 2, 5)) {
+   /* same vendor ie, copy from
+* subelement
+*/
+   memcpy(

Re: [RFC] cfg80211: Implement Multiple BSSID capability in scanning

2017-11-14 Thread Jouni Malinen
On Tue, Nov 14, 2017 at 02:39:31PM +, Peng Xu wrote:
> > I'm not even sure why this is necessary anyway though, do we really think
> > vendors will expect to be able to put vendor IEs inside the subelements and
> > override the ones outside?
> > 
> > Is there even any point for the WFA ones? It seems WMM really ought to be
> > the same for all anyway, for example.
> 
> I don't have any use case for such scenario. If vendor elements are unlikely 
> to
> be present in subelement, this logic can be removed.

As far as WMM element is concerned, I'd note that IEEE 802.11 standard
does not list EDCA Parameter Set element as one of the items that has to
be same for all the BSSs in a multiple BSSID set and as such, I'd
consider it to be allowed behavior for an AP to advertise different WMM
parameters for different nontransmitted BSSIDs.

As far as other vendor specific elements are concerned, there could
certainly be use cases for using different values for WPA element,
Hotspot 2.0 element, MBO/OCE element.

-- 
Jouni MalinenPGP id EFC895FA

Re: ath9k disconnects in 4.13 with reason=4 locally_generated=1

2017-11-03 Thread Jouni Malinen
On Fri, Nov 03, 2017 at 10:57:11AM +0800, Daniel Drake wrote:
> Endless OS recently upgraded from Linux 4.11 to Linux 4.13, and we now
> have a few reports of issues with ath9k wireless becoming unusable.
> 
> In the logs we can see that it authenticates, associates and completes
> the WPA 4 way handshake, before then being disconnected with:
> 
>  wlp2s0: CTRL-EVENT-DISCONNECTED bssid=74:26:ac:68:2f:c0 reason=4
> locally_generated=1

reason=4 is WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY. I'd expect the most
likely source of this to be one of the mac80211 code paths in mlme.c
where disconnection is triggered if the current AP become unreachable.
Getting a debug log from mac80211 might help in figuring out what is
causing this (there seem to be number of mlme_dbg() calls before most,
but not necessarily all, places where
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY is used).

-- 
Jouni MalinenPGP id EFC895FA

[RFC] cfg80211: Implement Multiple BSSID capability in scanning

2017-11-01 Thread Jouni Malinen
From: Peng Xu <p...@qti.qualcomm.com>

This extends cfg80211 BSS table processing to be able to parse Multiple
BSSID element from Beacon and Probe Response frames and to update the
BSS profiles in internal database for non-transmitted BSSs.

Signed-off-by: Peng Xu <p...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/wireless/core.h |   1 +
 net/wireless/scan.c | 537 ++--
 2 files changed, 526 insertions(+), 12 deletions(-)

diff --git a/net/wireless/core.h b/net/wireless/core.h
index 35165f4..3b4a566 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -139,6 +139,7 @@ extern int cfg80211_rdev_list_generation;
 struct cfg80211_internal_bss {
struct list_head list;
struct list_head hidden_list;
+   struct list_head nontrans_list;
struct rb_node rbn;
u64 ts_boottime;
unsigned long ts;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 9f0901f..a9e3b31 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -149,6 +149,7 @@ static bool __cfg80211_unlink_bss(struct 
cfg80211_registered_device *rdev,
}
 
list_del_init(>list);
+   list_del_init(>nontrans_list);
rb_erase(>rbn, >bss_tree);
rdev->bss_entries--;
WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(>bss_list),
@@ -1005,6 +1006,7 @@ cfg80211_bss_update(struct cfg80211_registered_device 
*rdev,
memcpy(new, tmp, sizeof(*new));
new->refcount = 1;
INIT_LIST_HEAD(>hidden_list);
+   INIT_LIST_HEAD(>nontrans_list);
 
if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
@@ -1086,18 +1088,235 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 
*ie, size_t ielen,
return channel;
 }
 
+u8 *gen_new_bssid(const u8 *bssid, u8 max_bssid, u8 mbssid_index, gfp_t gfp)
+{
+   int i;
+   u64 bssid_a, bssid_b, bssid_tmp = 0;
+   u64 lsb_n;
+   u8 *new_bssid;
+
+   for (i = 0; i < 5; i++) {
+   bssid_tmp = bssid_tmp | bssid[i];
+   bssid_tmp = bssid_tmp << 8;
+   }
+   bssid_tmp = bssid_tmp | bssid[5];
+
+   lsb_n = bssid_tmp & ((1 << max_bssid) - 1);
+   bssid_b = (lsb_n + mbssid_index) % (1 <<  max_bssid);
+   bssid_a = bssid_tmp & ~((1 << max_bssid) - 1);
+   bssid_tmp = bssid_a | bssid_b;
+
+   new_bssid = kzalloc(6, gfp);
+   if (!new_bssid)
+   return NULL;
+   for (i = 0; i < 6; i++) {
+   new_bssid[5 - i] = bssid_tmp & 0xFF;
+   bssid_tmp >>= 8;
+   }
+
+   return new_bssid;
+}
+
+size_t calculate_new_ie_len(const u8 *ie, size_t ielen, const u8 *subelement,
+   size_t subie_len)
+{
+   size_t new_ie_len;
+   const u8 *old_ie, *new_ie;
+   int delta;
+
+   new_ie_len = ielen;
+
+   /* calculate length difference between ssid ie */
+   old_ie = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
+   new_ie = cfg80211_find_ie(WLAN_EID_SSID, subelement, subie_len);
+   if (old_ie && new_ie) {
+   delta = new_ie[1] - old_ie[1];
+   new_ie_len += delta;
+   }
+
+   /* calculate length difference between FMS Descriptor ie */
+   old_ie = cfg80211_find_ie(WLAN_EID_FMS_DESCRIPTOR, ie, ielen);
+   new_ie = cfg80211_find_ie(WLAN_EID_FMS_DESCRIPTOR, subelement,
+ subie_len);
+   if (!old_ie && new_ie)
+   new_ie_len += new_ie[1];
+   else if (old_ie && new_ie)
+   new_ie_len += (new_ie[1] - old_ie[1]);
+
+   /* calculate length difference for same vendor ie */
+   new_ie = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, subelement,
+ subie_len);
+   while (new_ie && (new_ie - subelement) < subie_len) {
+   old_ie = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, ie, ielen);
+   while (old_ie && ((old_ie - ie) < ielen)) {
+   if (!memcmp(new_ie + 2, old_ie + 2, 5)) {
+   /* same vendor ie, calculate length difference*/
+   new_ie_len += (new_ie[1] - old_ie[1]);
+   break;
+   }
+   old_ie = cfg80211_find_ie(
+   WLAN_EID_VENDOR_SPECIFIC,
+   old_ie + old_ie[1] + 2,
+   ielen - (old_ie + old_ie[1] + 2 - ie));
+   }
+   new_ie = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC,
+ new_ie + new_ie[1] + 2,
+

[PATCH] nl80211: Define policy for packet pattern attributes

2017-10-06 Thread Jouni Malinen
From: Peng Xu <p...@qti.qualcomm.com>

Define a policy for packet pattern attributes in order to fix the
security vulnerability of buffer over read issue on
NL80211_PKTPAT_OFFSET (nla_get_u32() was used without checking the
attribute length).

Signed-off-by: Peng Xu <p...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/wireless/nl80211.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 90e212d..e99671f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -549,6 +549,14 @@ nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
[NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
 };
 
+/* policy for packet pattern attributes */
+static const struct nla_policy
+nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
+   [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
+   [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
+   [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
+};
+
 static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
 struct netlink_callback *cb,
 struct cfg80211_registered_device **rdev,
@@ -10563,7 +10571,8 @@ static int nl80211_set_wowlan(struct sk_buff *skb, 
struct genl_info *info)
u8 *mask_pat;
 
nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat,
-NULL, info->extack);
+nl80211_packet_pattern_policy,
+info->extack);
err = -EINVAL;
if (!pat_tb[NL80211_PKTPAT_MASK] ||
!pat_tb[NL80211_PKTPAT_PATTERN])
@@ -10812,7 +10821,8 @@ static int nl80211_parse_coalesce_rule(struct 
cfg80211_registered_device *rdev,
rem) {
u8 *mask_pat;
 
-   nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat, NULL, NULL);
+   nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat,
+nl80211_packet_pattern_policy, NULL);
if (!pat_tb[NL80211_PKTPAT_MASK] ||
!pat_tb[NL80211_PKTPAT_PATTERN])
return -EINVAL;
-- 
2.7.4



Re: [PATCH 1/4] cfg80211: Check if PMKID attribute is of expected size

2017-07-07 Thread Jouni Malinen
On Fri, Jul 07, 2017 at 11:27:56AM +0200, Johannes Berg wrote:
> All applied, thanks.
> 
> How did you find these? Some of them go way back, after all, and I
> don't think even coverity flagged them?

Through manual review of all the nl80211 attributes.. There have been
somewhat similar issues flagged as security issues in various kernel
components recently and that has triggered more scrutiny for the kernel
interfaces.

-- 
Jouni MalinenPGP id EFC895FA

[PATCH 4/4] cfg80211: Validate frequencies nested in NL80211_ATTR_SCAN_FREQUENCIES

2017-07-06 Thread Jouni Malinen
From: Srinivas Dasari <dasa...@qti.qualcomm.com>

validate_scan_freqs() retrieves frequencies from attributes
nested in the attribute NL80211_ATTR_SCAN_FREQUENCIES with
nla_get_u32(), which reads 4 bytes from each attribute
without validating the size of data received. Attributes
nested in NL80211_ATTR_SCAN_FREQUENCIES don't have an nla policy.

Validate size of each attribute before parsing to avoid potential buffer
overread.

Fixes: 2a519311926 ("cfg80211/nl80211: scanning (and mac80211 update to use 
it)")
Cc: sta...@vger.kernel.org
Signed-off-by: Srinivas Dasari <dasa...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/wireless/nl80211.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0a63b95..740d3c1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6469,6 +6469,9 @@ static int validate_scan_freqs(struct nlattr *freqs)
struct nlattr *attr1, *attr2;
int n_channels = 0, tmp1, tmp2;
 
+   nla_for_each_nested(attr1, freqs, tmp1)
+   if (nla_len(attr1) != sizeof(u32))
+   return 0;
nla_for_each_nested(attr1, freqs, tmp1) {
n_channels++;
/*
-- 
2.7.4



[PATCH 3/4] cfg80211: Define nla_policy for NL80211_ATTR_LOCAL_MESH_POWER_MODE

2017-07-06 Thread Jouni Malinen
From: Srinivas Dasari <dasa...@qti.qualcomm.com>

Buffer overread may happen as nl80211_set_station() reads 4 bytes
from the attribute NL80211_ATTR_LOCAL_MESH_POWER_MODE without
validating the size of data received when userspace sends less
than 4 bytes of data with NL80211_ATTR_LOCAL_MESH_POWER_MODE.
Define nla_policy for NL80211_ATTR_LOCAL_MESH_POWER_MODE to avoid
the buffer overread.

Fixes: 3b1c5a5307f ("{cfg,nl}80211: mesh power mode primitives and userspace 
access")
Cc: sta...@vger.kernel.org
Signed-off-by: Srinivas Dasari <dasa...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/wireless/nl80211.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index dcfeae0..0a63b95 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -347,6 +347,7 @@ static const struct nla_policy 
nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
[NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
[NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
+   [NL80211_ATTR_LOCAL_MESH_POWER_MODE] = {. type = NLA_U32 },
[NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
[NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
[NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
-- 
2.7.4



[PATCH 1/4] cfg80211: Check if PMKID attribute is of expected size

2017-07-06 Thread Jouni Malinen
From: Srinivas Dasari <dasa...@qti.qualcomm.com>

nla policy checks for only maximum length of the attribute data
when the attribute type is NLA_BINARY. If userspace sends less
data than specified, the wireless drivers may access illegal
memory. When type is NLA_UNSPEC, nla policy check ensures that
userspace sends minimum specified length number of bytes.

Remove type assignment to NLA_BINARY from nla_policy of
NL80211_ATTR_PMKID to make this NLA_UNSPEC and to make sure minimum
WLAN_PMKID_LEN bytes are received from userspace with
NL80211_ATTR_PMKID.

Fixes: 67fbb16be69d ("nl80211: PMKSA caching support")
Cc: sta...@vger.kernel.org
Signed-off-by: Srinivas Dasari <dasa...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/wireless/nl80211.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5487cd7..364291c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -291,8 +291,7 @@ static const struct nla_policy 
nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
[NL80211_ATTR_PID] = { .type = NLA_U32 },
[NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
-   [NL80211_ATTR_PMKID] = { .type = NLA_BINARY,
-.len = WLAN_PMKID_LEN },
+   [NL80211_ATTR_PMKID] = { .len = WLAN_PMKID_LEN },
[NL80211_ATTR_DURATION] = { .type = NLA_U32 },
[NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
[NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
-- 
2.7.4



Re: [PATCH] mac80211: Validate michael MIC before attempting packet decode.

2017-05-10 Thread Jouni Malinen
On Tue, May 09, 2017 at 02:16:31PM -0400, Michael Skeffington wrote:
> In order to allow wpa_supplicant to correctly identify a perceived WPA TKIP 
> key
> recovery attack the michael MIC must be checked before the packet decode is
> attempted.  A packet with an invalid MIC will always fail a decrypt check 
> which
> previously was being checked first.  Therefore the MIC failure bit of
> status flags
> describing the error would remain unset.

Which driver and WLAN hardware are you using? Michael MIC is encrypted,
so to be able to check that, the frame will obviously need to be
decrypted first. If that WEP decryption fails, this frame needs to be
dropped without indicating Michael MIC failure. WEP part here is
completely independent of Michael MIC.

It is possible that there is a driver that handles these steps in
hardware/firmware and if so, that driver may have a bug if you do not
see Michael MIC failures reported correctly. Anyway, as Johannes pointed
out, this part in mac80211 is in the correct sequence and that cannot be
changed since it would completely break TKIP for more or less all
software-based cases.

-- 
Jouni MalinenPGP id EFC895FA


[PATCH 2/2] cfg80211: Add support for FILS shared key authentication offload

2017-03-30 Thread Jouni Malinen
From: Vidyullatha Kanchanapally <vkanc...@qti.qualcomm.com>

Enhance nl80211 and cfg80211 connect request and response APIs to
support FILS shared key authentication offload. The new nl80211
attributes can be used to provide additional information to the driver
to establish a FILS connection. Also enhance the set/del PMKSA to allow
support for adding and deleting PMKSA based on FILS cache identifier.

Add a new feature flag that drivers can use to advertize support for
FILS shared key authentication and association in station mode when
using their own SME.

Signed-off-by: Vidyullatha Kanchanapally <vkanc...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/linux/ieee80211.h| 13 +++
 include/net/cfg80211.h   | 57 +++-
 include/uapi/linux/nl80211.h | 86 --
 net/wireless/nl80211.c   | 90 +---
 net/wireless/sme.c   | 25 +++-
 5 files changed, 259 insertions(+), 12 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 22bf067..294fa62 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1723,6 +1723,9 @@ enum ieee80211_statuscode {
WLAN_STATUS_REJECT_DSE_BAND = 96,
WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99,
WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103,
+   /* 802.11ai */
+   WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108,
+   WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109,
 };
 
 
@@ -2104,6 +2107,12 @@ enum ieee80211_key_len {
 #define FILS_NONCE_LEN 16
 #define FILS_MAX_KEK_LEN   64
 
+#define FILS_ERP_MAX_USERNAME_LEN  16
+#define FILS_ERP_MAX_REALM_LEN 253
+#define FILS_ERP_MAX_RRK_LEN   64
+
+#define PMK_MAX_LEN48
+
 /* Public action codes */
 enum ieee80211_pub_actioncode {
WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4,
@@ -2355,6 +2364,10 @@ enum ieee80211_sa_query_action {
 #define WLAN_AKM_SUITE_TDLSSUITE(0x000FAC, 7)
 #define WLAN_AKM_SUITE_SAE SUITE(0x000FAC, 8)
 #define WLAN_AKM_SUITE_FT_OVER_SAE SUITE(0x000FAC, 9)
+#define WLAN_AKM_SUITE_FILS_SHA256 SUITE(0x000FAC, 14)
+#define WLAN_AKM_SUITE_FILS_SHA384 SUITE(0x000FAC, 15)
+#define WLAN_AKM_SUITE_FT_FILS_SHA256  SUITE(0x000FAC, 16)
+#define WLAN_AKM_SUITE_FT_FILS_SHA384  SUITE(0x000FAC, 17)
 
 #define WLAN_MAX_KEY_LEN   32
 
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index da12d5b..042137d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2073,6 +2073,19 @@ struct cfg80211_bss_selection {
  * the BSSID of the current association, i.e., to the value that is
  * included in the Current AP address field of the Reassociation Request
  * frame.
+ * @fils_erp_username: EAP re-authentication protocol (ERP) username part of 
the
+ * NAI or %NULL if not specified. This is used to construct FILS wrapped
+ * data IE.
+ * @fils_erp_username_len: Length of @fils_erp_username in octets.
+ * @fils_erp_realm: EAP re-authentication protocol (ERP) realm part of NAI or
+ * %NULL if not specified. This specifies the domain name of ER server and
+ * is used to construct FILS wrapped data IE.
+ * @fils_erp_realm_len: Length of @fils_erp_realm in octets.
+ * @fils_erp_next_seq_num: The next sequence number to use in the FILS ERP
+ * messages. This is also used to construct FILS wrapped data IE.
+ * @fils_erp_rrk: ERP re-authentication Root Key (rRK) used to derive 
additional
+ * keys in FILS or %NULL if not specified.
+ * @fils_erp_rrk_len: Length of @fils_erp_rrk in octets.
  */
 struct cfg80211_connect_params {
struct ieee80211_channel *channel;
@@ -2098,6 +2111,13 @@ struct cfg80211_connect_params {
bool pbss;
struct cfg80211_bss_selection bss_select;
const u8 *prev_bssid;
+   const u8 *fils_erp_username;
+   size_t fils_erp_username_len;
+   const u8 *fils_erp_realm;
+   size_t fils_erp_realm_len;
+   u16 fils_erp_next_seq_num;
+   const u8 *fils_erp_rrk;
+   size_t fils_erp_rrk_len;
 };
 
 /**
@@ -2136,12 +2156,27 @@ enum wiphy_params_flags {
  * This structure is passed to the set/del_pmksa() method for PMKSA
  * caching.
  *
- * @bssid: The AP's BSSID.
- * @pmkid: The PMK material itself.
+ * @bssid: The AP's BSSID (may be %NULL).
+ * @pmkid: The identifier to refer a PMKSA.
+ * @pmk: The PMK for the PMKSA identified by @pmkid. This is used for key
+ * derivation by a FILS STA. Otherwise, %NULL.
+ * @pmk_len: Length of the @pmk. The length of @pmk can differ depending on
+ * the hash algorithm used to generate this.
+ * @ssid: SSID to specify the ESS within which a PMKSA is valid when using FILS
+ * cache identifier (may be %NULL).
+ * @ssid_len: Length of the @ssid in octets.
+ * @cache_id: 2-octet cache ide

[PATCH 1/2] cfg80211: Use a structure to pass connect response params

2017-03-30 Thread Jouni Malinen
From: Vidyullatha Kanchanapally <vkanc...@qti.qualcomm.com>

Currently the connect event from driver takes all the connection
response parameters as arguments. With support for new features these
response parameters can grow. Use a structure to pass these parameters
rather than passing them as function arguments.

Signed-off-by: Vidyullatha Kanchanapally <vkanc...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h |  91 +++---
 net/wireless/core.h|  20 ++-
 net/wireless/mlme.c|  20 ---
 net/wireless/nl80211.c |  30 +-
 net/wireless/nl80211.h |   7 +--
 net/wireless/sme.c | 149 ++---
 net/wireless/util.c|  12 +---
 7 files changed, 199 insertions(+), 130 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ffc0868..da12d5b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5136,6 +5136,60 @@ static inline void cfg80211_testmode_event(struct 
sk_buff *skb, gfp_t gfp)
 #endif
 
 /**
+ * struct cfg80211_connect_resp_params - Connection response params
+ * @status: Status code, %WLAN_STATUS_SUCCESS for successful connection, use
+ * %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
+ * the real status code for failures. If this call is used to report a
+ * failure due to a timeout (e.g., not receiving an Authentication frame
+ * from the AP) instead of an explicit rejection by the AP, -1 is used to
+ * indicate that this is a failure, but without a status code.
+ * @timeout_reason is used to report the reason for the timeout in that
+ * case.
+ * @bssid: The BSSID of the AP (may be %NULL)
+ * @bss: Entry of bss to which STA got connected to, can be obtained through
+ * cfg80211_get_bss() (may be %NULL). Only one parameter among @bssid and
+ * @bss needs to be specified.
+ * @req_ie: Association request IEs (may be %NULL)
+ * @req_ie_len: Association request IEs length
+ * @resp_ie: Association response IEs (may be %NULL)
+ * @resp_ie_len: Association response IEs length
+ * @timeout_reason: Reason for connection timeout. This is used when the
+ * connection fails due to a timeout instead of an explicit rejection from
+ * the AP. %NL80211_TIMEOUT_UNSPECIFIED is used when the timeout reason is
+ * not known. This value is used only if @status < 0 to indicate that the
+ * failure is due to a timeout and not due to explicit rejection by the AP.
+ * This value is ignored in other cases (@status >= 0).
+ */
+struct cfg80211_connect_resp_params {
+   int status;
+   const u8 *bssid;
+   struct cfg80211_bss *bss;
+   const u8 *req_ie;
+   size_t req_ie_len;
+   const u8 *resp_ie;
+   size_t resp_ie_len;
+   enum nl80211_timeout_reason timeout_reason;
+};
+
+/**
+ * cfg80211_connect_done - notify cfg80211 of connection result
+ *
+ * @dev: network device
+ * @params: connection response parameters
+ * @gfp: allocation flags
+ *
+ * It should be called by the underlying driver once execution of the 
connection
+ * request from connect() has been completed. This is similar to
+ * cfg80211_connect_bss(), but takes a structure pointer for connection 
response
+ * parameters. Only one of the functions among cfg80211_connect_bss(),
+ * cfg80211_connect_result(), cfg80211_connect_timeout(),
+ * and cfg80211_connect_done() should be called.
+ */
+void cfg80211_connect_done(struct net_device *dev,
+  struct cfg80211_connect_resp_params *params,
+  gfp_t gfp);
+
+/**
  * cfg80211_connect_bss - notify cfg80211 of connection result
  *
  * @dev: network device
@@ -5165,13 +5219,31 @@ static inline void cfg80211_testmode_event(struct 
sk_buff *skb, gfp_t gfp)
  * It should be called by the underlying driver once execution of the 
connection
  * request from connect() has been completed. This is similar to
  * cfg80211_connect_result(), but with the option of identifying the exact bss
- * entry for the connection. Only one of these functions should be called.
+ * entry for the connection. Only one of the functions among
+ * cfg80211_connect_bss(), cfg80211_connect_result(),
+ * cfg80211_connect_timeout(), and cfg80211_connect_done() should be called.
  */
-void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
- struct cfg80211_bss *bss, const u8 *req_ie,
- size_t req_ie_len, const u8 *resp_ie,
- size_t resp_ie_len, int status, gfp_t gfp,
- enum nl80211_timeout_reason timeout_reason);
+static inline void
+cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
+struct cfg80211_bss *bss, const u8 *req_ie,
+size_t req_ie_len, const u8 *resp_ie,
+size_t resp_ie_len, int status, gfp_t gfp,
+

[RFC v2] cfg80211: Add support for FILS shared key authentication offload

2017-03-09 Thread Jouni Malinen
From: "Kanchanapally, Vidyullatha" <vkanc...@qti.qualcomm.com>

Enhance nl80211 and cfg80211 connect request and response APIs to
support FILS shared key authentication Offload. The new nl80211
attributes can be used to provide additional information to the driver
to establish a FILS connection. Also enhance the set/del PMKSA to allow
support for adding and deleting PMKSA based on FILS cache identifier.

Add a new feature flag that drivers can use to advertize support for
FILS shared key authentication and association in station mode when
using their own SME.

Signed-off-by: Vidyullatha Kanchanapally <vkanc...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/linux/ieee80211.h|   9 +++
 include/net/cfg80211.h   | 143 ++---
 include/uapi/linux/nl80211.h |  86 ++-
 net/wireless/core.h  |  20 ++
 net/wireless/mlme.c  |  20 +++---
 net/wireless/nl80211.c   | 116 +-
 net/wireless/nl80211.h   |   7 +-
 net/wireless/sme.c   | 164 ++-
 net/wireless/util.c  |  12 +---
 9 files changed, 442 insertions(+), 135 deletions(-)

v2:
- address comments from Johannes
  * add a new struct cfg80211_connect_resp_params to replace the long
list of function parameters and use this within
struct cfg80211_event as well
  * add a DOC: section describing flow and PMK use

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 22bf067..51e2748 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1723,6 +1723,9 @@ enum ieee80211_statuscode {
WLAN_STATUS_REJECT_DSE_BAND = 96,
WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99,
WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103,
+   /* 802.11ai */
+   WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108,
+   WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109,
 };
 
 
@@ -2104,6 +2107,12 @@ enum ieee80211_key_len {
 #define FILS_NONCE_LEN 16
 #define FILS_MAX_KEK_LEN   64
 
+#define FILS_ERP_MAX_USERNAME_LEN  16
+#define FILS_ERP_MAX_REALM_LEN 253
+#define FILS_ERP_MAX_RRK_LEN   64
+
+#define PMK_MAX_LEN48
+
 /* Public action codes */
 enum ieee80211_pub_actioncode {
WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ffc0868..83845c5 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2073,6 +2073,17 @@ struct cfg80211_bss_selection {
  * the BSSID of the current association, i.e., to the value that is
  * included in the Current AP address field of the Reassociation Request
  * frame.
+ * @fils_erp_username: EAP re-authentication protocol (ERP) username part of 
the
+ * NAI. This is used to refer to the keys used in ERP, i.e., rRK and rIK.
+ * @fils_erp_username_len: Length of @fils_erp_username in octets.
+ * @fils_erp_realm: EAP re-authentication protocol (ERP) realm part of NAI. 
This
+ * specifies the domain name of ER server.
+ * @fils_erp_realm_len: Length of @fils_erp_realm in octets.
+ * @fils_erp_sequence_num: The start sequence number to be used in the next ERP
+ * message.
+ * @fils_erp_rrk: ERP re-authentication Root Key (rRK) used to derive 
additional
+ * keys in FILS.
+ * @fils_erp_rrk_len: Length of @fils_erp_rrk in octets.
  */
 struct cfg80211_connect_params {
struct ieee80211_channel *channel;
@@ -2098,6 +2109,13 @@ struct cfg80211_connect_params {
bool pbss;
struct cfg80211_bss_selection bss_select;
const u8 *prev_bssid;
+   const u8 *fils_erp_username;
+   size_t fils_erp_username_len;
+   const u8 *fils_erp_realm;
+   size_t fils_erp_realm_len;
+   u16 fils_erp_sequence_num;
+   const u8 *fils_erp_rrk;
+   size_t fils_erp_rrk_len;
 };
 
 /**
@@ -2137,11 +2155,24 @@ enum wiphy_params_flags {
  * caching.
  *
  * @bssid: The AP's BSSID.
- * @pmkid: The PMK material itself.
+ * @pmkid: The identifer to refer a PMKSA.
+ * @pmk: The PMK for the PMKSA identified by @pmkid. This is used for key
+ * derivation by a FILS STA. Otherwise, %NULL.
+ * @pmk_len: Length of the @pmk. The length of @pmk can differ depending on
+ * the hash algorithm used to generate this.
+ * @ssid: SSID to specify the ESS within which a PMKSA is valid.
+ * @ssid_len: Length of the @ssid in octets.
+ * @cache_id: Unsigned 16 bit identifier advertized by an AP identifying the
+ * scope of PMKSA. This is valid only if @ssid_len is non-zero.
  */
 struct cfg80211_pmksa {
const u8 *bssid;
const u8 *pmkid;
+   const u8 *pmk;
+   size_t pmk_len;
+   const u8 *ssid;
+   size_t ssid_len;
+   u16 cache_id;
 };
 
 /**
@@ -5136,6 +5167,78 @@ static inline void cfg80211_testmode_event(struct 
sk_buff *skb, gfp_t gf

[PATCH] mac80211_hwsim: Add channel 169 (5845 MHz)

2017-03-06 Thread Jouni Malinen
This channel is defined in the IEEE 802.11 standard and available in
number of countries, so extend the mac80211_hwsim channel list to cover
channel 169 to enable additional testing.

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 drivers/net/wireless/mac80211_hwsim.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/mac80211_hwsim.c 
b/drivers/net/wireless/mac80211_hwsim.c
index 7b9662a..8b823c7 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -350,6 +350,7 @@ static const struct ieee80211_channel hwsim_channels_5ghz[] 
= {
CHAN5G(5785), /* Channel 157 */
CHAN5G(5805), /* Channel 161 */
CHAN5G(5825), /* Channel 165 */
+   CHAN5G(5845), /* Channel 169 */
 };
 
 static const struct ieee80211_rate hwsim_rates[] = {
-- 
2.7.4



Re: [RFC] mac80211_hwsim: report survey data for scanned channels

2017-03-04 Thread Jouni Malinen
On Tue, Feb 21, 2017 at 11:31:18AM +0100, Johannes Berg wrote:
> Currently, hwsim is reporting survey data (only a fake noise floor)
> for the current channel. This breaks when the multi-channel support
> is enabled since then there's no current channel.
> 
> Make the dummy implementation closer to a real one and only report
> data while scanning, for all the scanned channels. At other times,
> no survey data might be available (in real hardware) due to power-
> save for example.

> Had this lying around - is it useful for anyone?

Yes, it seems to make the ap_acs hwsim test cases in hostap.git quite a
bit more useful in hitting proper acs.c coverage in hostapd.. And also
allow having to have hacks to force previous AP instance on the same
band just to be able to hit any of this code.

> - survey->filled = SURVEY_INFO_NOISE_DBM;
> + survey->filled = SURVEY_INFO_NOISE_DBM |
> +  SURVEY_INFO_CHANNEL_TIME |
> +  SURVEY_INFO_CHANNEL_TIME_BUSY;

This is pretty old, though.. :)  Had to remove the "CHANNEL_" part
here..

> + survey->channel_time =
> + survey->channel_time_busy = survey->channel_time/8;

.. and "channel_" in these to make this compile. Anyway, with those
trivial changes, the hwsim test cases did start looking more
interesting, so it would seem reasonable to get this applied.

-- 
Jouni MalinenPGP id EFC895FA


[RFC] cfg80211: Add support for FILS shared key authentication offload

2017-03-03 Thread Jouni Malinen
From: "Kanchanapally, Vidyullatha" <vkanc...@qti.qualcomm.com>

Enhance nl80211 and cfg80211 connect request and response APIs to
support FILS shared key authentication Offload. The new nl80211
attributes can be used to provide additional information to the driver
to establish a FILS connection. Also enhance the set/del PMKSA to allow
support for adding and deleting PMKSA based on FILS cache identifier.

Add a new feature flag that drivers can use to advertize support for
FILS shared key authentication and association in station mode when
using their own SME.

Signed-off-by: Vidyullatha Kanchanapally <vkanc...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/linux/ieee80211.h|   9 
 include/net/cfg80211.h   | 115 +++
 include/uapi/linux/nl80211.h |  48 --
 net/wireless/core.h  |  12 -
 net/wireless/mlme.c  |   1 +
 net/wireless/nl80211.c   |  89 ++---
 net/wireless/nl80211.h   |   5 +-
 net/wireless/sme.c   |  64 ++--
 net/wireless/util.c  |   4 ++
 9 files changed, 311 insertions(+), 36 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 22bf067..51e2748 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1723,6 +1723,9 @@ enum ieee80211_statuscode {
WLAN_STATUS_REJECT_DSE_BAND = 96,
WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99,
WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103,
+   /* 802.11ai */
+   WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108,
+   WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109,
 };
 
 
@@ -2104,6 +2107,12 @@ enum ieee80211_key_len {
 #define FILS_NONCE_LEN 16
 #define FILS_MAX_KEK_LEN   64
 
+#define FILS_ERP_MAX_USERNAME_LEN  16
+#define FILS_ERP_MAX_REALM_LEN 253
+#define FILS_ERP_MAX_RRK_LEN   64
+
+#define PMK_MAX_LEN48
+
 /* Public action codes */
 enum ieee80211_pub_actioncode {
WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 86c12f8..a5009d0 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2073,6 +2073,17 @@ struct cfg80211_bss_selection {
  * the BSSID of the current association, i.e., to the value that is
  * included in the Current AP address field of the Reassociation Request
  * frame.
+ * @fils_erp_username: EAP re-authentication protocol (ERP) username part of 
the
+ * NAI. This is used to refer to the keys used in ERP, i.e., rRK and rIK.
+ * @fils_erp_username_len: Length of @fils_erp_username in octets.
+ * @fils_erp_realm: EAP re-authentication protocol (ERP) realm part of NAI. 
This
+ * specifies the domain name of ER server.
+ * @fils_erp_realm_len: Length of @fils_erp_realm in octets.
+ * @fils_erp_sequence_num: The start sequence number to be used in the next ERP
+ * message.
+ * @fils_erp_rrk: ERP re-authentication Root Key (rRK) used to derive 
additional
+ * keys in FILS.
+ * @fils_erp_rrk_len: Length of @fils_erp_rrk in octets.
  */
 struct cfg80211_connect_params {
struct ieee80211_channel *channel;
@@ -2098,6 +2109,13 @@ struct cfg80211_connect_params {
bool pbss;
struct cfg80211_bss_selection bss_select;
const u8 *prev_bssid;
+   const u8 *fils_erp_username;
+   size_t fils_erp_username_len;
+   const u8 *fils_erp_realm;
+   size_t fils_erp_realm_len;
+   u16 fils_erp_sequence_num;
+   const u8 *fils_erp_rrk;
+   size_t fils_erp_rrk_len;
 };
 
 /**
@@ -2137,11 +2155,24 @@ enum wiphy_params_flags {
  * caching.
  *
  * @bssid: The AP's BSSID.
- * @pmkid: The PMK material itself.
+ * @pmkid: The identifer to refer a PMKSA.
+ * @pmk: The PMK for the PMKSA identified by @pmkid. This is used for key
+ * derivation by a FILS STA. Otherwise, %NULL.
+ * @pmk_len: Length of the @pmk. The length of @pmk can differ depending on
+ * the hash algorithm used to generate this.
+ * @ssid: SSID to specify the ESS within which a PMKSA is valid.
+ * @ssid_len: Length of the @ssid in octets.
+ * @cache_id: Unsigned 16 bit identifier advertized by an AP identifying the
+ * scope of PMKSA. This is valid only if @ssid_len is non-zero.
  */
 struct cfg80211_pmksa {
const u8 *bssid;
const u8 *pmkid;
+   const u8 *pmk;
+   size_t pmk_len;
+   const u8 *ssid;
+   size_t ssid_len;
+   u16 cache_id;
 };
 
 /**
@@ -5136,6 +5167,60 @@ static inline void cfg80211_testmode_event(struct 
sk_buff *skb, gfp_t gfp)
 #endif
 
 /**
+ * cfg80211_connect_done - notify cfg80211 of connection result
+ *
+ * @dev: network device
+ * @bssid: the BSSID of the AP
+ * @bss: entry of bss to which STA got connected to, can be obtained
+ * through cfg80211_get_bss (may be %NULL)
+ * @req_ie: as

Re: [RFC v2 1/2] cfg80211: support 4-way handshake offloading for WPA/WPA2-PSK

2017-02-21 Thread Jouni Malinen
On Tue, Feb 21, 2017 at 01:37:57PM +0100, Johannes Berg wrote:
> Add a new NL80211_ATTR_PMK attribute that might be passed as part
> of NL80211_CMD_CONNECT command, and contain the PSK (which is the
> PMK, hence the name.)

> diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
> +#define WLAN_PMK_LEN 32

> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
>  struct cfg80211_crypto_settings {
> + const u8 *psk;

> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> + [NL80211_ATTR_PMK] = { .len = WLAN_PMK_LEN },

While the existing WPA2-PSK cases all use 32 octet PMK, there are also
48 octet PMKs in use with EAP (Suite B 192-bit level and FILS with
SHA384). Patch 2/2 seemed to look at the PMK length as well.. Should the
same be done already with 1/2 so that the PSK case is separately
validating exact match with 32 octets in length for PMK = PSK while the
other cases allow longer PMK as well?

I never remember how the attr policy .len works, so that may already be
the implicit behavior here, but it would be clearer to be more explicit
about the possible lengths of the WLAN_ATTR_PMK and not assume that
WLAN_PMK_LEN definition is the only possible option.

-- 
Jouni MalinenPGP id EFC895FA


[PATCH] mac80211: Allocate a sync skcipher explicitly for FILS AEAD

2017-02-04 Thread Jouni Malinen
The skcipher could have been of the async variant which may return from
skcipher_encrypt() with -EINPROGRESS after having queued the request.
The FILS AEAD implementation here does not have code for dealing with
that possibility, so allocate a sync cipher explicitly to avoid
potential issues with hardware accelerators.

This is based on the patch sent out by Ard.

Fixes: 39404feee691 ("mac80211: FILS AEAD protection for station mode 
association frames")
Reported-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/mac80211/fils_aead.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/fils_aead.c b/net/mac80211/fils_aead.c
index e3bbe24..912f3e2c 100644
--- a/net/mac80211/fils_aead.c
+++ b/net/mac80211/fils_aead.c
@@ -192,7 +192,7 @@ static int aes_siv_encrypt(const u8 *key, size_t key_len,
 
/* CTR */
 
-   tfm2 = crypto_alloc_skcipher("ctr(aes)", 0, 0);
+   tfm2 = crypto_alloc_skcipher("ctr(aes)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm2)) {
kfree(tmp);
return PTR_ERR(tfm2);
@@ -251,7 +251,7 @@ static int aes_siv_decrypt(const u8 *key, size_t key_len,
 
/* CTR */
 
-   tfm2 = crypto_alloc_skcipher("ctr(aes)", 0, 0);
+   tfm2 = crypto_alloc_skcipher("ctr(aes)", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm2))
return PTR_ERR(tfm2);
/* K2 for CTR */
-- 
2.7.4



[PATCH] mac80211: Fix FILS AEAD protection in Association Request frame

2017-02-04 Thread Jouni Malinen
Incorrect num_elem parameter value (1 vs. 5) was used in the
aes_siv_encrypt() call. This resulted in only the first one of the five
AAD vectors to SIV getting included in calculation. This does not
protect all the contents correctly and would not interoperate with a
standard compliant implementation.

Fix this by using the correct number. A matching fix is needed in the AP
side (hostapd) to get FILS authentication working properly.

Fixes: 39404feee691 ("mac80211: FILS AEAD protection for station mode 
association frames")
Reported-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/mac80211/fils_aead.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

If there is still time, it would be nice to get this included in Linux
4.10 since fils_aead.c is being added there. If not, Cc: stable could be
added.

diff --git a/net/mac80211/fils_aead.c b/net/mac80211/fils_aead.c
index ecfdd97..e795aaa 100644
--- a/net/mac80211/fils_aead.c
+++ b/net/mac80211/fils_aead.c
@@ -272,7 +272,7 @@ int fils_encrypt_assoc_req(struct sk_buff *skb,
crypt_len = skb->data + skb->len - encr;
skb_put(skb, AES_BLOCK_SIZE);
return aes_siv_encrypt(assoc_data->fils_kek, assoc_data->fils_kek_len,
-  encr, crypt_len, 1, addr, len, encr);
+  encr, crypt_len, 5, addr, len, encr);
 }
 
 int fils_decrypt_assoc_resp(struct ieee80211_sub_if_data *sdata,
-- 
2.7.4



[PATCH] wireless-regdb: Remove DFS requirement for India (IN)

2017-01-30 Thread Jouni Malinen
The "Indoor Use of low power wireless equipment in the frequency band 5
GHz (Exemption from Licensing Requirement) Rules, 2005" notification by
Ministry of Communications and Information Technology (Wireless Planning
and Coordination Wing) (New Delhi, the 28th January 2005) does not
mandate use of DFS, so remove the DFS flag from the 5250-5330 MHz band
in India.

In addition, increase the TX power limit to 23 dBm to match the 200 mW
maximum mentioned in the same notification. Also use the exact ranges
from that notification and enable use of 160 MHz channels in the
5150-5350 MHz band.

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 db.txt | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/db.txt b/db.txt
index 7964cfb..05108e0 100644
--- a/db.txt
+++ b/db.txt
@@ -580,11 +580,10 @@ country IL: DFS-ETSI
(5150 - 5250 @ 80), (200 mW), NO-OUTDOOR, AUTO-BW
(5250 - 5350 @ 80), (200 mW), NO-OUTDOOR, DFS, AUTO-BW
 
-country IN: DFS-JP
+country IN:
(2402 - 2482 @ 40), (20)
-   (5170 - 5250 @ 80), (20), AUTO-BW
-   (5250 - 5330 @ 80), (20), DFS, AUTO-BW
-   (5735 - 5835 @ 80), (20)
+   (5150 - 5350 @ 160), (23)
+   (5725 - 5875 @ 80), (23)
 
 country IR: DFS-JP
(2402 - 2482 @ 40), (20)
-- 
2.7.4



[PATCH 4/4] cfg80211: Fix documentation for connect result

2017-01-12 Thread Jouni Malinen
The function documentation for cfg80211_connect_bss() and
cfg80211_connect_result() was still claiming that they are used only for
a success case while these functions can now be used to report both
success and various failure cases. The actual use cases were already
described in the connect() documentation.

Update the function specific comments to note the failure cases and also
describe how the special status == -1 case is used in
cfg80211_connect_bss() to indicate a connection timeout based on the
internal implementation in cfg80211_connect_timeout().

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9b3427c..ed3d595 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5086,9 +5086,14 @@ static inline void cfg80211_testmode_event(struct 
sk_buff *skb, gfp_t gfp)
  * @req_ie_len: association request IEs length
  * @resp_ie: association response IEs (may be %NULL)
  * @resp_ie_len: assoc response IEs length
- * @status: status code, 0 for successful connection, use
+ * @status: status code, %WLAN_STATUS_SUCCESS for successful connection, use
  *  %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
- *  the real status code for failures.
+ * the real status code for failures. If this call is used to report a
+ * failure due to a timeout (e.g., not receiving an Authentication frame
+ * from the AP) instead of an explicit rejection by the AP, -1 is used to
+ * indicate that this is a failure, but without a status code.
+ * @timeout_reason is used to report the reason for the timeout in that
+ * case.
  * @gfp: allocation flags
  * @timeout_reason: reason for connection timeout. This is used when the
  * connection fails due to a timeout instead of an explicit rejection from
@@ -5097,10 +5102,10 @@ static inline void cfg80211_testmode_event(struct 
sk_buff *skb, gfp_t gfp)
  * failure is due to a timeout and not due to explicit rejection by the AP.
  * This value is ignored in other cases (@status >= 0).
  *
- * It should be called by the underlying driver whenever connect() has
- * succeeded. This is similar to cfg80211_connect_result(), but with the
- * option of identifying the exact bss entry for the connection. Only one of
- * these functions should be called.
+ * It should be called by the underlying driver once execution of the 
connection
+ * request from connect() has been completed. This is similar to
+ * cfg80211_connect_result(), but with the option of identifying the exact bss
+ * entry for the connection. Only one of these functions should be called.
  */
 void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
  struct cfg80211_bss *bss, const u8 *req_ie,
@@ -5117,13 +5122,15 @@ void cfg80211_connect_bss(struct net_device *dev, const 
u8 *bssid,
  * @req_ie_len: association request IEs length
  * @resp_ie: association response IEs (may be %NULL)
  * @resp_ie_len: assoc response IEs length
- * @status: status code, 0 for successful connection, use
+ * @status: status code, %WLAN_STATUS_SUCCESS for successful connection, use
  * %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
  * the real status code for failures.
  * @gfp: allocation flags
  *
- * It should be called by the underlying driver whenever connect() has
- * succeeded.
+ * It should be called by the underlying driver once execution of the 
connection
+ * request from connect() has been completed. This is similar to
+ * cfg80211_connect_bss() which allows the exact bss entry to be specified. 
Only
+ * one of these functions should be called.
  */
 static inline void
 cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
-- 
2.7.4



[PATCH v2 3/4] cfg80211: Specify the reason for connect timeout

2017-01-12 Thread Jouni Malinen
From: Purushottam Kushwaha <pkush...@qti.qualcomm.com>

This enhances the connect timeout API to also carry the reason for the
timeout. These reason codes for the connect time out are represented by
enum nl80211_timeout_reason and are passed to user space through a new
attribute NL80211_ATTR_TIMEOUT_REASON (u32).

Signed-off-by: Purushottam Kushwaha <pkush...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 18 ++
 include/uapi/linux/nl80211.h | 21 +
 net/wireless/core.h  |  4 +++-
 net/wireless/mlme.c  |  3 ++-
 net/wireless/nl80211.c   |  8 ++--
 net/wireless/nl80211.h   |  3 ++-
 net/wireless/sme.c   | 39 +++
 net/wireless/util.c  |  2 +-
 8 files changed, 76 insertions(+), 22 deletions(-)

v2:
- update cfg80211_connect_bss() comment to note that timeout_reason
  gets ignored for status >= 0
- rename CFG80211_CONN_AUTH_FAILED to CFG80211_CONN_AUTH_FAILED_TIMEOUT
  to be consistent with association (which needs both
  failure-due-to-reject and failure-due-to-timeout)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 4456491..9b3427c 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5090,6 +5090,12 @@ static inline void cfg80211_testmode_event(struct 
sk_buff *skb, gfp_t gfp)
  *  %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
  *  the real status code for failures.
  * @gfp: allocation flags
+ * @timeout_reason: reason for connection timeout. This is used when the
+ * connection fails due to a timeout instead of an explicit rejection from
+ * the AP. %NL80211_TIMEOUT_UNSPECIFIED is used when the timeout reason is
+ * not known. This value is used only if @status < 0 to indicate that the
+ * failure is due to a timeout and not due to explicit rejection by the AP.
+ * This value is ignored in other cases (@status >= 0).
  *
  * It should be called by the underlying driver whenever connect() has
  * succeeded. This is similar to cfg80211_connect_result(), but with the
@@ -5099,7 +5105,8 @@ static inline void cfg80211_testmode_event(struct sk_buff 
*skb, gfp_t gfp)
 void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
  struct cfg80211_bss *bss, const u8 *req_ie,
  size_t req_ie_len, const u8 *resp_ie,
- size_t resp_ie_len, int status, gfp_t gfp);
+ size_t resp_ie_len, int status, gfp_t gfp,
+ enum nl80211_timeout_reason timeout_reason);
 
 /**
  * cfg80211_connect_result - notify cfg80211 of connection result
@@ -5125,7 +5132,8 @@ cfg80211_connect_result(struct net_device *dev, const u8 
*bssid,
u16 status, gfp_t gfp)
 {
cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, resp_ie,
-resp_ie_len, status, gfp);
+resp_ie_len, status, gfp,
+NL80211_TIMEOUT_UNSPECIFIED);
 }
 
 /**
@@ -5136,6 +5144,7 @@ cfg80211_connect_result(struct net_device *dev, const u8 
*bssid,
  * @req_ie: association request IEs (maybe be %NULL)
  * @req_ie_len: association request IEs length
  * @gfp: allocation flags
+ * @timeout_reason: reason for connection timeout.
  *
  * It should be called by the underlying driver whenever connect() has failed
  * in a sequence where no explicit authentication/association rejection was
@@ -5145,10 +5154,11 @@ cfg80211_connect_result(struct net_device *dev, const 
u8 *bssid,
  */
 static inline void
 cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,
-const u8 *req_ie, size_t req_ie_len, gfp_t gfp)
+const u8 *req_ie, size_t req_ie_len, gfp_t gfp,
+enum nl80211_timeout_reason timeout_reason)
 {
cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, NULL, 0, -1,
-gfp);
+gfp, timeout_reason);
 }
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 6b17feb..c51b40c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1996,6 +1996,10 @@ enum nl80211_commands {
  * better BSSs. The attribute value is a packed structure
  * value as specified by  nl80211_bss_select_rssi_adjust.
  *
+ * @NL80211_ATTR_TIMEOUT_REASON: The reason for which an operation timed out.
+ * u32 attribute with an  nl80211_timeout_reason value. This is used,
+ * e.g., with %NL80211_CMD_CONNECT event.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2405,6 +2409,8 @@ enum nl80211_attrs {
NL80211_AT

[PATCH v3 1/4] cfg80211: Add support to randomize TA of Public Action frames

2017-01-12 Thread Jouni Malinen
From: vamsi krishna <vam...@qti.qualcomm.com>

Add support to use a random local address (Address 2 = TA in transmit
and the same address in receive functionality) for Public Action frames
in order to improve privacy of WLAN clients. Applications fill the
random transmit address in the frame buffer in the NL80211_CMD_FRAME
command. This can be used only with the drivers that indicate support
for random local address by setting the new
NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA and/or
NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED in ext_features.

The driver needs to configure receive behavior to accept frames to the
specified random address during the time the frame exchange is pending
and such frames need to be acknowledged similarly to frames sent to the
local permanent address when this random address functionality is not
used.

Signed-off-by: vamsi krishna <vam...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/uapi/linux/nl80211.h |  6 ++
 net/wireless/mlme.c  | 21 +++--
 2 files changed, 25 insertions(+), 2 deletions(-)

v3:
- moved to the beginning of the series since there were no pending
  comments on this patch; no other changes

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 174f4b3..908886c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4699,6 +4699,10 @@ enum nl80211_feature_flags {
  * configuration (AP/mesh) with VHT rates.
  * @NL80211_EXT_FEATURE_FILS_STA: This driver supports Fast Initial Link Setup
  * with user space SME (NL80211_CMD_AUTHENTICATE) in station mode.
+ * @NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA: This driver supports randomized TA
+ * in @NL80211_CMD_FRAME while not associated.
+ * @NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED: This driver supports
+ * randomized TA in @NL80211_CMD_FRAME while associated.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4714,6 +4718,8 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_BEACON_RATE_HT,
NL80211_EXT_FEATURE_BEACON_RATE_VHT,
NL80211_EXT_FEATURE_FILS_STA,
+   NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA,
+   NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED,
 
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 1c63a77..b876f40 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -662,8 +662,25 @@ int cfg80211_mlme_mgmt_tx(struct 
cfg80211_registered_device *rdev,
return err;
}
 
-   if (!ether_addr_equal(mgmt->sa, wdev_address(wdev)))
-   return -EINVAL;
+   if (!ether_addr_equal(mgmt->sa, wdev_address(wdev))) {
+   /* Allow random TA to be used with Public Action frames if the
+* driver has indicated support for this. Otherwise, only allow
+* the local address to be used.
+*/
+   if (!ieee80211_is_action(mgmt->frame_control) ||
+   mgmt->u.action.category != WLAN_CATEGORY_PUBLIC)
+   return -EINVAL;
+   if (!wdev->current_bss &&
+   !wiphy_ext_feature_isset(
+   >wiphy,
+   NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA))
+   return -EINVAL;
+   if (wdev->current_bss &&
+   !wiphy_ext_feature_isset(
+   >wiphy,
+   NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED))
+   return -EINVAL;
+   }
 
/* Transmit the Action frame as requested by user space */
return rdev_mgmt_tx(rdev, wdev, params, cookie);
-- 
2.7.4



[PATCH v4 2/4] cfg80211: Add support to sched scan to report better BSSs

2017-01-12 Thread Jouni Malinen
From: vamsi krishna <vam...@qti.qualcomm.com>

Enhance sched scan to support option of finding a better BSS while in
connected state. Firmware scans the medium and reports when it finds a
known BSS which has better RSSI than the current connected BSS. New
attributes to specify the relative RSSI (compared to the current BSS)
are added to the sched scan to implement this.

Signed-off-by: vamsi krishna <vam...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 36 +---
 include/uapi/linux/nl80211.h | 30 ++
 net/wireless/nl80211.c   | 44 
 3 files changed, 99 insertions(+), 11 deletions(-)

v4:
- rebased on top of the random TA patch
- update comments to cover possibility of negative relative_rssi
- use NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST only if
  NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI is present
- remove unnecessary nl80211_send_wowlan_nd() argument change
- remove invalid rssi_adjust.band comparison (different enum)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index cb13789..4456491 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1620,6 +1620,17 @@ struct cfg80211_sched_scan_plan {
 };
 
 /**
+ * struct cfg80211_bss_select_adjust - BSS selection with RSSI adjustment.
+ *
+ * @band: band of BSS which should match for RSSI level adjustment.
+ * @delta: value of RSSI level adjustment.
+ */
+struct cfg80211_bss_select_adjust {
+   enum nl80211_band band;
+   s8 delta;
+};
+
+/**
  * struct cfg80211_sched_scan_request - scheduled scan request description
  *
  * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans)
@@ -1654,6 +1665,16 @@ struct cfg80211_sched_scan_plan {
  * cycle.  The driver may ignore this parameter and start
  * immediately (or at any other time), if this feature is not
  * supported.
+ * @relative_rssi_set: Indicates whether @relative_rssi is set or not.
+ * @relative_rssi: Relative RSSI threshold in dB to restrict scan result
+ * reporting in connected state to cases where a matching BSS is determined
+ * to have better or slightly worse RSSI than the current connected BSS.
+ * The relative RSSI threshold values are ignored in disconnected state.
+ * @rssi_adjust: delta dB of RSSI preference to be given to the BSSs that 
belong
+ * to the specified band while deciding whether a better BSS is reported
+ * using @relative_rssi. If delta is a negative number, the BSSs that
+ * belong to the specified band will be penalized by delta dB in relative
+ * comparisions.
  */
 struct cfg80211_sched_scan_request {
struct cfg80211_ssid *ssids;
@@ -1673,6 +1694,10 @@ struct cfg80211_sched_scan_request {
u8 mac_addr[ETH_ALEN] __aligned(2);
u8 mac_addr_mask[ETH_ALEN] __aligned(2);
 
+   bool relative_rssi_set;
+   s8 relative_rssi;
+   struct cfg80211_bss_select_adjust rssi_adjust;
+
/* internal */
struct wiphy *wiphy;
struct net_device *dev;
@@ -1981,17 +2006,6 @@ struct cfg80211_ibss_params {
 };
 
 /**
- * struct cfg80211_bss_select_adjust - BSS selection with RSSI adjustment.
- *
- * @band: band of BSS which should match for RSSI level adjustment.
- * @delta: value of RSSI level adjustment.
- */
-struct cfg80211_bss_select_adjust {
-   enum nl80211_band band;
-   s8 delta;
-};
-
-/**
  * struct cfg80211_bss_selection - connection parameters for BSS selection.
  *
  * @behaviour: requested BSS selection behaviour.
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 908886c..6b17feb 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1982,6 +1982,20 @@ enum nl80211_commands {
  * @NL80211_ATTR_BSSID: The BSSID of the AP. Note that %NL80211_ATTR_MAC is 
also
  * used in various commands/events for specifying the BSSID.
  *
+ * @NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI: Relative RSSI threshold by which
+ * other BSSs has to be better or slightly worse than the current
+ * connected BSS so that they get reported to user space.
+ * This will give an opportunity to userspace to consider connecting to
+ * other matching BSSs which have better or slightly worse RSSI than
+ * the current connected BSS by using an offloaded operation to avoid
+ * unnecessary wakeups.
+ *
+ * @NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST: When present the RSSI level for BSSs 
in
+ * the specified band is to be adjusted before doing
+ * %NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI based comparision to figure out
+ * better BSSs. The attribute value is a packed structure
+ * value as specified by  nl80211_bss_select_rssi_adjust.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use

[PATCH 3/3] cfg80211: Specify the reason for connect timeout

2017-01-09 Thread Jouni Malinen
From: Purushottam Kushwaha <pkush...@qti.qualcomm.com>

This enhances the connect timeout API to also carry the reason for the
timeout. These reason codes for the connect time out are represented by
enum nl80211_timeout_reason and are passed to user space through a new
attribute NL80211_ATTR_TIMEOUT_REASON (u32).

Signed-off-by: Purushottam Kushwaha <pkush...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 15 +++
 include/uapi/linux/nl80211.h | 21 +
 net/wireless/core.h  |  4 +++-
 net/wireless/mlme.c  |  3 ++-
 net/wireless/nl80211.c   |  8 ++--
 net/wireless/nl80211.h   |  3 ++-
 net/wireless/sme.c   | 33 -
 net/wireless/util.c  |  2 +-
 8 files changed, 70 insertions(+), 19 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9dc11d3..44277fe 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5090,6 +5090,9 @@ static inline void cfg80211_testmode_event(struct sk_buff 
*skb, gfp_t gfp)
  *  %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
  *  the real status code for failures.
  * @gfp: allocation flags
+ * @timeout_reason: reason for connection timeout. This is used when the
+ * connection fails due to a timeout instead of an explicit rejection from
+ * the AP. 0 (NL80211_CONNECT_TIMEOUT_UNSPECIFIED) is used for other cases.
  *
  * It should be called by the underlying driver whenever connect() has
  * succeeded. This is similar to cfg80211_connect_result(), but with the
@@ -5099,7 +5102,8 @@ static inline void cfg80211_testmode_event(struct sk_buff 
*skb, gfp_t gfp)
 void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
  struct cfg80211_bss *bss, const u8 *req_ie,
  size_t req_ie_len, const u8 *resp_ie,
- size_t resp_ie_len, int status, gfp_t gfp);
+ size_t resp_ie_len, int status, gfp_t gfp,
+ enum nl80211_timeout_reason timeout_reason);
 
 /**
  * cfg80211_connect_result - notify cfg80211 of connection result
@@ -5125,7 +5129,8 @@ cfg80211_connect_result(struct net_device *dev, const u8 
*bssid,
u16 status, gfp_t gfp)
 {
cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, resp_ie,
-resp_ie_len, status, gfp);
+resp_ie_len, status, gfp,
+NL80211_TIMEOUT_UNSPECIFIED);
 }
 
 /**
@@ -5136,6 +5141,7 @@ cfg80211_connect_result(struct net_device *dev, const u8 
*bssid,
  * @req_ie: association request IEs (maybe be %NULL)
  * @req_ie_len: association request IEs length
  * @gfp: allocation flags
+ * @timeout_reason: reason for connection timeout.
  *
  * It should be called by the underlying driver whenever connect() has failed
  * in a sequence where no explicit authentication/association rejection was
@@ -5145,10 +5151,11 @@ cfg80211_connect_result(struct net_device *dev, const 
u8 *bssid,
  */
 static inline void
 cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,
-const u8 *req_ie, size_t req_ie_len, gfp_t gfp)
+const u8 *req_ie, size_t req_ie_len, gfp_t gfp,
+enum nl80211_timeout_reason timeout_reason)
 {
cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, NULL, 0, -1,
-gfp);
+gfp, timeout_reason);
 }
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index ebed28e..aa008f0 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1995,6 +1995,10 @@ enum nl80211_commands {
  * better BSSs. The attribute value is a packed structure
  * value as specified by  nl80211_bss_select_rssi_adjust.
  *
+ * @NL80211_ATTR_TIMEOUT_REASON: The reason for which an operation timed out.
+ * u32 attribute with an  nl80211_timeout_reason value. This is used,
+ * e.g., with %NL80211_CMD_CONNECT event.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2404,6 +2408,8 @@ enum nl80211_attrs {
NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
 
+   NL80211_ATTR_TIMEOUT_REASON,
+
/* add attributes here, update the policy in nl80211.c */
 
__NL80211_ATTR_AFTER_LAST,
@@ -4788,6 +4794,21 @@ enum nl80211_connect_failed_reason {
 };
 
 /**
+ * enum nl80211_timeout_reason - timeout reasons
+ *
+ * @NL80211_TIMEOUT_UNSPECIFIED: Timeout reason unspecified.
+ * @NL80211_TIMEOUT_SCAN: Scan (AP discovery) timed out.
+ * @NL80211_TIMEOUT_AUTH: Authentication timed out.
+ * @NL80211_TIMEOUT_ASSOC: Association tim

[PATCH v2 2/3] cfg80211: Add support to randomize TA of Public Action frames

2017-01-09 Thread Jouni Malinen
From: vamsi krishna <vam...@qti.qualcomm.com>

Add support to use a random local address (Address 2 = TA in transmit
and the same address in receive functionality) for Public Action frames
in order to improve privacy of WLAN clients. Applications fill the
random transmit address in the frame buffer in the NL80211_CMD_FRAME
command. This can be used only with the drivers that indicate support
for random local address by setting the new
NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA and/or
NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED in ext_features.

The driver needs to configure receive behavior to accept frames to the
specified random address during the time the frame exchange is pending
and such frames need to be acknowledged similarly to frames sent to the
local permanent address when this random address functionality is not
used.

Signed-off-by: vamsi krishna <vam...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/uapi/linux/nl80211.h |  6 ++
 net/wireless/mlme.c  | 21 +++--
 2 files changed, 25 insertions(+), 2 deletions(-)

v2:
- remove unnecessary NL80211_ATTR_MGMT_TX_RANDOM_SA and allow address
  change based on the driver capability flag without requiring
  explicit per-frame indication from user space
- rename "SA" to "TA" to be more accurate for the RX/ACK purposes

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 4e8bf28..ebed28e 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4727,6 +4727,10 @@ enum nl80211_feature_flags {
  * @NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI: The driver supports 
sched_scan
  * for reporting BSSs with better RSSI than the current connected BSS
  * (%NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI).
+ * @NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA: This driver supports randomized TA
+ * in @NL80211_CMD_FRAME while not associated.
+ * @NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED: This driver supports
+ * randomized TA in @NL80211_CMD_FRAME while associated.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4743,6 +4747,8 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_BEACON_RATE_VHT,
NL80211_EXT_FEATURE_FILS_STA,
NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,
+   NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA,
+   NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED,
 
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 1c63a77..b876f40 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -662,8 +662,25 @@ int cfg80211_mlme_mgmt_tx(struct 
cfg80211_registered_device *rdev,
return err;
}
 
-   if (!ether_addr_equal(mgmt->sa, wdev_address(wdev)))
-   return -EINVAL;
+   if (!ether_addr_equal(mgmt->sa, wdev_address(wdev))) {
+   /* Allow random TA to be used with Public Action frames if the
+* driver has indicated support for this. Otherwise, only allow
+* the local address to be used.
+*/
+   if (!ieee80211_is_action(mgmt->frame_control) ||
+   mgmt->u.action.category != WLAN_CATEGORY_PUBLIC)
+   return -EINVAL;
+   if (!wdev->current_bss &&
+   !wiphy_ext_feature_isset(
+   >wiphy,
+   NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA))
+   return -EINVAL;
+   if (wdev->current_bss &&
+   !wiphy_ext_feature_isset(
+   >wiphy,
+   NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED))
+   return -EINVAL;
+   }
 
/* Transmit the Action frame as requested by user space */
return rdev_mgmt_tx(rdev, wdev, params, cookie);
-- 
2.7.4



[PATCH v3 1/3] cfg80211: Add support to sched scan to report better BSSs

2017-01-09 Thread Jouni Malinen
From: vamsi krishna <vam...@qti.qualcomm.com>

Enhance sched scan to support option of finding a better BSS while in
connected state. Firmware scans the medium and reports when it finds a
known BSS which has better RSSI than the current connected BSS. New
attributes to specify the relative RSSI (compared to the current BSS)
are added to the sched scan to implement this.

Signed-off-by: vamsi krishna <vam...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 36 ++--
 include/uapi/linux/nl80211.h | 29 ++
 net/wireless/nl80211.c   | 49 ++--
 3 files changed, 101 insertions(+), 13 deletions(-)

v3:
- use struct cfg80211_bss_select_adjust as the data structure for
  specifying band preference (instead of attr hardcoded for 5 GHz)
- add relative_rssi_set boolean to have a robust mechanism for
  determining whether the NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI
  attribute was included

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index cb13789..9dc11d3 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1620,6 +1620,17 @@ struct cfg80211_sched_scan_plan {
 };
 
 /**
+ * struct cfg80211_bss_select_adjust - BSS selection with RSSI adjustment.
+ *
+ * @band: band of BSS which should match for RSSI level adjustment.
+ * @delta: value of RSSI level adjustment.
+ */
+struct cfg80211_bss_select_adjust {
+   enum nl80211_band band;
+   s8 delta;
+};
+
+/**
  * struct cfg80211_sched_scan_request - scheduled scan request description
  *
  * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans)
@@ -1654,6 +1665,16 @@ struct cfg80211_sched_scan_plan {
  * cycle.  The driver may ignore this parameter and start
  * immediately (or at any other time), if this feature is not
  * supported.
+ * @relative_rssi_set: Indicates whether @relative_rssi is set or not.
+ * @relative_rssi: Relative RSSI threshold in dB to restrict scan result
+ * reporting in connected state to cases where a matching BSS is determined
+ * to have better RSSI than the current connected BSS. The relative RSSI
+ * threshold values are ignored in disconnected state.
+ * @rssi_adjust: delta dB of RSSI preference to be given to the BSSs that 
belong
+ * to the specified band while deciding whether a better BSS is reported
+ * using @relative_rssi. If delta is a negative number, the BSSs that
+ * belong to the specified band will be penalized by delta dB in relative
+ * comparisions.
  */
 struct cfg80211_sched_scan_request {
struct cfg80211_ssid *ssids;
@@ -1673,6 +1694,10 @@ struct cfg80211_sched_scan_request {
u8 mac_addr[ETH_ALEN] __aligned(2);
u8 mac_addr_mask[ETH_ALEN] __aligned(2);
 
+   bool relative_rssi_set;
+   s8 relative_rssi;
+   struct cfg80211_bss_select_adjust rssi_adjust;
+
/* internal */
struct wiphy *wiphy;
struct net_device *dev;
@@ -1981,17 +2006,6 @@ struct cfg80211_ibss_params {
 };
 
 /**
- * struct cfg80211_bss_select_adjust - BSS selection with RSSI adjustment.
- *
- * @band: band of BSS which should match for RSSI level adjustment.
- * @delta: value of RSSI level adjustment.
- */
-struct cfg80211_bss_select_adjust {
-   enum nl80211_band band;
-   s8 delta;
-};
-
-/**
  * struct cfg80211_bss_selection - connection parameters for BSS selection.
  *
  * @behaviour: requested BSS selection behaviour.
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 174f4b3..4e8bf28 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1982,6 +1982,19 @@ enum nl80211_commands {
  * @NL80211_ATTR_BSSID: The BSSID of the AP. Note that %NL80211_ATTR_MAC is 
also
  * used in various commands/events for specifying the BSSID.
  *
+ * @NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI: Relative RSSI threshold by which
+ * other BSSs has to be better than the current connected BSS so that they
+ * get reported to user space. This will give an opportunity to userspace
+ * to consider connecting to other matching BSSs which have better RSSI
+ * than the current connected BSS by using an offloaded operation to avoid
+ * unnecessary wakeups.
+ *
+ * @NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST: When present the RSSI level for BSSs 
in
+ * the specified band is to be adjusted before doing
+ * %NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI based comparision to figure out
+ * better BSSs. The attribute value is a packed structure
+ * value as specified by  nl80211_bss_select_rssi_adjust.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2388,6 +2401,9 @@ enum nl80211_attrs {
 
NL80211_ATTR_BSSID,
 
+   NL80211_ATTR_SCHED_

[PATCH] cfg80211: Random local address for Public Action frame exchange

2016-12-20 Thread Jouni Malinen
From: vamsi krishna <vam...@qti.qualcomm.com>

Add support to use random local address (Address 2 = SA in transmit and
the same address in receive functionality) for Public Action frames in
order to improve privacy of WLAN clients. Applications fill the random
source address in the frame buffer along with setting the
NL80211_ATTR_RANDOM_SA flag when using the NL80211_CMD_FRAME command.
This can be used only with the drivers that indicate support for random
local address by setting the new NL80211_EXT_FEATURE_MGMT_TX_RANDOM_SA
and/or NL80211_EXT_FEATURE_MGMT_TX_RANDOM_SA_CONNECTED in ext_features.

The driver needs to configure receive behavior to accept frames to the
specified random address during the time the frame exchange is pending
and such frames need to be acknowledged similarly to frames sent to the
local permanent address when this random address functionality is not
used.

Signed-off-by: vamsi krishna <vam...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   |  6 ++
 include/uapi/linux/nl80211.h | 16 
 net/wireless/mlme.c  |  5 -
 net/wireless/nl80211.c   | 14 ++
 4 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ca2ac1c..c442e4c 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2303,6 +2303,11 @@ struct cfg80211_update_ft_ies_params {
  * @dont_wait_for_ack: tells the low level not to wait for an ack
  * @n_csa_offsets: length of csa_offsets array
  * @csa_offsets: array of all the csa offsets in the frame
+ * @random_sa: indicates whether the source address is randomized. When this is
+ * true, the driver needs to transmit the management frame using the
+ * address specified in the SA field (Address 2) in the buffer and the
+ * driver needs to receive and acknowledge the response frame to this
+ * address instead of its permanent MAC address.
  */
 struct cfg80211_mgmt_tx_params {
struct ieee80211_channel *chan;
@@ -2314,6 +2319,7 @@ struct cfg80211_mgmt_tx_params {
bool dont_wait_for_ack;
int n_csa_offsets;
const u16 *csa_offsets;
+   bool random_sa;
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index d74e10b..cffc117 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -567,6 +567,9 @@
  * %NL80211_ATTR_CSA_C_OFFSETS_TX is an array of offsets to CSA
  * counters which will be updated to the current value. This attribute
  * is used during CSA period.
+ * When sending a Public Action frame, %NL80211_ATTR_MGMT_TX_RANDOM_SA can
+ * be used to indicate that random local address (SA) is used for the
+ * exchange.
  * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this
  * command may be used with the corresponding cookie to cancel the wait
  * time if it is known that it is no longer necessary.
@@ -1915,6 +1918,11 @@ enum nl80211_commands {
  * %NL80211_ATTR_IFTYPE, %NL80211_ATTR_EXT_CAPA,
  * %NL80211_ATTR_EXT_CAPA_MASK, to specify the extended capabilities per
  * interface type.
+ * @NL80211_ATTR_MGMT_TX_RANDOM_SA: A flag attribute indicating whether the
+ * source address is randomized in frames sent using %NL80211_CMD_FRAME.
+ * If this flag is not set, the source address field is verified to match
+ * local MAC address. Random SA can be used only with Public Action frames
+ * (e.g., GAS/ANQP).
  *
  * @NL80211_ATTR_MU_MIMO_GROUP_DATA: array of 24 bytes that defines a MU-MIMO
  * groupID for monitor mode.
@@ -2386,6 +2394,8 @@ enum nl80211_attrs {
 
NL80211_ATTR_BSSID,
 
+   NL80211_ATTR_MGMT_TX_RANDOM_SA,
+
/* add attributes here, update the policy in nl80211.c */
 
__NL80211_ATTR_AFTER_LAST,
@@ -4697,6 +4707,10 @@ enum nl80211_feature_flags {
  * configuration (AP/mesh) with VHT rates.
  * @NL80211_EXT_FEATURE_FILS_STA: This driver supports Fast Initial Link Setup
  * with user space SME (NL80211_CMD_AUTHENTICATE) in station mode.
+ * @NL80211_EXT_FEATURE_MGMT_TX_RANDOM_SA: This driver supports randomized SA
+ * in @NL80211_CMD_FRAME while not associated.
+ * @NL80211_EXT_FEATURE_MGMT_TX_RANDOM_SA_CONNECTED: This driver supports
+ * randomized SA in @NL80211_CMD_FRAME while associated.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4712,6 +4726,8 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_BEACON_RATE_HT,
NL80211_EXT_FEATURE_BEACON_RATE_VHT,
NL80211_EXT_FEATURE_FILS_STA,
+   NL80211_EXT_FEATURE_MGMT_TX_RANDOM_SA,
+   NL80211_EXT_FEATURE_MGMT_TX_RANDOM_SA_CONNECTED,
 
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
inde

Re: ath10k firmware sends probes on DFS channels without radar detection

2016-12-15 Thread Jouni Malinen
On Thu, Dec 15, 2016 at 06:53:47PM +0100, Jean-Pierre Tosoni wrote:
> > > Thanks for the suggestion, I already tried something like this in
> > > wmi.c, with the same result:
> > >
> > > - Before patching the firmware scans DFS channels actively (with
> > probes).
> > >
> > > - After patching, the firmware scans DFS channels passively *until*
> > > any beacon is received on the DFS channel. When *any* beacon is seen,
> > > the firmware decides to scan actively on its own, without any new
> > > IR/RADAR info from the driver.
> > >
> > > So, your patch is required but not sufficient.
> > >
> > > Somehow I was able to overcome this by reloading the regulation domain
> > > in the radio card before each scan request:

Interesting.. I'm not completely sure what could have changed the
behavior based on beacon hint. I thought it was cfg80211, but if the
simple change for doing NO_IR | RADAR is not sufficient, it would seem
to imply that something else can do this. Some more debugging to do, I
guess.

> The distinction between NO_IR and CHAN_RADAR is not very clear to me.
> NO_IR appears only in the world regulatory domain so it's not relevant here.

NO_IR is a combination of not allowing AP, IBSS, or active scanning
without having somehow been enabled by another device. RADAR has that
same impact and in addition, requirement for doing radar detection and
DFS by a master device.

> I'd say
>  "the CHAN_RADAR flag should always make the firmware never do IR when
> probing"
> ...maybe, except if the channel is the operating channel. (this should
> exclude
> unassociated stations)

For most cases, I'd agree that active scanning should not be used on DFS
channels. That said, unicast Probe Request frame to the current AP while
associated could be a reasonable exception. In addition, WPS with PBC
depends on Probe Request frames to allow PBC session overlap detection,
so there might be sufficient justification to allow Probe Request frame
to be sent out for a very short duration (couple of seconds) after
seeing a Beacon frame on the channel for such special cases.

-- 
Jouni MalinenPGP id EFC895FA


Re: ath10k firmware sends probes on DFS channels without radar detection

2016-12-14 Thread Jouni Malinen
On Tue, Dec 06, 2016 at 06:02:52PM +0100, Jean-Pierre Tosoni wrote:
> This follows on the previous discussion
>   "Client station sends probes on DFS channels"
> 
> Problem:
> The combination of QCA988X firmware v10.2.4.70-2 + ath10k +
> wpa_supplicant do not comply with the norm ETSI/EN 301-893
> section 4.7; because they can send probes for 600s when no
> AP is around.
> 
> Analysis:
> The problem seems to lie in the firmware, which regards the presence
> of *any* beacon as a proof that the channel is radar-clean for 600s.

I don't think this is really firmware, but cfg80211 regulatory code and
how it interacts with ath10k..

> - there is no obvious fix working in ath10k.
> - the issue does not show up with other mac80211 devices like ath9k.
> - wpa_supplicant considers this is a kernel issue [2]

There seems to be a difference between ath9k (mac80211-based Probe
Request frame sending) and ath10k (firmware) in this area for active
scanning. mac80211 uses IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR
while ath10k uses IEEE80211_CHAN_NO_IR. I'd assume this difference
results in ath10k using cfg80211 beacon hints (etc.) to update the NO_IR
flag and that might be behind the difference you see.

Could you check whether the following change gets you the behavior you
want to see here? I have not had a chance to test this yet, but based on
code review, it looks like something that brings the same behavior to
ath10k that ath9k has for this through mac80211.


diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index aa545a1..758dbbd 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -2973,7 +2973,8 @@ static int ath10k_update_channel_list(struct ath10k *ar)
ch->chan_radar =
!!(channel->flags & IEEE80211_CHAN_RADAR);
 
-   passive = channel->flags & IEEE80211_CHAN_NO_IR;
+   passive = channel->flags & (IEEE80211_CHAN_NO_IR |
+   IEEE80211_CHAN_RADAR);
ch->passive = passive;
 
ch->freq = channel->center_freq;

-- 
Jouni MalinenPGP id EFC895FA


[PATCH v2 2/2] cfg80211: Add support to sched scan to report better BSSs

2016-12-02 Thread Jouni Malinen
From: vamsi krishna <vam...@qti.qualcomm.com>

Enhance sched scan to support option of finding a better BSS while in
connected state. Firmware scans the medium and reports when it finds a
known BSS which has better RSSI than the current connected BSS. New
attributes to specify the relative RSSI (compared to the current BSS)
are added to the sched scan to implement this.

Signed-off-by: vamsi krishna <vam...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 19 +++
 include/uapi/linux/nl80211.h | 18 ++
 net/wireless/nl80211.c   | 29 +++--
 3 files changed, 64 insertions(+), 2 deletions(-)

v2: address comments from Luca, Arend, and Johannes

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ef42749..dcdd0c4 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1626,6 +1626,22 @@ struct cfg80211_sched_scan_plan {
  * cycle.  The driver may ignore this parameter and start
  * immediately (or at any other time), if this feature is not
  * supported.
+ * @relative_rssi: Relative RSSI threshold in dB to restrict scan result
+ * reporting in connected state to cases where a matching BSS is determined
+ * to have better RSSI than the current connected BSS. The relative RSSI
+ * threshold values are ignored in disconnected state.
+ * @relative_rssi_5g_pref: The amount of RSSI preference in dB that is given to
+ * a 5 GHz BSS over 2.4 GHz BSS while looking for better BSSs in connected
+ * state. A negative value can be passed if 2.4 GHz band should be given
+ * priority to 5 GHz band.
+ * If the current connected BSS is in the 2.4 GHz band, other BSSs in the
+ * 2.4 GHz band to be reported should have better RSSI by @relative_rssi
+ * and other BSSs in the 5 GHz band to be reported should have better RSSI
+ * by (@relative_rssi - @relative_rssi_5g_pref).
+ * If the current connected BSS is in the 5 GHz band, other BSSs in the
+ * 2.4 GHz band to be reported should have better RSSI by
+ * (@relative_rssi + @relative_rssi_5g_pref) and other BSSs in the 5 GHz
+ * band to be reported should have better RSSI by by @relative_rssi.
  */
 struct cfg80211_sched_scan_request {
struct cfg80211_ssid *ssids;
@@ -1645,6 +1661,9 @@ struct cfg80211_sched_scan_request {
u8 mac_addr[ETH_ALEN] __aligned(2);
u8 mac_addr_mask[ETH_ALEN] __aligned(2);
 
+   s8 relative_rssi;
+   s8 relative_rssi_5g_pref;
+
/* internal */
struct wiphy *wiphy;
struct net_device *dev;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 6b76e3b..fc29bdb 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1980,6 +1980,17 @@ enum nl80211_commands {
  * @NL80211_ATTR_BSSID: The BSSID of the AP. Note that %NL80211_ATTR_MAC is 
also
  * used in various commands/events for specifying the BSSID.
  *
+ * @NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI: Relative RSSI threshold by which
+ * other BSSs has to be better than the current connected BSS so that they
+ * get reported to user space. This will give an opportunity to userspace
+ * to consider connecting to other matching BSSs which have better RSSI
+ * than the current connected BSS by using an offloaded operation to avoid
+ * unnecessary wakeups.
+ *
+ * @NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI_5G_PREF: The amount of RSSI 
preference
+ * to be given to 5 GHz APs over 2.4 GHz APs while searching for better
+ * BSSs than the current connected BSS.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2386,6 +2397,9 @@ enum nl80211_attrs {
 
NL80211_ATTR_BSSID,
 
+   NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
+   NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI_5G_PREF,
+
/* add attributes here, update the policy in nl80211.c */
 
__NL80211_ATTR_AFTER_LAST,
@@ -4697,6 +4711,9 @@ enum nl80211_feature_flags {
  * configuration (AP/mesh) with VHT rates.
  * @NL80211_EXT_FEATURE_FILS_STA: This driver supports Fast Initial Link Setup
  * with user space SME (NL80211_CMD_AUTHENTICATE) in station mode.
+ * @NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI: The driver supports 
sched_scan
+ * for reporting BSSs with better RSSI than the current connected BSS
+ * (%NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI).
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4712,6 +4729,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_BEACON_RATE_HT,
NL80211_EXT_FEATURE_BEACON_RATE_VHT,
NL80211_EXT_FEATURE_FILS_STA,
+   NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,
 
/* add new features before th

[PATCH v2 1/2] nl80211: Use different attrs for BSSID and random MAC addr in scan req

2016-12-02 Thread Jouni Malinen
From: Vamsi Krishna <vam...@qti.qualcomm.com>

NL80211_ATTR_MAC was used to set both the specific BSSID to be scanned
and the random MAC address to be used when privacy is enabled. When both
the features are enabled, both the BSSID and the local MAC address were
getting same value causing Probe Request frames to go with unintended
DA. Hence, this has been fixed by using a different NL80211_ATTR_BSSID
attribute to set the specific BSSID (which was the more recent addition
in cfg80211) for a scan.

Backwards compatibility with old userspace software is maintained to
some extent by allowing NL80211_ATTR_MAC to be used to set the specific
BSSID when scanning without enabling random MAC address use.

Scanning with random source MAC address was introduced by commit
ad2b26abc157 ("cfg80211: allow drivers to support random MAC addresses
for scan") and the issue was introduced with the addition of the second
user for the same attribute in commit 818965d39177 ("cfg80211: Allow a
scan request for a specific BSSID").

Fixes: 818965d39177 ("cfg80211: Allow a scan request for a specific BSSID")
Signed-off-by: Vamsi Krishna <vam...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/uapi/linux/nl80211.h |  7 ++-
 net/wireless/nl80211.c   | 16 +++-
 2 files changed, 21 insertions(+), 2 deletions(-)

v2: address comments from Luca and Johannes

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 259c9c7..6b76e3b 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -323,7 +323,7 @@
  * @NL80211_CMD_GET_SCAN: get scan results
  * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters
  * %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
- * probe requests at CCK rate or not. %NL80211_ATTR_MAC can be used to
+ * probe requests at CCK rate or not. %NL80211_ATTR_BSSID can be used to
  * specify a BSSID to scan for; if not included, the wildcard BSSID will
  * be used.
  * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to
@@ -1977,6 +1977,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED: Indicates whether or not 
multicast
  * packets should be send out as unicast to all stations (flag attribute).
  *
+ * @NL80211_ATTR_BSSID: The BSSID of the AP. Note that %NL80211_ATTR_MAC is 
also
+ * used in various commands/events for specifying the BSSID.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2381,6 +2384,8 @@ enum nl80211_attrs {
 
NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED,
 
+   NL80211_ATTR_BSSID,
+
/* add attributes here, update the policy in nl80211.c */
 
__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e4f718e..7762231 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -404,6 +404,7 @@ enum nl80211_multicast_groups {
.len = FILS_MAX_KEK_LEN },
[NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN },
[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
+   [NL80211_ATTR_BSSID] = { .len = ETH_ALEN },
 };
 
 /* policy for the key attributes */
@@ -6703,7 +6704,20 @@ static int nl80211_trigger_scan(struct sk_buff *skb, 
struct genl_info *info)
request->no_cck =
nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
 
-   if (info->attrs[NL80211_ATTR_MAC])
+   /* Initial implementation used NL80211_ATTR_MAC to set the specific
+* BSSID to scan for. This was problematic because that same attribute
+* was already used for another purpose (local random MAC address). The
+* NL80211_ATTR_BSSID attribute was added to fix this. For backwards
+* compatibility with older userspace components, also use the
+* NL80211_ATTR_MAC value here if it can be determined to be used for
+* the specific BSSID use case instead of the random MAC address
+* (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use).
+*/
+   if (info->attrs[NL80211_ATTR_BSSID])
+   memcpy(request->bssid,
+  nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN);
+   else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) &&
+info->attrs[NL80211_ATTR_MAC])
memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
   ETH_ALEN);
else
-- 
1.9.1



Re: Break-it testing for wifi

2016-11-23 Thread Jouni Malinen
On Tue, Nov 22, 2016 at 08:59:39AM -0800, Ben Greear wrote:
> On 11/22/2016 02:56 AM, Johannes Berg wrote:
> >On Mon, 2016-11-21 at 08:10 -0800, Ben Greear wrote:
> >>1)  Allow supplicant to do bad state-machine transitions (start 4-way
> >>before associating, for instance).
> >
> >Why would you do that? In order to test the AP implementation?
> 
> Yes.  And really, you should be able to do similar things on the AP to test 
> stations,
> or on IBSS/Mesh devices, etc.  hostapd already has some options to corrupt or
> drop a percentage of various management frames.  Supplicant does not as far
> as I know.

I'm not sure adding a specific option to corrupt or drop a management
frame is the best approach here. Both hostapd and wpa_supplicant have
multiple mechanisms to enable testing in CONFIG_TESTING_OPTIONS=y builds
and the most flexible cases allow the management and EAPOL frame
processing to be handled by a test script through the control interface.
This provides much more control on how to misbehave and allows that to
be done at higher layer components without having to hardcode stuff in
hostapd/wpa_supplicant (or kernel for that matter). In case of
mac80211_hwsim tests, this is done in the python scripts (see
tests/hwsim directory in hostap.git).

> Currently, supplicant can (at least with some small patches that I carry),
> add custom information elements to probe requests and similar.  But, some 
> things
> are built by mac80211 (rate-sets advertised, for instance).  So, I was 
> thinking of slightly extending
> the API so that user-space could over-ride whatever mac80211 might normally
> build itself.  That lets you more properly fuzz things from user space.

For many cases, I'd expect it to be more flexible to override full frame
payload from a test script rather than come up with more detailed (and
more complex to implement) APIs.. As far as cfg80211/mac80211 is
concerned, it might be convenient to have a command that allows user
space to force a STA entry to a specific state when working in station
mode (hostapd can already do this in AP mode). This would allow the
existing offchannel management frame TX/RX operations to be used to
perform arbitrary exchanges and with the forced state changes, this
could cover more cases related to negotiating unexpected combinations or
exchanges frames in unexpected sequence, etc.

> >>4)  Maybe some specific tests like putting in over-flow sized lengths
> >>of IEs.
> >
> >Again, fuzzing would cover this?
> 
> Yes, but for ease of use, and to cover frames generated by mac80211, I
> was thinking:
> 
> echo 0.25 > /debug/.../wlan0/mgt_fuzzer
> 
> The fuzzer would then corrupt 25% of the management frames.  And instead of 
> just randomly
> scribbling, it could also parse the frames and do some more clever (and still 
> pseudo-random)
> modifications to the frames, like re-writing IEs with bad lengths, flipping 
> bits in specific portions of the
> frame we feel might find problems, etc.

Why would this be in mac80211? I would much rather handle this type of
fuzzing operations in user space and just provide generic interfaces in
cfg80211 to allow the messages to be exchanged. For most parts, this
capability exists already today..

> >>Has anyone done anything similar they would like to share?
> >>
> >>Johannes:  Any interest in having such a framework in upstream
> >>kernels?

hostap.git tests/hwsim has quite a few such functions in testing use. I
don't think I'd support kernel changes in the style that you are
thinking of here, but I would very much support providing more generic
interfaces, where required, to allow this type of testing to be
performed from user space scripts.

> Well, there is a decent chance you could crash some firmware if you sent
> corrupted EAPOL frames to it.  And just possibly some drivers inspect packets 
> as well,
> so I was thinking that fully transmitting the frames out of the system might
> have some use.  And specifically for me, I am trying to test remote systems,
> so hwsim would not be useful for that.
> 

Lots of this capability is already there in mac80211, cfg80211, hostapd,
and wpa_supplicant.. While mac80211_hwsim tests are one of the main use
cases for this, this works fine with any mac80211-based driver for
over-the-air testing as well. For AP mode, it is possible to override
most of management frame and EAPOL processing. For STA mode, EAPOL
processing can be fully overridden and quite a few management frame
exchanges can also be handled from test scripts through wpa_supplicant
control interface, but there may still exists some more constraints on
preventing some testing combinations.

> But, if local Linux (and local userspace) itself is the test target, then 
> hwsim shou

[PATCH 2/2] cfg80211: Add support to sched scan to report better BSSs

2016-11-23 Thread Jouni Malinen
From: vamsi krishna <vam...@qti.qualcomm.com>

Enhance sched scan to support option of finding a better BSS while in
connected state. Firmware scans the medium and reports when it finds a
known BSS which has a significantly better RSSI than the current
connected BSS.

Signed-off-by: vamsi krishna <vam...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 17 +
 include/uapi/linux/nl80211.h | 17 +
 net/wireless/nl80211.c   | 32 ++--
 3 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ef42749..c62c42a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1626,6 +1626,20 @@ struct cfg80211_sched_scan_plan {
  * cycle.  The driver may ignore this parameter and start
  * immediately (or at any other time), if this feature is not
  * supported.
+ * @relative_rssi: Relative RSSI threshold to restrict scan result reporting in
+ * connected state to cases where a matching BSS is determined to have a
+ * significantly better RSSI than the current connected BSS.
+ * @relative_rssi_5g_pref: The amount of RSSI preference that is given to a
+ * 5 GHz BSS over 2.4 GHz BSS while looking for better BSSs in connected
+ * state.
+ * If the current connected BSS is in the 2.4 GHz band, other BSSs in the
+ * 2.4 GHz band to be reported should have better RSSI by @relative_rssi
+ * and other BSSs in the 5 GHz band to be reported should have better RSSI
+ * by (@relative_rssi - @relative_rssi_5g_pref).
+ * If the current connected BSS is in the 5 GHz band, other BSSs in the
+ * 2.4 GHz band to be reported should have better RSSI by
+ * (@relative_rssi + @relative_rssi_5g_pref) and other BSSs in the 5 GHz
+ * band to be reported should have better RSSI by by @relative_rssi.
  */
 struct cfg80211_sched_scan_request {
struct cfg80211_ssid *ssids;
@@ -1645,6 +1659,9 @@ struct cfg80211_sched_scan_request {
u8 mac_addr[ETH_ALEN] __aligned(2);
u8 mac_addr_mask[ETH_ALEN] __aligned(2);
 
+   int relative_rssi;
+   int relative_rssi_5g_pref;
+
/* internal */
struct wiphy *wiphy;
struct net_device *dev;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 984a35ac..34b16a4 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1981,6 +1981,16 @@ enum nl80211_commands {
  * %NL80211_ATTR_MAC has also been used in various commands/events for
  * specifying the BSSID.
  *
+ * @NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI: Relative RSSI threshold by which
+ * other BSSs has to be better than the current connected BSS so that they
+ * get reported to user space. This will give an opportunity to userspace
+ * to consider connecting to other matching BSSs which have better RSSI
+ * than the current connected BSS.
+ *
+ * @NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI_5G_PREF: The amount of RSSI 
preference
+ * to be given to 5 GHz APs over 2.4 GHz APs while searching for better
+ * BSSs than the current connected BSS.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2387,6 +2397,9 @@ enum nl80211_attrs {
 
NL80211_ATTR_BSSID,
 
+   NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
+   NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI_5G_PREF,
+
/* add attributes here, update the policy in nl80211.c */
 
__NL80211_ATTR_AFTER_LAST,
@@ -4698,6 +4711,9 @@ enum nl80211_feature_flags {
  * configuration (AP/mesh) with VHT rates.
  * @NL80211_EXT_FEATURE_FILS_STA: This driver supports Fast Initial Link Setup
  * with user space SME (NL80211_CMD_AUTHENTICATE) in station mode.
+ * @NL80211_EXT_FEATURE_SCHED_SCAN_BETTER_BSS: The driver supports sched_scan
+ * for reporting BSSs with better RSSI than the current connected BSS
+ * (%NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI).
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4713,6 +4729,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_BEACON_RATE_HT,
NL80211_EXT_FEATURE_BEACON_RATE_VHT,
NL80211_EXT_FEATURE_FILS_STA,
+   NL80211_EXT_FEATURE_SCHED_SCAN_BETTER_BSS,
 
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8db5cb1..af018a5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -405,6 +405,8 @@ enum nl80211_multicast_groups {
[NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN },
[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
[NL80211_ATTR_BSSID] =

[PATCH v2] cfg80211: Add support to update connection parameters

2016-10-27 Thread Jouni Malinen
From: vamsi krishna <vam...@qti.qualcomm.com>

Add functionality to update the connection parameters when in connected
state, so that driver/firmware uses the updated parameters for
subsequent roaming. This is for drivers that support internal BSS
selection and roaming. The new command does not change the current
association state, i.e., it can be used to update IE contents for future
(re)associations without causing an immediate disassociation or
reassociation with the current BSS.

This commit implements the required functionality for updating IEs for
(Re)Association Request frame only. Other parameters can be added in
future when required.

Signed-off-by: vamsi krishna <vam...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 24 
 include/uapi/linux/nl80211.h |  7 +++
 net/wireless/nl80211.c   | 39 +++
 net/wireless/rdev-ops.h  | 12 
 net/wireless/trace.h | 18 ++
 5 files changed, 100 insertions(+)

v2:
- Address the comments from Arend and Johannes:
  * replace _valid struct with u32 changed
  * fix couple of typos in the comments
  * remove unnecessary wrapper function from sme.c
  * use C99 initializer to clear struct data
  * use wdev_lock/unlock() around the current_bss check and driver call
- fix EOPNOTSUPP logic in nl80211_update_connect_params()

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 41ae3f5..c575583 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2051,6 +2051,18 @@ struct cfg80211_connect_params {
 };
 
 /**
+ * enum cfg80211_connect_params_changed - Connection parameters being updated
+ *
+ * This enum provides information of all connect parameters that
+ * have to be updated as part of update_connect_params() call.
+ *
+ * @UPDATE_ASSOC_IES: Indicates whether association request IEs are updated
+ */
+enum cfg80211_connect_params_changed {
+   UPDATE_ASSOC_IES= BIT(0),
+};
+
+/**
  * enum wiphy_params_flags - set_wiphy_params bitfield values
  * @WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed
  * @WIPHY_PARAM_RETRY_LONG: wiphy->retry_long has changed
@@ -2571,6 +2583,14 @@ struct cfg80211_nan_func {
  * cases, the result of roaming is indicated with a call to
  * cfg80211_roamed() or cfg80211_roamed_bss().
  * (invoked with the wireless_dev mutex held)
+ * @update_connect_params: Update the connect parameters while connected to a
+ * BSS. The updated parameters can be used by driver/firmware for
+ * subsequent BSS selection (roaming) decisions and to form the
+ * Authentication/(Re)Association Request frames. This call does not
+ * request an immediate disassociation or reassociation with the current
+ * BSS, i.e., this impacts only subsequent (re)associations. The bits in
+ * changed are defined in  cfg80211_connect_params_changed.
+ * (invoked with the wireless_dev mutex held)
  * @disconnect: Disconnect from the BSS/ESS or stop connection attempts if
  *  connection is in progress. Once done, call cfg80211_disconnected() in
  *  case connection was already established (invoked with the
@@ -2858,6 +2878,10 @@ struct cfg80211_ops {
 
int (*connect)(struct wiphy *wiphy, struct net_device *dev,
   struct cfg80211_connect_params *sme);
+   int (*update_connect_params)(struct wiphy *wiphy,
+struct net_device *dev,
+struct cfg80211_connect_params *sme,
+u32 changed);
int (*disconnect)(struct wiphy *wiphy, struct net_device *dev,
  u16 reason_code);
 
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index e21d23d..67b464f 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -888,6 +888,11 @@
  * This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and
  * %NL80211_ATTR_COOKIE.
  *
+ * @NL80211_CMD_UPDATE_CONNECT_PARAMS: Update one or more connect parameters
+ * for subsequent roaming cases if the driver or firmware uses internal
+ * BSS selection. This command can be issued only while connected and it
+ * does not result in a change for the current association.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1085,6 +1090,8 @@ enum nl80211_commands {
 
NL80211_CMD_SET_MULTICAST_TO_UNICAST,
 
+   NL80211_CMD_UPDATE_CONNECT_PARAMS,
+
/* add new commands above here */
 
/* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 46b2e8c..26821d4 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8778,6 +8778,37 @@ static int nl80211_connect(struct sk_buff *skb,

[PATCH v2 8/9] mac80211: FILS AEAD protection for station mode association frames

2016-10-26 Thread Jouni Malinen
This adds support for encrypting (Re)Association Request frame and
decryption (Re)Association Response frame when using FILS in station
mode.

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/mac80211/Makefile  |   1 +
 net/mac80211/aes_cmac.c|   8 +-
 net/mac80211/aes_cmac.h|   4 +
 net/mac80211/fils_aead.c   | 347 +
 net/mac80211/fils_aead.h   |  19 +++
 net/mac80211/ieee80211_i.h |   4 +
 net/mac80211/mlme.c|  27 
 7 files changed, 406 insertions(+), 4 deletions(-)
 create mode 100644 net/mac80211/fils_aead.c
 create mode 100644 net/mac80211/fils_aead.h

diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index f9137a8..0b202b3 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -19,6 +19,7 @@ mac80211-y := \
aes_gcm.o \
aes_cmac.o \
aes_gmac.o \
+   fils_aead.o \
cfg.o \
ethtool.o \
rx.o \
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c
index bdf0790..d0bd5ff 100644
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
@@ -23,7 +23,7 @@
 #define AAD_LEN 20
 
 
-static void gf_mulx(u8 *pad)
+void gf_mulx(u8 *pad)
 {
int i, carry;
 
@@ -35,9 +35,9 @@ static void gf_mulx(u8 *pad)
pad[AES_BLOCK_SIZE - 1] ^= 0x87;
 }
 
-static void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
-   const u8 *addr[], const size_t *len, u8 *mac,
-   size_t mac_len)
+void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
+const u8 *addr[], const size_t *len, u8 *mac,
+size_t mac_len)
 {
u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
const u8 *pos, *end;
diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h
index 3702041..c827e1d 100644
--- a/net/mac80211/aes_cmac.h
+++ b/net/mac80211/aes_cmac.h
@@ -11,6 +11,10 @@
 
 #include 
 
+void gf_mulx(u8 *pad);
+void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
+const u8 *addr[], const size_t *len, u8 *mac,
+size_t mac_len);
 struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[],
   size_t key_len);
 void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
diff --git a/net/mac80211/fils_aead.c b/net/mac80211/fils_aead.c
new file mode 100644
index 000..afc7efc
--- /dev/null
+++ b/net/mac80211/fils_aead.c
@@ -0,0 +1,347 @@
+/*
+ * FILS AEAD for (Re)Association Request/Response frames
+ * Copyright 2016, Qualcomm Atheros, Inc.
+ *
+ * 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 
+#include 
+#include 
+
+#include "ieee80211_i.h"
+#include "aes_cmac.h"
+#include "fils_aead.h"
+
+static int aes_s2v(struct crypto_cipher *tfm,
+  size_t num_elem, const u8 *addr[], size_t len[], u8 *v)
+{
+   u8 d[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE];
+   size_t i;
+   const u8 *data[2];
+   size_t data_len[2], data_elems;
+
+   /* D = AES-CMAC(K, ) */
+   memset(tmp, 0, AES_BLOCK_SIZE);
+   data[0] = tmp;
+   data_len[0] = AES_BLOCK_SIZE;
+   aes_cmac_vector(tfm, 1, data, data_len, d, AES_BLOCK_SIZE);
+
+   for (i = 0; i < num_elem - 1; i++) {
+   /* D = dbl(D) xor AES_CMAC(K, Si) */
+   gf_mulx(d); /* dbl */
+   aes_cmac_vector(tfm, 1, [i], [i], tmp,
+   AES_BLOCK_SIZE);
+   crypto_xor(d, tmp, AES_BLOCK_SIZE);
+   }
+
+   if (len[i] >= AES_BLOCK_SIZE) {
+   /* len(Sn) >= 128 */
+   size_t j;
+   const u8 *pos;
+
+   /* T = Sn xorend D */
+
+   /* Use a temporary buffer to perform xorend on Sn (addr[i]) to
+* avoid modifying the const input argument.
+*/
+   data[0] = addr[i];
+   data_len[0] = len[i] - AES_BLOCK_SIZE;
+   pos = addr[i] + data_len[0];
+   for (j = 0; j < AES_BLOCK_SIZE; j++)
+   tmp[j] = pos[j] ^ d[j];
+   data[1] = tmp;
+   data_len[1] = AES_BLOCK_SIZE;
+   data_elems = 2;
+   } else {
+   /* len(Sn) < 128 */
+   /* T = dbl(D) xor pad(Sn) */
+   gf_mulx(d); /* dbl */
+   memset(tmp, 0, AES_BLOCK_SIZE);
+   memcpy(tmp, addr[i], len[i]);
+   tmp[len[i]] = 0x80;
+   crypto_xor(d, tmp, AES_BLOCK_SIZE);
+   data[0] = d;
+   data_len[0] = sizeof(d);
+   data_elems = 1;
+   }
+   /* V = AES-CMAC(K, T) */
+   aes_cmac_vector(tfm, data_elems, data, data_len, v, AES_BLOCK_SIZE)

[PATCH v2 9/9] mac80211: Claim Fast Initial Link Setup (FILS) STA support

2016-10-26 Thread Jouni Malinen
With the previous commits, initial FILS authentication/association
support is now functional in mac80211-based drivers for station role
(and FILS AP case is covered by user space in hostapd withotu requiring
mac80211 changes).

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/mac80211/main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0d9163c..1822c77 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -549,6 +549,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t 
priv_data_len,
   NL80211_FEATURE_MAC_ON_CREATE |
   NL80211_FEATURE_USERSPACE_MPM |
   NL80211_FEATURE_FULL_AP_CLIENT_STATE;
+   wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA);
 
if (!ops->hw_scan)
wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
-- 
1.9.1



[PATCH v2 5/9] cfg80211: Add Fast Initial Link Setup (FILS) auth algs

2016-10-26 Thread Jouni Malinen
This defines authentication algorithms for FILS (IEEE 802.11ai).

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/linux/ieee80211.h|  3 +++
 include/uapi/linux/nl80211.h |  6 ++
 net/wireless/nl80211.c   | 21 +++--
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index d428adf..793a017 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1576,6 +1576,9 @@ struct ieee80211_vht_operation {
 #define WLAN_AUTH_SHARED_KEY 1
 #define WLAN_AUTH_FT 2
 #define WLAN_AUTH_SAE 3
+#define WLAN_AUTH_FILS_SK 4
+#define WLAN_AUTH_FILS_SK_PFS 5
+#define WLAN_AUTH_FILS_PK 6
 #define WLAN_AUTH_LEAP 128
 
 #define WLAN_AUTH_CHALLENGE_LEN 128
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f7e0791..dcf8f6f 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3667,6 +3667,9 @@ enum nl80211_bss_status {
  * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r)
  * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP)
  * @NL80211_AUTHTYPE_SAE: Simultaneous authentication of equals
+ * @NL80211_AUTHTYPE_FILS_SK: Fast Initial Link Setup shared key
+ * @NL80211_AUTHTYPE_FILS_SK_PFS: Fast Initial Link Setup shared key with PFS
+ * @NL80211_AUTHTYPE_FILS_PK: Fast Initial Link Setup public key
  * @__NL80211_AUTHTYPE_NUM: internal
  * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm
  * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by
@@ -3679,6 +3682,9 @@ enum nl80211_auth_type {
NL80211_AUTHTYPE_FT,
NL80211_AUTHTYPE_NETWORK_EAP,
NL80211_AUTHTYPE_SAE,
+   NL80211_AUTHTYPE_FILS_SK,
+   NL80211_AUTHTYPE_FILS_SK_PFS,
+   NL80211_AUTHTYPE_FILS_PK,
 
/* keep last */
__NL80211_AUTHTYPE_NUM,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 1a51bd4..893e321 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3777,12 +3777,23 @@ static bool nl80211_valid_auth_type(struct 
cfg80211_registered_device *rdev,
if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
auth_type == NL80211_AUTHTYPE_SAE)
return false;
+   if (!wiphy_ext_feature_isset(>wiphy,
+NL80211_EXT_FEATURE_FILS_STA) &&
+   (auth_type == NL80211_AUTHTYPE_FILS_SK ||
+auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
+auth_type == NL80211_AUTHTYPE_FILS_PK))
+   return false;
return true;
case NL80211_CMD_CONNECT:
case NL80211_CMD_START_AP:
/* SAE not supported yet */
if (auth_type == NL80211_AUTHTYPE_SAE)
return false;
+   /* FILS not supported yet */
+   if (auth_type == NL80211_AUTHTYPE_FILS_SK ||
+   auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
+   auth_type == NL80211_AUTHTYPE_FILS_PK)
+   return false;
return true;
default:
return false;
@@ -7809,12 +7820,18 @@ static int nl80211_authenticate(struct sk_buff *skb, 
struct genl_info *info)
if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
return -EINVAL;
 
-   if (auth_type == NL80211_AUTHTYPE_SAE &&
+   if ((auth_type == NL80211_AUTHTYPE_SAE ||
+auth_type == NL80211_AUTHTYPE_FILS_SK ||
+auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
+auth_type == NL80211_AUTHTYPE_FILS_PK) &&
!info->attrs[NL80211_ATTR_AUTH_DATA])
return -EINVAL;
 
if (info->attrs[NL80211_ATTR_AUTH_DATA]) {
-   if (auth_type != NL80211_AUTHTYPE_SAE)
+   if (auth_type != NL80211_AUTHTYPE_SAE &&
+   auth_type != NL80211_AUTHTYPE_FILS_SK &&
+   auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
+   auth_type != NL80211_AUTHTYPE_FILS_PK)
return -EINVAL;
auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
-- 
1.9.1



[PATCH v2 0/9] cfg80211/mac80211: Fast Initial Link Setup (IEEE 802.11ai)

2016-10-26 Thread Jouni Malinen
This series adds support for using mac80211-based drivers with Fast
Initial Link Setup as defined in IEEE 802.11ai (to be published early
next year; no more technical changes are expected at this point). The
fils branch in git://w1.fi/hostap.git includes matching commits for
hostapd and wpa_supplicant to use this functionality and initial set of
mac80211_hwsim test cases for the functionality. Actually, most of the
commits are already in the master branch, i.e., only the changes
depending on the nl80211.h changes from this kernel patchset are waiting
in the fils branch.

This series covers only the FILS authentication/association
functionality from IEEE 802.11ai, i.e., the other changes like scanning
optimizations are not included.

v2: Updates to address comments from Johannes

Jouni Malinen (9):
  cfg80211: Rename SAE_DATA to more generic AUTH_DATA
  mac80211: Allow AUTH_DATA to be used for FILS
  cfg80211: Add feature flag for Fast Initial Link Setup (FILS) as STA
  cfg80211: Define IEEE P802.11ai (FILS) information elements
  cfg80211: Add Fast Initial Link Setup (FILS) auth algs
  cfg80211: Add KEK/nonces for FILS association frames
  mac80211: Add FILS auth alg mapping
  mac80211: FILS AEAD protection for station mode association frames
  mac80211: Claim Fast Initial Link Setup (FILS) STA support

 include/linux/ieee80211.h|  26 
 include/net/cfg80211.h   |  40 -
 include/uapi/linux/nl80211.h |  30 +++-
 net/mac80211/Makefile|   1 +
 net/mac80211/aes_cmac.c  |   8 +-
 net/mac80211/aes_cmac.h  |   4 +
 net/mac80211/fils_aead.c | 347 +++
 net/mac80211/fils_aead.h |  19 +++
 net/mac80211/ieee80211_i.h   |   4 +
 net/mac80211/main.c  |   1 +
 net/mac80211/mlme.c  |  57 ++-
 net/wireless/core.h  |   2 +-
 net/wireless/mlme.c  |   6 +-
 net/wireless/nl80211.c   |  51 +--
 14 files changed, 561 insertions(+), 35 deletions(-)
 create mode 100644 net/mac80211/fils_aead.c
 create mode 100644 net/mac80211/fils_aead.h

-- 
1.9.1



[PATCH 3/8] cfg80211: Add feature flag for Fast Initial Link Setup (FILS)

2016-10-25 Thread Jouni Malinen
This defines a feature flag that drivers can use to indicate that they
support (IEEE 802.11ai) when using user space SME
(NL80211_CMD_AUTHENTICATE) in station mode.

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/uapi/linux/nl80211.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 528aa48..39e1647 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4641,6 +4641,8 @@ enum nl80211_feature_flags {
  * configuration (AP/mesh) with HT rates.
  * @NL80211_EXT_FEATURE_BEACON_RATE_VHT: Driver supports beacon rate
  * configuration (AP/mesh) with VHT rates.
+ * @NL80211_EXT_FEATURE_FILS: This driver supports Fast Initial Link Setup with
+ * user space SME (NL80211_CMD_AUTHENTICATE) in station mode.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4655,6 +4657,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_BEACON_RATE_LEGACY,
NL80211_EXT_FEATURE_BEACON_RATE_HT,
NL80211_EXT_FEATURE_BEACON_RATE_VHT,
+   NL80211_EXT_FEATURE_FILS,
 
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
-- 
1.9.1



[PATCH 8/8] mac80211: Claim Fast Initial Link Setup (FILS) support

2016-10-25 Thread Jouni Malinen
With the previous commits, initial FILS support is now functional in
mac80211-based drivers for both AP and stations roles.

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/mac80211/main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0d9163c..3e9ca80 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -549,6 +549,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t 
priv_data_len,
   NL80211_FEATURE_MAC_ON_CREATE |
   NL80211_FEATURE_USERSPACE_MPM |
   NL80211_FEATURE_FULL_AP_CLIENT_STATE;
+   wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS);
 
if (!ops->hw_scan)
wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
-- 
1.9.1



[PATCH 5/8] cfg80211: Add KEK/nonces for FILS association frames

2016-10-25 Thread Jouni Malinen
The new nl80211 attributes can be used to provide KEK and nonces to
allow the driver to encrypt and decrypt FILS (Re)Association
Request/Response frames in station mode.

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/linux/ieee80211.h|  3 +++
 include/net/cfg80211.h   |  9 +
 include/uapi/linux/nl80211.h |  8 
 net/wireless/nl80211.c   | 17 +
 4 files changed, 37 insertions(+)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 9a523d9..a39beb9 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2076,6 +2076,9 @@ enum ieee80211_key_len {
 #define IEEE80211_GCMP_MIC_LEN 16
 #define IEEE80211_GCMP_PN_LEN  6
 
+#define FILS_NONCE_LEN 16
+#define FILS_MAX_KEK_LEN   64
+
 /* Public action codes */
 enum ieee80211_pub_actioncode {
WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 2667917..a3045f1 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1842,6 +1842,12 @@ enum cfg80211_assoc_req_flags {
  * @ht_capa_mask:  The bits of ht_capa which are to be used.
  * @vht_capa: VHT capability override
  * @vht_capa_mask: VHT capability mask indicating which fields to use
+ * @fils_kek: FILS KEK for protecting (Re)Association Request/Response frame or
+ * %NULL if FILS is not used.
+ * @fils_kek_len: Length of fils_kek in octets
+ * @fils_nonces: FILS nonces (part of AAD) for protecting (Re)Association
+ * Request/Response frame or %NULL if FILS is not used. This field starts
+ * with 16 octets of STA Nonce followed by 16 octets of AP Nonce.
  */
 struct cfg80211_assoc_request {
struct cfg80211_bss *bss;
@@ -1853,6 +1859,9 @@ struct cfg80211_assoc_request {
struct ieee80211_ht_cap ht_capa;
struct ieee80211_ht_cap ht_capa_mask;
struct ieee80211_vht_cap vht_capa, vht_capa_mask;
+   const u8 *fils_kek;
+   size_t fils_kek_len;
+   const u8 *fils_nonces;
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 5d36e83..b468a89 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1938,6 +1938,11 @@ enum nl80211_commands {
  * attribute.
  * @NL80211_ATTR_NAN_MATCH: used to report a match. This is a nested attribute.
  * See  nl80211_nan_match_attributes.
+ * @NL80211_ATTR_FILS_KEK: KEK for FILS (Re)Association Request/Response frame
+ * protection.
+ * @NL80211_ATTR_FILS_NONCES: Nonces (part of AAD) for FILS (Re)Association
+ * Request/Response frame protection. This attribute contains the 16 octet
+ * STA Nonce followed by 16 octets of AP Nonce.
  *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -2338,6 +2343,9 @@ enum nl80211_attrs {
NL80211_ATTR_NAN_FUNC,
NL80211_ATTR_NAN_MATCH,
 
+   NL80211_ATTR_FILS_KEK,
+   NL80211_ATTR_FILS_NONCES,
+
/* add attributes here, update the policy in nl80211.c */
 
__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ebd7eaf..a06145c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -414,6 +414,10 @@ enum nl80211_multicast_groups {
[NL80211_ATTR_NAN_MASTER_PREF] = { .type = NLA_U8 },
[NL80211_ATTR_NAN_DUAL] = { .type = NLA_U8 },
[NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
+   [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
+   .len = FILS_MAX_KEK_LEN },
+   [NL80211_ATTR_FILS_NONCES] = { .type = NLA_BINARY,
+  .len = 2 * FILS_NONCE_LEN },
 };
 
 /* policy for the key attributes */
@@ -8019,6 +8023,19 @@ static int nl80211_associate(struct sk_buff *skb, struct 
genl_info *info)
req.flags |= ASSOC_REQ_USE_RRM;
}
 
+   if (info->attrs[NL80211_ATTR_FILS_KEK]) {
+   req.fils_kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
+   req.fils_kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
+   }
+
+   if (info->attrs[NL80211_ATTR_FILS_NONCES]) {
+   if (nla_len(info->attrs[NL80211_ATTR_FILS_NONCES]) !=
+   2 * FILS_NONCE_LEN)
+   return -EINVAL;
+   req.fils_nonces =
+   nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
+   }
+
err = nl80211_crypto_settings(rdev, info, , 1);
if (!err) {
wdev_lock(dev->ieee80211_ptr);
-- 
1.9.1



[PATCH 7/8] mac80211: FILS AEAD protection for station mode association frames

2016-10-25 Thread Jouni Malinen
This adds support for encrypting (Re)Association Request frame and
decryption (Re)Association Response frame when using FILS in station
mode.

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/mac80211/Makefile  |   1 +
 net/mac80211/aes_cmac.c|   8 +-
 net/mac80211/aes_cmac.h|   4 +
 net/mac80211/fils_aead.c   | 354 +
 net/mac80211/fils_aead.h   |  19 +++
 net/mac80211/ieee80211_i.h |   5 +
 net/mac80211/mlme.c|  34 -
 7 files changed, 420 insertions(+), 5 deletions(-)
 create mode 100644 net/mac80211/fils_aead.c
 create mode 100644 net/mac80211/fils_aead.h

diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index f9137a8..0b202b3 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -19,6 +19,7 @@ mac80211-y := \
aes_gcm.o \
aes_cmac.o \
aes_gmac.o \
+   fils_aead.o \
cfg.o \
ethtool.o \
rx.o \
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c
index bdf0790..d0bd5ff 100644
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
@@ -23,7 +23,7 @@
 #define AAD_LEN 20
 
 
-static void gf_mulx(u8 *pad)
+void gf_mulx(u8 *pad)
 {
int i, carry;
 
@@ -35,9 +35,9 @@ static void gf_mulx(u8 *pad)
pad[AES_BLOCK_SIZE - 1] ^= 0x87;
 }
 
-static void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
-   const u8 *addr[], const size_t *len, u8 *mac,
-   size_t mac_len)
+void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
+const u8 *addr[], const size_t *len, u8 *mac,
+size_t mac_len)
 {
u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
const u8 *pos, *end;
diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h
index 3702041..c827e1d 100644
--- a/net/mac80211/aes_cmac.h
+++ b/net/mac80211/aes_cmac.h
@@ -11,6 +11,10 @@
 
 #include 
 
+void gf_mulx(u8 *pad);
+void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem,
+const u8 *addr[], const size_t *len, u8 *mac,
+size_t mac_len);
 struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[],
   size_t key_len);
 void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
diff --git a/net/mac80211/fils_aead.c b/net/mac80211/fils_aead.c
new file mode 100644
index 000..358c2cb
--- /dev/null
+++ b/net/mac80211/fils_aead.c
@@ -0,0 +1,354 @@
+/*
+ * FILS AEAD for (Re)Association Request/Response frames
+ * Copyright 2016, Qualcomm Atheros, Inc.
+ *
+ * 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 
+#include 
+#include 
+
+#include "ieee80211_i.h"
+#include "aes_cmac.h"
+#include "fils_aead.h"
+
+static int aes_s2v(struct crypto_cipher *tfm,
+  size_t num_elem, const u8 *addr[], size_t len[], u8 *v)
+{
+   u8 d[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE];
+   size_t i;
+   const u8 *data[2];
+   size_t data_len[2], data_elems;
+
+   /* D = AES-CMAC(K, ) */
+   memset(tmp, 0, AES_BLOCK_SIZE);
+   data[0] = tmp;
+   data_len[0] = AES_BLOCK_SIZE;
+   aes_cmac_vector(tfm, 1, data, data_len, d, AES_BLOCK_SIZE);
+
+   for (i = 0; i < num_elem - 1; i++) {
+   /* D = dbl(D) xor AES_CMAC(K, Si) */
+   gf_mulx(d); /* dbl */
+   aes_cmac_vector(tfm, 1, [i], [i], tmp,
+   AES_BLOCK_SIZE);
+   crypto_xor(d, tmp, AES_BLOCK_SIZE);
+   }
+
+   if (len[i] >= AES_BLOCK_SIZE) {
+   /* len(Sn) >= 128 */
+   size_t j;
+   const u8 *pos;
+
+   /* T = Sn xorend D */
+
+   /* Use a temporary buffer to perform xorend on Sn (addr[i]) to
+* avoid modifying the const input argument.
+*/
+   data[0] = addr[i];
+   data_len[0] = len[i] - AES_BLOCK_SIZE;
+   pos = addr[i] + data_len[0];
+   for (j = 0; j < AES_BLOCK_SIZE; j++)
+   tmp[j] = pos[j] ^ d[j];
+   data[1] = tmp;
+   data_len[1] = AES_BLOCK_SIZE;
+   data_elems = 2;
+   } else {
+   /* len(Sn) < 128 */
+   /* T = dbl(D) xor pad(Sn) */
+   gf_mulx(d); /* dbl */
+   memset(tmp, 0, AES_BLOCK_SIZE);
+   memcpy(tmp, addr[i], len[i]);
+   tmp[len[i]] = 0x80;
+   crypto_xor(d, tmp, AES_BLOCK_SIZE);
+   data[0] = d;
+   data_len[0] = sizeof(d);
+   data_elems = 1;
+   }
+   /* V = AES-CMAC(K, T) */
+   aes_cmac_vector(tfm, data_elems, data, data_len, v, AES_BLOCK_SIZE)

[PATCH 4/8] cfg80211: Add Fast Initial Link Setup (FILS) auth algs

2016-10-25 Thread Jouni Malinen
This defines authentication algorithms for FILS (IEEE 802.11ai).

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/linux/ieee80211.h|  3 +++
 include/uapi/linux/nl80211.h |  6 ++
 net/wireless/nl80211.c   | 21 +++--
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index a80516f..9a523d9 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1576,6 +1576,9 @@ struct ieee80211_vht_operation {
 #define WLAN_AUTH_SHARED_KEY 1
 #define WLAN_AUTH_FT 2
 #define WLAN_AUTH_SAE 3
+#define WLAN_AUTH_FILS_SK 4
+#define WLAN_AUTH_FILS_SK_PFS 5
+#define WLAN_AUTH_FILS_PK 6
 #define WLAN_AUTH_LEAP 128
 
 #define WLAN_AUTH_CHALLENGE_LEN 128
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 39e1647..5d36e83 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3663,6 +3663,9 @@ enum nl80211_bss_status {
  * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r)
  * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP)
  * @NL80211_AUTHTYPE_SAE: Simultaneous authentication of equals
+ * @NL80211_AUTHTYPE_FILS_SK: Fast Initial Link Setup shared key
+ * @NL80211_AUTHTYPE_FILS_SK_PFS: Fast Initial Link Setup shared key with PFS
+ * @NL80211_AUTHTYPE_FILS_PK: Fast Initial Link Setup public key
  * @__NL80211_AUTHTYPE_NUM: internal
  * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm
  * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by
@@ -3675,6 +3678,9 @@ enum nl80211_auth_type {
NL80211_AUTHTYPE_FT,
NL80211_AUTHTYPE_NETWORK_EAP,
NL80211_AUTHTYPE_SAE,
+   NL80211_AUTHTYPE_FILS_SK,
+   NL80211_AUTHTYPE_FILS_SK_PFS,
+   NL80211_AUTHTYPE_FILS_PK,
 
/* keep last */
__NL80211_AUTHTYPE_NUM,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 36dd300..ebd7eaf 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3762,12 +3762,23 @@ static bool nl80211_valid_auth_type(struct 
cfg80211_registered_device *rdev,
if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
auth_type == NL80211_AUTHTYPE_SAE)
return false;
+   if (!wiphy_ext_feature_isset(>wiphy,
+NL80211_EXT_FEATURE_FILS) &&
+   (auth_type == NL80211_AUTHTYPE_FILS_SK ||
+auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
+auth_type == NL80211_AUTHTYPE_FILS_PK))
+   return false;
return true;
case NL80211_CMD_CONNECT:
case NL80211_CMD_START_AP:
/* SAE not supported yet */
if (auth_type == NL80211_AUTHTYPE_SAE)
return false;
+   /* FILS not supported yet */
+   if (auth_type == NL80211_AUTHTYPE_FILS_SK ||
+   auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
+   auth_type == NL80211_AUTHTYPE_FILS_PK)
+   return false;
return true;
default:
return false;
@@ -7796,12 +7807,18 @@ static int nl80211_authenticate(struct sk_buff *skb, 
struct genl_info *info)
if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
return -EINVAL;
 
-   if (auth_type == NL80211_AUTHTYPE_SAE &&
+   if ((auth_type == NL80211_AUTHTYPE_SAE ||
+auth_type == NL80211_AUTHTYPE_FILS_SK ||
+auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
+auth_type == NL80211_AUTHTYPE_FILS_PK) &&
!info->attrs[NL80211_ATTR_AUTH_DATA])
return -EINVAL;
 
if (info->attrs[NL80211_ATTR_AUTH_DATA]) {
-   if (auth_type != NL80211_AUTHTYPE_SAE)
+   if (auth_type != NL80211_AUTHTYPE_SAE &&
+   auth_type != NL80211_AUTHTYPE_FILS_SK &&
+   auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
+   auth_type != NL80211_AUTHTYPE_FILS_PK)
return -EINVAL;
auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
-- 
1.9.1



[PATCH 6/8] mac80211: Add FILS auth alg mapping

2016-10-25 Thread Jouni Malinen
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/mac80211/mlme.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b6222f2..b815f2d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2618,6 +2618,9 @@ static void ieee80211_rx_mgmt_auth(struct 
ieee80211_sub_if_data *sdata,
case WLAN_AUTH_LEAP:
case WLAN_AUTH_FT:
case WLAN_AUTH_SAE:
+   case WLAN_AUTH_FILS_SK:
+   case WLAN_AUTH_FILS_SK_PFS:
+   case WLAN_AUTH_FILS_PK:
break;
case WLAN_AUTH_SHARED_KEY:
if (ifmgd->auth_data->expected_transaction != 4) {
@@ -4479,6 +4482,15 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data 
*sdata,
case NL80211_AUTHTYPE_SAE:
auth_alg = WLAN_AUTH_SAE;
break;
+   case NL80211_AUTHTYPE_FILS_SK:
+   auth_alg = WLAN_AUTH_FILS_SK;
+   break;
+   case NL80211_AUTHTYPE_FILS_SK_PFS:
+   auth_alg = WLAN_AUTH_FILS_SK_PFS;
+   break;
+   case NL80211_AUTHTYPE_FILS_PK:
+   auth_alg = WLAN_AUTH_FILS_PK;
+   break;
default:
return -EOPNOTSUPP;
}
-- 
1.9.1



[PATCH 2/8] mac80211: Allow AUTH_DATA to be used for FILS

2016-10-25 Thread Jouni Malinen
The special SAE case should be limited only for SAE since the more
generic AUTH_DATA can now be used with other authentication algorithms
as well.

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 net/mac80211/mlme.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 32fd295..b6222f2 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4491,9 +4491,11 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data 
*sdata,
auth_data->bss = req->bss;
 
if (req->auth_data_len >= 4) {
-   __le16 *pos = (__le16 *) req->auth_data;
-   auth_data->sae_trans = le16_to_cpu(pos[0]);
-   auth_data->sae_status = le16_to_cpu(pos[1]);
+   if (req->auth_type == NL80211_AUTHTYPE_SAE) {
+   __le16 *pos = (__le16 *) req->auth_data;
+   auth_data->sae_trans = le16_to_cpu(pos[0]);
+   auth_data->sae_status = le16_to_cpu(pos[1]);
+   }
memcpy(auth_data->data, req->auth_data + 4,
   req->auth_data_len - 4);
auth_data->data_len += req->auth_data_len - 4;
-- 
1.9.1



[PATCH 1/8] cfg80211: Rename SAE_DATA to more generic AUTH_DATA

2016-10-25 Thread Jouni Malinen
This adds defines and nl80211 extensions to allow FILS Authentication to
be implemented similarly to SAE. FILS does not need the special rules
for Authentication transaction number, but it does need to add non-IE
fields. The previously used NL80211_ATTR_SAE_DATA can be reused for this
to avoid having to duplicate that implementation. Rename that attribute
to more generic NL80211_ATTR_AUTH_DATA (with backwards compatibility
define for NL80211_SAE_DATA).

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 10 +-
 include/uapi/linux/nl80211.h |  9 ++---
 net/mac80211/mlme.c  | 12 ++--
 net/wireless/core.h  |  2 +-
 net/wireless/mlme.c  |  6 +++---
 net/wireless/nl80211.c   | 18 +-
 6 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ec39f89..2667917 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1789,9 +1789,9 @@ struct cfg80211_bss {
  * @key_len: length of WEP key for shared key authentication
  * @key_idx: index of WEP key for shared key authentication
  * @key: WEP key for shared key authentication
- * @sae_data: Non-IE data to use with SAE or %NULL. This starts with
- * Authentication transaction sequence number field.
- * @sae_data_len: Length of sae_data buffer in octets
+ * @auth_data: IE and non-IE data to use with SAE/FILS or %NULL. This starts
+ * with Authentication transaction sequence number field.
+ * @auth_data_len: Length of auth_data buffer in octets
  */
 struct cfg80211_auth_request {
struct cfg80211_bss *bss;
@@ -1800,8 +1800,8 @@ struct cfg80211_auth_request {
enum nl80211_auth_type auth_type;
const u8 *key;
u8 key_len, key_idx;
-   const u8 *sae_data;
-   size_t sae_data_len;
+   const u8 *auth_data;
+   size_t auth_data_len;
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 1362d24..528aa48 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1638,8 +1638,10 @@ enum nl80211_commands {
  * the connection request from a station. nl80211_connect_failed_reason
  * enum has different reasons of connection failure.
  *
- * @NL80211_ATTR_SAE_DATA: SAE elements in Authentication frames. This starts
- * with the Authentication transaction sequence number field.
+ * @NL80211_ATTR_AUTH_DATA: Fields and elements in Authentication frames. This
+ * starts with the Authentication transaction sequence number field and is
+ * used with authentication algorithms that need special fields to be added
+ * into the frames (SAE and FILS).
  *
  * @NL80211_ATTR_VHT_CAPABILITY: VHT Capability information element (from
  * association request when used with NL80211_CMD_NEW_STATION)
@@ -2195,7 +2197,7 @@ enum nl80211_attrs {
 
NL80211_ATTR_CONN_FAILED_REASON,
 
-   NL80211_ATTR_SAE_DATA,
+   NL80211_ATTR_AUTH_DATA,
 
NL80211_ATTR_VHT_CAPABILITY,
 
@@ -2347,6 +2349,7 @@ enum nl80211_attrs {
 #define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION
 #defineNL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG
 #define NL80211_ATTR_IFACE_SOCKET_OWNER NL80211_ATTR_SOCKET_OWNER
+#define NL80211_ATTR_SAE_DATA NL80211_ATTR_AUTH_DATA
 
 /*
  * Allow user space programs to use #ifdef on new attributes by defining them
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c8d3a9b..32fd295 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4483,20 +4483,20 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data 
*sdata,
return -EOPNOTSUPP;
}
 
-   auth_data = kzalloc(sizeof(*auth_data) + req->sae_data_len +
+   auth_data = kzalloc(sizeof(*auth_data) + req->auth_data_len +
req->ie_len, GFP_KERNEL);
if (!auth_data)
return -ENOMEM;
 
auth_data->bss = req->bss;
 
-   if (req->sae_data_len >= 4) {
-   __le16 *pos = (__le16 *) req->sae_data;
+   if (req->auth_data_len >= 4) {
+   __le16 *pos = (__le16 *) req->auth_data;
auth_data->sae_trans = le16_to_cpu(pos[0]);
auth_data->sae_status = le16_to_cpu(pos[1]);
-   memcpy(auth_data->data, req->sae_data + 4,
-  req->sae_data_len - 4);
-   auth_data->data_len += req->sae_data_len - 4;
+   memcpy(auth_data->data, req->auth_data + 4,
+  req->auth_data_len - 4);
+   auth_data->data_len += req->auth_data_len - 4;
}
 
if (req->ie && req->ie_len) {
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 21e3188..fb2fcd5 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -345,7 +345,7 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device 
*r

[PATCH 0/8] cfg80211/mac80211: Fast Initial Link Setup (IEEE 802.11ai)

2016-10-25 Thread Jouni Malinen
This series adds support for using mac80211-based drivers with Fast
Initial Link Setup as defined in IEEE 802.11ai (to be published early
next year; no more technical changes are expected at this point). The
fils branch in git://w1.fi/hostap.git includes matching commits for
hostapd and wpa_supplicant to use this functionality and initial set of
mac80211_hwsim test cases for the functionality. Actually, most of the
commits are already in the master branch, i.e., only the changes
depending on the nl80211.h changes from this kernel patchset are waiting
in the fils branch.

This series covers only the FILS authentication/association
functionality from IEEE 802.11ai, i.e., the other changes like scanning
optimizations are not included.

Jouni Malinen (8):
  cfg80211: Rename SAE_DATA to more generic AUTH_DATA
  mac80211: Allow AUTH_DATA to be used for FILS
  cfg80211: Add feature flag for Fast Initial Link Setup (FILS)
  cfg80211: Add Fast Initial Link Setup (FILS) auth algs
  cfg80211: Add KEK/nonces for FILS association frames
  mac80211: Add FILS auth alg mapping
  mac80211: FILS AEAD protection for station mode association frames
  mac80211: Claim Fast Initial Link Setup (FILS) support

 include/linux/ieee80211.h|   6 +
 include/net/cfg80211.h   |  19 ++-
 include/uapi/linux/nl80211.h |  26 +++-
 net/mac80211/Makefile|   1 +
 net/mac80211/aes_cmac.c  |   8 +-
 net/mac80211/aes_cmac.h  |   4 +
 net/mac80211/fils_aead.c | 354 +++
 net/mac80211/fils_aead.h |  19 +++
 net/mac80211/ieee80211_i.h   |   5 +
 net/mac80211/main.c  |   1 +
 net/mac80211/mlme.c  |  64 ++--
 net/wireless/core.h  |   2 +-
 net/wireless/mlme.c  |   6 +-
 net/wireless/nl80211.c   |  56 +--
 14 files changed, 535 insertions(+), 36 deletions(-)
 create mode 100644 net/mac80211/fils_aead.c
 create mode 100644 net/mac80211/fils_aead.h

-- 
1.9.1



Re: [PATCH] cfg80211: add key management offload feature

2016-10-14 Thread Jouni Malinen
On Tue, Sep 27, 2016 at 02:36:15PM +0200, Johannes Berg wrote:
> > + * @NL80211_ATTR_AUTHORIZED: flag attribute, if set indicates that the
> > + *  connection is authorized.
> > @@ -2267,6 +2270,8 @@ enum nl80211_attrs {
> > +   NL80211_ATTR_AUTHORIZED,
> 
> This already exists, no?
> 
> NL80211_STA_FLAG_AUTHORIZED should be more or less equivalent, if you
> do it per station (or just for the AP in case of managed connection)

It does indeed have a very similar meaning to the proposed
NL80211_ATTR_AUTHORIZED. However, NL80211_STA_FLAG_AUTHORIZED is
something that gets nested in NL80211_ATTR_STA or used with the mask/set
struct in NL80211_ATTR_STA_FLAGS2. I'm not sure either of those would
really be very clean ways to use with a connection/roam event..

> > @@ -3687,6 +3692,9 @@ enum nl80211_key_attributes {
> > +   NL80211_KEY_REPLAY_CTR,
> > +   NL80211_KEY_KCK,
> > +   NL80211_KEY_KEK,
> 
> I don't think we should conflate the (P)MK and *TK concepts in nl80211,
> they're both keys, but they're completely separate in terms of expected
> usage.
> 
> 
> Ilan and I looked at this, considering 4-way-HS offload after 1X
> authentication, and think that the more natural API would be to add all
> the necessary data to the PMKSA cache entry. Thus, a PMKSA cache entry
> for a device that does 4-way-handshake offloading would include the PMK
> (or perhaps MSK?), and for FT it would also including the PMK-R0,
> PMKR0Name (and possibly the MDID, or can it be derived?)

PMKSA caching cases, FT protocol, and 4-way handshake following EAP
might be doable in this manner and that might indeed be the cleanest
approach there. However, there will also be need to cover possibility
for offloading FILS at some point in the future.. For FILS with shared
key, the configuration will actually include ERP keys that are not bound
to any specific Authenticator/AP/BSSID and do not really have a PMKSA
cache entry.. At latest at that point, I'd think we'll end up needing
something else and that something else could be defined already now to
cover all these cases instead of trying to force the current cases to go
through NL80211_CMD_SET_PMKSA.


> However, I'm wondering what exactly the offloads here do. Jouni, could
> you also chime in with the QCA (vendor command) design?

The QCA vendor command/event allows multiple different authentication
cases to be offloaded to the driver (well, firmware) and depending on
the driver/firmware version, there could be a bit different behavior
based on whether the particular exchange was offloaded. In other words,
there is automatic fallback to wpa_supplicant completing the exchange if
the driver does not report that it was completed.

> In particular, with key management offloaded, it's not clear to me what
> exactly the roles of the device and host are here. I'm considering that
> the device would handle the 4-way and 2-way handshakes, but then you
> wouldn't need the KEK/KCK/ReplayCounter in the host, so there wouldn't
> be much point in giving them to it.
> But if the device doesn't do that, what exactly *does* it do?

One of the key uses is to allow the Wi-Fi firmware to complete roaming
(say, 4-way handshake based on existing PMKSA) when the host processor
is not awake (i.e., wpa_supplicant is not running at all). However, this
does not mean that we would necessarily offload all EAPOL-Key
processing. GTK rekeying and the initial 4-way handshake for the first
connection to an ESS might be performed by wpa_supplicant especially in
cases where the host is awake anyway. That's why those PTK-related
values need to be kept in sync between the driver/firmware and host
(wpa_supplicant).

-- 
Jouni MalinenPGP id EFC895FA


Re: [PATCH] nl80211: add key management offload feature

2016-10-14 Thread Jouni Malinen
On Tue, Sep 27, 2016 at 01:24:24PM +0200, Arend Van Spriel wrote:
> On 27-9-2016 12:56, Amitkumar Karwar wrote:
> > From: lihz <l...@marvell.com>
> 
> minor thing. Could you use another prefix iso 'nl80211:'. That has
> different expectation for me at least, ie. changes in nl80211 api, but
> this patch is for hostap repo so 'hostap:' or 'wpa_supp:' would be
> better fit here.

Well.. That's for the context of linux-wireless. As far as the actual
commit in hostap.git and the hostap mailing list (now with the correct
address) is concerned, "nl80211:" is the correct prefix to use in the
commit message.

> > diff --git a/src/common/defs.h b/src/common/defs.h
> > @@ -148,7 +148,9 @@ enum wpa_alg {
> > -   WPA_ALG_BIP_CMAC_256
> > +   WPA_ALG_BIP_CMAC_256,
> > +   WPA_ALG_PMK_R0,
> > +   WPA_ALG_PMK_R0_NAME,

I guess I could kind of understand WPA_ALG_PMK_R0 as a new "algorithm"
since this is also used to configure keys, but PMK-R0-Name is going
pretty far in that regard. It most certainly is not a key..

> >  #define WLAN_CIPHER_SUITE_SMS4 0x00147201
> > +#define WLAN_CIPHER_SUITE_PMK  0x00147202
> > +#define WLAN_CIPHER_SUITE_PMK_R0   0x00147203
> > +#define WLAN_CIPHER_SUITE_PMK_R0_NAME  0x00147204

As noted previously, it is not acceptable to assign new AKMs from
someone else's OUI. Once there is consensus on what values are needed, I
can assign the needed values from the 00:13:74 OUI.

> > diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
> > @@ -2675,21 +2675,34 @@ static int wpa_driver_nl80211_set_key(const char 
> > *ifname, struct i802_bss *bss,
> > -#ifdef CONFIG_DRIVER_NL80211_QCA
> > -   if (alg == WPA_ALG_PMK &&
> > -   (drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
> > -   wpa_printf(MSG_DEBUG, "%s: calling issue_key_mgmt_set_key",
> > -  __func__);
> > -   ret = issue_key_mgmt_set_key(drv, key, key_len);
> > -   return ret;
> > +
> > +   if ((alg == WPA_ALG_PMK || alg == WPA_ALG_PMK_R0 ||
> > +alg == WPA_ALG_PMK_R0_NAME) &&

I understand PMK as a new key that is being configured. For FT, I'm not
completely sure about PMK-R0 as a separate algorithm and especially not
about using this interface for setting PMK-R0-Name which is tightly
coupled name with a specific PMK-R0 and not something that one would
configure separately.

> > diff --git a/src/drivers/driver_nl80211_event.c 
> > b/src/drivers/driver_nl80211_event.c
> > @@ -2065,18 +2065,6 @@ static void do_process_drv_event(struct i802_bss 
> > *bss, int cmd,
> > wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
> >cmd, nl80211_command_to_string(cmd), bss->ifname);
> >  
> > -   if (cmd == NL80211_CMD_ROAM &&
> > -   (drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
> > -   /*
> > -* Device will use roam+auth vendor event to indicate
> > -* roaming, so ignore the regular roam event.
> > -*/
> > -   wpa_printf(MSG_DEBUG,
> > -  "nl80211: Ignore roam event (cmd=%d), device will 
> > use vendor event roam+auth",
> > -  cmd);
> > -   return;
> > -   }

It is not going to be acceptable to break the existing mechanism that
uses QCA vendor specific commands/events. In other words, the new
extensions need to be done in a backwards compatible manner that allow
both to work based on driver capabilities.

> > diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c
> > @@ -37,6 +37,10 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned 
> > char *src_addr,
> > +   wpa_sm_set_key(sm, WPA_ALG_PMK_R0, NULL, 0, 1, NULL,
> > +  0, sm->pmk_r0, PMK_LEN);
> > +   wpa_sm_set_key(sm, WPA_ALG_PMK_R0_NAME, NULL, 0, 1, NULL,
> > +  0, sm->pmk_r0_name, WPA_PMK_NAME_LEN);

This looks quite bad. I don't think I can really support two separate
nl80211 commands to set a PMK-R0 and the matching PMK-R0-Name, i.e.,
this should really be a single (atomic) operation.

-- 
Jouni MalinenPGP id EFC895FA


[PATCH] cfg80211: Add support to update connection parameters

2016-10-13 Thread Jouni Malinen
From: vamsi krishna <vam...@qti.qualcomm.com>

Add functionality to update the connection parameters when in connected
state, so that driver/firmware uses the updated parameters for
subsequent roaming. This is for drivers that support internal BSS
selection and roaming. The new command does not change the current
association state, i.e., it can be used to update IE contents for future
(re)associations without causing an immediate disassociation or
reassociation with the current BSS.

This commit implements the required functionality for updating IEs for
(Re)Association Request frame only. Other parameters can be added in
future when required.

Signed-off-by: vamsi krishna <vam...@qti.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 22 ++
 include/uapi/linux/nl80211.h |  7 +++
 net/wireless/core.h  |  4 
 net/wireless/nl80211.c   | 33 +
 net/wireless/rdev-ops.h  | 13 +
 net/wireless/sme.c   | 10 ++
 net/wireless/trace.h | 19 +++
 7 files changed, 108 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 5000ec7..a4fc28a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2044,6 +2044,18 @@ struct cfg80211_connect_params {
 };
 
 /**
+ * struct cfg80211_connect_params_valid - Connection parameters to be updated
+ *
+ * This structure provides information of all connect parameters that
+ * have to be updated as part of update_connect_params() call.
+ *
+ * @assoc_ies_valid: Indicates whether association request IEs are updated
+ */
+struct cfg80211_connect_params_valid {
+   bool assoc_ies_valid;
+};
+
+/**
  * enum wiphy_params_flags - set_wiphy_params bitfield values
  * @WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed
  * @WIPHY_PARAM_RETRY_LONG: wiphy->retry_long has changed
@@ -2564,6 +2576,12 @@ struct cfg80211_nan_func {
  * cases, the result of roaming is indicated with a call to
  * cfg80211_roamed() or cfg80211_roamed_bss().
  * (invoked with the wireless_dev mutex held)
+ * @update_connect_params: Update the connect parameters while connected to a
+ * BSS. The updated parameters can be used by driver/firmware for
+ * subsequent BSS selection (roaming) decisions and to form the
+ * Authentication/(Re)Association Request frames. This call does not
+ * request an immediate disassociation or reassociation with the current
+ * BSS, i.e., this impacts only subsequence (re)associations.
  * @disconnect: Disconnect from the BSS/ESS. Once done, call
  * cfg80211_disconnected().
  * (invoked with the wireless_dev mutex held)
@@ -2848,6 +2866,10 @@ struct cfg80211_ops {
 
int (*connect)(struct wiphy *wiphy, struct net_device *dev,
   struct cfg80211_connect_params *sme);
+   int (*update_connect_params)(struct wiphy *wiphy,
+struct net_device *dev,
+struct cfg80211_connect_params *sme,
+struct cfg80211_connect_params_valid 
*cpv);
int (*disconnect)(struct wiphy *wiphy, struct net_device *dev,
  u16 reason_code);
 
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 1362d24..ee85ce1 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -874,6 +874,11 @@
  * This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and
  * %NL80211_ATTR_COOKIE.
  *
+ * @NL80211_CMD_UPDATE_CONNECT_PARAMS: Update one or more connect parameters
+ * for subsequent roaming cases if the driver or firmware uses internal
+ * BSS selection. This command can be issued only while connected and it
+ * does not result in a change for the current association.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1069,6 +1074,8 @@ enum nl80211_commands {
NL80211_CMD_CHANGE_NAN_CONFIG,
NL80211_CMD_NAN_MATCH,
 
+   NL80211_CMD_UPDATE_CONNECT_PARAMS,
+
/* add new commands above here */
 
/* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 21e3188..7b8c8d1 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -383,6 +383,10 @@ int cfg80211_connect(struct cfg80211_registered_device 
*rdev,
 struct cfg80211_connect_params *connect,
 struct cfg80211_cached_keys *connkeys,
 const u8 *prev_bssid);
+int cfg80211_update_connect_params(struct cfg80211_registered_device *rdev,
+  struct net_device *dev,
+  struct cfg80211_connect_params *connect,
+  struct cfg80211_connect_p

Re: [PATCH 6/6] cfg80211: reduce connect key caching struct size

2016-09-28 Thread Jouni Malinen
On Tue, Sep 13, 2016 at 04:44:28PM +0200, Johannes Berg wrote:
> After the previous patches, connect keys can only (correctly)
> be used for storing static WEP keys. Therefore, remove all the
> data for dealing with key index 4/5 and reduce the size of the
> key material to the maximum for WEP keys.

> diff --git a/net/wireless/core.h b/net/wireless/core.h

>  struct cfg80211_cached_keys {
> - struct key_params params[6];
> - u8 data[6][WLAN_MAX_KEY_LEN];
> - int def, defmgmt;
> + struct key_params params[4];
> + u8 data[4][WLAN_KEY_LEN_WEP104];
> + int def;
>  };

As noted in our irc discussion, this is not really a good thing to do.
WEXT compat code uses this structure for all ciphers, not just static
WEP keys. BIP configuration can use key index 4-5 and the key lengths
can go up to 32 bytes instead of WLAN_KEY_LEN_WEP104. In other words,
this patch should be dropped or reverted since it causes kernel panics
due to memory corruption when writing beyond this reduced size
structure.

This was found with hwsim tests and after full day of running full test
runs, a compressed form for easy triggering of the issue was found:

hostap/tests/hwsim/vm$ ./vm-run.sh wext_pmf wext_pmf wext_pmf wext_pmf wext_pmf 
wext_pmf
Starting test run in a virtual machine
./run-all.sh: passing the following args to run-tests.py: wext_pmf wext_pmf 
wext_pmf wext_pmf wext_pmf wext_pmf 
START wext_pmf 1/6
PASS wext_pmf 7.384815 2016-09-28 20:36:15.644646
START wext_pmf 2/6
qemu-system-x86_64: 9pfs:virtfs_reset: One or more uncluncked fids found during 
reset
qemu-system-x86_64: 9pfs:virtfs_reset: One or more uncluncked fids found during 
reset
KERNEL CRASHED!

-- 
Jouni MalinenPGP id EFC895FA


[PATCH] hostap: Mark the Host AP driver obsolete

2016-09-27 Thread Jouni Malinen
This is old code for old hardware and it is not really accurate to claim
this to be maintained anymore. Change the status to "Obsolete" to make
it clearer that minor cleanup and other unnecessary changes from
automated tools is not necessarily beneficial and has larger risk of
breaking something without being quickly noticed due to lack of testing.

In addition, remove the old mailing list that does not work anymore and
point the web-page to a more accurate URL.

Signed-off-by: Jouni Malinen <j...@w1.fi>
---
 MAINTAINERS | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index efd69c76..20de5f9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5593,10 +5593,9 @@ F:   
Documentation/devicetree/bindings/scsi/hisilicon-sas.txt
 
 HOST AP DRIVER
 M:     Jouni Malinen <j...@w1.fi>
-L: hos...@shmoo.com (subscribers-only)
 L: linux-wireless@vger.kernel.org
-W: http://hostap.epitest.fi/
-S: Maintained
+W: http://w1.fi/hostap-driver.html
+S: Obsolete
 F: drivers/net/wireless/intersil/hostap/
 
 HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER
-- 
1.9.1


-- 
Jouni MalinenPGP id EFC895FA


[PATCH] cfg80211: Add HT and VHT information in start_ap

2016-08-15 Thread Jouni Malinen
From: Peng Xu <p...@qca.qualcomm.com>

Add HT and VHT information in struct cfg80211_ap_settings when
starting ap so that driver does not need to parse IE to obtain
the information.

Signed-off-by: Peng Xu <p...@qca.qualcomm.com>
Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 15 +++
 include/uapi/linux/nl80211.h | 16 
 net/wireless/nl80211.c   | 28 
 3 files changed, 59 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9c23f4d3..6292d35 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -676,6 +676,12 @@ struct cfg80211_acl_data {
struct mac_address mac_addrs[];
 };
 
+enum ht_vht_support {
+   HT_VHT_DISABLED,
+   HT_VHT_ENABLED,
+   HT_VHT_NOT_INDICATED
+};
+
 /**
  * struct cfg80211_ap_settings - AP configuration
  *
@@ -700,6 +706,10 @@ struct cfg80211_acl_data {
  * MAC address based access control
  * @pbss: If set, start as a PCP instead of AP. Relevant for DMG
  * networks.
+ * @ht_enabled: if HT capability is enabled/disabled/not indicated
+ * @vht_enabled: if VHT capability is enabled/disabled/not indicated
+ * @require_ht: require stations to support HT PHY
+ * @require_vht: require stations to support VHT PHY
  */
 struct cfg80211_ap_settings {
struct cfg80211_chan_def chandef;
@@ -719,6 +729,11 @@ struct cfg80211_ap_settings {
bool p2p_opp_ps;
const struct cfg80211_acl_data *acl;
bool pbss;
+   enum ht_vht_support ht_enabled;
+   enum ht_vht_support vht_enabled;
+   enum ht_vht_support require_ht;
+   enum ht_vht_support require_vht;
+
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 2206941..3ce88ff 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1867,6 +1867,17 @@ enum nl80211_commands {
  * @NL80211_ATTR_MESH_PEER_AID: Association ID for the mesh peer (u16). This is
  * used to pull the stored data for mesh peer in power save state.
  *
+ * @NL80211_ATTR_HT_ENABLED: u8 value to indicate if HT capability is enabled.
+ * 0=disabled, 1=enabled, not being included as being no value available
+ * @NL80211_ATTR_VHT_ENABLED: u8 value to indicate if VHT capability is 
enabled.
+ * 0=disabled, 1=enabled, not being included as being no value available
+ * @NL80211_ATTR_REQUIRE_HT: u8 value to require stations to support HT phy.
+ * 0=not required, 1=required, not being included as being no value
+ * available
+ * @NL80211_ATTR_REQUIRE_VHT: u8 value to require stations to support VHT phy.
+ * 0=not required, 1=required, not being included as being no value
+ * available
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2261,6 +2272,11 @@ enum nl80211_attrs {
 
NL80211_ATTR_MESH_PEER_AID,
 
+   NL80211_ATTR_HT_ENABLED,
+   NL80211_ATTR_VHT_ENABLED,
+   NL80211_ATTR_REQUIRE_HT,
+   NL80211_ATTR_REQUIRE_VHT,
+
/* add attributes here, update the policy in nl80211.c */
 
__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4997857..5f66abf 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -409,6 +409,10 @@ static const struct nla_policy 
nl80211_policy[NUM_NL80211_ATTR] = {
.len = VHT_MUMIMO_GROUPS_DATA_LEN
},
[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = { .len = ETH_ALEN },
+   [NL80211_ATTR_HT_ENABLED] { .type = NLA_U8 },
+   [NL80211_ATTR_VHT_ENABLED] { .type = NLA_U8 },
+   [NL80211_ATTR_REQUIRE_HT] { .type = NLA_U8 },
+   [NL80211_ATTR_REQUIRE_VHT] { .type = NLA_U8 },
 };
 
 /* policy for the key attributes */
@@ -3557,6 +3561,30 @@ static int nl80211_start_ap(struct sk_buff *skb, struct 
genl_info *info)
return PTR_ERR(params.acl);
}
 
+   if (info->attrs[NL80211_ATTR_HT_ENABLED])
+   params.ht_enabled = nla_get_u8(
+   info->attrs[NL80211_ATTR_HT_ENABLED]);
+   else
+   params.ht_enabled = HT_VHT_NOT_INDICATED;
+
+   if (info->attrs[NL80211_ATTR_VHT_ENABLED])
+   params.vht_enabled = nla_get_u8(
+   info->attrs[NL80211_ATTR_VHT_ENABLED]);
+   else
+   params.vht_enabled = HT_VHT_NOT_INDICATED;
+
+   if (info->attrs[NL80211_ATTR_REQUIRE_HT])
+   params.require_ht = nla_get_u8(
+   info->attrs[NL80211_ATTR_REQUIRE_HT]);
+   else
+   params.require_ht = HT_VHT_NOT_INDICATED;
+
+   if (info->attrs[NL80211_ATTR_REQUIRE_VHT])
+   params.require_vht = nla_get_u8(
+   info->attrs[NL80211_ATTR_REQUIRE_VHT]);
+   else
+  

Re: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler

2016-07-22 Thread Jouni Malinen
On Fri, Jul 22, 2016 at 03:59:47PM +, Amitkumar Karwar wrote:
> I am trying to understand the problem you mentioned during IGTK rekeying. 
> Today I ran tests with two stations connecting an AP. MFP is enabled on all 
> of them.
> 
> On hostapd side, my observation is add_key() is always called followed by 
> set_default_mgmt_key(). set_default_mgmt_key() sets the key added by 
> add_key() as default key.
> 
> We are ignoring set_default_mgmt_key() and updating Tx key index during 
> add_key() itself.
> 
> Your concerns is we should not update Tx key index during add_key(). Reason 
> is IGTK rekeying is not yet completed with all stations. Right?

Correct. set_default_mgmt_key() does not have much effect for the very
first IGTK configuration, but whenever doing IGTK rekeying, hostapd
behaves just like it does with GTK rekeying. In other words, a different
Key ID is selected (alternating between 4 and 5), a random new IGTK is
generated, the new IGTK is configured to the local driver (but the old
IGTK is still supposed to be used for TX), each associated STA is
notified of the new IGTK, the new IGTK is taken into use once the group
key handshake has completed with each associated STA. It is that last
operation that needs set_default_mgmt_key() to allow this rekeying to
work correctly. If you update the TX Key ID on add_key(), you'll risk
sending out frames that some of the associated STAs do not yet have a
key to validate.

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


Re: [PATCH 5/9] mwifiex: cfg80211 set_default_mgmt_key handler

2016-07-21 Thread Jouni Malinen
On Thu, Jul 21, 2016 at 09:18:11AM +, Amitkumar Karwar wrote:
> > From: Kalle Valo [mailto:kv...@codeaurora.org]
> > Is it correct to ignore the key index? I see that brcmfmac ignores it as
> > well but I want to still confirm this.
> > 
> > Does this mean that with this patcfh mwifiex properly supports MFP?
> 
> Yes. We do pass MFP tests with this patch.

Did you test IGTK rekeying? This patch looks exactly as broken as it did
the last time it was proposed more than a year ago and after the same
concern not receiving any reaction.. hostapd will configure two
different IGTKs with different Key IDs and change the TX key on the AP
once all associated STAs have the new key. If the driver does not
support updating the TX key index, either the old or the new STAs
associated after rekeying will not have the correct key.

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


Re: [PATCH] mac80211_hwsim: Added vendor echo command

2016-06-25 Thread Jouni Malinen
On Sat, Jun 25, 2016 at 06:08:01PM +0200, Erik Stromdahl wrote:
> The mac80211_hwsim driver is currently defining the QCA vendor ID
> 0x001374 for some reason.

That is used for allowing nl80211 vendor specific commands and events to
be tested. The particular vendor command was properly assigned from the
QCA 00:13:74 OUI.

> Also, all current vendor commands are using the "QCA_" prefix, hence
> the reason why I decided to add the new vendor command with the
> "QCA_" prefix as well.
> 
> Anyway, I understand that you don't want the hwsim driver bloated
> with definitions that does not belong there.

That's not the issue here; the issue is in getting vendor subcommands
assigned by the entity who controls the OUI that is used. 

> Is there any reason why hwsim uses the QCA vendor id?

Yes, that's an OUI for which there is a process that allows new values
to be assigned.. I happen to be the one who is in control of assigning
such values.

> Perhaps it would be best if the hwsim driver would define its own vendor id?

That would need an OUI which are a bit expensive to acquire. I don't see
any point for mac80211_hwsim to need a different OUI since there is
already a friendly vendor who has provided an OUI that can be used for
this type of purposes.

In other words, you just need to follow the process defined for
assigning unique vendor subcommands/attribute identifiers for this OUI
00:13:74 and that process is what I pointed out in the previous email:

> >As far as the QCA vendor specific identifiers are concerned, their
> >assignment process is described here:
> >http://w1.fi/cgit/hostap/plain/src/common/qca-vendor.h

All you need to do is to prepare a hostap.git contribution that requests
a new subcommand/attribute to be assigned and once that gets applied to
the hostap.git master branch, the values have been assigned and can be
used for whatever purpose they were assigned, e.g., in mac80211_hwsim.

More details on how to make such a hostap.git contribution:
http://w1.fi/cgit/hostap/plain/CONTRIBUTIONS

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


Re: [PATCH] mac80211_hwsim: Added vendor echo command

2016-06-24 Thread Jouni Malinen
On Fri, Jun 24, 2016 at 10:13:54AM +0200, Erik Stromdahl wrote:
> The purpose of the echo command is to provide a test
> facility for user space programs.

> diff --git a/drivers/net/wireless/mac80211_hwsim.c 
> b/drivers/net/wireless/mac80211_hwsim.c
> @@ -332,14 +332,16 @@ static const struct ieee80211_rate hwsim_rates[] = {
>  #define QCA_NL80211_SUBCMD_TEST 1
> +#define QCA_NL80211_SUBCMD_ECHO 2

NAK. That QCA vendor specific value has not been assigned nor have I
even seen a request to assign such a value.

>  enum qca_nl80211_vendor_subcmds {
>   QCA_WLAN_VENDOR_ATTR_TEST = 8,
> - QCA_WLAN_VENDOR_ATTR_MAX = QCA_WLAN_VENDOR_ATTR_TEST
> + QCA_WLAN_VENDOR_ATTR_ECHO,

And this vendor attribute value has already been assigned for another
purpose.

It is no acceptable to pick arbitrary values of identifiers without
proper request to the owner of the OUI that is used to assign the
values.

As far as the QCA vendor specific identifiers are concerned, their
assignment process is described here:
http://w1.fi/cgit/hostap/plain/src/common/qca-vendor.h

Please do not submit kernel changes that use any unassigned vendor
identifier or even worse, a value that have already been assigned for a
completely different purpose.
 
-- 
Jouni MalinenPGP id EFC895FA
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] mac80211: Encrypt "Group addressed privacy" action frames

2016-06-21 Thread Jouni Malinen
On Tue, Jun 21, 2016 at 03:16:22PM +0900, Masashi Honma wrote:
> On 2016年06月21日 06:25, Jouni Malinen wrote:
> > What about RX side?
> 
> Previously, MGTK and IGTK was identical key.
> Now new wpa_supplicant can provide correct IGTK.

> I have tested with new IGTK, RX side can work without
> modification.

Please keep in mind that "working" here means two things:
(1) being able decrypt the frame,
(2) being able to reject the frame if it was not properly protected. It
is that (2) that is unlikely to be covered here..

We actually cover (2) for some cases by "accident" since
ieee80211_rx_h_decrypt() assigns rx->key to rx->sta->gtk[i] if one is
available. I'm not completely sure this is correct since it applies to
management frame as well, but that's the way commit
897bed8b4320774e56f282cdc1cceb4d77442797 ('mac80211: clean up RX key
checks') implemented it (Johannes: Could you please take a look whether
that gtk[] case was really supposed to apply for non-Data frames?).
Interestingly, even on the TX side, we had code that picked tx->key for
these group addressed Action frames, but that got then cleared later..

That said, if rx->sta->gtk[i] is not set for any value of i, we would
not enforce encryption of "group addressed privacy" Action frames as far
as I can tell. This may be a pretty small window since RX MGTK is
supposed to get set immediately for each peer. However, I would not be
surprised if there were indeed a window between adding the STA entry and
marking it authorized and configuring the RX MGTK. And even if this is
not possible, this should really be commented somewhere so that there is
less of a change of accidentally optimizing or cleaning up something
that is needed for this to be protected..

And when operating with PMF enabled, this is clearly broken, i.e., the
RX path accepts BIP protected version of the broadcast Mesh Action frame
while that frame needs to be rejected since it was not encrypted with
CCMP/GCMP.

To cover all these RX cases properly, I'd expect there to be RX path
changes that use ieee80211_is_group_privacy_action() and reject some
cases.. This should like be there in the !ieee80211_has_protected(fc)
case in ieee80211_rx_h_decrypt() before selecting the key and if
ieee80211_is_group_privacy_action() returns true, return RX_DROP_MONITOR
would be needed.

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


Re: [PATCH v2] mac80211: Encrypt "Group addressed privacy" action frames

2016-06-21 Thread Jouni Malinen
On Tue, Jun 21, 2016 at 03:23:39PM +0900, Masashi Honma wrote:

> diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
> +static inline bool ieee80211_is_group_privacy_action(struct ieee80211_hdr 
> *hdr)

This is somewhat problematic since no indication of the frame length is
passed in here and we are reading beyond the frame header below.. Maybe
this should use the same style as ieee80211_is_robust_mgmt_frame()
instead, i.e., use skb as the argument and define
_ieee80211_is_group_privacy_action() to take in struct ieee80211_hdr *.

> + return mgmt->u.action.category == WLAN_CATEGORY_MESH_ACTION ||
> + mgmt->u.action.category == WLAN_CATEGORY_MULTIHOP_ACTION;

These read the buffer at offset 24, i.e., just after the header. This
should do same as ieee80211_is_robust_mgmt_frame(), i.e., return false
if skb->len < 25.

> diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
> @@ -608,7 +611,6 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
>   bool skip_hw = false;
>  
>   /* TODO: add threshold stuff again */
> -
>   switch (tx->key->conf.cipher) {
>   case WLAN_CIPHER_SUITE_WEP40:
>   case WLAN_CIPHER_SUITE_WEP104:

This looks completely separate item and I don't see why we would even
delete that empty line.. In any case, it should probably not be in this
patch.
 
-- 
Jouni MalinenPGP id EFC895FA
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ath9k: Support 4.9Ghz channels on AR9580 adapter.

2016-06-21 Thread Jouni Malinen
On Tue, Jun 21, 2016 at 11:02:20AM +1000, Julian Calaby wrote:
> I've only done this work as I hate to see people's efforts go to
> waste and I feel that there's enough roadblocks in the way of
> actually using this functionality that casual idiots won't be able
> to.

Are these really ready to go to the upstream kernel in this state and
without the other changes that would be needed to operate correctly?
What is the use case for these and how have these been tested?

> This is compile tested only as I cannot test this for real as I lack
> both the hardware and license required.

I don't think this is sufficient when touching this type of area. I
would not apply these without proper testing and full set of
functionality being available. I see no point in ath9k defining
additional channels if all those new channels can cause is harm and not
correct functionality. This channel list addition looks like the easiest
part to handle compared to the other patches needed for 4.9 GHz and this
would be the last patch on my list to get accepted..


> diff --git a/drivers/net/wireless/ath/ath9k/common-init.c 
> b/drivers/net/wireless/ath/ath9k/common-init.c
> +#ifdef ATH9K_49_GHZ_CHAN
> + /* 4.9Ghz channels, public safety channels, license is required in US
> +  * and most other regulatory domains!
> +  */
> + CHAN5G(4915, 38), /* Channel 183 */
> + CHAN5G(4920, 39), /* Channel 184 */
> + CHAN5G(4925, 40), /* Channel 185 */
> + CHAN5G(4935, 41), /* Channel 187 */
> + CHAN5G(4940, 42), /* Channel 188 */
> + CHAN5G(4945, 43), /* Channel 189 */
> + CHAN5G(4960, 44), /* Channel 192 */
> + CHAN5G(4970, 45), /* Channel 194 */
> + CHAN5G(4980, 46), /* Channel 196 */

Where are these channels defined and are these really correct
frequencies for them? Please note that many of the 4.9 GHz channels have
channel starting frequencies like 4.9375 GHz and 4.0025 GHz, i.e.,
fractional MHz.. While US public safety may not have all those cases,
even there are some 0.5 MHz cases. In addition, those channel numbers
sound more like some of the channels defined in Japan rather than US
public safety operating class. In addition, some of these channels seem
to be outside the US public safety range.

Is this trying to add 4.9 GHz channels in general for multiple different
use cases? And if so, what are those use cases? Or is this only for some
public safety cases? And if so, for which regulatory domains?

To be frank, I really don't see how this would be even close to a state
that should be accepted into the upstream tree.

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


Re: [PATCH] mac80211: Encrypt "Group addressed privacy" action frames

2016-06-20 Thread Jouni Malinen
On Mon, Jun 20, 2016 at 09:51:28AM +0900, Masashi Honma wrote:
> On 2016年06月18日 18:11, Jouni Malinen wrote:
> Yes. This patch breaks backward compatibility.
> I do not have smart idea to avoid also.
> I will create new define like this.
> CONFIG_MAC80211_MESH_GROUP_ADDRESSED_PRIVACY

Do we really want that? Group addressed privacy is what the standard
requires to be used with mesh and if we make it build time configurable,
we'll just end up with two different implementation that will never
interoperate with each other.. I don't really see any better option for
this apart from fixing this and requiring all STAs in a secure mesh to
be updated in synchronized manner. This way it will be a one time issue,
but that won't be there forever.

If something is needed to for temporary backwards compatibility support,
that should be something that can be enabled at runtime (and be disabled
by default). That said, I'm not sure I'd go with that extra complexity
taken into account how badly (i.e., completely incorrectly) the PMF case
was implemented in wpa_supplicant. I'm not planning on adding any
backwards compatibility mode there for due to the previous behavior not
really being good from security view point either (using the same key
with two different algorithms).
 
-- 
Jouni MalinenPGP id EFC895FA
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mac80211: Fix mesh estab_plinks counting in STA removal case

2016-06-19 Thread Jouni Malinen
If a user space program (e.g., wpa_supplicant) deletes a STA entry that
is currently in NL80211_PLINK_ESTAB state, the number of established
plinks counter was not decremented and this could result in rejecting
new plink establishment before really hitting the real maximum plink
limit. For !user_mpm case, this decrementation is handled by
mesh_plink_deactive().

Fix this by decrementing estab_plinks on STA deletion
(mesh_sta_cleanup() gets called from there) so that the counter has a
correct value and the Beacon frame advertisement in Mesh Configuration
element shows the proper value for capability to accept additional
peers.

Signed-off-by: Jouni Malinen <j...@w1.fi>
---
 net/mac80211/mesh.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 21b1fdf..6a1603b 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -148,14 +148,17 @@ u32 mesh_accept_plinks_update(struct 
ieee80211_sub_if_data *sdata)
 void mesh_sta_cleanup(struct sta_info *sta)
 {
struct ieee80211_sub_if_data *sdata = sta->sdata;
-   u32 changed;
+   u32 changed = 0;
 
/*
 * maybe userspace handles peer allocation and peering, but in either
 * case the beacon is still generated by the kernel and we might need
 * an update.
 */
-   changed = mesh_accept_plinks_update(sdata);
+   if (sdata->u.mesh.user_mpm &&
+   sta->mesh->plink_state == NL80211_PLINK_ESTAB)
+   changed |= mesh_plink_dec_estab_count(sdata);
+   changed |= mesh_accept_plinks_update(sdata);
if (!sdata->u.mesh.user_mpm) {
changed |= mesh_plink_deactivate(sta);
del_timer_sync(>mesh->plink_timer);
-- 
1.9.1


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


Re: [PATCH] mac80211: Encrypt "Group addressed privacy" action frames

2016-06-18 Thread Jouni Malinen
On Wed, Jun 15, 2016 at 02:38:32PM +0900, Masashi Honma wrote:
> Previously, the action frames to group address was not encrypted. But
> [1] "Table 8-38 Category values" indicates "Mesh" and "Multihop" category
> action frames should be encrypted (Group addressed privacy == yes). And the
> encyption key should be MGTK ([1] 10.13 Group addressed robust management 
> frame
> procedures). So this patch modifies the code to make it suitable for spec.

>  net/mac80211/tx.c | 20 
>  1 file changed, 20 insertions(+)

What about RX side? Shouldn't there be a matching change there to
enforce use of group addressed privacy for the specific Action
categories? This will make devices using fixed implementation not
interoperate with devices using older version, I'd assume, but it looks
like the current use of mesh with RSN is pretty hopelessly broken as far
as no PMF case is concerned at least when using the wpa_supplicant
implementation (sets IGTK incorrectly and ends up using BIP even when
PMF was not enabled), so there does not seem to be any convenient way of
addressing this apart from requiring all devices in the MBSS to get
updated to the fixed versions.

> diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
> +static bool debug_noinline
> +ieee80211_is_group_privacy_action(struct ieee80211_hdr *hdr)

And this helper should likely be in some more generic location so that
it could be shared for TX and RX..

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


[PATCH] cfg80211: Allow cfg80211_connect_result() errors to be distinguished

2016-05-30 Thread Jouni Malinen
Previously, the status parameter to cfg80211_connect_result() was
documented as using WLAN_STATUS_UNSPECIFIED_FAILURE (1) when the real
status code for the failure is not known. This value can be used by an
AP (and often is) and as such, user space cannot distinguish between
explicitly rejected authentication/association and not being able to
even try to associate or not receiving a response from the AP.

Add a new inline function, cfg80211_connect_timeout(), to be used when
the driver knows that the connection attempt failed due to a reason
where connection could not be attempt or no response was received from
the AP. The internal functions now allow a negative status value (-1) to
be used as an indication of this special case. This results in the
NL80211_ATTR_TIMED_OUT to be added to the NL80211_CMD_CONNECT event to
allow user space to determine this case was hit. For backwards
compatibility, NL80211_STATUS_CODE with the value
WLAN_STATUS_UNSPECIFIED_FAILURE is still indicated in the event in such
a case.

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 54 ++--
 include/uapi/linux/nl80211.h |  7 +-
 net/wireless/core.h  |  4 ++--
 net/wireless/nl80211.c   |  7 --
 net/wireless/nl80211.h   |  2 +-
 net/wireless/sme.c   |  6 ++---
 6 files changed, 58 insertions(+), 22 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 58cdd42..b60c244 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2367,19 +2367,26 @@ struct cfg80211_qos_map {
  * (invoked with the wireless_dev mutex held)
  *
  * @connect: Connect to the ESS with the specified parameters. When connected,
- * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
- * If the connection fails for some reason, call cfg80211_connect_result()
- * with the status from the AP. The driver is allowed to roam to other
- * BSSes within the ESS when the other BSS matches the connect parameters.
- * When such roaming is initiated by the driver, the driver is expected to
- * verify that the target matches the configured security parameters and
- * to use Reassociation Request frame instead of Association Request frame.
- * The connect function can also be used to request the driver to perform
- * a specific roam when connected to an ESS. In that case, the prev_bssid
+ * call cfg80211_connect_result()/cfg80211_connect_bss() with status code
+ * %WLAN_STATUS_SUCCESS. If the connection fails for some reason, call
+ * cfg80211_connect_result()/cfg80211_connect_bss() with the status code
+ * from the AP or cfg80211_connect_timeout() if no frame with status code
+ * was received.
+ *
+ * The driver is allowed to roam to other BSSes within the ESS when the
+ * other BSS matches the connect parameters. When such roaming is initiated
+ * by the driver, the driver is expected to verify that the target matches
+ * the configured security parameters and to use Reassociation Request
+ * frame instead of Association Request frame.
+ *
+ * The connect function can also be used to request the driver to perform a
+ * specific roam when connected to an ESS. In that case, the prev_bssid
  * parameter is set to the BSSID of the currently associated BSS as an
- * indication of requesting reassociation. In both the driver-initiated and
- * new connect() call initiated roaming cases, the result of roaming is
- * indicated with a call to cfg80211_roamed() or cfg80211_roamed_bss().
+ * indication of requesting reassociation.
+ *
+ * In both the driver-initiated and new connect() call initiated roaming
+ * cases, the result of roaming is indicated with a call to
+ * cfg80211_roamed() or cfg80211_roamed_bss().
  * (invoked with the wireless_dev mutex held)
  * @disconnect: Disconnect from the BSS/ESS.
  * (invoked with the wireless_dev mutex held)
@@ -4736,6 +4743,29 @@ cfg80211_connect_result(struct net_device *dev, const u8 
*bssid,
 }
 
 /**
+ * cfg80211_connect_timeout - notify cfg80211 of connection timeout
+ *
+ * @dev: network device
+ * @bssid: the BSSID of the AP
+ * @req_ie: association request IEs (maybe be %NULL)
+ * @req_ie_len: association request IEs length
+ * @gfp: allocation flags
+ *
+ * It should be called by the underlying driver whenever connect() has failed
+ * in a sequence where no explicit authentication/association rejection was
+ * received from the AP. This could happen, e.g., due to not being able to send
+ * out the Authentication or Association Request frame or timing out while
+ * waiting for the response.
+ */
+static inline void
+cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,
+const u8 *req_ie, size_t req_ie_len, gfp_t gfp)
+{
+   cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, NULL,

Re: [PATCH v2] ath10k: remove VHT capabilities from 2.4GHz

2016-04-27 Thread Jouni Malinen
On Wed, Apr 27, 2016 at 12:13:46PM +0530, Krishna Chaitanya wrote:
> On Wed, Apr 27, 2016 at 1:40 AM, Ben Greear <gree...@candelatech.com> wrote:
> > On 04/26/2016 01:07 PM, Krishna Chaitanya wrote:
> >> Are these Broadcom IEs documented somewhere? If yes,
> >> then its a matter of parsing them and adding support to
> >> minstrel_ht, isn't it? major work would be in minstrel.

> > The end result, as far as I can tell,
> > is you would just have to tell mac80211 to allow
> > VHT on 2.4Ghz, and revert this patch that Kalle is proposing.
> 
> Ideally as this is vendor specific it makes sense to implement this
> at Driver/FW level rather than implementing it at a common stack
> like mac80211.
> 
> > Maybe someone that actually knows about these IEs can explain why
> > they are worth using?
> 
> These IE's can be parsed in the driver without any mac80211 involvement.

Sure, these are vendor specific elements, but they are simply
encapsulating the standard VHT elements that we already handle within
mac80211 for STA functionality and hostapd for AP functionality. I don't
see why we would make this any more complex for 2.4 GHz 256-QAM support
than extending the existing locations that support the VHT elements.

The main reason for me in using these particular vendor specific
elements is in them being already supported by number of deployed
devices. There is also support for these in hostapd (vendor_vht=1 in
hostapd.conf) and as far as I know, this used to work with ath10k for AP
mode (and this patch we discuss here may break that). The main missing
functionality is for the matching STA side support with mac80211 and
that's where the changes, IMHO, would fit in nicely in mac80211 next to
the places where we handle the matching standard VHT elements in the 5
GHz band.
 
-- 
Jouni MalinenPGP id EFC895FA
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] cfg80211: Improve Connect/Associate command documentation

2016-04-06 Thread Jouni Malinen
The roaming cases for the Connect command were not fully covered and
neither Connect nor Associate command uses of the prev_bssid parameter
were very clear. Add details to describe how the prev_bssid argument is
supposed to be used and when the driver should use association or
reassociation.

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h   | 26 +++---
 include/uapi/linux/nl80211.h | 16 +---
 2 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b39277e..5ec2036 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1750,7 +1750,12 @@ enum cfg80211_assoc_req_flags {
  * @ie_len: Length of ie buffer in octets
  * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
  * @crypto: crypto settings
- * @prev_bssid: previous BSSID, if not %NULL use reassociate frame
+ * @prev_bssid: previous BSSID, if not %NULL use reassociate frame. This is 
used
+ * to indicate a request to reassociate within the ESS instead of a request
+ * do the initial association with the ESS. When included, this is set to
+ * the BSSID of the current association, i.e., to the value that is
+ * included in the Current AP address field of the Reassociation Request
+ * frame.
  * @flags:  See  cfg80211_assoc_req_flags
  * @ht_capa:  HT Capabilities over-rides.  Values set in ht_capa_mask
  * will be used in ht_capa.  Un-supported values will be ignored.
@@ -1925,7 +1930,12 @@ struct cfg80211_bss_selection {
  * @pbss: if set, connect to a PCP instead of AP. Valid for DMG
  * networks.
  * @bss_select: criteria to be used for BSS selection.
- * @prev_bssid: previous BSSID, if not %NULL use reassociate frame
+ * @prev_bssid: previous BSSID, if not %NULL use reassociate frame. This is 
used
+ * to indicate a request to reassociate within the ESS instead of a request
+ * do the initial association with the ESS. When included, this is set to
+ * the BSSID of the current association, i.e., to the value that is
+ * included in the Current AP address field of the Reassociation Request
+ * frame.
  */
 struct cfg80211_connect_params {
struct ieee80211_channel *channel;
@@ -2377,7 +2387,17 @@ struct cfg80211_qos_map {
  * @connect: Connect to the ESS with the specified parameters. When connected,
  * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
  * If the connection fails for some reason, call cfg80211_connect_result()
- * with the status from the AP.
+ * with the status from the AP. The driver is allowed to roam to other
+ * BSSes within the ESS when the other BSS matches the connect parameters.
+ * When such roaming is initiated by the driver, the driver is expected to
+ * verify that the target matches the configured security parameters and
+ * to use Reassociation Request frame instead of Association Request frame.
+ * The connect function can also be used to request the driver to perform
+ * a specific roam when connected to an ESS. In that case, the prev_bssid
+ * parameter is set to the BSSID of the currently associated BSS as an
+ * indication of requesting reassociation. In both the driver-initiated and
+ * new connect() call initiated roaming cases, the result of roaming is
+ * indicated with a call to cfg80211_roamed() or cfg80211_roamed_bss().
  * (invoked with the wireless_dev mutex held)
  * @disconnect: Disconnect from the BSS/ESS.
  * (invoked with the wireless_dev mutex held)
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 6da52d7..b460628 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -429,7 +429,11 @@
  * @NL80211_CMD_ASSOCIATE: association request and notification; like
  * NL80211_CMD_AUTHENTICATE but for Association and Reassociation
  * (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request,
- * MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives).
+ * MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives). The
+ * %NL80211_ATTR_PREV_BSSID attribute is used to specify whether the
+ * request is for the initial association to an ESS (that attribute not
+ * included) or for reassociation within the ESS (that attribute is
+ * included).
  * @NL80211_CMD_DEAUTHENTICATE: deauthentication request and notification; like
  * NL80211_CMD_AUTHENTICATE but for Deauthentication frames (similar to
  * MLME-DEAUTHENTICATION.request and MLME-DEAUTHENTICATE.indication
@@ -479,6 +483,9 @@
  * set of BSSID,frequency parameters is used (i.e., either the enforcing
  * %NL80211_ATTR_MAC,%NL80211_ATTR_WIPHY_FREQ or the less strict
  * %NL80211_ATTR_MAC_HINT and %NL80211_ATTR_WIPHY_FREQ_HINT).
+ * %NL80211_ATTR_PREV_BSSID can be used to request a reassociation within
+ * the ESS i

[PATCH 1/2] cfg80211: Add option to specify previous BSSID for Connect command

2016-03-29 Thread Jouni Malinen
This extends NL80211_CMD_CONNECT to allow the NL80211_ATTR_PREV_BSSID
attribute to be used similarly to way this was already allowed with
NL80211_CMD_ASSOCIATE. This allows user space to request reassociation
(instead of association) when already connected to an AP. This provides
an option to reassociate within an ESS without having to disconnect and
associate with the AP.

Signed-off-by: Jouni Malinen <jo...@qca.qualcomm.com>
---
 include/net/cfg80211.h | 2 ++
 net/wireless/nl80211.c | 4 
 net/wireless/trace.h   | 6 --
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0bbfbf3..5fbb14d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1923,6 +1923,7 @@ struct cfg80211_bss_selection {
  * @pbss: if set, connect to a PCP instead of AP. Valid for DMG
  * networks.
  * @bss_select: criteria to be used for BSS selection.
+ * @prev_bssid: previous BSSID, if not %NULL use reassociate frame
  */
 struct cfg80211_connect_params {
struct ieee80211_channel *channel;
@@ -1947,6 +1948,7 @@ struct cfg80211_connect_params {
struct ieee80211_vht_cap vht_capa_mask;
bool pbss;
struct cfg80211_bss_selection bss_select;
+   const u8 *prev_bssid;
 };
 
 /**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d6c6449..a98665a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8024,6 +8024,10 @@ static int nl80211_connect(struct sk_buff *skb, struct 
genl_info *info)
connect.mfp = NL80211_MFP_NO;
}
 
+   if (info->attrs[NL80211_ATTR_PREV_BSSID])
+   connect.prev_bssid =
+   nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
+
if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
connect.channel = nl80211_get_valid_chan(
wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ]);
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 09b242b..8da1fae 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1259,6 +1259,7 @@ TRACE_EVENT(rdev_connect,
__field(bool, privacy)
__field(u32, wpa_versions)
__field(u32, flags)
+   MAC_ENTRY(prev_bssid)
),
TP_fast_assign(
WIPHY_ASSIGN;
@@ -1270,13 +1271,14 @@ TRACE_EVENT(rdev_connect,
__entry->privacy = sme->privacy;
__entry->wpa_versions = sme->crypto.wpa_versions;
__entry->flags = sme->flags;
+   MAC_ASSIGN(prev_bssid, sme->prev_bssid);
),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
  ", ssid: %s, auth type: %d, privacy: %s, wpa versions: %u, "
- "flags: %u",
+ "flags: %u, previous bssid: " MAC_PR_FMT,
  WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid,
  __entry->auth_type, BOOL_TO_STR(__entry->privacy),
- __entry->wpa_versions, __entry->flags)
+ __entry->wpa_versions, __entry->flags, MAC_PR_ARG(prev_bssid))
 );
 
 TRACE_EVENT(rdev_set_cqm_rssi_config,
-- 
1.9.1

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


  1   2   3   >