18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant - SME 3fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt * Copyright (c) 2009-2014, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_supp/eapol_supp_sm.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_common.h" 17a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#include "common/sae.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/wpa.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/pmksa_cache.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpas_glue.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_supplicant.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_supplicant.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "notify.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bss.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "scan.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sme.h" 3004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "hs20_supplicant.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SME_AUTH_TIMEOUT 5 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SME_ASSOC_TIMEOUT 5 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_auth_timer(void *eloop_ctx, void *timeout_ctx); 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx); 3704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx); 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_stop_sa_query(struct wpa_supplicant *wpa_s); 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 44d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 45a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic int index_within_array(const int *array, int idx) 46a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 47a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt int i; 48a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt for (i = 0; i < idx; i++) { 49cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (array[i] <= 0) 50a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 51a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 52a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 1; 53a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 54a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 55a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 56a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic int sme_set_sae_group(struct wpa_supplicant *wpa_s) 57a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 58a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt int *groups = wpa_s->conf->sae_groups; 59cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int default_groups[] = { 19, 20, 21, 25, 26, 0 }; 60a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 61cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!groups || groups[0] <= 0) 62a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt groups = default_groups; 63a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 64a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* Configuration may have changed, so validate current index */ 65a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!index_within_array(groups, wpa_s->sme.sae_group_index)) 66a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 67a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 68a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt for (;;) { 69a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt int group = groups[wpa_s->sme.sae_group_index]; 70a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (group < 0) 71a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt break; 72a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sae_set_group(&wpa_s->sme.sae, group) == 0) { 73a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected SAE group %d", 74a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.group); 75a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 76a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 77a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae_group_index++; 78a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 79a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 80a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 81a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 82a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 83a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 84a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s, 85a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt struct wpa_ssid *ssid, 86a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt const u8 *bssid) 87d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 88d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpabuf *buf; 89a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t len; 90a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 91a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (ssid->passphrase == NULL) { 92a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: No password available"); 93a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return NULL; 94a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 95d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 96a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sme_set_sae_group(wpa_s) < 0) { 97a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: Failed to select group"); 98a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return NULL; 99a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 100a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 101a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sae_prepare_commit(wpa_s->own_addr, bssid, 102a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt (u8 *) ssid->passphrase, 103a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_strlen(ssid->passphrase), 104a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt &wpa_s->sme.sae) < 0) { 105a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE"); 106a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return NULL; 107a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 108a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 109a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt len = wpa_s->sme.sae_token ? wpabuf_len(wpa_s->sme.sae_token) : 0; 110a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + len); 111d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (buf == NULL) 112d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return NULL; 113d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 114d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_le16(buf, 1); /* Transaction seq# */ 115d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS); 116a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token); 117d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 118d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return buf; 119d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 120d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 121d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 122d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic struct wpabuf * sme_auth_build_sae_confirm(struct wpa_supplicant *wpa_s) 123d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 124d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpabuf *buf; 125d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 126a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN); 127d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (buf == NULL) 128d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return NULL; 129d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 130d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_le16(buf, 2); /* Transaction seq# */ 131d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS); 132a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sae_write_confirm(&wpa_s->sme.sae, buf); 133d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 134d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return buf; 135d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 136d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 137d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 138d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 139d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 140d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic void sme_send_authentication(struct wpa_supplicant *wpa_s, 141d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_bss *bss, struct wpa_ssid *ssid, 142d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int start) 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_auth_params params; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *old_ssid; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *md = NULL; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, bssid_changed; 153d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpabuf *resp = NULL; 15409f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt u8 ext_capab[18]; 155a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt int ext_capab_len; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) { 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_ERROR, "SME: No scan result available for " 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the network"); 160fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_done(wpa_s); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_bss = bss; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->reassociate = 0; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freq = bss->freq; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bssid = bss->bssid; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid = bss->ssid; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid_len = bss->ssid_len; 1731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.p2p = ssid->p2p_group; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.ssid_len != params.ssid_len || 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(wpa_s->sme.ssid, params.ssid, params.ssid_len) != 0) 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.prev_bssid_set = 0; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.freq = params.freq; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->sme.ssid, params.ssid, params.ssid_len); 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ssid_len = params.ssid_len; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = WPA_AUTH_ALG_OPEN; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->leap) { 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->non_leap == 0) 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = WPA_AUTH_ALG_LEAP; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg |= WPA_AUTH_ALG_LEAP; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */ 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->auth_alg) { 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = ssid->auth_alg; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: " 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "0x%x", params.auth_alg); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 201d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 202d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_key_mgmt_sae(ssid->key_mgmt)) { 203d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const u8 *rsn; 204d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ie_data ied; 205d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 206d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); 207d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (rsn && 208d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0) { 209d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_key_mgmt_sae(ied.key_mgmt)) { 210d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Using SAE auth_alg"); 211d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt params.auth_alg = WPA_AUTH_ALG_SAE; 212d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 213d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 214d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 215d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < NUM_WEP_KEYS; i++) { 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->wep_key_len[i]) 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wep_key[i] = ssid->wep_key[i]; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wep_key_len[i] = ssid->wep_key_len[i]; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wep_tx_keyidx = ssid->wep_tx_keyidx; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid_changed = !is_zero_ether_addr(wpa_s->bssid); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->bssid, 0, ETH_ALEN); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid_changed) 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_bssid_changed(wpa_s); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) || 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_bss_get_ie(bss, WLAN_EID_RSN)) && 2321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_key_mgmt_wpa(ssid->key_mgmt)) { 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int try_opportunistic; 234d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt try_opportunistic = (ssid->proactive_key_caching < 0 ? 235d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->conf->okc : 236d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ssid->proactive_key_caching) && 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (ssid->proto & WPA_PROTO_RSN); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid, 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt try_opportunistic) == 0) 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_set_suites(wpa_s, bss, ssid, 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie, 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &wpa_s->sme.assoc_req_ie_len)) { 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA " 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key management and encryption suites"); 248fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_done(wpa_s); 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && 25261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) { 25361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 25461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Both WPA and non-WPA IEEE 802.1X enabled in configuration - 25561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * use non-WPA since the scan results did not indicate that the 25661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * AP is using WPA or WPA2. 25761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 25861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 25961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = 0; 2601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) { 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_set_suites(wpa_s, NULL, ssid, 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie, 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &wpa_s->sme.assoc_req_ie_len)) { 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA " 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key management and encryption suites (no " 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "scan results)"); 268fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_done(wpa_s); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) { 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps_ie; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid)); 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_ie && wpabuf_len(wps_ie) <= 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->sme.assoc_req_ie)) { 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = wpabuf_len(wps_ie); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->sme.assoc_req_ie, wpabuf_head(wps_ie), 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = 0; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = 0; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN) 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt md = ie + 2; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (md) { 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Prepare for the next transition */ 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ft_prepare_auth_request(wpa_s->wpa, ie); 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (md && wpa_key_mgmt_ft(ssid->key_mgmt)) { 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.assoc_req_ie_len + 5 < 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->sme.assoc_req_ie)) { 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rsn_mdie *mdie; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos = wpa_s->sme.assoc_req_ie + 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_MOBILITY_DOMAIN; 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = sizeof(*mdie); 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mdie = (struct rsn_mdie *) pos; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mdie->mobility_domain, md, 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MOBILITY_DOMAIN_ID_LEN); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mdie->ft_capab = md[MOBILITY_DOMAIN_ID_LEN]; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len += 5; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.ft_used && 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(md, wpa_s->sme.mobility_domain, 2) == 0 && 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_has_ptk(wpa_s->wpa)) { 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying to use FT " 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "over-the-air"); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = WPA_AUTH_ALG_FT; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ie = wpa_s->sme.ft_ies; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ie_len = wpa_s->sme.ft_ies_len; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 328d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->sme.mfp = ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ? 329d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->conf->pmf : ssid->ieee80211w; 330d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->sme.mfp != NO_MGMT_FRAME_PROTECTION) { 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ie_data _ie; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 && 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _ie.capabilities & 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) { 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected AP supports " 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "MFP: require MFP"); 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED; 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) { 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(wpa_s->sme.assoc_req_ie) - 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len; 3511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len, 3521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid->p2p_group); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res >= 0) 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len += res; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_HS20 35951b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (is_hs20_network(wpa_s, ssid, bss)) { 36004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *hs20; 36104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hs20 = wpabuf_alloc(20); 36204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hs20) { 363f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid); 364c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt size_t len; 365c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 366f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpas_hs20_add_indication(hs20, pps_mo_id); 367c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt len = sizeof(wpa_s->sme.assoc_req_ie) - 368c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt wpa_s->sme.assoc_req_ie_len; 369c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (wpabuf_len(hs20) <= len) { 370c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memcpy(wpa_s->sme.assoc_req_ie + 371c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt wpa_s->sme.assoc_req_ie_len, 372c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt wpabuf_head(hs20), wpabuf_len(hs20)); 373c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt wpa_s->sme.assoc_req_ie_len += wpabuf_len(hs20); 374c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt } 37504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_free(hs20); 37604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 37704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 37804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_HS20 */ 37904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 38009f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab, 38109f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt sizeof(ext_capab)); 382a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (ext_capab_len > 0) { 3831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 *pos = wpa_s->sme.assoc_req_ie; 3841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->sme.assoc_req_ie_len > 0 && pos[0] == WLAN_EID_RSN) 3851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos += 2 + pos[1]; 386a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memmove(pos + ext_capab_len, pos, 3871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sme.assoc_req_ie_len - 3881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (pos - wpa_s->sme.assoc_req_ie)); 389a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.assoc_req_ie_len += ext_capab_len; 390a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memcpy(pos, ext_capab, ext_capab_len); 3911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 393d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 394d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (params.auth_alg == WPA_AUTH_ALG_SAE) { 395d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (start) 396a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt resp = sme_auth_build_sae_commit(wpa_s, ssid, 397a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt bss->bssid); 398d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt else 399d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt resp = sme_auth_build_sae_confirm(wpa_s); 400fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (resp == NULL) { 401fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_done(wpa_s); 402d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 403fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 404d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt params.sae_data = wpabuf_head(resp); 405d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt params.sae_data_len = wpabuf_len(resp); 406a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.state = start ? SAE_COMMITTED : SAE_CONFIRMED; 407d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 408d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 409d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_cancel_scan(wpa_s); 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Trying to authenticate with " MACSTR 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid), 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ssid_txt(params.ssid, params.ssid_len), params.freq); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_clear_keys(wpa_s, bss->bssid); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt old_ssid = wpa_s->current_ssid; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid = ssid; 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_initiate_eapol(wpa_s); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (old_ssid != wpa_s->current_ssid) 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_network_changed(wpa_s); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 426f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt#ifdef CONFIG_P2P 427f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt /* 428f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt * If multi-channel concurrency is not supported, check for any 429f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt * frequency conflict. In case of any frequency conflict, remove the 430f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt * least prioritized connection. 431f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt */ 432f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt if (wpa_s->num_multichan_concurrent < 2) { 433f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt int freq, num; 434f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt num = get_shared_radio_freqs(wpa_s, &freq, 1); 435f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt if (num > 0 && freq > 0 && freq != params.freq) { 436f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt wpa_printf(MSG_DEBUG, 437f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt "Conflicting frequency found (%d != %d)", 438f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt freq, params.freq); 439f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt if (wpas_p2p_handle_frequency_conflicts(wpa_s, 440f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt params.freq, 441f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt ssid) < 0) { 442f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt wpas_connection_failed(wpa_s, bss->bssid); 443f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 444f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt wpabuf_free(resp); 445f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt wpas_connect_work_done(wpa_s); 446f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt return; 447f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt } 448f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt } 449f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt } 450f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt#endif /* CONFIG_P2P */ 451f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.auth_alg = params.auth_alg; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_authenticate(wpa_s, ¶ms) < 0) { 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Authentication request to the " 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "driver failed"); 4561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_connection_failed(wpa_s, bss->bssid); 457c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 458d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_free(resp); 459fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_done(wpa_s); 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s, 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Association will be started based on the authentication event from 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the driver. 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 470d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 471d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_free(resp); 472d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 473d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 474d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 475fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void sme_auth_start_cb(struct wpa_radio_work *work, int deinit) 476fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 477fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_connect_work *cwork = work->ctx; 478fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_supplicant *wpa_s = work->wpa_s; 479fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 480fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (deinit) { 481bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (work->started) 482bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_s->connect_work = NULL; 483bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 484fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_free(cwork); 485fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 486fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 487fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 488fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->connect_work = work; 489fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 4902e425d69801667e42b4874548f2a49dc16e95617Dmitry Shmidt if (cwork->bss_removed || 4912e425d69801667e42b4874548f2a49dc16e95617Dmitry Shmidt !wpas_valid_bss_ssid(wpa_s, cwork->bss, cwork->ssid)) { 492fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: BSS/SSID entry for authentication not valid anymore - drop connection attempt"); 493fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_done(wpa_s); 494fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 495fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 496fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 497fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sme_send_authentication(wpa_s, cwork->bss, cwork->ssid, 1); 498fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 499fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 500fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 501d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid sme_authenticate(struct wpa_supplicant *wpa_s, 502d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_bss *bss, struct wpa_ssid *ssid) 503d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 504fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_connect_work *cwork; 505fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 506fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (bss == NULL || ssid == NULL) 507fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 508fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->connect_work) { 509fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reject sme_authenticate() call since connect_work exist"); 510fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 511fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 512fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 513f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (radio_work_pending(wpa_s, "sme-connect")) { 514df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt /* 515df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt * The previous sme-connect work might no longer be valid due to 516df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt * the fact that the BSS list was updated. In addition, it makes 517df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt * sense to adhere to the 'newer' decision. 518df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt */ 519df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 520df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt "SME: Remove previous pending sme-connect"); 521df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt radio_remove_works(wpa_s, "sme-connect", 0); 522f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 523f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 524fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cwork = os_zalloc(sizeof(*cwork)); 525fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cwork == NULL) 526fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 527fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cwork->bss = bss; 528fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cwork->ssid = ssid; 529fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cwork->sme = 1; 530fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 531a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifdef CONFIG_SAE 532a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.state = SAE_NOTHING; 533a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.send_confirm = 0; 534cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_s->sme.sae_group_index = 0; 535a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#endif /* CONFIG_SAE */ 536fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 537fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (radio_add_work(wpa_s, bss->freq, "sme-connect", 1, 538fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sme_auth_start_cb, cwork) < 0) 539fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_free(cwork); 540d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 541d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 542d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 543d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 544d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 545d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction, 546d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u16 status_code, const u8 *data, size_t len) 547d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 548d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE authentication transaction %u " 549d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "status code %u", auth_transaction, status_code); 550a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 551a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (auth_transaction == 1 && 552a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ && 553a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.state == SAE_COMMITTED && 554a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->current_bss && wpa_s->current_ssid) { 555a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE anti-clogging token " 556a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "requested"); 557a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpabuf_free(wpa_s->sme.sae_token); 558a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae_token = wpabuf_alloc_copy(data, len); 559a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sme_send_authentication(wpa_s, wpa_s->current_bss, 560a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->current_ssid, 1); 561a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 562a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 563a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 564a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (auth_transaction == 1 && 565a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt status_code == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED && 566a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.state == SAE_COMMITTED && 567a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->current_bss && wpa_s->current_ssid) { 568a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE group not supported"); 569a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae_group_index++; 570a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sme_set_sae_group(wpa_s) < 0) 571a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; /* no other groups enabled */ 572a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Try next enabled SAE group"); 573a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sme_send_authentication(wpa_s, wpa_s->current_bss, 574a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->current_ssid, 1); 575a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 576a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 577d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 578d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (status_code != WLAN_STATUS_SUCCESS) 579d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 580d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 581d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (auth_transaction == 1) { 582cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int *groups = wpa_s->conf->sae_groups; 583cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 584d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit"); 585d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->current_bss == NULL || 586d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->current_ssid == NULL) 587d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 588a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (wpa_s->sme.sae.state != SAE_COMMITTED) 589d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 590cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (groups && groups[0] <= 0) 591cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt groups = NULL; 592a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL, 593cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt groups) != WLAN_STATUS_SUCCESS) 594d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 595a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 596a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sae_process_commit(&wpa_s->sme.sae) < 0) { 597a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: Failed to process peer " 598a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "commit"); 599a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 600a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 601a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 602a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpabuf_free(wpa_s->sme.sae_token); 603a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae_token = NULL; 604d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sme_send_authentication(wpa_s, wpa_s->current_bss, 605d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->current_ssid, 0); 606d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 607d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } else if (auth_transaction == 2) { 608d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE confirm"); 609a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (wpa_s->sme.sae.state != SAE_CONFIRMED) 610d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 611a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sae_check_confirm(&wpa_s->sme.sae, data, len) < 0) 612d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 613a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.state = SAE_ACCEPTED; 614a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sae_clear_temp_data(&wpa_s->sme.sae); 615d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; 616d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 617d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 618d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 620d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data) 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event " 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "when network is not selected"); 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state != WPA_AUTHENTICATING) { 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event " 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "when not in authenticating state"); 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(wpa_s->pending_bssid, data->auth.peer, ETH_ALEN) != 0) { 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication with " 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unexpected peer " MACSTR, 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(data->auth.peer)); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication response: peer=" MACSTR 647d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt " auth_type=%d auth_transaction=%d status_code=%d", 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(data->auth.peer), data->auth.auth_type, 649d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt data->auth.auth_transaction, data->auth.status_code); 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SME: Authentication response IEs", 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->auth.ies, data->auth.ies_len); 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 655d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 656d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (data->auth.auth_type == WLAN_AUTH_SAE) { 657d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int res; 658d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt res = sme_sae_auth(wpa_s, data->auth.auth_transaction, 659d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt data->auth.status_code, data->auth.ies, 660d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt data->auth.ies_len); 661d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (res < 0) { 662d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 663d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 664d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 665d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 666d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (res != 1) 667d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 668a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 669a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "SME: SAE completed - setting PMK for " 670a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "4-way handshake"); 671a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN); 672d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 673d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 674d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth.status_code != WLAN_STATUS_SUCCESS) { 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication failed (status " 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "code %d)", data->auth.status_code); 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth.status_code != 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG || 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.auth_alg == data->auth.auth_type || 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP) { 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 68404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6889767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt wpas_connect_work_done(wpa_s); 6899767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data->auth.auth_type) { 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_AUTH_OPEN: 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_SHARED; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying SHARED auth"); 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_associate(wpa_s, wpa_s->current_bss, 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid); 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_AUTH_SHARED_KEY: 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_LEAP; 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying LEAP auth"); 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_associate(wpa_s, wpa_s->current_bss, 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid); 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth.auth_type == WLAN_AUTH_FT) { 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data edata; 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&edata, 0, sizeof(edata)); 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt edata.ft_ies.ies = data->auth.ies; 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt edata.ft_ies.ies_len = data->auth.ies_len; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(edata.ft_ies.target_ap, data->auth.peer, ETH_ALEN); 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &edata); 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_associate(wpa_s, ssid->mode, data->auth.peer, 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->auth.auth_type); 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode, 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, u16 auth_type) 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_associate_params params; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 733c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_HT_OVERRIDES 734c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct ieee80211_ht_capabilities htcaps; 735c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct ieee80211_ht_capabilities htcaps_mask; 736c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */ 7372f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt#ifdef CONFIG_VHT_OVERRIDES 7382f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt struct ieee80211_vht_capabilities vhtcaps; 7392f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt struct ieee80211_vht_capabilities vhtcaps_mask; 7402f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt#endif /* CONFIG_VHT_OVERRIDES */ 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bssid = bssid; 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid = wpa_s->sme.ssid; 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid_len = wpa_s->sme.ssid_len; 7469ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt params.freq.freq = wpa_s->sme.freq; 74704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params.bg_scan_period = wpa_s->current_ssid ? 74804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->current_ssid->bg_scan_period : -1; 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_ie = wpa_s->sme.assoc_req_ie_len ? 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie : NULL; 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len; 752fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params.pairwise_suite = wpa_s->pairwise_cipher; 753fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params.group_suite = wpa_s->group_cipher; 75415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt params.key_mgmt_suite = wpa_s->key_mgmt; 75515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt params.wpa_proto = wpa_s->wpa_proto; 756c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_HT_OVERRIDES 757c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(&htcaps, 0, sizeof(htcaps)); 758c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(&htcaps_mask, 0, sizeof(htcaps_mask)); 759c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params.htcaps = (u8 *) &htcaps; 760c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params.htcaps_mask = (u8 *) &htcaps_mask; 761c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_apply_ht_overrides(wpa_s, wpa_s->current_ssid, ¶ms); 762c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */ 7632f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt#ifdef CONFIG_VHT_OVERRIDES 7642f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt os_memset(&vhtcaps, 0, sizeof(vhtcaps)); 7652f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask)); 7662f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt params.vhtcaps = &vhtcaps; 7672f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt params.vhtcaps_mask = &vhtcaps_mask; 7682f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt wpa_supplicant_apply_vht_overrides(wpa_s, wpa_s->current_ssid, ¶ms); 7692f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt#endif /* CONFIG_VHT_OVERRIDES */ 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) { 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_ie = wpa_s->sme.ft_ies; 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_ie_len = wpa_s->sme.ft_ies_len; 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.mode = mode; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.mgmt_frame_protection = wpa_s->sme.mfp; 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.prev_bssid_set) 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.prev_bssid = wpa_s->sme.prev_bssid; 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid), 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "", 7849ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt params.freq.freq); 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params.wpa_ie == NULL || 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0) 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt < 0) { 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Could not parse own IEs?!"); 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&elems, 0, sizeof(elems)); 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (elems.rsn_ie) { 7951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.wpa_proto = WPA_PROTO_RSN; 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2, 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.rsn_ie_len + 2); 7981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (elems.wpa_ie) { 7991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.wpa_proto = WPA_PROTO_WPA; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2, 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.wpa_ie_len + 2); 802f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } else if (elems.osen) { 803f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt params.wpa_proto = WPA_PROTO_OSEN; 804f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.osen - 2, 805f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt elems.osen_len + 2); 8061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0); 8081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group) 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.p2p = 1; 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->parent->set_sta_uapsd) 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.uapsd = wpa_s->parent->sta_uapsd; 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.uapsd = -1; 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_associate(wpa_s, ¶ms) < 0) { 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Association request to the " 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "driver failed"); 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 82004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(SME_ASSOC_TIMEOUT, 0, sme_assoc_timer, wpa_s, 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md, 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ies, size_t ies_len) 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (md == NULL || ies == NULL) { 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Remove mobility domain"); 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->sme.ft_ies); 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies = NULL; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies_len = 0; 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_used = 0; 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->sme.mobility_domain, md, MOBILITY_DOMAIN_ID_LEN); 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "SME: FT IEs", ies, ies_len); 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->sme.ft_ies); 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies = os_malloc(ies_len); 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.ft_ies == NULL) 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->sme.ft_ies, ies, ies_len); 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies_len = ies_len; 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_deauth(struct wpa_supplicant *wpa_s) 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int bssid_changed; 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid_changed = !is_zero_ether_addr(wpa_s->bssid); 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_DEAUTH_LEAVING) < 0) { 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Deauth request to the driver " 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed"); 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.prev_bssid_set = 0; 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->bssid, 0, ETH_ALEN); 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid_changed) 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_bssid_changed(wpa_s); 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_assoc_reject(struct wpa_supplicant *wpa_s, 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data *data) 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association with " MACSTR " failed: " 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status code %d", MAC2STR(wpa_s->pending_bssid), 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->assoc_reject.status_code); 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * For now, unconditionally terminate the previous authentication. In 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * theory, this should not be needed, but mac80211 gets quite confused 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * if the authentication is left pending.. Some roaming cases might 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * benefit from using the previous authentication, so this could be 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * optimized in the future. 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_deauth(wpa_s); 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data *data) 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication timed out"); 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 901c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data *data) 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association timed out"); 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_disassoc(struct wpa_supplicant *wpa_s, 915c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt struct disassoc_info *info) 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Disassociation event received"); 9181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->sme.prev_bssid_set) { 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cfg80211/mac80211 can get into somewhat confused state if 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the AP only disassociates us and leaves us in authenticated 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state. For now, force the state to be cleared to avoid 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * confusing errors if we try to associate with the AP again. 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Deauthenticate to clear " 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "driver state"); 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_deauthenticate(wpa_s, wpa_s->sme.prev_bssid, 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_DEAUTH_LEAVING); 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_auth_timer(void *eloop_ctx, void *timeout_ctx) 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state == WPA_AUTHENTICATING) { 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication timeout"); 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_deauth(wpa_s); 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx) 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state == WPA_ASSOCIATING) { 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_DEBUG, "SME: Association timeout"); 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_deauth(wpa_s); 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_state_changed(struct wpa_supplicant *wpa_s) 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure timers are cleaned up appropriately. */ 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state != WPA_ASSOCIATING) 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state != WPA_AUTHENTICATING) 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s, 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *prev_pending_bssid) 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * mac80211-workaround to force deauth on failed auth cmd, 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * requires us to remain in authenticating state to allow the 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * second authentication attempt to be continued properly. 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Allow pending authentication " 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to proceed after disconnection event"); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN); 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Re-arm authentication timer in case auth fails for whatever reason. 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s, 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_deinit(struct wpa_supplicant *wpa_s) 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->sme.ft_ies); 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies = NULL; 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies_len = 0; 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_stop_sa_query(wpa_s); 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 993a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifdef CONFIG_SAE 994a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpabuf_free(wpa_s->sme.sae_token); 995a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae_token = NULL; 996a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sae_clear_data(&wpa_s->sme.sae); 997a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#endif /* CONFIG_SAE */ 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 100104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL); 100204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 100304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 100404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 100504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void sme_send_2040_bss_coex(struct wpa_supplicant *wpa_s, 100604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *chan_list, u8 num_channels, 100704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 num_intol) 100804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 100904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct ieee80211_2040_bss_coex_ie *bc_ie; 101004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct ieee80211_2040_intol_chan_report *ic_report; 101104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *buf; 101204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1013d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt wpa_printf(MSG_DEBUG, "SME: Send 20/40 BSS Coexistence to " MACSTR 1014d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt " (num_channels=%u num_intol=%u)", 1015d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt MAC2STR(wpa_s->bssid), num_channels, num_intol); 1016d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "SME: 20/40 BSS Intolerant Channels", 1017d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt chan_list, num_channels); 101804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 101904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt buf = wpabuf_alloc(2 + /* action.category + action_code */ 102004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct ieee80211_2040_bss_coex_ie) + 102104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct ieee80211_2040_intol_chan_report) + 102204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_channels); 102304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (buf == NULL) 102404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 102504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 102604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC); 102704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, WLAN_PA_20_40_BSS_COEX); 102804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 102904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bc_ie = wpabuf_put(buf, sizeof(*bc_ie)); 103004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bc_ie->element_id = WLAN_EID_20_40_BSS_COEXISTENCE; 103104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bc_ie->length = 1; 103204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (num_intol) 103304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bc_ie->coex_param |= WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ; 103404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 103504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (num_channels > 0) { 103604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ic_report = wpabuf_put(buf, sizeof(*ic_report)); 103704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ic_report->element_id = WLAN_EID_20_40_BSS_INTOLERANT; 103804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ic_report->length = num_channels + 1; 103904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ic_report->op_class = 0; 104004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(wpabuf_put(buf, num_channels), chan_list, 104104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_channels); 104204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 104304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 104404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 104504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->own_addr, wpa_s->bssid, 104604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_head(buf), wpabuf_len(buf), 0) < 0) { 104704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, 104804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "SME: Failed to send 20/40 BSS Coexistence frame"); 104904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 105004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 105104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_free(buf); 105204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 105304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 105404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 105504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint sme_proc_obss_scan(struct wpa_supplicant *wpa_s) 105604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 105704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss; 105804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *ie; 105904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 ht_cap; 106004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 chan_list[P2P_MAX_CHANNELS], channel; 106104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 num_channels = 0, num_intol = 0, i; 106204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 106304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->sme.sched_obss_scan) 106404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 106504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 106604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.sched_obss_scan = 0; 106704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->current_bss || wpa_s->wpa_state != WPA_COMPLETED) 106804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 106904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 107004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 107104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Check whether AP uses regulatory triplet or channel triplet in 107204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * country info. Right now the operating class of the BSS channel 107304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * width trigger event is "unknown" (IEEE Std 802.11-2012 10.15.12), 107404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * based on the assumption that operating class triplet is not used in 107504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * beacon frame. If the First Channel Number/Operating Extension 107604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Identifier octet has a positive integer value of 201 or greater, 107704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * then its operating class triplet. 107804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 107904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * TODO: If Supported Operating Classes element is present in beacon 108004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * frame, have to lookup operating class in Annex E and fill them in 108104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 2040 coex frame. 108204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 108304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_COUNTRY); 108404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ie && (ie[1] >= 6) && (ie[5] >= 201)) 108504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 108604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 108704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(chan_list, 0, sizeof(chan_list)); 108804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 108904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { 109004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Skip other band bss */ 10914b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt enum hostapd_hw_mode mode; 10924b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt mode = ieee80211_freq_to_chan(bss->freq, &channel); 10934b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (mode != HOSTAPD_MODE_IEEE80211G && 10944b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt mode != HOSTAPD_MODE_IEEE80211B) 109504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt continue; 109604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 109704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie = wpa_bss_get_ie(bss, WLAN_EID_HT_CAP); 109804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ht_cap = (ie && (ie[1] == 26)) ? WPA_GET_LE16(ie + 2) : 0; 1099d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt wpa_printf(MSG_DEBUG, "SME OBSS scan BSS " MACSTR 1100d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt " freq=%u chan=%u ht_cap=0x%x", 1101d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt MAC2STR(bss->bssid), bss->freq, channel, ht_cap); 110204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 110304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!ht_cap || (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)) { 1104d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT) 1105d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt num_intol++; 1106d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 110704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Check whether the channel is already considered */ 110804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < num_channels; i++) { 110904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (channel == chan_list[i]) 111004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 111104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 111204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (i != num_channels) 111304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt continue; 111404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 111504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan_list[num_channels++] = channel; 111604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 111704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 111804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 111904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sme_send_2040_bss_coex(wpa_s, chan_list, num_channels, num_intol); 112004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 112104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 112204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 112304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 112404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, 112504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 num_modes, 112604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum hostapd_hw_mode mode) 112704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 112804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 i; 112904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 113004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < num_modes; i++) { 113104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (modes[i].mode == mode) 113204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return &modes[i]; 113304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 113404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 113504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return NULL; 113604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 113704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 113804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 113904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpa_setband_scan_freqs_list(struct wpa_supplicant *wpa_s, 114004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum hostapd_hw_mode band, 114104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_driver_scan_params *params) 114204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 114304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Include only supported channels for the specified band */ 114404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct hostapd_hw_modes *mode; 114504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int count, i; 114604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 114704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band); 114804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (mode == NULL) { 114904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* No channels supported in this band - use empty list */ 115004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params->freqs = os_zalloc(sizeof(int)); 115104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 115204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 115304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 115461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params->freqs = os_calloc(mode->num_channels + 1, sizeof(int)); 115504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (params->freqs == NULL) 115604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 115704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (count = 0, i = 0; i < mode->num_channels; i++) { 115804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED) 115904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt continue; 116004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params->freqs[count++] = mode->channels[i].freq; 116104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 116204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 116304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 116404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 116504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx) 116604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 116704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 116804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_driver_scan_params params; 116904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 117004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->current_bss) { 117104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME OBSS: Ignore scan request"); 117204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 117304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 117404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 117504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 117604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, ¶ms); 11772271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt params.low_priority = 1; 117804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME OBSS: Request an OBSS scan"); 117904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 118004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_supplicant_trigger_scan(wpa_s, ¶ms)) 118104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan"); 118204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 118304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.sched_obss_scan = 1; 118404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(params.freqs); 118504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 118604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_register_timeout(wpa_s->sme.obss_scan_int, 0, 118704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sme_obss_scan_timeout, wpa_s, NULL); 118804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 118904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 119004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 119104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable) 119204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 119304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *ie; 119404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss = wpa_s->current_bss; 119504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 119661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_hw_modes *hw_mode = NULL; 119761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int i; 119804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 119904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL); 120004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.sched_obss_scan = 0; 120104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!enable) 120204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 120304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1204d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 1205d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * Schedule OBSS scan if driver is using station SME in wpa_supplicant 1206d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * or it expects OBSS scan to be performed by wpa_supplicant. 1207d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 1208d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) || 1209d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OBSS_SCAN)) || 1210d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ssid == NULL || ssid->mode != IEEE80211_MODE_INFRA) 1211d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 121204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 121361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!wpa_s->hw.modes) 121461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 121561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 121661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* only HT caps in 11g mode are relevant */ 121761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < wpa_s->hw.num_modes; i++) { 121861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hw_mode = &wpa_s->hw.modes[i]; 121961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hw_mode->mode == HOSTAPD_MODE_IEEE80211G) 122061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 122161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 122261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 122361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Driver does not support HT40 for 11g or doesn't have 11g. */ 122461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (i == wpa_s->hw.num_modes || !hw_mode || 122561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !(hw_mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) 122661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 122704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 122804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss == NULL || bss->freq < 2400 || bss->freq > 2500) 122904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; /* Not associated on 2.4 GHz band */ 123004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 123104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Check whether AP supports HT40 */ 123204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_CAP); 123304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!ie || ie[1] < 2 || 123404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt !(WPA_GET_LE16(ie + 2) & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) 123504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; /* AP does not support HT40 */ 123604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 123704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie = wpa_bss_get_ie(wpa_s->current_bss, 123804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS); 123904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!ie || ie[1] < 14) 124004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; /* AP does not request OBSS scans */ 124104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 124204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.obss_scan_int = WPA_GET_LE16(ie + 6); 124304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->sme.obss_scan_int < 10) { 124404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME: Invalid OBSS Scan Interval %u " 124504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "replaced with the minimum 10 sec", 124604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.obss_scan_int); 124704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.obss_scan_int = 10; 124804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 124904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME: OBSS Scan Interval %u sec", 125004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.obss_scan_int); 125104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_register_timeout(wpa_s->sme.obss_scan_int, 0, 125204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sme_obss_scan_timeout, wpa_s, NULL); 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const unsigned int sa_query_max_timeout = 1000; 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const unsigned int sa_query_retry_timeout = 201; 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int sme_check_sa_query_timeout(struct wpa_supplicant *wpa_s) 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 tu; 1264fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime now, passed; 1265fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&now); 1266fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_reltime_sub(&now, &wpa_s->sme.sa_query_start, &passed); 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tu = (passed.sec * 1000000 + passed.usec) / 1024; 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sa_query_max_timeout < tu) { 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: SA Query timed out"); 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_stop_sa_query(wpa_s); 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_deauthenticate( 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s, WLAN_REASON_PREV_AUTH_NOT_VALID); 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_send_sa_query_req(struct wpa_supplicant *wpa_s, 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *trans_id) 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 req[2 + WLAN_SA_QUERY_TR_ID_LEN]; 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Sending SA Query Request to " 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(wpa_s->bssid)); 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "SME: SA Query Transaction ID", 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trans_id, WLAN_SA_QUERY_TR_ID_LEN); 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req[0] = WLAN_ACTION_SA_QUERY; 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req[1] = WLAN_SA_QUERY_REQUEST; 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(req + 2, trans_id, WLAN_SA_QUERY_TR_ID_LEN); 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->own_addr, wpa_s->bssid, 12931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt req, sizeof(req), 0) < 0) 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Failed to send SA Query " 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request"); 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_sa_query_timer(void *eloop_ctx, void *timeout_ctx) 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int timeout, sec, usec; 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *trans_id, *nbuf; 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.sa_query_count > 0 && 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_check_sa_query_timeout(wpa_s)) 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 130961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt nbuf = os_realloc_array(wpa_s->sme.sa_query_trans_id, 131061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->sme.sa_query_count + 1, 131161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WLAN_SA_QUERY_TR_ID_LEN); 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nbuf == NULL) 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.sa_query_count == 0) { 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Starting a new SA Query procedure */ 1316fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&wpa_s->sme.sa_query_start); 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trans_id = nbuf + wpa_s->sme.sa_query_count * WLAN_SA_QUERY_TR_ID_LEN; 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_trans_id = nbuf; 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_count++; 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1322661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN) < 0) { 1323661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_printf(MSG_DEBUG, "Could not generate SA Query ID"); 1324661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return; 1325661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = sa_query_retry_timeout; 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sec = ((timeout / 1000) * 1024) / 1000; 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usec = (timeout % 1000) * 1024; 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sec, usec, sme_sa_query_timer, wpa_s, NULL); 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association SA Query attempt %d", 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_count); 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_send_sa_query_req(wpa_s, trans_id); 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_start_sa_query(struct wpa_supplicant *wpa_s) 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_sa_query_timer(wpa_s, NULL); 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void sme_stop_sa_query(struct wpa_supplicant *wpa_s) 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_sa_query_timer, wpa_s, NULL); 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->sme.sa_query_trans_id); 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_trans_id = NULL; 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_count = 0; 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa, 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *da, u16 reason_code) 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 13580c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt struct os_reltime now; 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state != WPA_COMPLETED) 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 1363d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (ssid == NULL || 1364d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ? 1365d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->conf->pmf : ssid->ieee80211w) == NO_MGMT_FRAME_PROTECTION) 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reason_code != WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA && 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason_code != WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA) 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.sa_query_count > 0) 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13750c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt os_get_reltime(&now); 13760c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt if (wpa_s->sme.last_unprot_disconnect.sec && 13770c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt !os_reltime_expired(&now, &wpa_s->sme.last_unprot_disconnect, 10)) 13780c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt return; /* limit SA Query procedure frequency */ 13790c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt wpa_s->sme.last_unprot_disconnect = now; 13800c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Unprotected disconnect dropped - " 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "possible AP/STA state mismatch - trigger SA Query"); 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_start_sa_query(wpa_s); 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa, 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len) 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.sa_query_trans_id == NULL || 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len < 1 + WLAN_SA_QUERY_TR_ID_LEN || 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0] != WLAN_SA_QUERY_RESPONSE) 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query response from " 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]); 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < wpa_s->sme.sa_query_count; i++) { 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(wpa_s->sme.sa_query_trans_id + 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i * WLAN_SA_QUERY_TR_ID_LEN, 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data + 1, WLAN_SA_QUERY_TR_ID_LEN) == 0) 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i >= wpa_s->sme.sa_query_count) { 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: No matching SA Query " 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "transaction identifier found"); 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reply to pending SA Query received " 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from " MACSTR, MAC2STR(sa)); 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_stop_sa_query(wpa_s); 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 1421