[PATCH 1/5] PASN: Derive KDK only when required
Ilan Peer
ilan.peer at intel.com
Thu Apr 8 10:06:20 BST 2021
When a PTK derivation is done as part of PASN authentication
flow, a KDK derivation should be done iff higher layer protocol
is supported by both parties.
Fix the code accordingly, so KDK would be derived iff both sides
support Secure LTF.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
src/ap/ieee802_11.c | 15 +++++++++++++--
src/ap/sta_info.h | 1 +
wpa_supplicant/pasn_supplicant.c | 15 ++++++++++++++-
wpa_supplicant/wpa_supplicant_i.h | 1 +
4 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 877d03e3aa..e4dd2b4b3f 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -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,17 @@ 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");
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index efa48e7e3d..27e72f9a01 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -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;
diff --git a/wpa_supplicant/pasn_supplicant.c b/wpa_supplicant/pasn_supplicant.c
index 53ba21c5a8..c0db686dfe 100644
--- a/wpa_supplicant/pasn_supplicant.c
+++ b/wpa_supplicant/pasn_supplicant.c
@@ -1052,6 +1052,19 @@ 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 +1493,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;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 8813ddb710..49007cfc2e 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -539,6 +539,7 @@ struct wpas_pasn {
int cipher;
u16 group;
int freq;
+ size_t kdk_len;
u8 trans_seq;
u8 status;
--
2.17.1
More information about the Hostap
mailing list