[PATCH 3/4] WPA: Support deriving KDK based on capabilities

Ilan Peer ilan.peer at intel.com
Wed Dec 16 06:01:39 EST 2020


Derive the KDK as part of PMK to PTK derivation if
forced by configuration or in case both the local
station and the AP declare support for secure LTF.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 src/rsn_supp/wpa.c         | 27 +++++++++++++++++++++------
 src/rsn_supp/wpa.h         |  2 +-
 src/rsn_supp/wpa_ft.c      | 22 ++++++++++++++++++----
 src/rsn_supp/wpa_i.h       |  2 +-
 wpa_supplicant/wpas_glue.c |  2 +-
 5 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index ed9aaae1a3..95f9e63765 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -579,7 +579,7 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
 			  const struct wpa_eapol_key *key, struct wpa_ptk *ptk)
 {
 	const u8 *z = NULL;
-	size_t z_len = 0;
+	size_t z_len = 0, kdk_len;
 	int akmp;
 
 #ifdef CONFIG_IEEE80211R
@@ -603,11 +603,19 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
 		akmp |= WPA_KEY_MGMT_PSK_SHA256;
 	}
 #endif /* CONFIG_OWE */
+
+	if (sm->force_kdk_derivation ||
+	    (sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
+	     sm->ap_rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
+
 	return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
 			      sm->own_addr, sm->bssid, sm->snonce,
 			      key->key_nonce, ptk, akmp,
 			      sm->pairwise_cipher, z, z_len,
-			      sm->kdk ? WPA_KDK_MAX_LEN : 0);
+			      kdk_len);
 }
 
 
@@ -3188,7 +3196,7 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
 		sm->p2p = config->p2p;
 		sm->wpa_rsc_relaxation = config->wpa_rsc_relaxation;
 		sm->owe_ptk_workaround = config->owe_ptk_workaround;
-		sm->kdk = config->kdk;
+		sm->force_kdk_derivation = config->force_kdk_derivation;
 #ifdef CONFIG_FILS
 		if (config->fils_cache_id) {
 			sm->fils_cache_id_set = 1;
@@ -3211,7 +3219,7 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
 		sm->wpa_rsc_relaxation = 0;
 		sm->owe_ptk_workaround = 0;
 		sm->beacon_prot = 0;
-		sm->kdk = 0;
+		sm->force_kdk_derivation = 0;
 	}
 }
 
@@ -4134,7 +4142,7 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
 	const u8 *g_sta = NULL;
 	size_t g_sta_len = 0;
 	const u8 *g_ap = NULL;
-	size_t g_ap_len = 0;
+	size_t g_ap_len = 0, kdk_len;
 	struct wpabuf *pub = NULL;
 
 	os_memcpy(sm->bssid, bssid, ETH_ALEN);
@@ -4362,6 +4370,13 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
 		goto fail;
 	}
 
+	if (sm->force_kdk_derivation ||
+	    (sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
+	     sm->ap_rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
+
 	if (fils_pmk_to_ptk(sm->pmk, sm->pmk_len, sm->own_addr, sm->bssid,
 			    sm->fils_nonce, sm->fils_anonce,
 			    dh_ss ? wpabuf_head(dh_ss) : NULL,
@@ -4369,7 +4384,7 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
 			    &sm->ptk, ick, &ick_len,
 			    sm->key_mgmt, sm->pairwise_cipher,
 			    sm->fils_ft, &sm->fils_ft_len,
-			    sm->kdk ? WPA_KDK_MAX_LEN : 0) < 0) {
+			    kdk_len) < 0) {
 		wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK");
 		goto fail;
 	}
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 2b181653eb..005d9f428e 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -132,7 +132,7 @@ struct rsn_supp_config {
 	int owe_ptk_workaround;
 	const u8 *fils_cache_id;
 	int beacon_prot;
-	int kdk;
+	int force_kdk_derivation;
 };
 
 #ifndef CONFIG_NO_WPA
diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c
index cbf3caeb01..d113fd9a20 100644
--- a/src/rsn_supp/wpa_ft.c
+++ b/src/rsn_supp/wpa_ft.c
@@ -35,7 +35,7 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
 	const u8 *anonce = key->key_nonce;
 	int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
 	const u8 *mpmk;
-	size_t mpmk_len;
+	size_t mpmk_len, kdk_len;
 
 	if (sm->xxkey_len > 0) {
 		mpmk = sm->xxkey;
@@ -65,10 +65,17 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
 	wpa_ft_pasn_store_r1kh(sm, src_addr);
 #endif /* CONFIG_PASN*/
 
+	if (sm->force_kdk_derivation ||
+	    (sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
+	     sm->ap_rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
+
 	return wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce, anonce,
 				 sm->own_addr, sm->bssid, sm->pmk_r1_name, ptk,
 				 ptk_name, sm->key_mgmt, sm->pairwise_cipher,
-				 sm->kdk ? WPA_KDK_MAX_LEN : 0);
+				 kdk_len);
 }
 
 
@@ -536,7 +543,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
 	int ret;
 	const u8 *bssid;
 	const u8 *kck;
-	size_t kck_len;
+	size_t kck_len, kdk_len;
 	int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
 	const u8 *anonce, *snonce;
 
@@ -663,11 +670,18 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
 	wpa_ft_pasn_store_r1kh(sm, bssid);
 #endif /* CONFIG_PASN*/
 
+	if (sm->force_kdk_derivation ||
+	    (sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
+	     sm->ap_rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
+
 	if (wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce,
 			      anonce, sm->own_addr, bssid,
 			      sm->pmk_r1_name, &sm->ptk, ptk_name, sm->key_mgmt,
 			      sm->pairwise_cipher,
-			      sm->kdk ? WPA_KDK_MAX_LEN : 0) < 0)
+			      kdk_len) < 0)
 		return -1;
 
 	if (wpa_key_mgmt_fils(sm->key_mgmt)) {
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index 5f68282617..7ea1cd2dba 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -82,7 +82,7 @@ struct wpa_sm {
 	 * If set Key Derivation Key should be derived as part of PMK to
 	 * PTK derivation.
 	 */
-	int kdk;
+	int force_kdk_derivation;
 
 	u8 own_addr[ETH_ALEN];
 	const char *ifname;
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 80f04551d2..befd6d52d4 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -1476,7 +1476,7 @@ void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
 	}
 #ifdef CONFIG_PASN
 #ifdef CONFIG_TESTING_OPTIONS
-	conf.kdk = wpa_s->conf->force_kdk_derivation;
+	conf.force_kdk_derivation = wpa_s->conf->force_kdk_derivation;
 #endif /* CONFIG_TESTING_OPTIONS */
 #endif /* CONFIG_PASN*/
 	wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL);
-- 
2.17.1




More information about the Hostap mailing list