]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
PASN: Derive KDK only when required
authorIlan Peer <ilan.peer@intel.com>
Thu, 8 Apr 2021 09:06:20 +0000 (12:06 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 10 Apr 2021 08:55:55 +0000 (11:55 +0300)
When a PTK derivation is done as part of PASN authentication flow, a KDK
derivation should be done if and only if the higher layer protocol is
supported by both parties.

Fix the code accordingly, so KDK would be derived if and only if both
sides support Secure LTF.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
src/ap/ieee802_11.c
src/ap/sta_info.h
wpa_supplicant/pasn_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 877d03e3aa5ac50d41a227a8904a96e5b46cb7c7..1b0384dfc913db6bbd98116d6056f190bec3d343 100644 (file)
@@ -2646,7 +2646,7 @@ static void pasn_fils_auth_resp(struct hostapd_data *hapd,
                              wpabuf_head(pasn->secret),
                              wpabuf_len(pasn->secret),
                              &sta->pasn->ptk, sta->pasn->akmp,
-                             sta->pasn->cipher, WPA_KDK_MAX_LEN);
+                             sta->pasn->cipher, sta->pasn->kdk_len);
        if (ret) {
                wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to derive PTK");
                goto fail;
@@ -2883,7 +2883,7 @@ pasn_derive_keys(struct hostapd_data *hapd, struct sta_info *sta,
        ret = pasn_pmk_to_ptk(pmk, pmk_len, sta->addr, hapd->own_addr,
                              wpabuf_head(secret), wpabuf_len(secret),
                              &sta->pasn->ptk, sta->pasn->akmp,
-                             sta->pasn->cipher, WPA_KDK_MAX_LEN);
+                             sta->pasn->cipher, sta->pasn->kdk_len);
        if (ret) {
                wpa_printf(MSG_DEBUG, "PASN: Failed to derive PTK");
                return -1;
@@ -3151,6 +3151,15 @@ static void handle_auth_pasn_1(struct hostapd_data *hapd, struct sta_info *sta,
        sta->pasn->akmp = rsn_data.key_mgmt;
        sta->pasn->cipher = rsn_data.pairwise_cipher;
 
+       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))))
+               sta->pasn->kdk_len = WPA_KDK_MAX_LEN;
+       else
+               sta->pasn->kdk_len = 0;
+       wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", sta->pasn->kdk_len);
+
        if (!elems.pasn_params || !elems.pasn_params_len) {
                wpa_printf(MSG_DEBUG,
                           "PASN: No PASN Parameters element found");
index efa48e7e3d8de14a2b7a65f5a38b88586953781a..27e72f9a0164813c3f3be5c5ffc4bad75d8c2841 100644 (file)
@@ -88,6 +88,7 @@ struct pasn_data {
        u16 group;
        u8 trans_seq;
        u8 wrapped_data_format;
+       size_t kdk_len;
 
        u8 hash[SHA384_MAC_LEN];
        struct wpa_ptk ptk;
index 53ba21c5a852cbb815ef06219eb54260634a7327..d483175b78bb645503987e4f5917fa559662bc3a 100644 (file)
@@ -1052,6 +1052,17 @@ static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
        pasn->cipher = cipher;
        pasn->group = group;
        pasn->freq = freq;
+
+       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))))
+               pasn->kdk_len = WPA_KDK_MAX_LEN;
+       else
+               pasn->kdk_len = 0;
+       wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", pasn->kdk_len);
+
        os_memcpy(pasn->bssid, bssid, ETH_ALEN);
 
        wpa_printf(MSG_DEBUG,
@@ -1480,7 +1491,7 @@ int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
                              wpa_s->own_addr, pasn->bssid,
                              wpabuf_head(secret), wpabuf_len(secret),
                              &pasn->ptk, pasn->akmp, pasn->cipher,
-                             WPA_KDK_MAX_LEN);
+                             pasn->kdk_len);
        if (ret) {
                wpa_printf(MSG_DEBUG, "PASN: Failed to derive PTK");
                goto fail;
index 8813ddb710052e8c7435767d2c7ea2bed6c76ebc..49007cfc2e8fe5a02c7ad27baf83066669ae24b7 100644 (file)
@@ -539,6 +539,7 @@ struct wpas_pasn {
        int cipher;
        u16 group;
        int freq;
+       size_t kdk_len;
 
        u8 trans_seq;
        u8 status;