]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add helper functions for parsing RSNXE capabilities
authorJouni Malinen <j@w1.fi>
Sat, 10 Apr 2021 09:43:38 +0000 (12:43 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 10 Apr 2021 09:43:38 +0000 (12:43 +0300)
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>
src/ap/drv_callbacks.c
src/ap/ieee802_11.c
src/ap/wpa_auth.c
src/ap/wpa_auth_ft.c
src/common/ieee802_11_common.c
src/common/ieee802_11_common.h
src/rsn_supp/wpa.c
src/rsn_supp/wpa_ft.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/events.c
wpa_supplicant/pasn_supplicant.c

index 290d354a016c9183cc3a55be0c53d3504b8ad7f8..ec5abf166b234875694ac1eda6a9b7d14a1ea21c 100644 (file)
@@ -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));
index 7b96ba07d10831c86d0c78a337f72e12cd042ea2..b404e84affe51e8809a217222c01619cbbe1dd68 100644 (file)
@@ -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));
index ef0595c572b0c418bd75e1237a0b1802eb9b4d82..59cd46aa4601b8274af5ec0d2b70176c3bd33d15 100644 (file)
@@ -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;
index 32b745651ace85d86f0ebda77824cd1abfd472f0..e80086b93d8d9002a864faea0fc5f011a6854a39 100644 (file)
@@ -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;
index 5b80db6d3b83c2adc5affd5e201e9cb46df0157f..96681843e2582d2aec1122708d526d831291a1d2 100644 (file)
@@ -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)
index 8a16f1666221346b0a214da4860fd079021144b2..fe2b1bca601b8c3ab0e5ca44a87d53b311a49da0 100644 (file)
@@ -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);
 
index 672d66428cfc6deafc04aeff211867112e5833b3..78e2380b15e8d6a1b039301ccb199cdd7eb394ec 100644 (file)
@@ -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;
index fce6e77e7fb915134539dcf9918812a53fcba096..2669da9b3fa8904320c0765d74cfa43642d204cf 100644 (file)
@@ -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;
index 062c64ee4c8d5e608c0f0e7fa47f23aeb45009aa..bf83e41686a0b03ef6c7e0551971c6ecfc653bd2 100644 (file)
@@ -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)
index 717a5eefbfd75b69b01cfff8604be63ae231f24f..b3c07f926b69080e7129fc5452f22bdda8ca2aa7 100644 (file)
@@ -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
index edb5508002a1ae79b3b66207a0e1c2883acbdec4..baf4c2643e4263d3f07acde99b2ab2733b479b63 100644 (file)
@@ -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;