[RFC v2 73/99] wpa_supplicant: Add security parameters to NAN DP request and response
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Tue Dec 23 03:52:17 PST 2025
Add CSID and password parameters to NAN_NDP_REQUEST and NAN_NDP_RESPONSE
commands.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
src/common/nan_defs.h | 2 +
wpa_supplicant/nan_supplicant.c | 113 +++++++++++++++++++++++++++++---
2 files changed, 106 insertions(+), 9 deletions(-)
diff --git a/src/common/nan_defs.h b/src/common/nan_defs.h
index 649326eae8..53130cc4a0 100644
--- a/src/common/nan_defs.h
+++ b/src/common/nan_defs.h
@@ -468,6 +468,8 @@ enum nan_cipher_suite_id {
NAN_CS_GTK_GCMP_256 = 6,
NAN_CS_PK_PASN_128 = 7,
NAN_CS_PK_PASN_256 = 8,
+ /* Keep last */
+ NAN_CS_MAX,
};
/* See Table 121 (Cipher Suite attribute field format) */
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index c4b9222a73..e781b904be 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -1265,14 +1265,70 @@ static int wpas_nan_set_ndp_schedule(struct wpa_supplicant *wpa_s,
}
+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)
+{
+ u8 service_id[NAN_SERVICE_ID_LEN];
+
+ if (ndp->sec.csid < NAN_CS_NONE || ndp->sec.csid >= NAN_CS_MAX) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Invalid CSID value: %d",
+ ndp->sec.csid);
+ return -1;
+ }
+
+ if (ndp->sec.csid == NAN_CS_NONE)
+ return 0;
+
+ /* Security parameters are not needed in confirmation */
+ if (ndp->type == NAN_NDP_ACTION_CONF)
+ return 0;
+
+ if (!(wpa_s->nan_supported_csids & BIT(ndp->sec.csid))) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Requested CSID %d not supported",
+ ndp->sec.csid);
+ return -1;
+ }
+
+ if (!pwd || os_strlen(pwd) == 0) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Password required for CSID %d",
+ ndp->sec.csid);
+ return -1;
+ }
+
+ /*
+ * Get service ID from the local handle (subscribe on
+ * requester and publish on responder)
+ */
+ if (!nan_de_is_valid_instance_id(wpa_s->nan_de,
+ handle,
+ ndp->type == NAN_NDP_ACTION_RESP,
+ service_id)) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Invalid service instance handle: %d",
+ handle);
+ return -1;
+ }
+
+ return nan_crypto_derive_nd_pmk(pwd, 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> */
+ peer_id=<peer_instance_id> ssi=<hexdata> qos=<slots:latency>
+ [csid = <cipher_suite> password=<string>] */
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;
+ char *pos, *pwd = NULL;
int handle = -1;
int ret = -1;
@@ -1360,7 +1416,10 @@ int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
pos);
goto fail;
}
-
+ } else if (os_strcmp(token, "csid") == 0) {
+ ndp.sec.csid = atoi(pos);
+ } else if (os_strcmp(token, "password") == 0) {
+ pwd = pos;
} else {
wpa_printf(MSG_DEBUG, "NAN: Unknown parameter: %s",
token);
@@ -1393,6 +1452,14 @@ int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
goto fail;
}
+ /* Derive NDP PMK if needed */
+ if (wpas_nan_fill_nd_pmk(wpa_s, &ndp, handle,
+ ndp.ndp_id.peer_nmi, pwd) < 0) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Failed to derive NDP PMK");
+ goto fail;
+ }
+
if (wpas_nan_set_ndp_schedule(wpa_s, &ndp)) {
wpa_printf(MSG_DEBUG,
"NAN: Failed to set NDP schedule");
@@ -1414,13 +1481,15 @@ fail:
/* Command format NAN_NDP_RESPONSE accept|reject peer_nmi=<nmi>
[reason_code=<reject_reason>]
[ndi=<ifname> handle=<service_handle> init_ndi=<ndi>
- ndp_id=<id> [ssi=<hexdata>] [qos=<slots:latency>]] */
+ ndp_id=<id> [ssi=<hexdata>] [qos=<slots:latency>]
+ [csid=<csid> password=<string>]] */
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;
+ char *pos, *pwd = NULL;
+ int handle = -1;
int ret = -1;
os_memset(&ndp, 0, sizeof(ndp));
@@ -1519,6 +1588,12 @@ int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd)
pos);
goto fail;
}
+ } else if (os_strcmp(token, "handle") == 0) {
+ handle = atoi(pos);
+ } else if (os_strcmp(token, "csid") == 0) {
+ ndp.sec.csid = atoi(pos);
+ } else if (os_strcmp(token, "password") == 0) {
+ pwd = pos;
} else {
wpa_printf(MSG_DEBUG, "NAN: Unknown parameter: %s",
token);
@@ -1527,11 +1602,35 @@ int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd)
/* Validate required parameters for accept case */
if (ndp.u.resp.status == NAN_NDP_STATUS_ACCEPTED) {
+ u8 *publisher_nmi;
+
if (is_zero_ether_addr(ndp.u.resp.resp_ndi)) {
wpa_printf(MSG_DEBUG,
"NAN: Missing required parameter for accept: ndi");
goto fail;
}
+
+ /* If we initiated the NDP setup, we are the subscriber */
+ if (ether_addr_equal(ndp.u.resp.resp_ndi,
+ ndp.ndp_id.init_ndi)) {
+ ndp.type = NAN_NDP_ACTION_CONF;
+ publisher_nmi = ndp.ndp_id.peer_nmi;
+ } else {
+ publisher_nmi = wpa_s->own_addr;
+ }
+
+ if (handle < 1) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Missing required parameter for accept: handle");
+ goto fail;
+ }
+
+ /* Fill the ND-PMK if needed */
+ if (wpas_nan_fill_nd_pmk(wpa_s, &ndp, handle,
+ publisher_nmi, pwd)) {
+ wpa_printf(MSG_DEBUG, "NAN: Failed to derive NDP PMK");
+ goto fail;
+ }
}
/* Validate common required parameters */
@@ -1564,10 +1663,6 @@ int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd)
goto fail;
}
- /* If we initiated the NDP setup, this must be the confirmation */
- if (ether_addr_equal(ndp.u.resp.resp_ndi, ndp.ndp_id.init_ndi))
- ndp.type = NAN_NDP_ACTION_CONF;
-
ret = nan_handle_ndp_setup(wpa_s->nan, &ndp);
if (ret < 0)
wpa_printf(MSG_DEBUG, "NAN: Failed to handle NDP response");
--
2.49.0
More information about the Hostap
mailing list