aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-09-30 12:29:39 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-10-17 05:02:11 -0400
commite39e5b5e7206767a0f1be0e5cb7acbd0db87ae60 (patch)
treee2c8641581e3ff336586bd08fbf978da72c9a514 /net
parent0f4126e8918985ccc1beb936efd4b9d1e9005a63 (diff)
cfg80211: Allow user space to specify non-IEs to SAE Authentication
SAE extends Authentication frames with fields that are not information elements. NL80211_ATTR_IE is not suitable for these, so introduce a new attribute that can be used to specify the fields needed for SAE in station mode. Signed-off-by: Jouni Malinen <j@w1.fi> [change to verify that SAE is only used with authenticate command] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/wireless/core.h6
-rw-r--r--net/wireless/mlme.c11
-rw-r--r--net/wireless/nl80211.c60
-rw-r--r--net/wireless/sme.c2
4 files changed, 61 insertions, 18 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h
index a343be4a52bd..b8eb743fe7da 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -320,13 +320,15 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
320 const u8 *bssid, 320 const u8 *bssid,
321 const u8 *ssid, int ssid_len, 321 const u8 *ssid, int ssid_len,
322 const u8 *ie, int ie_len, 322 const u8 *ie, int ie_len,
323 const u8 *key, int key_len, int key_idx); 323 const u8 *key, int key_len, int key_idx,
324 const u8 *sae_data, int sae_data_len);
324int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 325int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
325 struct net_device *dev, struct ieee80211_channel *chan, 326 struct net_device *dev, struct ieee80211_channel *chan,
326 enum nl80211_auth_type auth_type, const u8 *bssid, 327 enum nl80211_auth_type auth_type, const u8 *bssid,
327 const u8 *ssid, int ssid_len, 328 const u8 *ssid, int ssid_len,
328 const u8 *ie, int ie_len, 329 const u8 *ie, int ie_len,
329 const u8 *key, int key_len, int key_idx); 330 const u8 *key, int key_len, int key_idx,
331 const u8 *sae_data, int sae_data_len);
330int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 332int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
331 struct net_device *dev, 333 struct net_device *dev,
332 struct ieee80211_channel *chan, 334 struct ieee80211_channel *chan,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 8016fee0752b..460d49325741 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -273,7 +273,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
273 const u8 *bssid, 273 const u8 *bssid,
274 const u8 *ssid, int ssid_len, 274 const u8 *ssid, int ssid_len,
275 const u8 *ie, int ie_len, 275 const u8 *ie, int ie_len,
276 const u8 *key, int key_len, int key_idx) 276 const u8 *key, int key_len, int key_idx,
277 const u8 *sae_data, int sae_data_len)
277{ 278{
278 struct wireless_dev *wdev = dev->ieee80211_ptr; 279 struct wireless_dev *wdev = dev->ieee80211_ptr;
279 struct cfg80211_auth_request req; 280 struct cfg80211_auth_request req;
@@ -293,6 +294,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
293 294
294 req.ie = ie; 295 req.ie = ie;
295 req.ie_len = ie_len; 296 req.ie_len = ie_len;
297 req.sae_data = sae_data;
298 req.sae_data_len = sae_data_len;
296 req.auth_type = auth_type; 299 req.auth_type = auth_type;
297 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 300 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
298 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 301 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
@@ -319,7 +322,8 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
319 enum nl80211_auth_type auth_type, const u8 *bssid, 322 enum nl80211_auth_type auth_type, const u8 *bssid,
320 const u8 *ssid, int ssid_len, 323 const u8 *ssid, int ssid_len,
321 const u8 *ie, int ie_len, 324 const u8 *ie, int ie_len,
322 const u8 *key, int key_len, int key_idx) 325 const u8 *key, int key_len, int key_idx,
326 const u8 *sae_data, int sae_data_len)
323{ 327{
324 int err; 328 int err;
325 329
@@ -327,7 +331,8 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
327 wdev_lock(dev->ieee80211_ptr); 331 wdev_lock(dev->ieee80211_ptr);
328 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 332 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
329 ssid, ssid_len, ie, ie_len, 333 ssid, ssid_len, ie, ie_len,
330 key, key_len, key_idx); 334 key, key_len, key_idx,
335 sae_data, sae_data_len);
331 wdev_unlock(dev->ieee80211_ptr); 336 wdev_unlock(dev->ieee80211_ptr);
332 mutex_unlock(&rdev->devlist_mtx); 337 mutex_unlock(&rdev->devlist_mtx);
333 338
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0418a6d5c1a6..74d8123ada77 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -23,7 +23,6 @@
23#include "nl80211.h" 23#include "nl80211.h"
24#include "reg.h" 24#include "reg.h"
25 25
26static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type);
27static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, 26static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
28 struct genl_info *info, 27 struct genl_info *info,
29 struct cfg80211_crypto_settings *settings, 28 struct cfg80211_crypto_settings *settings,
@@ -355,6 +354,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
355 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, 354 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
356 [NL80211_ATTR_WDEV] = { .type = NLA_U64 }, 355 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
357 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 }, 356 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
357 [NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, },
358}; 358};
359 359
360/* policy for the key attributes */ 360/* policy for the key attributes */
@@ -2490,6 +2490,30 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
2490 return ret; 2490 return ret;
2491} 2491}
2492 2492
2493static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
2494 enum nl80211_auth_type auth_type,
2495 enum nl80211_commands cmd)
2496{
2497 if (auth_type > NL80211_AUTHTYPE_MAX)
2498 return false;
2499
2500 switch (cmd) {
2501 case NL80211_CMD_AUTHENTICATE:
2502 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
2503 auth_type == NL80211_AUTHTYPE_SAE)
2504 return false;
2505 return true;
2506 case NL80211_CMD_CONNECT:
2507 case NL80211_CMD_START_AP:
2508 /* SAE not supported yet */
2509 if (auth_type == NL80211_AUTHTYPE_SAE)
2510 return false;
2511 return true;
2512 default:
2513 return false;
2514 }
2515}
2516
2493static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) 2517static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2494{ 2518{
2495 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2519 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2559,7 +2583,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2559 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { 2583 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
2560 params.auth_type = nla_get_u32( 2584 params.auth_type = nla_get_u32(
2561 info->attrs[NL80211_ATTR_AUTH_TYPE]); 2585 info->attrs[NL80211_ATTR_AUTH_TYPE]);
2562 if (!nl80211_valid_auth_type(params.auth_type)) 2586 if (!nl80211_valid_auth_type(rdev, params.auth_type,
2587 NL80211_CMD_START_AP))
2563 return -EINVAL; 2588 return -EINVAL;
2564 } else 2589 } else
2565 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC; 2590 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
@@ -4852,11 +4877,6 @@ static int nl80211_dump_survey(struct sk_buff *skb,
4852 return res; 4877 return res;
4853} 4878}
4854 4879
4855static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type)
4856{
4857 return auth_type <= NL80211_AUTHTYPE_MAX;
4858}
4859
4860static bool nl80211_valid_wpa_versions(u32 wpa_versions) 4880static bool nl80211_valid_wpa_versions(u32 wpa_versions)
4861{ 4881{
4862 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 | 4882 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
@@ -4868,8 +4888,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
4868 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4888 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4869 struct net_device *dev = info->user_ptr[1]; 4889 struct net_device *dev = info->user_ptr[1];
4870 struct ieee80211_channel *chan; 4890 struct ieee80211_channel *chan;
4871 const u8 *bssid, *ssid, *ie = NULL; 4891 const u8 *bssid, *ssid, *ie = NULL, *sae_data = NULL;
4872 int err, ssid_len, ie_len = 0; 4892 int err, ssid_len, ie_len = 0, sae_data_len = 0;
4873 enum nl80211_auth_type auth_type; 4893 enum nl80211_auth_type auth_type;
4874 struct key_parse key; 4894 struct key_parse key;
4875 bool local_state_change; 4895 bool local_state_change;
@@ -4945,9 +4965,23 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
4945 } 4965 }
4946 4966
4947 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); 4967 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
4948 if (!nl80211_valid_auth_type(auth_type)) 4968 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
4949 return -EINVAL; 4969 return -EINVAL;
4950 4970
4971 if (auth_type == NL80211_AUTHTYPE_SAE &&
4972 !info->attrs[NL80211_ATTR_SAE_DATA])
4973 return -EINVAL;
4974
4975 if (info->attrs[NL80211_ATTR_SAE_DATA]) {
4976 if (auth_type != NL80211_AUTHTYPE_SAE)
4977 return -EINVAL;
4978 sae_data = nla_data(info->attrs[NL80211_ATTR_SAE_DATA]);
4979 sae_data_len = nla_len(info->attrs[NL80211_ATTR_SAE_DATA]);
4980 /* need to include at least Auth Transaction and Status Code */
4981 if (sae_data_len < 4)
4982 return -EINVAL;
4983 }
4984
4951 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; 4985 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
4952 4986
4953 /* 4987 /*
@@ -4959,7 +4993,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
4959 4993
4960 return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 4994 return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
4961 ssid, ssid_len, ie, ie_len, 4995 ssid, ssid_len, ie, ie_len,
4962 key.p.key, key.p.key_len, key.idx); 4996 key.p.key, key.p.key_len, key.idx,
4997 sae_data, sae_data_len);
4963} 4998}
4964 4999
4965static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, 5000static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
@@ -5596,7 +5631,8 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
5596 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { 5631 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
5597 connect.auth_type = 5632 connect.auth_type =
5598 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); 5633 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
5599 if (!nl80211_valid_auth_type(connect.auth_type)) 5634 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
5635 NL80211_CMD_CONNECT))
5600 return -EINVAL; 5636 return -EINVAL;
5601 } else 5637 } else
5602 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; 5638 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 6f39cb808302..055d59643616 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -179,7 +179,7 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
179 params->ssid, params->ssid_len, 179 params->ssid, params->ssid_len,
180 NULL, 0, 180 NULL, 0,
181 params->key, params->key_len, 181 params->key, params->key_len,
182 params->key_idx); 182 params->key_idx, NULL, 0);
183 case CFG80211_CONN_ASSOCIATE_NEXT: 183 case CFG80211_CONN_ASSOCIATE_NEXT:
184 BUG_ON(!rdev->ops->assoc); 184 BUG_ON(!rdev->ops->assoc);
185 wdev->conn->state = CFG80211_CONN_ASSOCIATING; 185 wdev->conn->state = CFG80211_CONN_ASSOCIATING;