SAE: Add RSNXE in Association Request and EAPOL-Key msg 2/4
Add the new RSNXE into (Re)Association Request frames and EAPOL-Key msg 2/4 when using SAE with hash-to-element mechanism enabled. This allows the AP to verify that there was no downgrade attack when both PWE derivation mechanisms are enabled. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
8401cdc8d4
commit
6d6c887751
9 changed files with 187 additions and 33 deletions
|
@ -655,43 +655,44 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
|
||||||
|
|
||||||
kde = sm->assoc_wpa_ie;
|
kde = sm->assoc_wpa_ie;
|
||||||
kde_len = sm->assoc_wpa_ie_len;
|
kde_len = sm->assoc_wpa_ie_len;
|
||||||
|
kde_buf = os_malloc(kde_len +
|
||||||
|
2 + RSN_SELECTOR_LEN + 3 +
|
||||||
|
sm->assoc_rsnxe_len +
|
||||||
|
2 + RSN_SELECTOR_LEN + 1);
|
||||||
|
if (!kde_buf)
|
||||||
|
goto failed;
|
||||||
|
os_memcpy(kde_buf, kde, kde_len);
|
||||||
|
kde = kde_buf;
|
||||||
|
|
||||||
#ifdef CONFIG_OCV
|
#ifdef CONFIG_OCV
|
||||||
if (wpa_sm_ocv_enabled(sm)) {
|
if (wpa_sm_ocv_enabled(sm)) {
|
||||||
struct wpa_channel_info ci;
|
struct wpa_channel_info ci;
|
||||||
u8 *pos;
|
u8 *pos;
|
||||||
|
|
||||||
|
pos = kde + kde_len;
|
||||||
if (wpa_sm_channel_info(sm, &ci) != 0) {
|
if (wpa_sm_channel_info(sm, &ci) != 0) {
|
||||||
wpa_printf(MSG_WARNING,
|
wpa_printf(MSG_WARNING,
|
||||||
"Failed to get channel info for OCI element in EAPOL-Key 2/4");
|
"Failed to get channel info for OCI element in EAPOL-Key 2/4");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
kde_buf = os_malloc(kde_len + 2 + RSN_SELECTOR_LEN + 3);
|
|
||||||
if (!kde_buf) {
|
|
||||||
wpa_printf(MSG_WARNING,
|
|
||||||
"Failed to allocate memory for KDE with OCI in EAPOL-Key 2/4");
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_memcpy(kde_buf, kde, kde_len);
|
|
||||||
kde = kde_buf;
|
|
||||||
pos = kde + kde_len;
|
|
||||||
if (ocv_insert_oci_kde(&ci, &pos) < 0)
|
if (ocv_insert_oci_kde(&ci, &pos) < 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
kde_len = pos - kde;
|
kde_len = pos - kde;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_OCV */
|
#endif /* CONFIG_OCV */
|
||||||
|
|
||||||
|
if (sm->assoc_rsnxe && sm->assoc_rsnxe_len) {
|
||||||
|
os_memcpy(kde + kde_len, sm->assoc_rsnxe, sm->assoc_rsnxe_len);
|
||||||
|
kde_len += sm->assoc_rsnxe_len;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
#ifdef CONFIG_P2P
|
||||||
if (sm->p2p) {
|
if (sm->p2p) {
|
||||||
kde_buf = os_malloc(kde_len + 2 + RSN_SELECTOR_LEN + 1);
|
|
||||||
if (kde_buf) {
|
|
||||||
u8 *pos;
|
u8 *pos;
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Add IP Address Request KDE "
|
|
||||||
"into EAPOL-Key 2/4");
|
wpa_printf(MSG_DEBUG,
|
||||||
os_memcpy(kde_buf, kde, kde_len);
|
"P2P: Add IP Address Request KDE into EAPOL-Key 2/4");
|
||||||
kde = kde_buf;
|
|
||||||
pos = kde + kde_len;
|
pos = kde + kde_len;
|
||||||
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
|
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
|
||||||
*pos++ = RSN_SELECTOR_LEN + 1;
|
*pos++ = RSN_SELECTOR_LEN + 1;
|
||||||
|
@ -700,7 +701,6 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
|
||||||
*pos++ = 0x01;
|
*pos++ = 0x01;
|
||||||
kde_len = pos - kde;
|
kde_len = pos - kde;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif /* CONFIG_P2P */
|
#endif /* CONFIG_P2P */
|
||||||
|
|
||||||
if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
|
if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
|
||||||
|
@ -2672,6 +2672,7 @@ void wpa_sm_deinit(struct wpa_sm *sm)
|
||||||
eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
|
eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
|
||||||
eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
|
eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
|
||||||
os_free(sm->assoc_wpa_ie);
|
os_free(sm->assoc_wpa_ie);
|
||||||
|
os_free(sm->assoc_rsnxe);
|
||||||
os_free(sm->ap_wpa_ie);
|
os_free(sm->ap_wpa_ie);
|
||||||
os_free(sm->ap_rsn_ie);
|
os_free(sm->ap_rsn_ie);
|
||||||
os_free(sm->ap_rsnxe);
|
os_free(sm->ap_rsnxe);
|
||||||
|
@ -3049,6 +3050,9 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
|
||||||
case WPA_PARAM_OCV:
|
case WPA_PARAM_OCV:
|
||||||
sm->ocv = value;
|
sm->ocv = value;
|
||||||
break;
|
break;
|
||||||
|
case WPA_PARAM_SAE_PWE:
|
||||||
|
sm->sae_pwe = value;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3226,6 +3230,83 @@ int wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wpa_sm_set_assoc_rsnxe_default - Generate own RSNXE from configuration
|
||||||
|
* @sm: Pointer to WPA state machine data from wpa_sm_init()
|
||||||
|
* @rsnxe: Pointer to buffer for RSNXE
|
||||||
|
* @rsnxe_len: Pointer to the length of the rsne buffer
|
||||||
|
* Returns: 0 on success, -1 on failure
|
||||||
|
*/
|
||||||
|
int wpa_sm_set_assoc_rsnxe_default(struct wpa_sm *sm, u8 *rsnxe,
|
||||||
|
size_t *rsnxe_len)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (!sm)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
res = wpa_gen_rsnxe(sm, rsnxe, *rsnxe_len);
|
||||||
|
if (res < 0)
|
||||||
|
return -1;
|
||||||
|
*rsnxe_len = res;
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_DEBUG, "RSN: Set own RSNXE default", rsnxe, *rsnxe_len);
|
||||||
|
|
||||||
|
if (sm->assoc_rsnxe) {
|
||||||
|
wpa_hexdump(MSG_DEBUG,
|
||||||
|
"RSN: Leave previously set RSNXE default",
|
||||||
|
sm->assoc_rsnxe, sm->assoc_rsnxe_len);
|
||||||
|
} else if (*rsnxe_len > 0) {
|
||||||
|
/*
|
||||||
|
* Make a copy of the RSNXE so that 4-Way Handshake gets the
|
||||||
|
* correct version of the IE even if it gets changed.
|
||||||
|
*/
|
||||||
|
sm->assoc_rsnxe = os_memdup(rsnxe, *rsnxe_len);
|
||||||
|
if (!sm->assoc_rsnxe)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
sm->assoc_rsnxe_len = *rsnxe_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wpa_sm_set_assoc_rsnxe - Set own RSNXE from (Re)AssocReq
|
||||||
|
* @sm: Pointer to WPA state machine data from wpa_sm_init()
|
||||||
|
* @ie: Pointer to IE data (starting from id)
|
||||||
|
* @len: IE length
|
||||||
|
* Returns: 0 on success, -1 on failure
|
||||||
|
*
|
||||||
|
* Inform WPA state machine about the RSNXE used in (Re)Association Request
|
||||||
|
* frame. The IE will be used to override the default value generated
|
||||||
|
* with wpa_sm_set_assoc_rsnxe_default().
|
||||||
|
*/
|
||||||
|
int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len)
|
||||||
|
{
|
||||||
|
if (!sm)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
os_free(sm->assoc_rsnxe);
|
||||||
|
if (!ie || len == 0) {
|
||||||
|
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
||||||
|
"RSN: clearing own RSNXE");
|
||||||
|
sm->assoc_rsnxe = NULL;
|
||||||
|
sm->assoc_rsnxe_len = 0;
|
||||||
|
} else {
|
||||||
|
wpa_hexdump(MSG_DEBUG, "RSN: set own RSNXE", ie, len);
|
||||||
|
sm->assoc_rsnxe = os_memdup(ie, len);
|
||||||
|
if (!sm->assoc_rsnxe)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
sm->assoc_rsnxe_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wpa_sm_set_ap_wpa_ie - Set AP WPA IE from Beacon/ProbeResp
|
* wpa_sm_set_ap_wpa_ie - Set AP WPA IE from Beacon/ProbeResp
|
||||||
* @sm: Pointer to WPA state machine data from wpa_sm_init()
|
* @sm: Pointer to WPA state machine data from wpa_sm_init()
|
||||||
|
|
|
@ -98,7 +98,8 @@ enum wpa_sm_conf_params {
|
||||||
WPA_PARAM_MGMT_GROUP,
|
WPA_PARAM_MGMT_GROUP,
|
||||||
WPA_PARAM_RSN_ENABLED,
|
WPA_PARAM_RSN_ENABLED,
|
||||||
WPA_PARAM_MFP,
|
WPA_PARAM_MFP,
|
||||||
WPA_PARAM_OCV
|
WPA_PARAM_OCV,
|
||||||
|
WPA_PARAM_SAE_PWE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rsn_supp_config {
|
struct rsn_supp_config {
|
||||||
|
@ -134,6 +135,9 @@ void wpa_sm_set_eapol(struct wpa_sm *sm, struct eapol_sm *eapol);
|
||||||
int wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
|
int wpa_sm_set_assoc_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
|
||||||
int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie,
|
int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie,
|
||||||
size_t *wpa_ie_len);
|
size_t *wpa_ie_len);
|
||||||
|
int wpa_sm_set_assoc_rsnxe_default(struct wpa_sm *sm, u8 *rsnxe,
|
||||||
|
size_t *rsnxe_len);
|
||||||
|
int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len);
|
||||||
int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
|
int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
|
||||||
int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
|
int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
|
||||||
int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len);
|
int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len);
|
||||||
|
|
|
@ -85,9 +85,12 @@ struct wpa_sm {
|
||||||
int rsn_enabled; /* Whether RSN is enabled in configuration */
|
int rsn_enabled; /* Whether RSN is enabled in configuration */
|
||||||
int mfp; /* 0 = disabled, 1 = optional, 2 = mandatory */
|
int mfp; /* 0 = disabled, 1 = optional, 2 = mandatory */
|
||||||
int ocv; /* Operating Channel Validation */
|
int ocv; /* Operating Channel Validation */
|
||||||
|
int sae_pwe; /* SAE PWE generation options */
|
||||||
|
|
||||||
u8 *assoc_wpa_ie; /* Own WPA/RSN IE from (Re)AssocReq */
|
u8 *assoc_wpa_ie; /* Own WPA/RSN IE from (Re)AssocReq */
|
||||||
size_t assoc_wpa_ie_len;
|
size_t assoc_wpa_ie_len;
|
||||||
|
u8 *assoc_rsnxe; /* Own RSNXE from (Re)AssocReq */
|
||||||
|
size_t assoc_rsnxe_len;
|
||||||
u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe;
|
u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe;
|
||||||
size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len;
|
size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len;
|
||||||
|
|
||||||
|
|
|
@ -342,6 +342,28 @@ int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len)
|
||||||
|
{
|
||||||
|
u8 *pos = rsnxe;
|
||||||
|
|
||||||
|
if (!wpa_key_mgmt_sae(sm->key_mgmt))
|
||||||
|
return 0; /* SAE not in use */
|
||||||
|
if (sm->sae_pwe != 1 && sm->sae_pwe != 2)
|
||||||
|
return 0; /* no supported extended RSN capabilities */
|
||||||
|
|
||||||
|
if (rsnxe_len < 3)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*pos++ = WLAN_EID_RSNX;
|
||||||
|
*pos++ = 1;
|
||||||
|
/* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is
|
||||||
|
* used for now */
|
||||||
|
*pos++ = BIT(WLAN_RSNX_CAPAB_SAE_H2E);
|
||||||
|
|
||||||
|
return pos - rsnxe;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wpa_parse_vendor_specific - Parse Vendor Specific IEs
|
* wpa_parse_vendor_specific - Parse Vendor Specific IEs
|
||||||
* @pos: Pointer to the IE header
|
* @pos: Pointer to the IE header
|
||||||
|
|
|
@ -62,5 +62,6 @@ struct wpa_eapol_ie_parse {
|
||||||
int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
|
int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
|
||||||
struct wpa_eapol_ie_parse *ie);
|
struct wpa_eapol_ie_parse *ie);
|
||||||
int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len);
|
int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len);
|
||||||
|
int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len);
|
||||||
|
|
||||||
#endif /* WPA_IE_H */
|
#endif /* WPA_IE_H */
|
||||||
|
|
|
@ -2411,7 +2411,7 @@ static int wpas_fst_update_mbie(struct wpa_supplicant *wpa_s,
|
||||||
static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
|
static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
|
||||||
union wpa_event_data *data)
|
union wpa_event_data *data)
|
||||||
{
|
{
|
||||||
int l, len, found = 0, wpa_found, rsn_found;
|
int l, len, found = 0, found_x = 0, wpa_found, rsn_found;
|
||||||
const u8 *p;
|
const u8 *p;
|
||||||
#if defined(CONFIG_IEEE80211R) || defined(CONFIG_OWE)
|
#if defined(CONFIG_IEEE80211R) || defined(CONFIG_OWE)
|
||||||
u8 bssid[ETH_ALEN];
|
u8 bssid[ETH_ALEN];
|
||||||
|
@ -2483,22 +2483,29 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
|
||||||
p, l);
|
p, l);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
|
if (!found &&
|
||||||
|
((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
|
||||||
(os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
|
(os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
|
||||||
(p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 4 &&
|
(p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 4 &&
|
||||||
(os_memcmp(&p[2], "\x50\x6F\x9A\x12", 4) == 0)) ||
|
(os_memcmp(&p[2], "\x50\x6F\x9A\x12", 4) == 0)) ||
|
||||||
(p[0] == WLAN_EID_RSN && p[1] >= 2)) {
|
(p[0] == WLAN_EID_RSN && p[1] >= 2))) {
|
||||||
if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
|
if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
|
||||||
break;
|
break;
|
||||||
found = 1;
|
found = 1;
|
||||||
wpa_find_assoc_pmkid(wpa_s);
|
wpa_find_assoc_pmkid(wpa_s);
|
||||||
|
}
|
||||||
|
if (!found_x && p[0] == WLAN_EID_RSNX) {
|
||||||
|
if (wpa_sm_set_assoc_rsnxe(wpa_s->wpa, p, len))
|
||||||
break;
|
break;
|
||||||
|
found_x = 1;
|
||||||
}
|
}
|
||||||
l -= len;
|
l -= len;
|
||||||
p += len;
|
p += len;
|
||||||
}
|
}
|
||||||
if (!found && data->assoc_info.req_ies)
|
if (!found && data->assoc_info.req_ies)
|
||||||
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
|
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
|
||||||
|
if (!found_x && data->assoc_info.req_ies)
|
||||||
|
wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
|
||||||
|
|
||||||
#ifdef CONFIG_FILS
|
#ifdef CONFIG_FILS
|
||||||
#ifdef CONFIG_SME
|
#ifdef CONFIG_SME
|
||||||
|
|
|
@ -591,6 +591,14 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
|
||||||
os_memcpy(pos, ext_capab, ext_capab_len);
|
os_memcpy(pos, ext_capab, ext_capab_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wpa_s->rsnxe_len > 0 &&
|
||||||
|
wpa_s->rsnxe_len <=
|
||||||
|
sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len) {
|
||||||
|
os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
|
||||||
|
wpa_s->rsnxe, wpa_s->rsnxe_len);
|
||||||
|
wpa_s->sme.assoc_req_ie_len += wpa_s->rsnxe_len;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HS20
|
#ifdef CONFIG_HS20
|
||||||
if (is_hs20_network(wpa_s, ssid, bss)) {
|
if (is_hs20_network(wpa_s, ssid, bss)) {
|
||||||
struct wpabuf *hs20;
|
struct wpabuf *hs20;
|
||||||
|
@ -884,6 +892,8 @@ static void sme_auth_start_cb(struct wpa_radio_work *work, int deinit)
|
||||||
/* Starting new connection, so clear the possibly used WPA IE from the
|
/* Starting new connection, so clear the possibly used WPA IE from the
|
||||||
* previous association. */
|
* previous association. */
|
||||||
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
|
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
|
||||||
|
wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
|
||||||
|
wpa_s->rsnxe_len = 0;
|
||||||
|
|
||||||
sme_send_authentication(wpa_s, cwork->bss, cwork->ssid, 1);
|
sme_send_authentication(wpa_s, cwork->bss, cwork->ssid, 1);
|
||||||
}
|
}
|
||||||
|
@ -1899,6 +1909,11 @@ pfs_fail:
|
||||||
elems.osen_len + 2);
|
elems.osen_len + 2);
|
||||||
} else
|
} else
|
||||||
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
|
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
|
||||||
|
if (elems.rsnxe)
|
||||||
|
wpa_sm_set_assoc_rsnxe(wpa_s->wpa, elems.rsnxe - 2,
|
||||||
|
elems.rsnxe_len + 2);
|
||||||
|
else
|
||||||
|
wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
|
||||||
if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group)
|
if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group)
|
||||||
params.p2p = 1;
|
params.p2p = 1;
|
||||||
|
|
||||||
|
|
|
@ -404,6 +404,8 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
|
||||||
wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
|
wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
|
||||||
wpa_sm_set_ap_rsnxe(wpa_s->wpa, NULL, 0);
|
wpa_sm_set_ap_rsnxe(wpa_s->wpa, NULL, 0);
|
||||||
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
|
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
|
||||||
|
wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
|
||||||
|
wpa_s->rsnxe_len = 0;
|
||||||
wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
|
wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
|
||||||
wpa_s->group_cipher = WPA_CIPHER_NONE;
|
wpa_s->group_cipher = WPA_CIPHER_NONE;
|
||||||
wpa_s->mgmt_group_cipher = 0;
|
wpa_s->mgmt_group_cipher = 0;
|
||||||
|
@ -1578,12 +1580,20 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
|
||||||
#ifdef CONFIG_OCV
|
#ifdef CONFIG_OCV
|
||||||
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, ssid->ocv);
|
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, ssid->ocv);
|
||||||
#endif /* CONFIG_OCV */
|
#endif /* CONFIG_OCV */
|
||||||
|
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SAE_PWE, wpa_s->conf->sae_pwe);
|
||||||
|
|
||||||
if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
|
if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
|
||||||
wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
|
wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpa_s->rsnxe_len = sizeof(wpa_s->rsnxe);
|
||||||
|
if (wpa_sm_set_assoc_rsnxe_default(wpa_s->wpa, wpa_s->rsnxe,
|
||||||
|
&wpa_s->rsnxe_len)) {
|
||||||
|
wpa_msg(wpa_s, MSG_WARNING, "RSN: Failed to generate RSNXE");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (0) {
|
if (0) {
|
||||||
#ifdef CONFIG_DPP
|
#ifdef CONFIG_DPP
|
||||||
} else if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP) {
|
} else if (wpa_s->key_mgmt == WPA_KEY_MGMT_DPP) {
|
||||||
|
@ -2995,6 +3005,12 @@ pfs_fail:
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_IEEE80211R */
|
#endif /* CONFIG_IEEE80211R */
|
||||||
|
|
||||||
|
if (wpa_s->rsnxe_len > 0 &&
|
||||||
|
wpa_s->rsnxe_len <= max_wpa_ie_len - wpa_ie_len) {
|
||||||
|
os_memcpy(wpa_ie + wpa_ie_len, wpa_s->rsnxe, wpa_s->rsnxe_len);
|
||||||
|
wpa_ie_len += wpa_s->rsnxe_len;
|
||||||
|
}
|
||||||
|
|
||||||
if (ssid->multi_ap_backhaul_sta) {
|
if (ssid->multi_ap_backhaul_sta) {
|
||||||
size_t multi_ap_ie_len;
|
size_t multi_ap_ie_len;
|
||||||
|
|
||||||
|
@ -3305,6 +3321,8 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
|
||||||
/* Starting new association, so clear the possibly used WPA IE from the
|
/* Starting new association, so clear the possibly used WPA IE from the
|
||||||
* previous association. */
|
* previous association. */
|
||||||
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
|
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
|
||||||
|
wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
|
||||||
|
wpa_s->rsnxe_len = 0;
|
||||||
|
|
||||||
wpa_ie = wpas_populate_assoc_ies(wpa_s, bss, ssid, ¶ms, NULL);
|
wpa_ie = wpas_populate_assoc_ies(wpa_s, bss, ssid, ¶ms, NULL);
|
||||||
if (!wpa_ie) {
|
if (!wpa_ie) {
|
||||||
|
|
|
@ -614,6 +614,9 @@ struct wpa_supplicant {
|
||||||
int eapol_received; /* number of EAPOL packets received after the
|
int eapol_received; /* number of EAPOL packets received after the
|
||||||
* previous association event */
|
* previous association event */
|
||||||
|
|
||||||
|
u8 rsnxe[20];
|
||||||
|
size_t rsnxe_len;
|
||||||
|
|
||||||
struct scard_data *scard;
|
struct scard_data *scard;
|
||||||
char imsi[20];
|
char imsi[20];
|
||||||
int mnc_len;
|
int mnc_len;
|
||||||
|
|
Loading…
Reference in a new issue