diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 7a62f96d6..fc1ed4f90 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -4828,6 +4828,7 @@ static const struct global_parse_data global_fields[] = { { INT(okc), 0 }, { INT(pmf), 0 }, { FUNC(sae_groups), 0 }, + { INT_RANGE(sae_pmkid_in_assoc, 0, 1), 0 }, { INT(dtim_period), 0 }, { INT(beacon_int), 0 }, { FUNC(ap_vendor_elements), 0 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 6a297ecfe..5b5c2fdba 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -1164,6 +1164,11 @@ struct wpa_config { */ int *sae_groups; + /** + * sae_pmkid_in_assoc - Whether to include PMKID in SAE Assoc Req + */ + int sae_pmkid_in_assoc; + /** * dtim_period - Default DTIM period in Beacon intervals * diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 77c326df5..91d5caa3f 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -1390,6 +1390,10 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) fprintf(f, "\n"); } + if (config->sae_pmkid_in_assoc) + fprintf(f, "sae_pmkid_in_assoc=%d\n", + config->sae_pmkid_in_assoc); + if (config->ap_vendor_elements) { int i, len = wpabuf_len(config->ap_vendor_elements); const u8 *p = wpabuf_head_u8(config->ap_vendor_elements); diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index dd5020179..7944368cf 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -1197,6 +1197,37 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction, } +static int sme_sae_set_pmk(struct wpa_supplicant *wpa_s) +{ + 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 (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) { @@ -1230,10 +1261,8 @@ void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s, 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) < 0) + return; } } @@ -1286,10 +1315,8 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data) 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) < 0) + return; } #endif /* CONFIG_SAE */