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>
master
Jouni Malinen 3 years ago
parent 663e190b72
commit d675d3b15b

@ -459,8 +459,8 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
if (hapd->conf->sae_pwe == 2 &&
sta->auth_alg == WLAN_AUTH_SAE &&
sta->sae && !sta->sae->h2e &&
elems.rsnxe && elems.rsnxe_len >= 1 &&
(elems.rsnxe[0] & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
WLAN_RSNX_CAPAB_SAE_H2E)) {
wpa_printf(MSG_INFO, "SAE: " MACSTR
" indicates support for SAE H2E, but did not use it",
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 ||
((hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF) &&
elems.rsnxe && elems.rsnxe_len >= 2 &&
(WPA_GET_LE16(elems.rsnxe) & BIT(WLAN_RSNX_CAPAB_SECURE_LTF))))
ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
WLAN_RSNX_CAPAB_SECURE_LTF)))
sta->pasn->kdk_len = WPA_KDK_MAX_LEN;
else
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 &&
sta->auth_alg == WLAN_AUTH_SAE &&
sta->sae && !sta->sae->h2e &&
elems.rsnxe && elems.rsnxe_len >= 1 &&
(elems.rsnxe[0] & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
WLAN_RSNX_CAPAB_SAE_H2E)) {
wpa_printf(MSG_INFO, "SAE: " MACSTR
" indicates support for SAE H2E, but did not use it",
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 ||
(sm->wpa_auth->conf.secure_ltf &&
sm->rsnxe && sm->rsnxe_len >= 4 &&
sm->rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
kdk_len = WPA_KDK_MAX_LEN;
else
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 ||
(sm->wpa_auth->conf.secure_ltf &&
sm->rsnxe && sm->rsnxe_len >= 4 &&
sm->rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
kdk_len = WPA_KDK_MAX_LEN;
else
kdk_len = 0;

@ -3198,8 +3198,7 @@ pmk_r1_derived:
if (sm->wpa_auth->conf.force_kdk_derivation ||
(sm->wpa_auth->conf.secure_ltf &&
sm->rsnxe && sm->rsnxe_len >= 4 &&
sm->rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
kdk_len = WPA_KDK_MAX_LEN;
else
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,
int primary_channel,
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);
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_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 */
if (sm->force_kdk_derivation ||
(sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
sm->ap_rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
(sm->secure_ltf &&
ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
kdk_len = WPA_KDK_MAX_LEN;
else
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 ||
(sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
sm->ap_rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
(sm->secure_ltf &&
ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
kdk_len = WPA_KDK_MAX_LEN;
else
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);
if (sm->force_kdk_derivation ||
(sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
sm->ap_rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
(sm->secure_ltf &&
ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
kdk_len = WPA_KDK_MAX_LEN;
else
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);
if (sm->force_kdk_derivation ||
(sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
sm->ap_rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
(sm->secure_ltf &&
ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
kdk_len = WPA_KDK_MAX_LEN;
else
kdk_len = 0;

@ -3012,19 +3012,17 @@ static int wpa_supplicant_ctrl_iface_scan_result(
ie2, 2 + ie2[1]);
}
rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
if (rsnxe && rsnxe[1] >= 1) {
if (rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_H2E)) {
ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
if (os_snprintf_error(end - pos, ret))
return -1;
pos += ret;
}
if (rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_PK)) {
ret = os_snprintf(pos, end - pos, "[SAE-PK]");
if (os_snprintf_error(end - pos, ret))
return -1;
pos += ret;
}
if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) {
ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
if (os_snprintf_error(end - pos, ret))
return -1;
pos += ret;
}
if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_PK)) {
ret = os_snprintf(pos, end - pos, "[SAE-PK]");
if (os_snprintf_error(end - pos, ret))
return -1;
pos += ret;
}
osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
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,
2 + ie2[1]);
rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
if (rsnxe && rsnxe[1] >= 1) {
if (rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_H2E)) {
ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
if (os_snprintf_error(end - pos, ret))
return -1;
pos += ret;
}
if (rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_PK)) {
ret = os_snprintf(pos, end - pos, "[SAE-PK]");
if (os_snprintf_error(end - pos, ret))
return -1;
pos += ret;
}
if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) {
ret = os_snprintf(pos, end - pos, "[SAE-H2E]");
if (os_snprintf_error(end - pos, ret))
return -1;
pos += ret;
}
if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_PK)) {
ret = os_snprintf(pos, end - pos, "[SAE-PK]");
if (os_snprintf_error(end - pos, ret))
return -1;
pos += ret;
}
osen_ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
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) {
int count;
const u8 *ie;
u8 rsnxe_capa = 0;
if (bss == orig_bss)
continue;
ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
if (ie && ie[1] >= 1)
rsnxe_capa = ie[2];
if (!(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)))
if (!(ieee802_11_rsnx_capab(ie, WLAN_RSNX_CAPAB_SAE_PK)))
continue;
/* 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;
}
if (beacon_rsnxe_len < 3 ||
!(beacon_rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
if (!ieee802_11_rsnx_capab(beacon_rsnxe,
WLAN_RSNX_CAPAB_SAE_H2E)) {
wpa_printf(MSG_DEBUG,
"PASN: AP does not support SAE H2E");
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 ||
(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF &&
beacon_rsnxe && beacon_rsnxe_len >= 4 &&
(WPA_GET_LE16(beacon_rsnxe + 2) &
BIT(WLAN_RSNX_CAPAB_SECURE_LTF))))
ieee802_11_rsnx_capab(beacon_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
pasn->kdk_len = WPA_KDK_MAX_LEN;
else
pasn->kdk_len = 0;

Loading…
Cancel
Save