[PATCH 35/97] wpa_supplicant: Add an option to set the GTK cipher suite for NDP setup

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue Apr 28 13:05:36 PDT 2026


From: Avraham Stern <avraham.stern at intel.com>

Add an option to set the required GTK cipher suite in NDP request
command. If a GTK is still not configured for the NDI for which the
NDP setup is requested, a new GTK will be randomized.

Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
 wpa_supplicant/nan_supplicant.c   | 71 +++++++++++++++++++++++++++++--
 wpa_supplicant/wpa_supplicant_i.h |  2 +
 2 files changed, 70 insertions(+), 3 deletions(-)

diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index 3a004abd24..db876fc098 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -2234,9 +2234,52 @@ static int wpas_nan_fill_nd_pmk(struct wpa_supplicant *wpa_s,
 }
 
 
+static int wpas_nan_set_gtk(struct wpa_supplicant *ndi_wpa_s,
+			    struct nan_ndp_params *ndp, int gtk_csid)
+{
+	if (ndi_wpa_s->ndi_gtk.gtk.gtk_len) {
+		if (ndi_wpa_s->ndi_gtk.csid != gtk_csid) {
+			wpa_printf(MSG_DEBUG,
+				   "NAN: NDI GTK CSID mismatch (expected %d, got %d)",
+				   gtk_csid, ndi_wpa_s->ndi_gtk.csid);
+			return -1;
+		}
+
+		os_memcpy(&ndp->sec.gtk, &ndi_wpa_s->ndi_gtk,
+			  sizeof(ndp->sec.gtk));
+		return 0;
+	}
+
+	ndp->sec.gtk.csid = gtk_csid;
+	if (gtk_csid == NAN_CS_GTK_GCMP_256 &&
+	    (ndi_wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP_256)) {
+		ndp->sec.gtk.gtk.gtk_len = 32;
+	} else if (gtk_csid == NAN_CS_GTK_CCMP_128 &&
+		   (ndi_wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_CCMP)) {
+		ndp->sec.gtk.gtk.gtk_len = 16;
+	} else {
+		wpa_printf(MSG_DEBUG,
+			   "NAN: NDI does not support GTK cipher suites");
+		return -1;
+	}
+
+	if (os_get_random(ndp->sec.gtk.gtk.gtk, ndp->sec.gtk.gtk.gtk_len) < 0) {
+		wpa_printf(MSG_DEBUG, "NAN: Failed to generate GTK");
+		return -1;
+	}
+
+	ndp->sec.gtk.id = 1;
+
+	wpa_hexdump_key(MSG_DEBUG, "NAN: Generated new GTK",
+			ndp->sec.gtk.gtk.gtk, ndp->sec.gtk.gtk.gtk_len);
+	return 0;
+}
+
+
 /* 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>|pmk=<hex>>] [interface_id=<hex>]*/
+   [csid = <cipher_suite> <password=<string>|pmk=<hex>>
+   [gtk_csid=<cipher_suite>]] [interface_id=<hex>] */
 int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
 {
 	struct nan_ndp_params ndp;
@@ -2246,6 +2289,8 @@ int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
 	const char *pwd = NULL, *pmk = NULL;
 	int handle = -1;
 	int ret = -1;
+	struct wpa_supplicant *ndi_wpa_s = NULL;
+	int gtk_csid = 0;
 
 	os_memset(&ndp, 0, sizeof(ndp));
 
@@ -2281,8 +2326,6 @@ int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
 				goto fail;
 			}
 		} else if (os_strcmp(token, "ndi") == 0) {
-			struct wpa_supplicant *ndi_wpa_s;
-
 			ndi_wpa_s = wpa_supplicant_get_iface(wpa_s->global,
 							     pos);
 			if (!ndi_wpa_s) {
@@ -2348,6 +2391,15 @@ int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
 					   pos);
 				goto fail;
 			}
+		} else if (os_strcmp(token, "gtk_csid") == 0) {
+			gtk_csid = atoi(pos);
+			if (gtk_csid != NAN_CS_GTK_CCMP_128 &&
+			    gtk_csid != NAN_CS_GTK_GCMP_256) {
+				wpa_printf(MSG_DEBUG,
+					   "NAN: Invalid GTK CSID value: %d",
+					   gtk_csid);
+				goto fail;
+			}
 		} else {
 			wpa_printf(MSG_INFO, "NAN: Unknown parameter: %s",
 				   token);
@@ -2396,6 +2448,19 @@ int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
 		goto fail;
 	}
 
+	if (gtk_csid) {
+		if (ndp.sec.csid == NAN_CS_NONE) {
+			wpa_printf(MSG_DEBUG,
+				   "NAN: GTK CSID specified without a valid NDP CSID");
+			goto fail;
+		}
+
+		if (wpas_nan_set_gtk(ndi_wpa_s, &ndp, gtk_csid) < 0) {
+			wpa_printf(MSG_DEBUG, "NAN: Failed to set NDP GTK");
+			goto fail;
+		}
+	}
+
 	wpa_printf(MSG_DEBUG, "NAN: Requesting NDP with peer " MACSTR
 		   " using handle %d", MAC2STR(ndp.ndp_id.peer_nmi),
 		   ndp.u.req.publish_inst_id);
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index d68dd582fb..17a55f0db7 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -21,6 +21,7 @@
 #include "config_ssid.h"
 #include "wmm_ac.h"
 #include "pasn/pasn_common.h"
+#include "nan/nan.h"
 
 extern const char *const wpa_supplicant_version;
 extern const char *const wpa_supplicant_license;
@@ -1738,6 +1739,7 @@ struct wpa_supplicant {
 	struct wpa_freq_range_list nan_disallowed_freqs;
 	u16 nan_max_bw;
 	unsigned int nan_ndi_ndp_refcount; /* Active NDP count on this NDI */
+	struct nan_gtk ndi_gtk;
 #endif /* CONFIG_NAN */
 #ifdef CONFIG_ENC_ASSOC
 	bool assoc_resp_encrypted; /* Whether (Re)Association Response frame
-- 
2.53.0




More information about the Hostap mailing list