RSNO: Include all RSNE/RSNXE variants in EAPOL-Key message 3/4

This allows all variants to be verified based on a protected frame to
achieve robust downgrade protection.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
Jouni Malinen 2024-07-29 17:20:22 +03:00 committed by Jouni Malinen
parent 6f522baa1b
commit 521374b978
8 changed files with 275 additions and 121 deletions

View file

@ -4665,82 +4665,8 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
wpa_ie = wpa_ie + wpa_ie[1] + 2; wpa_ie = wpa_ie + wpa_ie[1] + 2;
wpa_ie_len = wpa_ie[1] + 2; wpa_ie_len = wpa_ie[1] + 2;
} }
if ((sm->rsn_override && if ((conf->rsn_override_key_mgmt || conf->rsn_override_key_mgmt_2) &&
get_vendor_ie(wpa_ie, wpa_ie_len, RSNE_OVERRIDE_IE_VENDOR_TYPE)) || !rsn_is_snonce_cookie(sm->SNonce)) {
(sm->rsn_override_2 &&
get_vendor_ie(wpa_ie, wpa_ie_len,
RSNE_OVERRIDE_2_IE_VENDOR_TYPE))) {
const u8 *mde, *fte, *tie, *tie2 = NULL;
const u8 *override_rsne = NULL, *override_rsnxe = NULL;
const struct element *elem;
wpa_printf(MSG_DEBUG,
"RSN: Use RSNE/RSNXE override element contents");
mde = get_ie(wpa_ie, wpa_ie_len, WLAN_EID_MOBILITY_DOMAIN);
fte = get_ie(wpa_ie, wpa_ie_len, WLAN_EID_FAST_BSS_TRANSITION);
tie = get_ie(wpa_ie, wpa_ie_len, WLAN_EID_TIMEOUT_INTERVAL);
if (tie) {
const u8 *next = tie + 2 + tie[1];
tie2 = get_ie(next, wpa_ie + wpa_ie_len - next,
WLAN_EID_TIMEOUT_INTERVAL);
}
for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC,
wpa_ie, wpa_ie_len) {
if (elem->datalen >= 4) {
if (WPA_GET_BE32(elem->data) ==
(sm->rsn_override_2 ?
RSNE_OVERRIDE_2_IE_VENDOR_TYPE :
RSNE_OVERRIDE_IE_VENDOR_TYPE))
override_rsne = &elem->id;
if (WPA_GET_BE32(elem->data) ==
RSNXE_OVERRIDE_IE_VENDOR_TYPE)
override_rsnxe = &elem->id;
}
}
wpa_hexdump(MSG_DEBUG, "EAPOL-Key msg 3/4 IEs before edits",
wpa_ie, wpa_ie_len);
wpa_ie_buf3 = os_malloc(wpa_ie_len);
if (!wpa_ie_buf3)
goto done;
pos = wpa_ie_buf3;
if (override_rsne) {
*pos++ = WLAN_EID_RSN;
*pos++ = override_rsne[1] - 4;
os_memcpy(pos, &override_rsne[2 + 4],
override_rsne[1] - 4);
pos += override_rsne[1] - 4;
}
if (mde) {
os_memcpy(pos, mde, 2 + mde[1]);
pos += 2 + mde[1];
}
if (fte) {
os_memcpy(pos, fte, 2 + fte[1]);
pos += 2 + fte[1];
}
if (tie) {
os_memcpy(pos, tie, 2 + tie[1]);
pos += 2 + tie[1];
}
if (tie2) {
os_memcpy(pos, tie2, 2 + tie2[1]);
pos += 2 + tie2[1];
}
if (override_rsnxe) {
*pos++ = WLAN_EID_RSNX;
*pos++ = override_rsnxe[1] - 4;
os_memcpy(pos, &override_rsnxe[2 + 4],
override_rsnxe[1] - 4);
pos += override_rsnxe[1] - 4;
}
wpa_ie = wpa_ie_buf3;
wpa_ie_len = pos - wpa_ie_buf3;
wpa_hexdump(MSG_DEBUG, "EAPOL-Key msg 3/4 IEs after edits",
wpa_ie, wpa_ie_len);
} else if ((conf->rsn_override_key_mgmt ||
conf->rsn_override_key_mgmt_2) &&
!sm->rsn_override && !sm->rsn_override_2) {
u8 *ie; u8 *ie;
size_t ie_len; size_t ie_len;
u32 ids[] = { u32 ids[] = {

View file

@ -3629,6 +3629,24 @@ static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
return 0; return 0;
} }
if (selector == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
ie->rsne_override = pos;
ie->rsne_override_len = dlen;
return 0;
}
if (selector == RSNE_OVERRIDE_2_IE_VENDOR_TYPE) {
ie->rsne_override_2 = pos;
ie->rsne_override_2_len = dlen;
return 0;
}
if (selector == RSNXE_OVERRIDE_IE_VENDOR_TYPE) {
ie->rsnxe_override = pos;
ie->rsnxe_override_len = dlen;
return 0;
}
if (selector == RSN_SELECTION_IE_VENDOR_TYPE) { if (selector == RSN_SELECTION_IE_VENDOR_TYPE) {
ie->rsn_selection = p; ie->rsn_selection = p;
ie->rsn_selection_len = left; ie->rsn_selection_len = left;

View file

@ -714,6 +714,12 @@ struct wpa_eapol_ie_parse {
size_t wmm_len; size_t wmm_len;
const u8 *rsn_selection; const u8 *rsn_selection;
size_t rsn_selection_len; size_t rsn_selection_len;
const u8 *rsne_override;
size_t rsne_override_len;
const u8 *rsne_override_2;
size_t rsne_override_2_len;
const u8 *rsnxe_override;
size_t rsnxe_override_len;
u16 valid_mlo_gtks; /* bitmap of valid link GTK KDEs */ u16 valid_mlo_gtks; /* bitmap of valid link GTK KDEs */
const u8 *mlo_gtk[MAX_NUM_MLD_LINKS]; const u8 *mlo_gtk[MAX_NUM_MLD_LINKS];
size_t mlo_gtk_len[MAX_NUM_MLD_LINKS]; size_t mlo_gtk_len[MAX_NUM_MLD_LINKS];

View file

@ -2228,6 +2228,69 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
return -1; return -1;
} }
if (sm->proto == WPA_PROTO_RSN &&
sm->rsn_override != RSN_OVERRIDE_NOT_USED) {
if ((sm->ap_rsne_override && !ie->rsne_override) ||
(!sm->ap_rsne_override && ie->rsne_override) ||
(sm->ap_rsne_override && ie->rsne_override &&
(sm->ap_rsne_override_len != ie->rsne_override_len ||
os_memcmp(sm->ap_rsne_override, ie->rsne_override,
sm->ap_rsne_override_len) != 0))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN: RSNE Override element mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
wpa_hexdump(MSG_INFO,
"RSNE Override element in Beacon/ProbeResp",
sm->ap_rsne_override,
sm->ap_rsne_override_len);
wpa_hexdump(MSG_INFO,
"RSNE Override element in EAPOL-Key msg 3/4",
ie->rsne_override, ie->rsne_override_len);
wpa_sm_deauthenticate(sm,
WLAN_REASON_IE_IN_4WAY_DIFFERS);
return -1;
}
if ((sm->ap_rsne_override_2 && !ie->rsne_override_2) ||
(!sm->ap_rsne_override_2 && ie->rsne_override_2) ||
(sm->ap_rsne_override_2 && ie->rsne_override_2 &&
(sm->ap_rsne_override_2_len != ie->rsne_override_2_len ||
os_memcmp(sm->ap_rsne_override_2, ie->rsne_override_2,
sm->ap_rsne_override_2_len) != 0))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN: RSNE Override 2 element mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
wpa_hexdump(MSG_INFO,
"RSNE Override 2 element in Beacon/ProbeResp",
sm->ap_rsne_override_2,
sm->ap_rsne_override_2_len);
wpa_hexdump(MSG_INFO,
"RSNE Override 2 element in EAPOL-Key msg 3/4",
ie->rsne_override_2, ie->rsne_override_2_len);
wpa_sm_deauthenticate(sm,
WLAN_REASON_IE_IN_4WAY_DIFFERS);
return -1;
}
if ((sm->ap_rsnxe_override && !ie->rsnxe_override) ||
(!sm->ap_rsnxe_override && ie->rsnxe_override) ||
(sm->ap_rsnxe_override && ie->rsnxe_override &&
(sm->ap_rsnxe_override_len != ie->rsnxe_override_len ||
os_memcmp(sm->ap_rsnxe_override, ie->rsnxe_override,
sm->ap_rsnxe_override_len) != 0))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN: RSNXE Override element mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
wpa_hexdump(MSG_INFO,
"RSNXE Override element in Beacon/ProbeResp",
sm->ap_rsnxe_override,
sm->ap_rsnxe_override_len);
wpa_hexdump(MSG_INFO,
"RSNXE Override element in EAPOL-Key msg 3/4",
ie->rsnxe_override, ie->rsnxe_override_len);
wpa_sm_deauthenticate(sm,
WLAN_REASON_IE_IN_4WAY_DIFFERS);
return -1;
}
}
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R
if (wpa_key_mgmt_ft(sm->key_mgmt) && if (wpa_key_mgmt_ft(sm->key_mgmt) &&
wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0) wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0)
@ -4208,6 +4271,9 @@ void wpa_sm_deinit(struct wpa_sm *sm)
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);
os_free(sm->ap_rsne_override);
os_free(sm->ap_rsne_override_2);
os_free(sm->ap_rsnxe_override);
for (i = 0; i < MAX_NUM_MLD_LINKS; i++) { for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
os_free(sm->mlo.links[i].ap_rsne); os_free(sm->mlo.links[i].ap_rsne);
os_free(sm->mlo.links[i].ap_rsnxe); os_free(sm->mlo.links[i].ap_rsnxe);
@ -4813,6 +4879,23 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
} }
static const u8 * wpa_sm_get_ap_rsne(struct wpa_sm *sm, size_t *len)
{
if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE) {
*len = sm->ap_rsne_override_len;
return sm->ap_rsne_override;
}
if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE_2) {
*len = sm->ap_rsne_override_2_len;
return sm->ap_rsne_override_2;
}
*len = sm->ap_rsn_ie_len;
return sm->ap_rsn_ie;
}
/** /**
* wpa_sm_get_status - Get WPA state machine * wpa_sm_get_status - Get WPA state machine
* @sm: Pointer to WPA state machine data from wpa_sm_init() * @sm: Pointer to WPA state machine data from wpa_sm_init()
@ -4830,6 +4913,10 @@ int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
{ {
char *pos = buf, *end = buf + buflen; char *pos = buf, *end = buf + buflen;
int ret; int ret;
const u8 *rsne;
size_t rsne_len;
rsne = wpa_sm_get_ap_rsne(sm, &rsne_len);
ret = os_snprintf(pos, end - pos, ret = os_snprintf(pos, end - pos,
"pairwise_cipher=%s\n" "pairwise_cipher=%s\n"
@ -4851,10 +4938,10 @@ int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
} }
#endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP2 */
if (sm->mfp != NO_MGMT_FRAME_PROTECTION && sm->ap_rsn_ie) { if (sm->mfp != NO_MGMT_FRAME_PROTECTION && rsne) {
struct wpa_ie_data rsn; struct wpa_ie_data rsn;
if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn)
>= 0 && if (wpa_parse_wpa_ie_rsn(rsne, rsne_len, &rsn) >= 0 &&
rsn.capabilities & (WPA_CAPABILITY_MFPR | rsn.capabilities & (WPA_CAPABILITY_MFPR |
WPA_CAPABILITY_MFPC)) { WPA_CAPABILITY_MFPC)) {
ret = os_snprintf(pos, end - pos, "pmf=%d\n" ret = os_snprintf(pos, end - pos, "pmf=%d\n"
@ -4876,11 +4963,15 @@ int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
int wpa_sm_pmf_enabled(struct wpa_sm *sm) int wpa_sm_pmf_enabled(struct wpa_sm *sm)
{ {
struct wpa_ie_data rsn; struct wpa_ie_data rsn;
const u8 *rsne;
size_t rsne_len;
if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !sm->ap_rsn_ie) rsne = wpa_sm_get_ap_rsne(sm, &rsne_len);
if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !rsne)
return 0; return 0;
if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn) >= 0 && if (wpa_parse_wpa_ie_rsn(rsne, rsne_len, &rsn) >= 0 &&
rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC)) rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC))
return 1; return 1;
@ -4903,12 +4994,14 @@ int wpa_sm_ext_key_id_active(struct wpa_sm *sm)
int wpa_sm_ocv_enabled(struct wpa_sm *sm) int wpa_sm_ocv_enabled(struct wpa_sm *sm)
{ {
struct wpa_ie_data rsn; struct wpa_ie_data rsn;
const u8 *rsne;
size_t rsne_len;
if (!sm->ocv || !sm->ap_rsn_ie) rsne = wpa_sm_get_ap_rsne(sm, &rsne_len);
if (!sm->ocv || !rsne)
return 0; return 0;
return wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, return wpa_parse_wpa_ie_rsn(rsne, rsne_len, &rsn) >= 0 &&
&rsn) >= 0 &&
(rsn.capabilities & WPA_CAPABILITY_OCVC); (rsn.capabilities & WPA_CAPABILITY_OCVC);
} }
@ -5145,24 +5238,11 @@ int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
sm->ap_rsn_ie_len = 0; sm->ap_rsn_ie_len = 0;
} else { } else {
wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len); wpa_hexdump(MSG_DEBUG, "WPA: set AP RSN IE", ie, len);
if (ie[0] == WLAN_EID_VENDOR_SPECIFIC && len > 2 + 4) { sm->ap_rsn_ie = os_memdup(ie, len);
sm->ap_rsn_ie = os_malloc(len - 4); if (sm->ap_rsn_ie == NULL)
if (!sm->ap_rsn_ie) return -1;
return -1;
sm->ap_rsn_ie[0] = WLAN_EID_RSN;
sm->ap_rsn_ie[1] = len - 2 - 4;
os_memcpy(&sm->ap_rsn_ie[2], ie + 2 + 4, len - 2 - 4);
sm->ap_rsn_ie_len = len - 4;
wpa_hexdump(MSG_DEBUG,
"RSN: Converted RSNE override to RSNE",
sm->ap_rsn_ie, sm->ap_rsn_ie_len);
} else {
sm->ap_rsn_ie = os_memdup(ie, len);
if (sm->ap_rsn_ie == NULL)
return -1;
sm->ap_rsn_ie_len = len; sm->ap_rsn_ie_len = len;
}
} }
return 0; return 0;
@ -5191,24 +5271,86 @@ int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len)
sm->ap_rsnxe_len = 0; sm->ap_rsnxe_len = 0;
} else { } else {
wpa_hexdump(MSG_DEBUG, "WPA: set AP RSNXE", ie, len); wpa_hexdump(MSG_DEBUG, "WPA: set AP RSNXE", ie, len);
if (ie[0] == WLAN_EID_VENDOR_SPECIFIC && len > 2 + 4) { sm->ap_rsnxe = os_memdup(ie, len);
sm->ap_rsnxe = os_malloc(len - 4); if (!sm->ap_rsnxe)
if (!sm->ap_rsnxe) return -1;
return -1;
sm->ap_rsnxe[0] = WLAN_EID_RSNX;
sm->ap_rsnxe[1] = len - 2 - 4;
os_memcpy(&sm->ap_rsnxe[2], ie + 2 + 4, len - 2 - 4);
sm->ap_rsnxe_len = len - 4;
wpa_hexdump(MSG_DEBUG,
"RSN: Converted RSNXE override to RSNXE",
sm->ap_rsnxe, sm->ap_rsnxe_len);
} else {
sm->ap_rsnxe = os_memdup(ie, len);
if (!sm->ap_rsnxe)
return -1;
sm->ap_rsnxe_len = len; sm->ap_rsnxe_len = len;
} }
return 0;
}
int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len)
{
if (!sm)
return -1;
os_free(sm->ap_rsne_override);
if (!ie || len == 0) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Clearing AP RSNE Override element");
sm->ap_rsne_override = NULL;
sm->ap_rsne_override_len = 0;
} else {
wpa_hexdump(MSG_DEBUG, "RSN: Set AP RSNE Override element",
ie, len);
sm->ap_rsne_override = os_memdup(ie, len);
if (!sm->ap_rsne_override)
return -1;
sm->ap_rsne_override_len = len;
}
return 0;
}
int wpa_sm_set_ap_rsne_override_2(struct wpa_sm *sm, const u8 *ie, size_t len)
{
if (!sm)
return -1;
os_free(sm->ap_rsne_override_2);
if (!ie || len == 0) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Clearing AP RSNE Override 2 element");
sm->ap_rsne_override_2 = NULL;
sm->ap_rsne_override_2_len = 0;
} else {
wpa_hexdump(MSG_DEBUG, "RSN: Set AP RSNE Override 2 element",
ie, len);
sm->ap_rsne_override_2 = os_memdup(ie, len);
if (!sm->ap_rsne_override_2)
return -1;
sm->ap_rsne_override_2_len = len;
}
return 0;
}
int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len)
{
if (!sm)
return -1;
os_free(sm->ap_rsnxe_override);
if (!ie || len == 0) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Clearing AP RSNXE Override element");
sm->ap_rsnxe_override = NULL;
sm->ap_rsnxe_override_len = 0;
} else {
wpa_hexdump(MSG_DEBUG, "RSN: Set AP RSNXE Override element",
ie, len);
sm->ap_rsnxe_override = os_memdup(ie, len);
if (!sm->ap_rsnxe_override)
return -1;
sm->ap_rsnxe_override_len = len;
} }
return 0; return 0;

View file

@ -212,6 +212,9 @@ 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);
int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len);
int wpa_sm_set_ap_rsne_override_2(struct wpa_sm *sm, const u8 *ie, size_t len);
int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len);
int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen); int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen);
int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
@ -356,6 +359,24 @@ static inline int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie,
return -1; return -1;
} }
static inline int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie,
size_t len)
{
return -1;
}
static inline int wpa_sm_set_ap_rsne_override_2(struct wpa_sm *sm, const u8 *ie,
size_t len)
{
return -1;
}
static inline int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie,
size_t len)
{
return -1;
}
static inline int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen) static inline int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen)
{ {
return 0; return 0;

View file

@ -120,6 +120,9 @@ struct wpa_sm {
size_t assoc_rsnxe_len; 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;
u8 *ap_rsne_override, *ap_rsne_override_2, *ap_rsnxe_override;
size_t ap_rsne_override_len, ap_rsne_override_2_len,
ap_rsnxe_override_len;
#ifdef CONFIG_TDLS #ifdef CONFIG_TDLS
struct wpa_tdls_peer *tdls; struct wpa_tdls_peer *tdls;

View file

@ -416,6 +416,9 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0); wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
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_ap_rsne_override(wpa_s->wpa, NULL, 0);
wpa_sm_set_ap_rsne_override_2(wpa_s->wpa, NULL, 0);
wpa_sm_set_ap_rsnxe_override(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_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
wpa_s->rsnxe_len = 0; wpa_s->rsnxe_len = 0;
@ -1833,12 +1836,31 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
!!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN))); !!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
if (bss || !wpa_s->ap_ies_from_associnfo) { if (bss || !wpa_s->ap_ies_from_associnfo) {
const u8 *rsnoe = NULL, *rsno2e = NULL, *rsnxoe = NULL;
if (bss) {
bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
bss_rsnx = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
rsnoe = wpa_bss_get_vendor_ie(
bss, RSNE_OVERRIDE_IE_VENDOR_TYPE);
rsno2e = wpa_bss_get_vendor_ie(
bss, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
rsnxoe = wpa_bss_get_vendor_ie(
bss, RSNXE_OVERRIDE_IE_VENDOR_TYPE);
}
if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa, if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
bss_wpa ? 2 + bss_wpa[1] : 0) || bss_wpa ? 2 + bss_wpa[1] : 0) ||
wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn, wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
bss_rsn ? 2 + bss_rsn[1] : 0) || bss_rsn ? 2 + bss_rsn[1] : 0) ||
wpa_sm_set_ap_rsnxe(wpa_s->wpa, bss_rsnx, wpa_sm_set_ap_rsnxe(wpa_s->wpa, bss_rsnx,
bss_rsnx ? 2 + bss_rsnx[1] : 0)) bss_rsnx ? 2 + bss_rsnx[1] : 0) ||
wpa_sm_set_ap_rsne_override(wpa_s->wpa, rsnoe,
rsnoe ? 2 + rsnoe[1] : 0) ||
wpa_sm_set_ap_rsne_override_2(wpa_s->wpa, rsno2e,
rsno2e ? 2 + rsno2e[1] : 0) ||
wpa_sm_set_ap_rsnxe_override(wpa_s->wpa, rsnxoe,
rsnxoe ? 2 + rsnxoe[1] : 0))
return -1; return -1;
} }

View file

@ -425,13 +425,29 @@ static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s)
if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0)) if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
ret = -1; ret = -1;
ie = wpa_bss_get_rsne(wpa_s, curr, ssid, false); ie = wpa_bss_get_ie(curr, WLAN_EID_RSN);
if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0)) if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
ret = -1; ret = -1;
ie = wpa_bss_get_rsnxe(wpa_s, curr, ssid, false); ie = wpa_bss_get_ie(curr, WLAN_EID_RSNX);
if (wpa_sm_set_ap_rsnxe(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0)) if (wpa_sm_set_ap_rsnxe(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
ret = -1; ret = -1;
ie = wpa_bss_get_vendor_ie(curr, RSNE_OVERRIDE_IE_VENDOR_TYPE);
if (wpa_sm_set_ap_rsne_override(wpa_s->wpa, ie,
ie ? 2 + ie[1] : 0))
ret = -1;
ie = wpa_bss_get_vendor_ie(curr,
RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
if (wpa_sm_set_ap_rsne_override_2(wpa_s->wpa, ie,
ie ? 2 + ie[1] : 0))
ret = -1;
ie = wpa_bss_get_vendor_ie(curr, RSNXE_OVERRIDE_IE_VENDOR_TYPE);
if (wpa_sm_set_ap_rsnxe_override(wpa_s->wpa, ie,
ie ? 2 + ie[1] : 0))
ret = -1;
} else { } else {
ret = -1; ret = -1;
} }