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]; 704171258d30a612645aa061cede62233b5c58ca2aDmitry 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 1406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt/** 1416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * sme_auth_handle_rrm - Handle RRM aspects of current authentication attempt 1426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 1436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @bss: Pointer to the bss which is the target of authentication attempt 1446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 1456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void sme_auth_handle_rrm(struct wpa_supplicant *wpa_s, 1466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpa_bss *bss) 1476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 1486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const u8 rrm_ie_len = 5; 1496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 *pos; 1506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const u8 *rrm_ie; 1516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->rrm.rrm_used = 0; 1536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 1556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "RRM: Determining whether RRM can be used - device support: 0x%x", 1566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->drv_rrm_flags); 1576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt rrm_ie = wpa_bss_get_ie(bss, WLAN_EID_RRM_ENABLED_CAPABILITIES); 1596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!rrm_ie || !(bss->caps & IEEE80211_CAP_RRM)) { 1606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "RRM: No RRM in network"); 1616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 1626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 1636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!(wpa_s->drv_rrm_flags & 1656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES) || 1666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt !(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_QUIET)) { 1676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 1686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "RRM: Insufficient RRM support in driver - do not use RRM"); 1696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 1706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 1716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (sizeof(wpa_s->sme.assoc_req_ie) < 1736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->sme.assoc_req_ie_len + rrm_ie_len + 2) { 1746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_INFO, 1756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "RRM: Unable to use RRM, no room for RRM IE"); 1766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 1776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 1786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, "RRM: Adding RRM IE to Association Request"); 1806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len; 1816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memset(pos, 0, 2 + rrm_ie_len); 1826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt *pos++ = WLAN_EID_RRM_ENABLED_CAPABILITIES; 1836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt *pos++ = rrm_ie_len; 1846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* Set supported capabilites flags */ 1866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION) 1876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt *pos |= WLAN_RRM_CAPS_LINK_MEASUREMENT; 1886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->sme.assoc_req_ie_len += rrm_ie_len + 2; 1906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->rrm.rrm_used = 1; 1916c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 1926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 194d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic void sme_send_authentication(struct wpa_supplicant *wpa_s, 195d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_bss *bss, struct wpa_ssid *ssid, 196d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int start) 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_auth_params params; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *old_ssid; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *md = NULL; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, bssid_changed; 207d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpabuf *resp = NULL; 20809f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt u8 ext_capab[18]; 209a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt int ext_capab_len; 2107f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt int skip_auth; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) { 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_ERROR, "SME: No scan result available for " 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the network"); 215fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_done(wpa_s); 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2197f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt skip_auth = wpa_s->conf->reassoc_same_bss_optim && 2207f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt wpa_s->reassoc_same_bss; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_bss = bss; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->reassociate = 0; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freq = bss->freq; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bssid = bss->bssid; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid = bss->ssid; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid_len = bss->ssid_len; 2301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.p2p = ssid->p2p_group; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.ssid_len != params.ssid_len || 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(wpa_s->sme.ssid, params.ssid, params.ssid_len) != 0) 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.prev_bssid_set = 0; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.freq = params.freq; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->sme.ssid, params.ssid, params.ssid_len); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ssid_len = params.ssid_len; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = WPA_AUTH_ALG_OPEN; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->leap) { 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->non_leap == 0) 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = WPA_AUTH_ALG_LEAP; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg |= WPA_AUTH_ALG_LEAP; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */ 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->auth_alg) { 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = ssid->auth_alg; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: " 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "0x%x", params.auth_alg); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 258d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 2596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->sme.sae_pmksa_caching = 0; 260d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_key_mgmt_sae(ssid->key_mgmt)) { 261d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const u8 *rsn; 262d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ie_data ied; 263d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 264d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); 2656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!rsn) { 2666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 2676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "SAE enabled, but target BSS does not advertise RSN"); 2686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } else if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 && 2696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_key_mgmt_sae(ied.key_mgmt)) { 2706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Using SAE auth_alg"); 2716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params.auth_alg = WPA_AUTH_ALG_SAE; 2726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } else { 2736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 2746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "SAE enabled, but target BSS does not advertise SAE AKM for RSN"); 275d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 276d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 277d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < NUM_WEP_KEYS; i++) { 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->wep_key_len[i]) 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wep_key[i] = ssid->wep_key[i]; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wep_key_len[i] = ssid->wep_key_len[i]; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wep_tx_keyidx = ssid->wep_tx_keyidx; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid_changed = !is_zero_ether_addr(wpa_s->bssid); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->bssid, 0, ETH_ALEN); 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN); 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid_changed) 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_bssid_changed(wpa_s); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) || 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_bss_get_ie(bss, WLAN_EID_RSN)) && 2941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_key_mgmt_wpa(ssid->key_mgmt)) { 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int try_opportunistic; 296d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt try_opportunistic = (ssid->proactive_key_caching < 0 ? 297d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->conf->okc : 298d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ssid->proactive_key_caching) && 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (ssid->proto & WPA_PROTO_RSN); 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid, 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt try_opportunistic) == 0) 303216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt eapol_sm_notify_pmkid_attempt(wpa_s->eapol); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_set_suites(wpa_s, bss, ssid, 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie, 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &wpa_s->sme.assoc_req_ie_len)) { 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA " 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key management and encryption suites"); 310fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_done(wpa_s); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && 31461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) { 31561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 31661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Both WPA and non-WPA IEEE 802.1X enabled in configuration - 31761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * use non-WPA since the scan results did not indicate that the 31861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * AP is using WPA or WPA2. 31961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 32061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 32161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = 0; 3221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) { 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_set_suites(wpa_s, NULL, ssid, 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie, 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &wpa_s->sme.assoc_req_ie_len)) { 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA " 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key management and encryption suites (no " 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "scan results)"); 330fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_done(wpa_s); 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) { 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps_ie; 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid)); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_ie && wpabuf_len(wps_ie) <= 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->sme.assoc_req_ie)) { 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = wpabuf_len(wps_ie); 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->sme.assoc_req_ie, wpabuf_head(wps_ie), 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = 0; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = 0; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN) 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt md = ie + 2; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0); 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (md) { 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Prepare for the next transition */ 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ft_prepare_auth_request(wpa_s->wpa, ie); 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (md && wpa_key_mgmt_ft(ssid->key_mgmt)) { 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.assoc_req_ie_len + 5 < 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->sme.assoc_req_ie)) { 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rsn_mdie *mdie; 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos = wpa_s->sme.assoc_req_ie + 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_MOBILITY_DOMAIN; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = sizeof(*mdie); 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mdie = (struct rsn_mdie *) pos; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mdie->mobility_domain, md, 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MOBILITY_DOMAIN_ID_LEN); 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mdie->ft_capab = md[MOBILITY_DOMAIN_ID_LEN]; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len += 5; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.ft_used && 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(md, wpa_s->sme.mobility_domain, 2) == 0 && 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_has_ptk(wpa_s->wpa)) { 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying to use FT " 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "over-the-air"); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = WPA_AUTH_ALG_FT; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ie = wpa_s->sme.ft_ies; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ie_len = wpa_s->sme.ft_ies_len; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 390807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt wpa_s->sme.mfp = wpas_get_ssid_pmf(wpa_s, ssid); 391d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->sme.mfp != NO_MGMT_FRAME_PROTECTION) { 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ie_data _ie; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 && 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _ie.capabilities & 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) { 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected AP supports " 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "MFP: require MFP"); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) { 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(wpa_s->sme.assoc_req_ie) - 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len; 4121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len, 4131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid->p2p_group); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res >= 0) 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len += res; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_HS20 42051b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (is_hs20_network(wpa_s, ssid, bss)) { 42104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *hs20; 42204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hs20 = wpabuf_alloc(20); 42304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hs20) { 424f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid); 425c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt size_t len; 426c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 427f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpas_hs20_add_indication(hs20, pps_mo_id); 428c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt len = sizeof(wpa_s->sme.assoc_req_ie) - 429c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt wpa_s->sme.assoc_req_ie_len; 430c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (wpabuf_len(hs20) <= len) { 431c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memcpy(wpa_s->sme.assoc_req_ie + 432c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt wpa_s->sme.assoc_req_ie_len, 433c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt wpabuf_head(hs20), wpabuf_len(hs20)); 434c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt wpa_s->sme.assoc_req_ie_len += wpabuf_len(hs20); 435c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt } 43604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_free(hs20); 43704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 43804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 43904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_HS20 */ 44004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 44109f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab, 44209f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt sizeof(ext_capab)); 443a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (ext_capab_len > 0) { 4441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 *pos = wpa_s->sme.assoc_req_ie; 4451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->sme.assoc_req_ie_len > 0 && pos[0] == WLAN_EID_RSN) 4461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos += 2 + pos[1]; 447a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memmove(pos + ext_capab_len, pos, 4481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sme.assoc_req_ie_len - 4491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (pos - wpa_s->sme.assoc_req_ie)); 450a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.assoc_req_ie_len += ext_capab_len; 451a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memcpy(pos, ext_capab, ext_capab_len); 4521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4542f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) { 4552f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]; 4562f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt size_t len; 4572f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 4582f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt len = sizeof(wpa_s->sme.assoc_req_ie) - 4592f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_s->sme.assoc_req_ie_len; 4602f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (wpabuf_len(buf) <= len) { 4612f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_memcpy(wpa_s->sme.assoc_req_ie + 4622f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_s->sme.assoc_req_ie_len, 4632f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpabuf_head(buf), wpabuf_len(buf)); 4642f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_s->sme.assoc_req_ie_len += wpabuf_len(buf); 4652f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 4662f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 4672f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 4686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sme_auth_handle_rrm(wpa_s, bss); 4696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 470d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 4717f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE && 4726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, ssid, 0) == 0) 4736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt { 4746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 4756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "PMKSA cache entry found - try to use PMKSA caching instead of new SAE authentication"); 4766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params.auth_alg = WPA_AUTH_ALG_OPEN; 4776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->sme.sae_pmksa_caching = 1; 4786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 4796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4807f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE) { 481d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (start) 482a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt resp = sme_auth_build_sae_commit(wpa_s, ssid, 483a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt bss->bssid); 484d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt else 485d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt resp = sme_auth_build_sae_confirm(wpa_s); 486fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (resp == NULL) { 4876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpas_connection_failed(wpa_s, bss->bssid); 488d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 489fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 490d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt params.sae_data = wpabuf_head(resp); 491d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt params.sae_data_len = wpabuf_len(resp); 492a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.state = start ? SAE_COMMITTED : SAE_CONFIRMED; 493d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 494d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 495d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 4961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_cancel_scan(wpa_s); 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Trying to authenticate with " MACSTR 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid), 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ssid_txt(params.ssid, params.ssid_len), params.freq); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_clear_keys(wpa_s, bss->bssid); 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt old_ssid = wpa_s->current_ssid; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid = ssid; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_initiate_eapol(wpa_s); 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (old_ssid != wpa_s->current_ssid) 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_network_changed(wpa_s); 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 512f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt#ifdef CONFIG_P2P 513f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt /* 514f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt * If multi-channel concurrency is not supported, check for any 515f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt * frequency conflict. In case of any frequency conflict, remove the 516f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt * least prioritized connection. 517f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt */ 518f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt if (wpa_s->num_multichan_concurrent < 2) { 519f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt int freq, num; 520f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt num = get_shared_radio_freqs(wpa_s, &freq, 1); 521f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt if (num > 0 && freq > 0 && freq != params.freq) { 522f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt wpa_printf(MSG_DEBUG, 523f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt "Conflicting frequency found (%d != %d)", 524f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt freq, params.freq); 525f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt if (wpas_p2p_handle_frequency_conflicts(wpa_s, 526f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt params.freq, 527f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt ssid) < 0) { 528f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt wpas_connection_failed(wpa_s, bss->bssid); 529f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 530f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt wpabuf_free(resp); 531f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt wpas_connect_work_done(wpa_s); 532f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt return; 533f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt } 534f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt } 535f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt } 536f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt#endif /* CONFIG_P2P */ 537f9bdef99ce3b2858f2812c745a3d6bb093fb0e5dDmitry Shmidt 5387f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt if (skip_auth) { 5397f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt wpa_msg(wpa_s, MSG_DEBUG, 5407f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt "SME: Skip authentication step on reassoc-to-same-BSS"); 5417f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt wpabuf_free(resp); 5427f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt sme_associate(wpa_s, ssid->mode, bss->bssid, WLAN_AUTH_OPEN); 5437f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt return; 5447f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt } 5457f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt 5467f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.auth_alg = params.auth_alg; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_authenticate(wpa_s, ¶ms) < 0) { 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Authentication request to the " 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "driver failed"); 5511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_connection_failed(wpa_s, bss->bssid); 552c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 553d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_free(resp); 554fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_done(wpa_s); 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s, 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Association will be started based on the authentication event from 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the driver. 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 565d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 566d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_free(resp); 567d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 568d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 569d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 570fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void sme_auth_start_cb(struct wpa_radio_work *work, int deinit) 571fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 572fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_connect_work *cwork = work->ctx; 573fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_supplicant *wpa_s = work->wpa_s; 574fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 575fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (deinit) { 576bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (work->started) 577bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt wpa_s->connect_work = NULL; 578bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt 579fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_free(cwork); 580fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 581fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 582fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 583fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_s->connect_work = work; 584fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 5852e425d69801667e42b4874548f2a49dc16e95617Dmitry Shmidt if (cwork->bss_removed || 5862e425d69801667e42b4874548f2a49dc16e95617Dmitry Shmidt !wpas_valid_bss_ssid(wpa_s, cwork->bss, cwork->ssid)) { 587fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: BSS/SSID entry for authentication not valid anymore - drop connection attempt"); 588fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_done(wpa_s); 589fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 590fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 591fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 592fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sme_send_authentication(wpa_s, cwork->bss, cwork->ssid, 1); 593fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 594fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 595fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 596d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid sme_authenticate(struct wpa_supplicant *wpa_s, 597d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_bss *bss, struct wpa_ssid *ssid) 598d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 599fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct wpa_connect_work *cwork; 600fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 601fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (bss == NULL || ssid == NULL) 602fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 603fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (wpa_s->connect_work) { 604fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reject sme_authenticate() call since connect_work exist"); 605fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 606fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 607fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 608f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (radio_work_pending(wpa_s, "sme-connect")) { 609df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt /* 610df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt * The previous sme-connect work might no longer be valid due to 611df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt * the fact that the BSS list was updated. In addition, it makes 612df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt * sense to adhere to the 'newer' decision. 613df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt */ 614df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 615df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt "SME: Remove previous pending sme-connect"); 616df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt radio_remove_works(wpa_s, "sme-connect", 0); 617f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 618f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 619fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cwork = os_zalloc(sizeof(*cwork)); 620fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cwork == NULL) 621fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 622fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cwork->bss = bss; 623fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cwork->ssid = ssid; 624fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt cwork->sme = 1; 625fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 626a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifdef CONFIG_SAE 627a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.state = SAE_NOTHING; 628a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.send_confirm = 0; 629cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_s->sme.sae_group_index = 0; 630a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#endif /* CONFIG_SAE */ 631fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 632fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (radio_add_work(wpa_s, bss->freq, "sme-connect", 1, 633fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sme_auth_start_cb, cwork) < 0) 634fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpas_connect_work_free(cwork); 635d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 636d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 637d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 638d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 639d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 640d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction, 641d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u16 status_code, const u8 *data, size_t len) 642d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 6436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int *groups; 6446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 645d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE authentication transaction %u " 646d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "status code %u", auth_transaction, status_code); 647a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 648a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (auth_transaction == 1 && 649a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ && 650a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.state == SAE_COMMITTED && 651a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->current_bss && wpa_s->current_ssid) { 6526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int default_groups[] = { 19, 20, 21, 25, 26, 0 }; 6536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u16 group; 6546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt groups = wpa_s->conf->sae_groups; 6566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!groups || groups[0] <= 0) 6576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt groups = default_groups; 6586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 6596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (len < sizeof(le16)) { 6606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 6616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "SME: Too short SAE anti-clogging token request"); 6626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 6636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 6646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt group = WPA_GET_LE16(data); 6656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 6666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "SME: SAE anti-clogging token requested (group %u)", 6676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt group); 6686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (sae_group_allowed(&wpa_s->sme.sae, groups, group) != 6696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt WLAN_STATUS_SUCCESS) { 6706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_dbg(wpa_s, MSG_ERROR, 6716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "SME: SAE group %u of anti-clogging request is invalid", 6726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt group); 6736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 6746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 675a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpabuf_free(wpa_s->sme.sae_token); 6766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->sme.sae_token = wpabuf_alloc_copy(data + sizeof(le16), 6776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt len - sizeof(le16)); 678a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sme_send_authentication(wpa_s, wpa_s->current_bss, 679a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->current_ssid, 1); 680a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 681a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 682a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 683a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (auth_transaction == 1 && 684a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt status_code == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED && 685a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.state == SAE_COMMITTED && 686a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->current_bss && wpa_s->current_ssid) { 687a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE group not supported"); 688a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae_group_index++; 689a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sme_set_sae_group(wpa_s) < 0) 690a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; /* no other groups enabled */ 691a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Try next enabled SAE group"); 692a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sme_send_authentication(wpa_s, wpa_s->current_bss, 693a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->current_ssid, 1); 694a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 695a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 696d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 697d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (status_code != WLAN_STATUS_SUCCESS) 698d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 699d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 700d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (auth_transaction == 1) { 7014171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt u16 res; 7024171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt 7036c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt groups = wpa_s->conf->sae_groups; 704cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 705d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit"); 706d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->current_bss == NULL || 707d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->current_ssid == NULL) 708d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 709a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (wpa_s->sme.sae.state != SAE_COMMITTED) 710d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 711cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (groups && groups[0] <= 0) 712cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt groups = NULL; 7134171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt res = sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL, 7144171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt groups); 7154171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt if (res == SAE_SILENTLY_DISCARD) { 7164171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt wpa_printf(MSG_DEBUG, 7174171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt "SAE: Drop commit message due to reflection attack"); 7184171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt return 0; 7194171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt } 7204171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt if (res != WLAN_STATUS_SUCCESS) 721d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 722a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 723a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sae_process_commit(&wpa_s->sme.sae) < 0) { 724a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: Failed to process peer " 725a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "commit"); 726a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 727a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 728a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 729a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpabuf_free(wpa_s->sme.sae_token); 730a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae_token = NULL; 731d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sme_send_authentication(wpa_s, wpa_s->current_bss, 732d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->current_ssid, 0); 733d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 734d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } else if (auth_transaction == 2) { 735d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE confirm"); 736a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (wpa_s->sme.sae.state != SAE_CONFIRMED) 737d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 738a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sae_check_confirm(&wpa_s->sme.sae, data, len) < 0) 739d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 740a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_s->sme.sae.state = SAE_ACCEPTED; 741a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sae_clear_temp_data(&wpa_s->sme.sae); 742d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; 743d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 744d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 745d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 747d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data) 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event " 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "when network is not selected"); 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state != WPA_AUTHENTICATING) { 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event " 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "when not in authenticating state"); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(wpa_s->pending_bssid, data->auth.peer, ETH_ALEN) != 0) { 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication with " 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unexpected peer " MACSTR, 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(data->auth.peer)); 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication response: peer=" MACSTR 774d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt " auth_type=%d auth_transaction=%d status_code=%d", 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(data->auth.peer), data->auth.auth_type, 776d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt data->auth.auth_transaction, data->auth.status_code); 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SME: Authentication response IEs", 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->auth.ies, data->auth.ies_len); 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 782d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 783d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (data->auth.auth_type == WLAN_AUTH_SAE) { 784d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int res; 785d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt res = sme_sae_auth(wpa_s, data->auth.auth_transaction, 786d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt data->auth.status_code, data->auth.ies, 787d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt data->auth.ies_len); 788d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (res < 0) { 789d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 790d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 791d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 792d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 793d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (res != 1) 794d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 795a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 796a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "SME: SAE completed - setting PMK for " 797a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "4-way handshake"); 7986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN, 7996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->pending_bssid); 800d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 801d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 802d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth.status_code != WLAN_STATUS_SUCCESS) { 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication failed (status " 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "code %d)", data->auth.status_code); 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth.status_code != 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG || 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.auth_alg == data->auth.auth_type || 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP) { 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 81204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8169767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt wpas_connect_work_done(wpa_s); 8179767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data->auth.auth_type) { 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_AUTH_OPEN: 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_SHARED; 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying SHARED auth"); 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_associate(wpa_s, wpa_s->current_bss, 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid); 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_AUTH_SHARED_KEY: 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_LEAP; 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying LEAP auth"); 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_associate(wpa_s, wpa_s->current_bss, 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid); 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth.auth_type == WLAN_AUTH_FT) { 8424171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt if (wpa_ft_process_response(wpa_s->wpa, data->auth.ies, 8434171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt data->auth.ies_len, 0, 8444171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt data->auth.peer, NULL, 0) < 0) { 8454171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 8464171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt "SME: FT Authentication response processing failed"); 8474171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" 8484171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt MACSTR 8494171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt " reason=%d locally_generated=1", 8504171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt MAC2STR(wpa_s->pending_bssid), 8514171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt WLAN_REASON_DEAUTH_LEAVING); 8524171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 8534171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 8544171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt return; 8554171258d30a612645aa061cede62233b5c58ca2aDmitry Shmidt } 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_associate(wpa_s, ssid->mode, data->auth.peer, 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->auth.auth_type); 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode, 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, u16 auth_type) 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_associate_params params; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 869c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_HT_OVERRIDES 870c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct ieee80211_ht_capabilities htcaps; 871c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct ieee80211_ht_capabilities htcaps_mask; 872c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */ 8732f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt#ifdef CONFIG_VHT_OVERRIDES 8742f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt struct ieee80211_vht_capabilities vhtcaps; 8752f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt struct ieee80211_vht_capabilities vhtcaps_mask; 8762f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt#endif /* CONFIG_VHT_OVERRIDES */ 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bssid = bssid; 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid = wpa_s->sme.ssid; 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid_len = wpa_s->sme.ssid_len; 8829ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt params.freq.freq = wpa_s->sme.freq; 88304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params.bg_scan_period = wpa_s->current_ssid ? 88404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->current_ssid->bg_scan_period : -1; 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_ie = wpa_s->sme.assoc_req_ie_len ? 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie : NULL; 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len; 888fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params.pairwise_suite = wpa_s->pairwise_cipher; 889fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params.group_suite = wpa_s->group_cipher; 89015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt params.key_mgmt_suite = wpa_s->key_mgmt; 89115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt params.wpa_proto = wpa_s->wpa_proto; 892c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_HT_OVERRIDES 893c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(&htcaps, 0, sizeof(htcaps)); 894c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(&htcaps_mask, 0, sizeof(htcaps_mask)); 895c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params.htcaps = (u8 *) &htcaps; 896c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params.htcaps_mask = (u8 *) &htcaps_mask; 897c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_apply_ht_overrides(wpa_s, wpa_s->current_ssid, ¶ms); 898c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */ 8992f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt#ifdef CONFIG_VHT_OVERRIDES 9002f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt os_memset(&vhtcaps, 0, sizeof(vhtcaps)); 9012f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask)); 9022f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt params.vhtcaps = &vhtcaps; 9032f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt params.vhtcaps_mask = &vhtcaps_mask; 9042f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt wpa_supplicant_apply_vht_overrides(wpa_s, wpa_s->current_ssid, ¶ms); 9052f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt#endif /* CONFIG_VHT_OVERRIDES */ 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) { 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_ie = wpa_s->sme.ft_ies; 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_ie_len = wpa_s->sme.ft_ies_len; 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.mode = mode; 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.mgmt_frame_protection = wpa_s->sme.mfp; 9146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params.rrm_used = wpa_s->rrm.rrm_used; 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.prev_bssid_set) 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.prev_bssid = wpa_s->sme.prev_bssid; 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid), 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "", 9219ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt params.freq.freq); 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params.wpa_ie == NULL || 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0) 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt < 0) { 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Could not parse own IEs?!"); 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&elems, 0, sizeof(elems)); 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (elems.rsn_ie) { 9321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.wpa_proto = WPA_PROTO_RSN; 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2, 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.rsn_ie_len + 2); 9351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (elems.wpa_ie) { 9361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.wpa_proto = WPA_PROTO_WPA; 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2, 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.wpa_ie_len + 2); 939f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } else if (elems.osen) { 940f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt params.wpa_proto = WPA_PROTO_OSEN; 941f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.osen - 2, 942f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt elems.osen_len + 2); 9431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0); 9451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group) 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.p2p = 1; 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->parent->set_sta_uapsd) 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.uapsd = wpa_s->parent->sta_uapsd; 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.uapsd = -1; 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_associate(wpa_s, ¶ms) < 0) { 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Association request to the " 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "driver failed"); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 95704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(SME_ASSOC_TIMEOUT, 0, sme_assoc_timer, wpa_s, 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md, 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ies, size_t ies_len) 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (md == NULL || ies == NULL) { 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Remove mobility domain"); 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->sme.ft_ies); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies = NULL; 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies_len = 0; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_used = 0; 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->sme.mobility_domain, md, MOBILITY_DOMAIN_ID_LEN); 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "SME: FT IEs", ies, ies_len); 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->sme.ft_ies); 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies = os_malloc(ies_len); 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.ft_ies == NULL) 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->sme.ft_ies, ies, ies_len); 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies_len = ies_len; 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_deauth(struct wpa_supplicant *wpa_s) 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int bssid_changed; 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid_changed = !is_zero_ether_addr(wpa_s->bssid); 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_DEAUTH_LEAVING) < 0) { 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Deauth request to the driver " 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed"); 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.prev_bssid_set = 0; 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->bssid, 0, ETH_ALEN); 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid_changed) 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_bssid_changed(wpa_s); 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_assoc_reject(struct wpa_supplicant *wpa_s, 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data *data) 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association with " MACSTR " failed: " 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status code %d", MAC2STR(wpa_s->pending_bssid), 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->assoc_reject.status_code); 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_SAE 10236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->sme.sae_pmksa_caching && wpa_s->current_ssid && 10246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_key_mgmt_sae(wpa_s->current_ssid->key_mgmt)) { 10256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 10266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "PMKSA caching attempt rejected - drop PMKSA cache entry and fall back to SAE authentication"); 10276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_sm_aborted_cached(wpa_s->wpa); 10286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_s->current_ssid); 10296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->current_bss) { 10306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpa_bss *bss = wpa_s->current_bss; 10316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 10326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, 10346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt WLAN_REASON_DEAUTH_LEAVING); 10356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpas_connect_work_done(wpa_s); 10366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 10376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_supplicant_connect(wpa_s, bss, ssid); 10386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 10396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 10406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 10416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_SAE */ 10426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * For now, unconditionally terminate the previous authentication. In 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * theory, this should not be needed, but mac80211 gets quite confused 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * if the authentication is left pending.. Some roaming cases might 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * benefit from using the previous authentication, so this could be 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * optimized in the future. 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_deauth(wpa_s); 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data *data) 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication timed out"); 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 1059c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data *data) 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association timed out"); 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_disassoc(struct wpa_supplicant *wpa_s, 1073c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt struct disassoc_info *info) 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Disassociation event received"); 10761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->sme.prev_bssid_set) { 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cfg80211/mac80211 can get into somewhat confused state if 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the AP only disassociates us and leaves us in authenticated 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state. For now, force the state to be cleared to avoid 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * confusing errors if we try to associate with the AP again. 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Deauthenticate to clear " 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "driver state"); 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_deauthenticate(wpa_s, wpa_s->sme.prev_bssid, 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_DEAUTH_LEAVING); 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_auth_timer(void *eloop_ctx, void *timeout_ctx) 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state == WPA_AUTHENTICATING) { 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication timeout"); 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_deauth(wpa_s); 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx) 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state == WPA_ASSOCIATING) { 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_DEBUG, "SME: Association timeout"); 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_deauth(wpa_s); 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_state_changed(struct wpa_supplicant *wpa_s) 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure timers are cleaned up appropriately. */ 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state != WPA_ASSOCIATING) 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state != WPA_AUTHENTICATING) 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s, 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *prev_pending_bssid) 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * mac80211-workaround to force deauth on failed auth cmd, 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * requires us to remain in authenticating state to allow the 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * second authentication attempt to be continued properly. 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Allow pending authentication " 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to proceed after disconnection event"); 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN); 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Re-arm authentication timer in case auth fails for whatever reason. 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s, 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtvoid sme_clear_on_disassoc(struct wpa_supplicant *wpa_s) 11446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 11456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->sme.prev_bssid_set = 0; 11466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_SAE 11476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_free(wpa_s->sme.sae_token); 11486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->sme.sae_token = NULL; 11496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sae_clear_data(&wpa_s->sme.sae); 11506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_SAE */ 11516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_IEEE80211R 11526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->sme.ft_ies) 11536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sme_update_ft_ies(wpa_s, NULL, NULL, 0); 11546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_IEEE80211R */ 11556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 11566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 11576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_deinit(struct wpa_supplicant *wpa_s) 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->sme.ft_ies); 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies = NULL; 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies_len = 0; 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_stop_sa_query(wpa_s); 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 11666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt sme_clear_on_disassoc(wpa_s); 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 117004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL); 117104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 117204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 117304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 117404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void sme_send_2040_bss_coex(struct wpa_supplicant *wpa_s, 117504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *chan_list, u8 num_channels, 117604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 num_intol) 117704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 117804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct ieee80211_2040_bss_coex_ie *bc_ie; 117904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct ieee80211_2040_intol_chan_report *ic_report; 118004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *buf; 118104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1182d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt wpa_printf(MSG_DEBUG, "SME: Send 20/40 BSS Coexistence to " MACSTR 1183d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt " (num_channels=%u num_intol=%u)", 1184d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt MAC2STR(wpa_s->bssid), num_channels, num_intol); 1185d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "SME: 20/40 BSS Intolerant Channels", 1186d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt chan_list, num_channels); 118704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 118804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt buf = wpabuf_alloc(2 + /* action.category + action_code */ 118904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct ieee80211_2040_bss_coex_ie) + 119004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct ieee80211_2040_intol_chan_report) + 119104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_channels); 119204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (buf == NULL) 119304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 119404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 119504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC); 119604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, WLAN_PA_20_40_BSS_COEX); 119704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 119804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bc_ie = wpabuf_put(buf, sizeof(*bc_ie)); 119904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bc_ie->element_id = WLAN_EID_20_40_BSS_COEXISTENCE; 120004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bc_ie->length = 1; 120104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (num_intol) 120204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bc_ie->coex_param |= WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ; 120304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 120404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (num_channels > 0) { 120504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ic_report = wpabuf_put(buf, sizeof(*ic_report)); 120604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ic_report->element_id = WLAN_EID_20_40_BSS_INTOLERANT; 120704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ic_report->length = num_channels + 1; 120804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ic_report->op_class = 0; 120904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(wpabuf_put(buf, num_channels), chan_list, 121004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_channels); 121104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 121204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 121304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 121404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->own_addr, wpa_s->bssid, 121504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_head(buf), wpabuf_len(buf), 0) < 0) { 121604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, 121704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "SME: Failed to send 20/40 BSS Coexistence frame"); 121804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 121904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 122004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_free(buf); 122104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 122204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 122304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 122404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint sme_proc_obss_scan(struct wpa_supplicant *wpa_s) 122504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 122604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss; 122704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *ie; 122804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 ht_cap; 122904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 chan_list[P2P_MAX_CHANNELS], channel; 123004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 num_channels = 0, num_intol = 0, i; 123104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 123204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->sme.sched_obss_scan) 123304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 123404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 123504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.sched_obss_scan = 0; 123604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->current_bss || wpa_s->wpa_state != WPA_COMPLETED) 123704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 123804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 123904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 124004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Check whether AP uses regulatory triplet or channel triplet in 124104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * country info. Right now the operating class of the BSS channel 124204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * width trigger event is "unknown" (IEEE Std 802.11-2012 10.15.12), 124304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * based on the assumption that operating class triplet is not used in 124404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * beacon frame. If the First Channel Number/Operating Extension 124504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Identifier octet has a positive integer value of 201 or greater, 124604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * then its operating class triplet. 124704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 124804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * TODO: If Supported Operating Classes element is present in beacon 124904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * frame, have to lookup operating class in Annex E and fill them in 125004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 2040 coex frame. 125104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 125204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_COUNTRY); 125304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ie && (ie[1] >= 6) && (ie[5] >= 201)) 125404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 125504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 125604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(chan_list, 0, sizeof(chan_list)); 125704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 125804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { 125904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Skip other band bss */ 12604b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt enum hostapd_hw_mode mode; 12614b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt mode = ieee80211_freq_to_chan(bss->freq, &channel); 12624b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (mode != HOSTAPD_MODE_IEEE80211G && 12634b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt mode != HOSTAPD_MODE_IEEE80211B) 126404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt continue; 126504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 126604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie = wpa_bss_get_ie(bss, WLAN_EID_HT_CAP); 126704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ht_cap = (ie && (ie[1] == 26)) ? WPA_GET_LE16(ie + 2) : 0; 1268d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt wpa_printf(MSG_DEBUG, "SME OBSS scan BSS " MACSTR 1269d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt " freq=%u chan=%u ht_cap=0x%x", 1270d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt MAC2STR(bss->bssid), bss->freq, channel, ht_cap); 127104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 127204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!ht_cap || (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)) { 1273d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt if (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT) 1274d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt num_intol++; 1275d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt 127604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Check whether the channel is already considered */ 127704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < num_channels; i++) { 127804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (channel == chan_list[i]) 127904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 128004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 128104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (i != num_channels) 128204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt continue; 128304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 128404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan_list[num_channels++] = channel; 128504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 128604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 128704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 128804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sme_send_2040_bss_coex(wpa_s, chan_list, num_channels, num_intol); 128904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 129004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 129104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 129204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 129304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, 129404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 num_modes, 129504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum hostapd_hw_mode mode) 129604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 129704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 i; 129804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 129904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < num_modes; i++) { 130004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (modes[i].mode == mode) 130104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return &modes[i]; 130204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 130304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 130404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return NULL; 130504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 130604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 130704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 13086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic void wpa_obss_scan_freqs_list(struct wpa_supplicant *wpa_s, 13096c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct wpa_driver_scan_params *params) 131004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 13116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* Include only affected channels */ 131204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct hostapd_hw_modes *mode; 131304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int count, i; 13146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int start, end; 131504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 13166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, 13176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt HOSTAPD_MODE_IEEE80211G); 131804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (mode == NULL) { 131904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* No channels supported in this band - use empty list */ 132004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params->freqs = os_zalloc(sizeof(int)); 132104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 132204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 132304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 13246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->sme.ht_sec_chan == HT_SEC_CHAN_UNKNOWN && 13256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->current_bss) { 13266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt const u8 *ie; 13276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 13286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_OPERATION); 13296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (ie && ie[1] >= 2) { 13306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 o; 13316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 13326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt o = ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK; 13336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (o == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE) 13346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_ABOVE; 13356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt else if (o == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW) 13366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_BELOW; 13376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 13386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 13396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 13406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt start = wpa_s->assoc_freq - 10; 13416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt end = wpa_s->assoc_freq + 10; 13426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt switch (wpa_s->sme.ht_sec_chan) { 13436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt case HT_SEC_CHAN_UNKNOWN: 13446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* HT40+ possible on channels 1..9 */ 13456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->assoc_freq <= 2452) 13466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt start -= 20; 13476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* HT40- possible on channels 5-13 */ 13486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (wpa_s->assoc_freq >= 2432) 13496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt end += 20; 13506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 13516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt case HT_SEC_CHAN_ABOVE: 13526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt end += 20; 13536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 13546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt case HT_SEC_CHAN_BELOW: 13556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt start -= 20; 13566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt break; 13576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 13586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 13596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "OBSS: assoc_freq %d possible affected range %d-%d", 13606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->assoc_freq, start, end); 13616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 136261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params->freqs = os_calloc(mode->num_channels + 1, sizeof(int)); 136304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (params->freqs == NULL) 136404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 136504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (count = 0, i = 0; i < mode->num_channels; i++) { 13666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int freq; 13676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 136804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED) 136904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt continue; 13706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt freq = mode->channels[i].freq; 13716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (freq - 10 >= end || freq + 10 <= start) 13726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt continue; /* not affected */ 13736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params->freqs[count++] = freq; 137404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 137504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 137604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 137704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 137804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx) 137904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 138004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 138104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_driver_scan_params params; 138204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 138304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->current_bss) { 138404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME OBSS: Ignore scan request"); 138504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 138604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 138704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 138804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 13896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_obss_scan_freqs_list(wpa_s, ¶ms); 13902271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt params.low_priority = 1; 139104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME OBSS: Request an OBSS scan"); 139204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 139304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_supplicant_trigger_scan(wpa_s, ¶ms)) 139404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan"); 139504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 139604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.sched_obss_scan = 1; 139704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(params.freqs); 139804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 139904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_register_timeout(wpa_s->sme.obss_scan_int, 0, 140004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sme_obss_scan_timeout, wpa_s, NULL); 140104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 140204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 140304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 140404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable) 140504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 140604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *ie; 140704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss = wpa_s->current_bss; 140804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 140961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_hw_modes *hw_mode = NULL; 141061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int i; 141104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 141204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL); 141304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.sched_obss_scan = 0; 14146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_UNKNOWN; 141504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!enable) 141604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 141704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1418d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 1419d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * Schedule OBSS scan if driver is using station SME in wpa_supplicant 1420d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * or it expects OBSS scan to be performed by wpa_supplicant. 1421d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 1422d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) || 1423d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OBSS_SCAN)) || 1424d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ssid == NULL || ssid->mode != IEEE80211_MODE_INFRA) 1425d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 142604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 142761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!wpa_s->hw.modes) 142861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 142961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 143061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* only HT caps in 11g mode are relevant */ 143161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < wpa_s->hw.num_modes; i++) { 143261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hw_mode = &wpa_s->hw.modes[i]; 143361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hw_mode->mode == HOSTAPD_MODE_IEEE80211G) 143461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 143561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 143661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 143761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Driver does not support HT40 for 11g or doesn't have 11g. */ 143861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (i == wpa_s->hw.num_modes || !hw_mode || 143961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !(hw_mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) 144061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 144104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 144204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss == NULL || bss->freq < 2400 || bss->freq > 2500) 144304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; /* Not associated on 2.4 GHz band */ 144404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 144504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Check whether AP supports HT40 */ 144604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_CAP); 144704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!ie || ie[1] < 2 || 144804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt !(WPA_GET_LE16(ie + 2) & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) 144904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; /* AP does not support HT40 */ 145004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 145104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie = wpa_bss_get_ie(wpa_s->current_bss, 145204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS); 145304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!ie || ie[1] < 14) 145404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; /* AP does not request OBSS scans */ 145504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 145604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.obss_scan_int = WPA_GET_LE16(ie + 6); 145704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->sme.obss_scan_int < 10) { 145804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME: Invalid OBSS Scan Interval %u " 145904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "replaced with the minimum 10 sec", 146004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.obss_scan_int); 146104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.obss_scan_int = 10; 146204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 146304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME: OBSS Scan Interval %u sec", 146404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.obss_scan_int); 146504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_register_timeout(wpa_s->sme.obss_scan_int, 0, 146604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sme_obss_scan_timeout, wpa_s, NULL); 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const unsigned int sa_query_max_timeout = 1000; 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const unsigned int sa_query_retry_timeout = 201; 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int sme_check_sa_query_timeout(struct wpa_supplicant *wpa_s) 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 tu; 1478fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct os_reltime now, passed; 1479fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&now); 1480fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_reltime_sub(&now, &wpa_s->sme.sa_query_start, &passed); 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tu = (passed.sec * 1000000 + passed.usec) / 1024; 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sa_query_max_timeout < tu) { 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: SA Query timed out"); 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_stop_sa_query(wpa_s); 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_deauthenticate( 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s, WLAN_REASON_PREV_AUTH_NOT_VALID); 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_send_sa_query_req(struct wpa_supplicant *wpa_s, 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *trans_id) 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 req[2 + WLAN_SA_QUERY_TR_ID_LEN]; 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Sending SA Query Request to " 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(wpa_s->bssid)); 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "SME: SA Query Transaction ID", 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trans_id, WLAN_SA_QUERY_TR_ID_LEN); 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req[0] = WLAN_ACTION_SA_QUERY; 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req[1] = WLAN_SA_QUERY_REQUEST; 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(req + 2, trans_id, WLAN_SA_QUERY_TR_ID_LEN); 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->own_addr, wpa_s->bssid, 15071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt req, sizeof(req), 0) < 0) 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Failed to send SA Query " 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request"); 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_sa_query_timer(void *eloop_ctx, void *timeout_ctx) 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int timeout, sec, usec; 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *trans_id, *nbuf; 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.sa_query_count > 0 && 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_check_sa_query_timeout(wpa_s)) 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 152361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt nbuf = os_realloc_array(wpa_s->sme.sa_query_trans_id, 152461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->sme.sa_query_count + 1, 152561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WLAN_SA_QUERY_TR_ID_LEN); 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nbuf == NULL) 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.sa_query_count == 0) { 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Starting a new SA Query procedure */ 1530fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_get_reltime(&wpa_s->sme.sa_query_start); 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trans_id = nbuf + wpa_s->sme.sa_query_count * WLAN_SA_QUERY_TR_ID_LEN; 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_trans_id = nbuf; 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_count++; 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1536661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN) < 0) { 1537661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_printf(MSG_DEBUG, "Could not generate SA Query ID"); 1538661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return; 1539661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = sa_query_retry_timeout; 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sec = ((timeout / 1000) * 1024) / 1000; 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usec = (timeout % 1000) * 1024; 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sec, usec, sme_sa_query_timer, wpa_s, NULL); 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association SA Query attempt %d", 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_count); 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_send_sa_query_req(wpa_s, trans_id); 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_start_sa_query(struct wpa_supplicant *wpa_s) 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_sa_query_timer(wpa_s, NULL); 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void sme_stop_sa_query(struct wpa_supplicant *wpa_s) 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_sa_query_timer, wpa_s, NULL); 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->sme.sa_query_trans_id); 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_trans_id = NULL; 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_count = 0; 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa, 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *da, u16 reason_code) 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 15720c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt struct os_reltime now; 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state != WPA_COMPLETED) 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 1577807291d85bf857320aff6a8ade38c5f622ab9df8Dmitry Shmidt if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION) 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reason_code != WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA && 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason_code != WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA) 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.sa_query_count > 0) 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15870c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt os_get_reltime(&now); 15880c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt if (wpa_s->sme.last_unprot_disconnect.sec && 15890c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt !os_reltime_expired(&now, &wpa_s->sme.last_unprot_disconnect, 10)) 15900c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt return; /* limit SA Query procedure frequency */ 15910c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt wpa_s->sme.last_unprot_disconnect = now; 15920c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Unprotected disconnect dropped - " 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "possible AP/STA state mismatch - trigger SA Query"); 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_start_sa_query(wpa_s); 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa, 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len) 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.sa_query_trans_id == NULL || 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len < 1 + WLAN_SA_QUERY_TR_ID_LEN || 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0] != WLAN_SA_QUERY_RESPONSE) 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query response from " 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]); 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < wpa_s->sme.sa_query_count; i++) { 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(wpa_s->sme.sa_query_trans_id + 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i * WLAN_SA_QUERY_TR_ID_LEN, 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data + 1, WLAN_SA_QUERY_TR_ID_LEN) == 0) 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i >= wpa_s->sme.sa_query_count) { 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: No matching SA Query " 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "transaction identifier found"); 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reply to pending SA Query received " 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from " MACSTR, MAC2STR(sa)); 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_stop_sa_query(wpa_s); 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 1633