diff mbox series

[4/4] WPA_AUTH: Support deriving KDK based on capabilities

Message ID 20201216110140.8440-5-ilan.peer@intel.com
State Accepted
Headers show
Series Add RSNXE related changes to PASN | expand

Commit Message

Peer, Ilan Dec. 16, 2020, 11:01 a.m. UTC
Derive the KDK as part of PMK to PTK derivation if
forced by configuration or in case both the local
AP and the peer station declare support for secure LTF.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
---
 src/ap/wpa_auth.c      | 29 +++++++++++++++++++++--------
 src/ap/wpa_auth.h      |  2 +-
 src/ap/wpa_auth_ft.c   | 14 ++++++++++----
 src/ap/wpa_auth_glue.c |  2 +-
 4 files changed, 33 insertions(+), 14 deletions(-)
diff mbox series

Patch

diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 73d61b9fd6..25f6c8d9fe 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -2278,9 +2278,17 @@  static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
 			  struct wpa_ptk *ptk, int force_sha256)
 {
 	const u8 *z = NULL;
-	size_t z_len = 0;
+	size_t z_len = 0, kdk_len;
 	int akmp;
 
+	if (sm->wpa_auth->conf.force_kdk_derivation ||
+	    (sm->wpa_auth->conf.secure_ltf &&
+	     sm->rsnxe && sm->rsnxe_len >= 4 &&
+	     sm->rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
+
 #ifdef CONFIG_IEEE80211R_AP
 	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
 		if (sm->ft_completed) {
@@ -2293,8 +2301,7 @@  static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
 						 ptk, ptk_name,
 						 sm->wpa_key_mgmt,
 						 sm->pairwise,
-						 sm->wpa_auth->conf.kdk ?
-						 WPA_KDK_MAX_LEN : 0);
+						 kdk_len);
 		}
 		return wpa_auth_derive_ptk_ft(sm, ptk);
 	}
@@ -2312,8 +2319,7 @@  static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
 		akmp |= WPA_KEY_MGMT_PSK_SHA256;
 	return wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion",
 			      sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce,
-			      ptk, akmp, sm->pairwise, z, z_len,
-			      sm->wpa_auth->conf.kdk ? WPA_KDK_MAX_LEN : 0);
+			      ptk, akmp, sm->pairwise, z, z_len, kdk_len);
 }
 
 
@@ -2328,14 +2334,21 @@  int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk,
 	size_t ick_len;
 	int res;
 	u8 fils_ft[FILS_FT_MAX_LEN];
-	size_t fils_ft_len = 0;
+	size_t fils_ft_len = 0, kdk_len;
+
+	if (sm->wpa_auth->conf.force_kdk_derivation ||
+	    (sm->wpa_auth->conf.secure_ltf &&
+	     sm->rsnxe && sm->rsnxe_len >= 4 &&
+	     sm->rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
 
 	res = fils_pmk_to_ptk(pmk, pmk_len, sm->addr, sm->wpa_auth->addr,
 			      snonce, anonce, dhss, dhss_len,
 			      &sm->PTK, ick, &ick_len,
 			      sm->wpa_key_mgmt, sm->pairwise,
-			      fils_ft, &fils_ft_len,
-			      sm->wpa_auth->conf.kdk ? WPA_KDK_MAX_LEN : 0);
+			      fils_ft, &fils_ft_len, kdk_len);
 	if (res < 0)
 		return res;
 	sm->PTK_valid = true;
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index 129c65433d..ee9f721a00 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -272,7 +272,7 @@  struct wpa_auth_config {
 	 * If set Key Derivation Key should be derived as part of PMK to
 	 * PTK derivation.
 	 */
-	int kdk;
+	int force_kdk_derivation;
 };
 
 typedef enum {
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index 115a6fa2f3..6cdff65503 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -3066,7 +3066,7 @@  static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
 	const u8 *identity, *radius_cui;
 	size_t identity_len = 0, radius_cui_len = 0;
 	int use_sha384;
-	size_t pmk_r1_len;
+	size_t pmk_r1_len, kdk_len;
 
 	*resp_ies = NULL;
 	*resp_ies_len = 0;
@@ -3196,12 +3196,18 @@  pmk_r1_derived:
 	wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce",
 		    sm->ANonce, WPA_NONCE_LEN);
 
+	if (sm->wpa_auth->conf.force_kdk_derivation ||
+	    (sm->wpa_auth->conf.secure_ltf &&
+	     sm->rsnxe && sm->rsnxe_len >= 4 &&
+	     sm->rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF))
+		kdk_len = WPA_KDK_MAX_LEN;
+	else
+		kdk_len = 0;
+
 	if (wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce,
 			      sm->addr, sm->wpa_auth->addr, pmk_r1_name,
 			      &sm->PTK, ptk_name, sm->wpa_key_mgmt,
-			      pairwise,
-			      sm->wpa_auth->conf.kdk ?
-			      WPA_KDK_MAX_LEN : 0) < 0)
+			      pairwise, kdk_len) < 0)
 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
 
 	sm->pairwise = pairwise;
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index 0e9b838127..74d2322ab4 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -210,7 +210,7 @@  static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
 #endif /* CONFIG_DPP2 */
 #ifdef CONFIG_PASN
 #ifdef CONFIG_TESTING_OPTIONS
-	wconf->kdk = conf->force_kdk_derivation;
+	wconf->force_kdk_derivation = conf->force_kdk_derivation;
 #endif /* CONFIG_TESTING_OPTIONS */
 #endif /* CONFIG_PASN */
 }