Add helper functions for parsing RSNXE capabilities
Simplify the implementation by using shared functions for parsing the capabilities instead of using various similar but not exactly identical checks throughout the implementation. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
663e190b72
commit
d675d3b15b
11 changed files with 75 additions and 55 deletions
|
@ -459,8 +459,8 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
|
||||||
if (hapd->conf->sae_pwe == 2 &&
|
if (hapd->conf->sae_pwe == 2 &&
|
||||||
sta->auth_alg == WLAN_AUTH_SAE &&
|
sta->auth_alg == WLAN_AUTH_SAE &&
|
||||||
sta->sae && !sta->sae->h2e &&
|
sta->sae && !sta->sae->h2e &&
|
||||||
elems.rsnxe && elems.rsnxe_len >= 1 &&
|
ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
|
||||||
(elems.rsnxe[0] & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
|
WLAN_RSNX_CAPAB_SAE_H2E)) {
|
||||||
wpa_printf(MSG_INFO, "SAE: " MACSTR
|
wpa_printf(MSG_INFO, "SAE: " MACSTR
|
||||||
" indicates support for SAE H2E, but did not use it",
|
" indicates support for SAE H2E, but did not use it",
|
||||||
MAC2STR(sta->addr));
|
MAC2STR(sta->addr));
|
||||||
|
|
|
@ -3153,8 +3153,8 @@ static void handle_auth_pasn_1(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
|
|
||||||
if (hapd->conf->force_kdk_derivation ||
|
if (hapd->conf->force_kdk_derivation ||
|
||||||
((hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF) &&
|
((hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF) &&
|
||||||
elems.rsnxe && elems.rsnxe_len >= 2 &&
|
ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
|
||||||
(WPA_GET_LE16(elems.rsnxe) & BIT(WLAN_RSNX_CAPAB_SECURE_LTF))))
|
WLAN_RSNX_CAPAB_SECURE_LTF)))
|
||||||
sta->pasn->kdk_len = WPA_KDK_MAX_LEN;
|
sta->pasn->kdk_len = WPA_KDK_MAX_LEN;
|
||||||
else
|
else
|
||||||
sta->pasn->kdk_len = 0;
|
sta->pasn->kdk_len = 0;
|
||||||
|
@ -4693,8 +4693,8 @@ static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
if (hapd->conf->sae_pwe == 2 &&
|
if (hapd->conf->sae_pwe == 2 &&
|
||||||
sta->auth_alg == WLAN_AUTH_SAE &&
|
sta->auth_alg == WLAN_AUTH_SAE &&
|
||||||
sta->sae && !sta->sae->h2e &&
|
sta->sae && !sta->sae->h2e &&
|
||||||
elems.rsnxe && elems.rsnxe_len >= 1 &&
|
ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
|
||||||
(elems.rsnxe[0] & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
|
WLAN_RSNX_CAPAB_SAE_H2E)) {
|
||||||
wpa_printf(MSG_INFO, "SAE: " MACSTR
|
wpa_printf(MSG_INFO, "SAE: " MACSTR
|
||||||
" indicates support for SAE H2E, but did not use it",
|
" indicates support for SAE H2E, but did not use it",
|
||||||
MAC2STR(sta->addr));
|
MAC2STR(sta->addr));
|
||||||
|
|
|
@ -2283,8 +2283,7 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
|
||||||
|
|
||||||
if (sm->wpa_auth->conf.force_kdk_derivation ||
|
if (sm->wpa_auth->conf.force_kdk_derivation ||
|
||||||
(sm->wpa_auth->conf.secure_ltf &&
|
(sm->wpa_auth->conf.secure_ltf &&
|
||||||
sm->rsnxe && sm->rsnxe_len >= 4 &&
|
ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
|
||||||
sm->rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
|
|
||||||
kdk_len = WPA_KDK_MAX_LEN;
|
kdk_len = WPA_KDK_MAX_LEN;
|
||||||
else
|
else
|
||||||
kdk_len = 0;
|
kdk_len = 0;
|
||||||
|
@ -2338,8 +2337,7 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk,
|
||||||
|
|
||||||
if (sm->wpa_auth->conf.force_kdk_derivation ||
|
if (sm->wpa_auth->conf.force_kdk_derivation ||
|
||||||
(sm->wpa_auth->conf.secure_ltf &&
|
(sm->wpa_auth->conf.secure_ltf &&
|
||||||
sm->rsnxe && sm->rsnxe_len >= 4 &&
|
ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
|
||||||
sm->rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
|
|
||||||
kdk_len = WPA_KDK_MAX_LEN;
|
kdk_len = WPA_KDK_MAX_LEN;
|
||||||
else
|
else
|
||||||
kdk_len = 0;
|
kdk_len = 0;
|
||||||
|
|
|
@ -3198,8 +3198,7 @@ pmk_r1_derived:
|
||||||
|
|
||||||
if (sm->wpa_auth->conf.force_kdk_derivation ||
|
if (sm->wpa_auth->conf.force_kdk_derivation ||
|
||||||
(sm->wpa_auth->conf.secure_ltf &&
|
(sm->wpa_auth->conf.secure_ltf &&
|
||||||
sm->rsnxe && sm->rsnxe_len >= 4 &&
|
ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
|
||||||
sm->rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
|
|
||||||
kdk_len = WPA_KDK_MAX_LEN;
|
kdk_len = WPA_KDK_MAX_LEN;
|
||||||
else
|
else
|
||||||
kdk_len = 0;
|
kdk_len = 0;
|
||||||
|
|
|
@ -2403,6 +2403,35 @@ int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
|
||||||
|
unsigned int capab)
|
||||||
|
{
|
||||||
|
const u8 *end;
|
||||||
|
size_t flen, i;
|
||||||
|
u32 capabs = 0;
|
||||||
|
|
||||||
|
if (!rsnxe || rsnxe_len == 0)
|
||||||
|
return false;
|
||||||
|
end = rsnxe + rsnxe_len;
|
||||||
|
flen = (rsnxe[0] & 0x0f) + 1;
|
||||||
|
if (rsnxe + flen > end)
|
||||||
|
return false;
|
||||||
|
if (flen > 4)
|
||||||
|
flen = 4;
|
||||||
|
for (i = 0; i < flen; i++)
|
||||||
|
capabs |= rsnxe[i] << (8 * i);
|
||||||
|
|
||||||
|
return capabs & BIT(capab);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab)
|
||||||
|
{
|
||||||
|
return ieee802_11_rsnx_capab_len(rsnxe ? rsnxe + 2 : NULL,
|
||||||
|
rsnxe ? rsnxe[1] : 0, capab);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void hostapd_encode_edmg_chan(int edmg_enable, u8 edmg_channel,
|
void hostapd_encode_edmg_chan(int edmg_enable, u8 edmg_channel,
|
||||||
int primary_channel,
|
int primary_channel,
|
||||||
struct ieee80211_edmg_config *edmg)
|
struct ieee80211_edmg_config *edmg)
|
||||||
|
|
|
@ -269,6 +269,9 @@ int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
|
||||||
size_t nei_rep_len);
|
size_t nei_rep_len);
|
||||||
|
|
||||||
int ieee802_11_ext_capab(const u8 *ie, unsigned int capab);
|
int ieee802_11_ext_capab(const u8 *ie, unsigned int capab);
|
||||||
|
bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
|
||||||
|
unsigned int capab);
|
||||||
|
bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab);
|
||||||
int op_class_to_bandwidth(u8 op_class);
|
int op_class_to_bandwidth(u8 op_class);
|
||||||
int op_class_to_ch_width(u8 op_class);
|
int op_class_to_ch_width(u8 op_class);
|
||||||
|
|
||||||
|
|
|
@ -609,8 +609,8 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
|
||||||
#endif /* CONFIG_OWE */
|
#endif /* CONFIG_OWE */
|
||||||
|
|
||||||
if (sm->force_kdk_derivation ||
|
if (sm->force_kdk_derivation ||
|
||||||
(sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
|
(sm->secure_ltf &&
|
||||||
sm->ap_rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
|
ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
|
||||||
kdk_len = WPA_KDK_MAX_LEN;
|
kdk_len = WPA_KDK_MAX_LEN;
|
||||||
else
|
else
|
||||||
kdk_len = 0;
|
kdk_len = 0;
|
||||||
|
@ -4376,8 +4376,8 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sm->force_kdk_derivation ||
|
if (sm->force_kdk_derivation ||
|
||||||
(sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
|
(sm->secure_ltf &&
|
||||||
sm->ap_rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
|
ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
|
||||||
kdk_len = WPA_KDK_MAX_LEN;
|
kdk_len = WPA_KDK_MAX_LEN;
|
||||||
else
|
else
|
||||||
kdk_len = 0;
|
kdk_len = 0;
|
||||||
|
|
|
@ -69,8 +69,8 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
|
||||||
wpa_ft_pasn_store_r1kh(sm, src_addr);
|
wpa_ft_pasn_store_r1kh(sm, src_addr);
|
||||||
|
|
||||||
if (sm->force_kdk_derivation ||
|
if (sm->force_kdk_derivation ||
|
||||||
(sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
|
(sm->secure_ltf &&
|
||||||
sm->ap_rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
|
ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
|
||||||
kdk_len = WPA_KDK_MAX_LEN;
|
kdk_len = WPA_KDK_MAX_LEN;
|
||||||
else
|
else
|
||||||
kdk_len = 0;
|
kdk_len = 0;
|
||||||
|
@ -672,8 +672,8 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
|
||||||
wpa_ft_pasn_store_r1kh(sm, bssid);
|
wpa_ft_pasn_store_r1kh(sm, bssid);
|
||||||
|
|
||||||
if (sm->force_kdk_derivation ||
|
if (sm->force_kdk_derivation ||
|
||||||
(sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
|
(sm->secure_ltf &&
|
||||||
sm->ap_rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
|
ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
|
||||||
kdk_len = WPA_KDK_MAX_LEN;
|
kdk_len = WPA_KDK_MAX_LEN;
|
||||||
else
|
else
|
||||||
kdk_len = 0;
|
kdk_len = 0;
|
||||||
|
|
|
@ -3012,19 +3012,17 @@ static int wpa_supplicant_ctrl_iface_scan_result(
|
||||||
ie2, 2 + ie2[1]);
|
ie2, 2 + ie2[1]);
|
||||||
}
|
}
|
||||||
rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
|
rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
|
||||||
if (rsnxe && rsnxe[1] >= 1) {
|
if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) {
|
||||||
if (rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_H2E)) {
|
ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
|
||||||
ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
|
if (os_snprintf_error(end - pos, ret))
|
||||||
if (os_snprintf_error(end - pos, ret))
|
return -1;
|
||||||
return -1;
|
pos += ret;
|
||||||
pos += ret;
|
}
|
||||||
}
|
if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_PK)) {
|
||||||
if (rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_PK)) {
|
ret = os_snprintf(pos, end - pos, "[SAE-PK]");
|
||||||
ret = os_snprintf(pos, end - pos, "[SAE-PK]");
|
if (os_snprintf_error(end - pos, ret))
|
||||||
if (os_snprintf_error(end - pos, ret))
|
return -1;
|
||||||
return -1;
|
pos += ret;
|
||||||
pos += ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
|
osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
|
||||||
if (osen_ie)
|
if (osen_ie)
|
||||||
|
@ -5112,19 +5110,17 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
||||||
mesh ? "RSN" : "WPA2", ie2,
|
mesh ? "RSN" : "WPA2", ie2,
|
||||||
2 + ie2[1]);
|
2 + ie2[1]);
|
||||||
rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
|
rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
|
||||||
if (rsnxe && rsnxe[1] >= 1) {
|
if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) {
|
||||||
if (rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_H2E)) {
|
ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
|
||||||
ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
|
if (os_snprintf_error(end - pos, ret))
|
||||||
if (os_snprintf_error(end - pos, ret))
|
return -1;
|
||||||
return -1;
|
pos += ret;
|
||||||
pos += ret;
|
}
|
||||||
}
|
if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_PK)) {
|
||||||
if (rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_PK)) {
|
ret = os_snprintf(pos, end - pos, "[SAE-PK]");
|
||||||
ret = os_snprintf(pos, end - pos, "[SAE-PK]");
|
if (os_snprintf_error(end - pos, ret))
|
||||||
if (os_snprintf_error(end - pos, ret))
|
return -1;
|
||||||
return -1;
|
pos += ret;
|
||||||
pos += ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
|
osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
|
||||||
if (osen_ie)
|
if (osen_ie)
|
||||||
|
|
|
@ -1102,14 +1102,11 @@ static bool sae_pk_acceptable_bss_with_pk(struct wpa_supplicant *wpa_s,
|
||||||
dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
|
dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
|
||||||
int count;
|
int count;
|
||||||
const u8 *ie;
|
const u8 *ie;
|
||||||
u8 rsnxe_capa = 0;
|
|
||||||
|
|
||||||
if (bss == orig_bss)
|
if (bss == orig_bss)
|
||||||
continue;
|
continue;
|
||||||
ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
|
ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
|
||||||
if (ie && ie[1] >= 1)
|
if (!(ieee802_11_rsnx_capab(ie, WLAN_RSNX_CAPAB_SAE_PK)))
|
||||||
rsnxe_capa = ie[2];
|
|
||||||
if (!(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* TODO: Could be more thorough in checking what kind of
|
/* TODO: Could be more thorough in checking what kind of
|
||||||
|
|
|
@ -1021,8 +1021,8 @@ static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (beacon_rsnxe_len < 3 ||
|
if (!ieee802_11_rsnx_capab(beacon_rsnxe,
|
||||||
!(beacon_rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
|
WLAN_RSNX_CAPAB_SAE_H2E)) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"PASN: AP does not support SAE H2E");
|
"PASN: AP does not support SAE H2E");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1081,9 +1081,7 @@ static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
|
|
||||||
if (wpa_s->conf->force_kdk_derivation ||
|
if (wpa_s->conf->force_kdk_derivation ||
|
||||||
(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF &&
|
(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF &&
|
||||||
beacon_rsnxe && beacon_rsnxe_len >= 4 &&
|
ieee802_11_rsnx_capab(beacon_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
|
||||||
(WPA_GET_LE16(beacon_rsnxe + 2) &
|
|
||||||
BIT(WLAN_RSNX_CAPAB_SECURE_LTF))))
|
|
||||||
pasn->kdk_len = WPA_KDK_MAX_LEN;
|
pasn->kdk_len = WPA_KDK_MAX_LEN;
|
||||||
else
|
else
|
||||||
pasn->kdk_len = 0;
|
pasn->kdk_len = 0;
|
||||||
|
|
Loading…
Reference in a new issue