static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx);
static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx);
static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx);
-#ifdef CONFIG_IEEE80211W
static void sme_stop_sa_query(struct wpa_supplicant *wpa_s);
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_SAE
}
#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_IEEE80211W
wpa_s->sme.mfp = wpas_get_ssid_pmf(wpa_s, ssid);
if (wpa_s->sme.mfp != NO_MGMT_FRAME_PROTECTION) {
const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED;
}
}
-#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_P2P
if (wpa_s->global->p2p) {
#ifdef CONFIG_MBO
mbo_ie = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE);
- if (mbo_ie) {
+ if (!wpa_s->disable_mbo_oce && mbo_ie) {
int len;
len = wpas_mbo_ie(wpa_s, wpa_s->sme.assoc_req_ie +
}
-static void sme_external_auth_send_sae_commit(struct wpa_supplicant *wpa_s,
- const u8 *bssid,
- struct wpa_ssid *ssid)
+static int sme_external_auth_send_sae_commit(struct wpa_supplicant *wpa_s,
+ const u8 *bssid,
+ struct wpa_ssid *ssid)
{
struct wpabuf *resp, *buf;
resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1, 0);
- if (!resp)
- return;
+ if (!resp) {
+ wpa_printf(MSG_DEBUG, "SAE: Failed to build SAE commit");
+ return -1;
+ }
wpa_s->sme.sae.state = SAE_COMMITTED;
buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + wpabuf_len(resp));
if (!buf) {
wpabuf_free(resp);
- return;
+ return -1;
}
wpa_s->sme.seq_num++;
wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0);
wpabuf_free(resp);
wpabuf_free(buf);
+
+ return 0;
}
os_memset(¶ms, 0, sizeof(params));
params.status = status;
- params.ssid = wpa_s->sme.ext_auth.ssid;
- params.ssid_len = wpa_s->sme.ext_auth.ssid_len;
- params.bssid = wpa_s->sme.ext_auth.bssid;
+ params.ssid = wpa_s->sme.ext_auth_ssid;
+ params.ssid_len = wpa_s->sme.ext_auth_ssid_len;
+ params.bssid = wpa_s->sme.ext_auth_bssid;
+ if (wpa_s->conf->sae_pmkid_in_assoc && status == WLAN_STATUS_SUCCESS)
+ params.pmkid = wpa_s->sme.sae.pmkid;
wpa_drv_send_external_auth_status(wpa_s, ¶ms);
}
-static void sme_handle_external_auth_start(struct wpa_supplicant *wpa_s,
- union wpa_event_data *data)
+static int sme_handle_external_auth_start(struct wpa_supplicant *wpa_s,
+ union wpa_event_data *data)
{
struct wpa_ssid *ssid;
size_t ssid_str_len = data->external_auth.ssid_len;
(ssid->key_mgmt & (WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE)))
break;
}
- if (ssid)
- sme_external_auth_send_sae_commit(wpa_s,
- data->external_auth.bssid,
- ssid);
- else
- sme_send_external_auth_status(wpa_s,
- WLAN_STATUS_UNSPECIFIED_FAILURE);
+ if (!ssid ||
+ sme_external_auth_send_sae_commit(wpa_s, data->external_auth.bssid,
+ ssid) < 0)
+ return -1;
+
+ return 0;
}
return;
if (data->external_auth.action == EXT_AUTH_START) {
- os_memcpy(&wpa_s->sme.ext_auth, data,
- sizeof(struct external_auth));
+ if (!data->external_auth.bssid || !data->external_auth.ssid)
+ return;
+ os_memcpy(wpa_s->sme.ext_auth_bssid, data->external_auth.bssid,
+ ETH_ALEN);
+ os_memcpy(wpa_s->sme.ext_auth_ssid, data->external_auth.ssid,
+ data->external_auth.ssid_len);
+ wpa_s->sme.ext_auth_ssid_len = data->external_auth.ssid_len;
wpa_s->sme.seq_num = 0;
wpa_s->sme.sae.state = SAE_NOTHING;
wpa_s->sme.sae.send_confirm = 0;
wpa_s->sme.sae_group_index = 0;
- sme_handle_external_auth_start(wpa_s, data);
+ if (sme_handle_external_auth_start(wpa_s, data) < 0)
+ sme_send_external_auth_status(wpa_s,
+ WLAN_STATUS_UNSPECIFIED_FAILURE);
} else if (data->external_auth.action == EXT_AUTH_ABORT) {
/* Report failure to driver for the wrong trigger */
sme_send_external_auth_status(wpa_s,
wpa_s->current_ssid, 2);
else
sme_external_auth_send_sae_commit(
- wpa_s, wpa_s->sme.ext_auth.bssid,
+ wpa_s, wpa_s->sme.ext_auth_bssid,
wpa_s->current_ssid);
return 0;
}
wpa_s->sme.sae.state == SAE_COMMITTED &&
(external || wpa_s->current_bss) && wpa_s->current_ssid) {
wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE group not supported");
+ int_array_add_unique(&wpa_s->sme.sae_rejected_groups,
+ wpa_s->sme.sae.group);
wpa_s->sme.sae_group_index++;
if (sme_set_sae_group(wpa_s) < 0)
return -1; /* no other groups enabled */
wpa_s->current_ssid, 1);
else
sme_external_auth_send_sae_commit(
- wpa_s, wpa_s->sme.ext_auth.bssid,
+ wpa_s, wpa_s->sme.ext_auth_bssid,
wpa_s->current_ssid);
return 0;
}
if (groups && groups[0] <= 0)
groups = NULL;
res = sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
- groups);
+ groups, status_code ==
+ WLAN_STATUS_SAE_HASH_TO_ELEMENT);
if (res == SAE_SILENTLY_DISCARD) {
wpa_printf(MSG_DEBUG,
"SAE: Drop commit message due to reflection attack");
}
+static int sme_sae_set_pmk(struct wpa_supplicant *wpa_s, const u8 *bssid)
+{
+ wpa_printf(MSG_DEBUG,
+ "SME: SAE completed - setting PMK for 4-way handshake");
+ wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN,
+ wpa_s->sme.sae.pmkid, bssid);
+ if (wpa_s->conf->sae_pmkid_in_assoc) {
+ /* Update the own RSNE contents now that we have set the PMK
+ * and added a PMKSA cache entry based on the successfully
+ * completed SAE exchange. In practice, this will add the PMKID
+ * into RSNE. */
+ if (wpa_s->sme.assoc_req_ie_len + 2 + PMKID_LEN >
+ sizeof(wpa_s->sme.assoc_req_ie)) {
+ wpa_msg(wpa_s, MSG_WARNING,
+ "RSN: Not enough room for inserting own PMKID into RSNE");
+ return -1;
+ }
+ if (wpa_insert_pmkid(wpa_s->sme.assoc_req_ie,
+ &wpa_s->sme.assoc_req_ie_len,
+ wpa_s->sme.sae.pmkid) < 0)
+ return -1;
+ wpa_hexdump(MSG_DEBUG,
+ "SME: Updated Association Request IEs",
+ wpa_s->sme.assoc_req_ie,
+ wpa_s->sme.assoc_req_ie_len);
+ }
+
+ return 0;
+}
+
+
void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s,
const u8 *auth_frame, size_t len)
{
if (res != 1)
return;
- wpa_printf(MSG_DEBUG,
- "SME: SAE completed - setting PMK for 4-way handshake");
- wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN,
- wpa_s->sme.sae.pmkid, wpa_s->pending_bssid);
+ if (sme_sae_set_pmk(wpa_s, wpa_s->sme.ext_auth_bssid) < 0)
+ return;
}
}
if (res != 1)
return;
- wpa_printf(MSG_DEBUG, "SME: SAE completed - setting PMK for "
- "4-way handshake");
- wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN,
- wpa_s->sme.sae.pmkid, wpa_s->pending_bssid);
+ if (sme_sae_set_pmk(wpa_s, wpa_s->pending_bssid) < 0)
+ return;
}
#endif /* CONFIG_SAE */
if (wpa_s->sme.ft_ies || wpa_s->sme.ft_used)
sme_update_ft_ies(wpa_s, NULL, NULL, 0);
#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_IEEE80211W
sme_stop_sa_query(wpa_s);
-#endif /* CONFIG_IEEE80211W */
}
void sme_deinit(struct wpa_supplicant *wpa_s)
{
sme_clear_on_disassoc(wpa_s);
+#ifdef CONFIG_SAE
+ os_free(wpa_s->sme.sae_rejected_groups);
+ wpa_s->sme.sae_rejected_groups = NULL;
+#endif /* CONFIG_SAE */
eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
*/
if (!((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
(wpa_s->drv_flags & WPA_DRIVER_FLAGS_OBSS_SCAN)) ||
- ssid == NULL || ssid->mode != IEEE80211_MODE_INFRA)
+ ssid == NULL || ssid->mode != WPAS_MODE_INFRA)
return;
if (!wpa_s->hw.modes)
}
-#ifdef CONFIG_IEEE80211W
-
static const unsigned int sa_query_max_timeout = 1000;
static const unsigned int sa_query_retry_timeout = 201;
static const unsigned int sa_query_ch_switch_max_delay = 5000; /* in usec */
else if (data[0] == WLAN_SA_QUERY_RESPONSE)
sme_process_sa_query_response(wpa_s, sa, data, len);
}
-
-#endif /* CONFIG_IEEE80211W */