[PATCH v2 10/28] EPPKE: Add EPPKE support to PASN PTK derivation per IEEE P802.11bi/D2.0

Ainy Kumari ainy.kumari at oss.qualcomm.com
Tue Jan 6 05:45:20 PST 2026


Extend PASN PTK derivation to support EPPKE authentication as specified
in IEEE P802.11bi/D2.0, section 12.16.9.3.4. Update the PTK derivation
label and debug logging to distinguish between PASN and EPPKE
authentication. Update all relevant function calls to pass the
new is_eppke parameter.

Signed-off-by: Ainy Kumari <ainy.kumari at oss.qualcomm.com>
---
 src/ap/ieee802_11.c              |  3 ++-
 src/common/common_module_tests.c |  2 +-
 src/common/wpa_common.c          | 12 +++++++++---
 src/common/wpa_common.h          |  3 ++-
 src/pasn/pasn_common.h           |  1 +
 src/pasn/pasn_initiator.c        |  3 ++-
 src/pasn/pasn_responder.c        |  3 ++-
 7 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 611017da1..c1ff3fa8a 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2815,7 +2815,8 @@ static void pasn_fils_auth_resp(struct hostapd_data *hapd,
 			      wpabuf_len(pasn->secret),
 			      pasn_get_ptk(sta->pasn), pasn_get_akmp(sta->pasn),
 			      pasn_get_cipher(sta->pasn), sta->pasn->kdk_len,
-			      sta->pasn->kek_len, &sta->pasn->hash_alg);
+			      sta->pasn->kek_len, &sta->pasn->hash_alg,
+			      pasn->auth_alg == WLAN_AUTH_EPPKE);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to derive PTK");
 		goto fail;
diff --git a/src/common/common_module_tests.c b/src/common/common_module_tests.c
index 6b528eabd..bb6b9cf97 100644
--- a/src/common/common_module_tests.c
+++ b/src/common/common_module_tests.c
@@ -655,7 +655,7 @@ static int pasn_test_pasn_auth(void)
 			      spa_addr, bssid,
 			      dhss, sizeof(dhss),
 			      &ptk, WPA_KEY_MGMT_PASN, WPA_CIPHER_CCMP,
-			      WPA_KDK_MAX_LEN, 0, &hash_alg);
+			      WPA_KDK_MAX_LEN, 0, &hash_alg, false);
 
 	if (ret)
 		return ret;
diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
index 9bf675984..092365f24 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -1568,7 +1568,7 @@ static enum rsn_hash_alg pasn_select_hash_alg(int akmp, int cipher,
 
 
 /**
- * pasn_pmk_to_ptk - Calculate PASN PTK from PMK, addresses, etc.
+ * pasn_pmk_to_ptk - Calculate PASN/EPPKE PTK from PMK, addresses, etc.
  * @pmk: Pairwise master key
  * @pmk_len: Length of PMK
  * @spa: Suppplicant address
@@ -1582,13 +1582,15 @@ static enum rsn_hash_alg pasn_select_hash_alg(int akmp, int cipher,
  * @kdk_len: the length in octets that should be derived for HTLK. Can be zero.
  * @kek_len: The length in octets that should be derived for KEK. Can be zero.
  * @alg: Output variable for indicating the selected hash algorithm
+ * @is_eppke: EPPKE authentication
  * Returns: 0 on success, -1 on failure
  */
 int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len,
 		    const u8 *spa, const u8 *bssid,
 		    const u8 *dhss, size_t dhss_len,
 		    struct wpa_ptk *ptk, int akmp, int cipher,
-		    size_t kdk_len, size_t kek_len, enum rsn_hash_alg *alg)
+		    size_t kdk_len, size_t kek_len, enum rsn_hash_alg *alg,
+		    bool is_eppke)
 {
 	u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
 	       WPA_KDK_MAX_LEN];
@@ -1596,7 +1598,8 @@ int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len,
 	u8 *data;
 	size_t data_len, ptk_len;
 	int ret = -1;
-	const char *label = "PASN PTK Derivation";
+	const char *label = is_eppke ? "EPPKE PTK Derivation" :
+			    "PASN PTK Derivation";
 
 	if (!pmk || !pmk_len) {
 		wpa_printf(MSG_ERROR, "PASN: No PMK set for PTK derivation");
@@ -1609,6 +1612,9 @@ int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len,
 	}
 
 	/*
+	 * Use "EPPKE PTK Derivation" instead of “PASN PTK Derivation” for
+	 * EPPKE Authentication per IEEE P802.11bi/D2.0, section 12.16.9.3.4.
+	 *
 	 * PASN-PTK = KDF(PMK, “PASN PTK Derivation”, SPA || BSSID || DHss)
 	 *
 	 * KCK = L(PASN-PTK, 0, 256)
diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
index 8a3f23872..c90b44fab 100644
--- a/src/common/wpa_common.h
+++ b/src/common/wpa_common.h
@@ -780,7 +780,8 @@ int pasn_pmk_to_ptk(const u8 *pmk, size_t pmk_len,
 		    const u8 *spa, const u8 *bssid,
 		    const u8 *dhss, size_t dhss_len,
 		    struct wpa_ptk *ptk, int akmp, int cipher,
-		    size_t kdk_len, size_t kek_len, enum rsn_hash_alg *alg);
+		    size_t kdk_len, size_t kek_len, enum rsn_hash_alg *alg,
+		    bool is_eppke);
 
 size_t pasn_mic_len(enum rsn_hash_alg alg);
 
diff --git a/src/pasn/pasn_common.h b/src/pasn/pasn_common.h
index 58e11e44b..e71393496 100644
--- a/src/pasn/pasn_common.h
+++ b/src/pasn/pasn_common.h
@@ -49,6 +49,7 @@ struct pasn_data {
 	bool derive_kdk;
 	size_t kdk_len;
 	void *cb_ctx;
+	unsigned int auth_alg;
 
 #ifdef CONFIG_SAE
 	struct sae_pt *pt;
diff --git a/src/pasn/pasn_initiator.c b/src/pasn/pasn_initiator.c
index 74dde993b..a5091b562 100644
--- a/src/pasn/pasn_initiator.c
+++ b/src/pasn/pasn_initiator.c
@@ -1316,7 +1316,8 @@ int wpa_pasn_auth_rx(struct pasn_data *pasn, const u8 *data, size_t len,
 			      pasn->own_addr, pasn->peer_addr,
 			      wpabuf_head(secret), wpabuf_len(secret),
 			      &pasn->ptk, pasn->akmp, pasn->cipher,
-			      pasn->kdk_len, pasn->kek_len, &pasn->hash_alg);
+			      pasn->kdk_len, pasn->kek_len, &pasn->hash_alg,
+			      pasn->auth_alg == WLAN_AUTH_EPPKE);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "PASN: Failed to derive PTK");
 		goto fail;
diff --git a/src/pasn/pasn_responder.c b/src/pasn/pasn_responder.c
index 568442e28..21cf33cb3 100644
--- a/src/pasn/pasn_responder.c
+++ b/src/pasn/pasn_responder.c
@@ -414,7 +414,8 @@ pasn_derive_keys(struct pasn_data *pasn,
 			      wpabuf_head(secret), wpabuf_len(secret),
 			      &pasn->ptk, pasn->akmp,
 			      pasn->cipher, pasn->kdk_len, pasn->kek_len,
-			      &pasn->hash_alg);
+			      &pasn->hash_alg,
+			      pasn->auth_alg == WLAN_AUTH_EPPKE);
 	if (ret) {
 		wpa_printf(MSG_DEBUG, "PASN: Failed to derive PTK");
 		return -1;
-- 
2.25.1




More information about the Hostap mailing list