[PATCH 38/97] NAN: Parse the GTK KDE from key data
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Tue Apr 28 13:05:39 PDT 2026
From: Avraham Stern <avraham.stern at intel.com>
When a GTK is required for the NDP, parse the GTK KDE from the key
data field and save the GTK, its key ID and RSC in the NDP setup
data. The GTK will be installed for the NDI station when the NDP is
established.
Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
src/nan/nan_i.h | 4 ++++
src/nan/nan_sec.c | 48 +++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/src/nan/nan_i.h b/src/nan/nan_i.h
index 1d6956986b..772971ba84 100644
--- a/src/nan/nan_i.h
+++ b/src/nan/nan_i.h
@@ -66,6 +66,8 @@ struct nan_ptk {
* @pmk: PMK used for the secure NDP establishment
* @ptk: Derived PTK
* @local_gtk: Group Temporal Key information of the local NDI
+ * @peer_gtk: Group Temporal Key information of the peer NDI
+ * @peer_gtk_rsc: Receive sequence counter of the peer NDI GTK
*/
struct nan_ndp_sec {
bool present;
@@ -94,6 +96,8 @@ struct nan_ndp_sec {
struct nan_ptk ptk;
struct nan_gtk local_gtk;
+ struct nan_gtk peer_gtk;
+ u8 peer_gtk_rsc[WPA_KEY_RSC_LEN];
};
/*
diff --git a/src/nan/nan_sec.c b/src/nan/nan_sec.c
index 68310c94f1..dc65610bdf 100644
--- a/src/nan/nan_sec.c
+++ b/src/nan/nan_sec.c
@@ -435,9 +435,10 @@ static int nan_sec_rx_key_data(struct nan_data *nan,
enum wpa_alg alg;
if (((peer_capab & NAN_CS_INFO_CAPA_GTK_SUPP_MASK) >>
- NAN_CS_INFO_CAPA_GTK_SUPP_POS) == NAN_CS_INFO_CAPA_GTK_SUPP_NONE) {
+ NAN_CS_INFO_CAPA_GTK_SUPP_POS) == NAN_CS_INFO_CAPA_GTK_SUPP_NONE &&
+ ndp_sec->peer_gtk.csid == NAN_CS_NONE) {
wpa_printf(MSG_DEBUG,
- "NAN: SEC: Peer does not support IGTK/BIGTK, ignore key data");
+ "NAN: SEC: Peer does not support GTK/IGTK/BIGTK, ignore key data");
return 0;
}
@@ -538,6 +539,38 @@ static int nan_sec_rx_key_data(struct nan_data *nan,
bigtk_kde->bigtk, key_len);
}
+ if (ie.gtk && ie.gtk_len) {
+ struct wpa_gtk_kde *gtk_kde =
+ (struct wpa_gtk_kde *)ie.gtk;
+ int gtk_cipher = ndp_sec->peer_gtk.csid == NAN_CS_GTK_GCMP_256 ?
+ WPA_CIPHER_GCMP_256 : WPA_CIPHER_CCMP;
+ size_t gtk_len = wpa_cipher_key_len(gtk_cipher);
+
+ if (ie.gtk_len != WPA_GTK_KDE_PREFIX_LEN + gtk_len) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: SEC: Invalid GTK KDE length: %zu (expected %zu)",
+ ie.gtk_len,
+ WPA_GTK_KDE_PREFIX_LEN + gtk_len);
+ goto fail;
+ }
+
+ /* GTK key ID must be 1 or 2, see Wi-Fi Aware Specification v4.0,
+ * section 7.1.3.2
+ */
+ if (gtk_kde->keyid < 1 || gtk_kde->keyid > 2) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: SEC: Invalid GTK key index: %u",
+ gtk_kde->keyid);
+ goto fail;
+ }
+
+ ndp_sec->peer_gtk.id = gtk_kde->keyid;
+ os_memcpy(ndp_sec->peer_gtk.gtk.gtk, gtk_kde->gtk, gtk_len);
+ ndp_sec->peer_gtk.gtk.gtk_len = gtk_len;
+ wpa_hexdump_key(MSG_DEBUG, "NAN: SEC: Received GTK",
+ gtk_kde->gtk, gtk_len);
+ }
+
ret = 0;
fail:
wpabuf_clear_free(key_data);
@@ -562,7 +595,7 @@ int nan_sec_rx(struct nan_data *nan, struct nan_peer *peer,
size_t shared_key_desc_len;
u16 info, desc, key_data_len;
size_t total_len;
- u8 instance_id, cipher, capab, gtk_csid;
+ u8 instance_id, cipher, capab, gtk_csid = NAN_CS_NONE;
u8 *pos;
int ret;
@@ -661,7 +694,6 @@ int nan_sec_rx(struct nan_data *nan, struct nan_peer *peer,
* be ignored:
* key->len: as the key length is derived from the cipher suite.
* key->iv: not needed for AES Key WRAP
- * key->rsc: to avoid implicit assumption of a single GTK.
*/
if (key->type != NAN_KEY_DESC) {
wpa_printf(MSG_DEBUG,
@@ -701,6 +733,14 @@ int nan_sec_rx(struct nan_data *nan, struct nan_peer *peer,
return -1;
}
+ if (gtk_csid != NAN_CS_NONE) {
+ wpa_printf(MSG_DEBUG, "NAN: SEC: Peer GTK CSID=%u", gtk_csid);
+
+ os_memcpy(ndp_sec->peer_gtk_rsc, key->key_rsc,
+ sizeof(key->key_rsc));
+ ndp_sec->peer_gtk.csid = gtk_csid;
+ }
+
switch (msg->oui_subtype) {
case NAN_SUBTYPE_DATA_PATH_REQUEST:
if (!(info & WPA_KEY_INFO_ACK))
--
2.53.0
More information about the Hostap
mailing list