aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-09-30 12:29:40 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-10-17 05:02:12 -0400
commit6b8ece3a7031523a05a535761108775b1b67d272 (patch)
tree3eed867cf7205809de80b22f04ee08ccc5bbe9ea /net/mac80211/mlme.c
parente39e5b5e7206767a0f1be0e5cb7acbd0db87ae60 (diff)
mac80211: Allow station mode SAE to be implemented in user space
SAE uses two rounds of Authentication frames and both rounds require considerable calculation to be done. This commit extends the existing station mode authentication request to allow more control for user space programs to build the SAE fields and to run the authentication step ones. Only the second round with authentication transaction sequence 2 will result in moving to authenticated state. Signed-off-by: Jouni Malinen <j@w1.fi> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 04334b0b6b4e..f24884a60614 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1917,6 +1917,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1917 case WLAN_AUTH_OPEN: 1917 case WLAN_AUTH_OPEN:
1918 case WLAN_AUTH_LEAP: 1918 case WLAN_AUTH_LEAP:
1919 case WLAN_AUTH_FT: 1919 case WLAN_AUTH_FT:
1920 case WLAN_AUTH_SAE:
1920 break; 1921 break;
1921 case WLAN_AUTH_SHARED_KEY: 1922 case WLAN_AUTH_SHARED_KEY:
1922 if (ifmgd->auth_data->expected_transaction != 4) { 1923 if (ifmgd->auth_data->expected_transaction != 4) {
@@ -1936,6 +1937,15 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1936 ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; 1937 ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
1937 run_again(ifmgd, ifmgd->auth_data->timeout); 1938 run_again(ifmgd, ifmgd->auth_data->timeout);
1938 1939
1940 if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE &&
1941 ifmgd->auth_data->expected_transaction != 2) {
1942 /*
1943 * Report auth frame to user space for processing since another
1944 * round of Authentication frames is still needed.
1945 */
1946 return RX_MGMT_CFG80211_RX_AUTH;
1947 }
1948
1939 /* move station state to auth */ 1949 /* move station state to auth */
1940 mutex_lock(&sdata->local->sta_mtx); 1950 mutex_lock(&sdata->local->sta_mtx);
1941 sta = sta_info_get(sdata, bssid); 1951 sta = sta_info_get(sdata, bssid);
@@ -2762,13 +2772,23 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
2762 drv_mgd_prepare_tx(local, sdata); 2772 drv_mgd_prepare_tx(local, sdata);
2763 2773
2764 if (auth_data->bss->proberesp_ies) { 2774 if (auth_data->bss->proberesp_ies) {
2775 u16 trans = 1;
2776 u16 status = 0;
2777
2765 sdata_info(sdata, "send auth to %pM (try %d/%d)\n", 2778 sdata_info(sdata, "send auth to %pM (try %d/%d)\n",
2766 auth_data->bss->bssid, auth_data->tries, 2779 auth_data->bss->bssid, auth_data->tries,
2767 IEEE80211_AUTH_MAX_TRIES); 2780 IEEE80211_AUTH_MAX_TRIES);
2768 2781
2769 auth_data->expected_transaction = 2; 2782 auth_data->expected_transaction = 2;
2770 ieee80211_send_auth(sdata, 1, auth_data->algorithm, 0, 2783
2771 auth_data->ie, auth_data->ie_len, 2784 if (auth_data->algorithm == WLAN_AUTH_SAE) {
2785 trans = auth_data->sae_trans;
2786 status = auth_data->sae_status;
2787 auth_data->expected_transaction = trans;
2788 }
2789
2790 ieee80211_send_auth(sdata, trans, auth_data->algorithm, status,
2791 auth_data->data, auth_data->data_len,
2772 auth_data->bss->bssid, 2792 auth_data->bss->bssid,
2773 auth_data->bss->bssid, NULL, 0, 0); 2793 auth_data->bss->bssid, NULL, 0, 0);
2774 } else { 2794 } else {
@@ -3329,19 +3349,33 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
3329 case NL80211_AUTHTYPE_NETWORK_EAP: 3349 case NL80211_AUTHTYPE_NETWORK_EAP:
3330 auth_alg = WLAN_AUTH_LEAP; 3350 auth_alg = WLAN_AUTH_LEAP;
3331 break; 3351 break;
3352 case NL80211_AUTHTYPE_SAE:
3353 auth_alg = WLAN_AUTH_SAE;
3354 break;
3332 default: 3355 default:
3333 return -EOPNOTSUPP; 3356 return -EOPNOTSUPP;
3334 } 3357 }
3335 3358
3336 auth_data = kzalloc(sizeof(*auth_data) + req->ie_len, GFP_KERNEL); 3359 auth_data = kzalloc(sizeof(*auth_data) + req->sae_data_len +
3360 req->ie_len, GFP_KERNEL);
3337 if (!auth_data) 3361 if (!auth_data)
3338 return -ENOMEM; 3362 return -ENOMEM;
3339 3363
3340 auth_data->bss = req->bss; 3364 auth_data->bss = req->bss;
3341 3365
3366 if (req->sae_data_len >= 4) {
3367 __le16 *pos = (__le16 *) req->sae_data;
3368 auth_data->sae_trans = le16_to_cpu(pos[0]);
3369 auth_data->sae_status = le16_to_cpu(pos[1]);
3370 memcpy(auth_data->data, req->sae_data + 4,
3371 req->sae_data_len - 4);
3372 auth_data->data_len += req->sae_data_len - 4;
3373 }
3374
3342 if (req->ie && req->ie_len) { 3375 if (req->ie && req->ie_len) {
3343 memcpy(auth_data->ie, req->ie, req->ie_len); 3376 memcpy(&auth_data->data[auth_data->data_len],
3344 auth_data->ie_len = req->ie_len; 3377 req->ie, req->ie_len);
3378 auth_data->data_len += req->ie_len;
3345 } 3379 }
3346 3380
3347 if (req->key && req->key_len) { 3381 if (req->key && req->key_len) {