[RFC v2 82/99] wpa_supplicant: Support NDP setup with PMK

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue Dec 23 03:52:26 PST 2025


Add control interface API to configure PMK directly and skip derivation
from password.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 wpa_supplicant/nan_supplicant.c | 60 ++++++++++++++++++++++++++-------
 1 file changed, 48 insertions(+), 12 deletions(-)

diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index ccb477e5da..8571d83f58 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -1270,7 +1270,8 @@ static int wpas_nan_fill_nd_pmk(struct wpa_supplicant *wpa_s,
 				struct nan_ndp_params *ndp,
 				int handle,
 				const u8 *publisher_nmi,
-				const char *pwd)
+				const char *pwd_pmk,
+				bool pmk)
 {
 	u8 service_id[NAN_SERVICE_ID_LEN];
 
@@ -1295,9 +1296,9 @@ static int wpas_nan_fill_nd_pmk(struct wpa_supplicant *wpa_s,
 			return -1;
 	}
 
-	if (!pwd || os_strlen(pwd) == 0) {
+	if (!pwd_pmk || os_strlen(pwd_pmk) == 0) {
 		wpa_printf(MSG_DEBUG,
-			   "NAN: Password required for CSID %d",
+			   "NAN: Password/PMK required for CSID %d",
 			   ndp->sec.csid);
 		return -1;
 	}
@@ -1316,20 +1317,39 @@ static int wpas_nan_fill_nd_pmk(struct wpa_supplicant *wpa_s,
 		return -1;
 	}
 
-	return nan_crypto_derive_nd_pmk(pwd, service_id, ndp->sec.csid,
+	if (pmk) {
+		if (os_strlen(pwd_pmk) != PMK_LEN * 2) {
+			wpa_printf(MSG_DEBUG,
+				   "NAN: Invalid PMK length: %zu",
+				   os_strlen(pwd_pmk));
+			return -1;
+		}
+
+		if (hexstr2bin(pwd_pmk, ndp->sec.pmk, PMK_LEN) < 0) {
+			wpa_printf(MSG_DEBUG,
+				   "NAN: Invalid PMK hex data: %s",
+				   pwd_pmk);
+			return -1;
+		}
+
+		return 0;
+	}
+
+	/* Derive PMK from password */
+	return nan_crypto_derive_nd_pmk(pwd_pmk, service_id, ndp->sec.csid,
 					publisher_nmi, ndp->sec.pmk);
 }
 
 
 /* Command format NAN_NDP_REQUEST handle=<id> ndi=<ifname> peer_nmi=<nmi>
    peer_id=<peer_instance_id> ssi=<hexdata> qos=<slots:latency>
-   [csid = <cipher_suite> password=<string>] */
+   [csid = <cipher_suite> <password=<string>|pmk=<hex>>] */
 int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
 {
 	struct nan_ndp_params ndp;
 	struct wpabuf *ssi_buf = NULL;
 	char *token, *context = NULL;
-	char *pos, *pwd = NULL;
+	char *pos, *pwd = NULL, *pmk = NULL;
 	int handle = -1;
 	int ret = -1;
 
@@ -1421,6 +1441,8 @@ int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
 			ndp.sec.csid = atoi(pos);
 		} else if (os_strcmp(token, "password") == 0) {
 			pwd = pos;
+		} else if (os_strcmp(token, "pmk") == 0) {
+			pmk = pos;
 		} else {
 			wpa_printf(MSG_DEBUG, "NAN: Unknown parameter: %s",
 				   token);
@@ -1453,9 +1475,15 @@ int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
 		goto fail;
 	}
 
-	/* Derive NDP PMK if needed */
+	if (pmk && pwd) {
+		wpa_printf(MSG_DEBUG,
+			   "NAN: Specify only one of password or pmk");
+		goto fail;
+	}
+
 	if (wpas_nan_fill_nd_pmk(wpa_s, &ndp, handle,
-				 ndp.ndp_id.peer_nmi, pwd) < 0) {
+				 ndp.ndp_id.peer_nmi, pmk ? pmk : pwd,
+				 !!pmk) < 0) {
 		wpa_printf(MSG_DEBUG,
 			   "NAN: Failed to derive NDP PMK");
 		goto fail;
@@ -1483,13 +1511,13 @@ fail:
    [reason_code=<reject_reason>]
    [ndi=<ifname> handle=<service_handle> init_ndi=<ndi>
    ndp_id=<id> [ssi=<hexdata>] [qos=<slots:latency>]
-   [csid=<csid> password=<string>]] */
+   [csid=<csid> <password=<string>|pmk=<hex>]] */
 int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd)
 {
 	struct nan_ndp_params ndp;
 	struct wpabuf *ssi_buf = NULL;
 	char *token, *context = NULL;
-	char *pos, *pwd = NULL;
+	char *pos, *pwd = NULL, *pmk = NULL;
 	int handle = -1;
 	int ret = -1;
 
@@ -1595,6 +1623,8 @@ int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd)
 			ndp.sec.csid = atoi(pos);
 		} else if (os_strcmp(token, "password") == 0) {
 			pwd = pos;
+		} else if (os_strcmp(token, "pmk") == 0) {
+			pmk = pos;
 		} else {
 			wpa_printf(MSG_DEBUG, "NAN: Unknown parameter: %s",
 				   token);
@@ -1626,9 +1656,15 @@ int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd)
 			goto fail;
 		}
 
-		/* Fill the ND-PMK if needed */
+		if (pmk && pwd) {
+			wpa_printf(MSG_DEBUG,
+				   "NAN: Specify only one of password or pmk");
+			goto fail;
+		}
+
 		if (wpas_nan_fill_nd_pmk(wpa_s, &ndp, handle,
-					 publisher_nmi, pwd)) {
+					 publisher_nmi, pmk ? pmk : pwd,
+					 !!pmk) < 0) {
 			wpa_printf(MSG_DEBUG, "NAN: Failed to derive NDP PMK");
 			goto fail;
 		}
-- 
2.49.0




More information about the Hostap mailing list