RSN: Verify RSNXE match between Beacon/ProbeResp and EAPOL-Key msg 3/4
If the AP advertises RSN Extension element, it has to be advertised consistently in the unprotected (Beacon and Probe Response) and protected (EAPOL-Key msg 3/4) frames. Verify that this is the case. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
3134bb13a8
commit
146889e3ca
9 changed files with 85 additions and 9 deletions
|
@ -1365,6 +1365,16 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((sm->ap_rsnxe && !ie->rsnxe) ||
|
||||
(!sm->ap_rsnxe && ie->rsnxe) ||
|
||||
(sm->ap_rsnxe && ie->rsnxe &&
|
||||
(sm->ap_rsnxe_len != ie->rsnxe_len ||
|
||||
os_memcmp(sm->ap_rsnxe, ie->rsnxe, sm->ap_rsnxe_len) != 0))) {
|
||||
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
|
||||
"WPA: RSNXE mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
if (wpa_key_mgmt_ft(sm->key_mgmt) &&
|
||||
wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0)
|
||||
|
@ -2664,6 +2674,7 @@ void wpa_sm_deinit(struct wpa_sm *sm)
|
|||
os_free(sm->assoc_wpa_ie);
|
||||
os_free(sm->ap_wpa_ie);
|
||||
os_free(sm->ap_rsn_ie);
|
||||
os_free(sm->ap_rsnxe);
|
||||
wpa_sm_drop_sa(sm);
|
||||
os_free(sm->ctx);
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
|
@ -3283,6 +3294,39 @@ int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpa_sm_set_ap_rsnxe - Set AP RSNXE from Beacon/ProbeResp
|
||||
* @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 Beacon / Probe Response
|
||||
* frame.
|
||||
*/
|
||||
int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len)
|
||||
{
|
||||
if (!sm)
|
||||
return -1;
|
||||
|
||||
os_free(sm->ap_rsnxe);
|
||||
if (!ie || len == 0) {
|
||||
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: clearing AP RSNXE");
|
||||
sm->ap_rsnxe = NULL;
|
||||
sm->ap_rsnxe_len = 0;
|
||||
} else {
|
||||
wpa_hexdump(MSG_DEBUG, "WPA: set AP RSNXE", ie, len);
|
||||
sm->ap_rsnxe = os_memdup(ie, len);
|
||||
if (!sm->ap_rsnxe)
|
||||
return -1;
|
||||
|
||||
sm->ap_rsnxe_len = len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpa_sm_parse_own_wpa_ie - Parse own WPA/RSN IE
|
||||
* @sm: Pointer to WPA state machine data from wpa_sm_init()
|
||||
|
|
|
@ -136,6 +136,7 @@ int wpa_sm_set_assoc_wpa_ie_default(struct wpa_sm *sm, u8 *wpa_ie,
|
|||
size_t *wpa_ie_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_rsnxe(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_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
|
||||
|
@ -260,6 +261,12 @@ static inline int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static inline int wpa_sm_set_ap_rsnxe(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)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -88,8 +88,8 @@ struct wpa_sm {
|
|||
|
||||
u8 *assoc_wpa_ie; /* Own WPA/RSN IE from (Re)AssocReq */
|
||||
size_t assoc_wpa_ie_len;
|
||||
u8 *ap_wpa_ie, *ap_rsn_ie;
|
||||
size_t ap_wpa_ie_len, ap_rsn_ie_len;
|
||||
u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe;
|
||||
size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len;
|
||||
|
||||
#ifdef CONFIG_TDLS
|
||||
struct wpa_tdls_peer *tdls;
|
||||
|
|
|
@ -506,6 +506,11 @@ int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
|
|||
ie->rsn_ie_len = pos[1] + 2;
|
||||
wpa_hexdump(MSG_DEBUG, "WPA: RSN IE in EAPOL-Key",
|
||||
ie->rsn_ie, ie->rsn_ie_len);
|
||||
} else if (*pos == WLAN_EID_RSNX) {
|
||||
ie->rsnxe = pos;
|
||||
ie->rsnxe_len = pos[1] + 2;
|
||||
wpa_hexdump(MSG_DEBUG, "WPA: RSNXE in EAPOL-Key",
|
||||
ie->rsnxe, ie->rsnxe_len);
|
||||
} else if (*pos == WLAN_EID_MOBILITY_DOMAIN &&
|
||||
pos[1] >= sizeof(struct rsn_mdie)) {
|
||||
ie->mdie = pos;
|
||||
|
|
|
@ -23,6 +23,8 @@ struct wpa_eapol_ie_parse {
|
|||
size_t mac_addr_len;
|
||||
const u8 *igtk;
|
||||
size_t igtk_len;
|
||||
const u8 *rsnxe;
|
||||
size_t rsnxe_len;
|
||||
const u8 *mdie;
|
||||
size_t mdie_len;
|
||||
const u8 *ftie;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue