aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
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/wireless/nl80211.c
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/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c60
1 files changed, 48 insertions, 12 deletions
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;