[v8,12/15] AP: FILS Extended Key ID support
diff mbox series

Message ID 20191031091901.2889-13-alexander@wetzel-home.de
State New
Headers show
  • Support seamless PTK rekeys with Extended Key ID
Related show

Commit Message

Alexander Wetzel Oct. 31, 2019, 9:18 a.m. UTC
IEEE 802.11ai - 2016 is missing any instructions how to handle FILS in
combination with Extended Key ID. There are two obvious ways:

 1) FILS connections can only use keyid 0 and the STAs decide on rekey
    if they can use Extended Key ID or not.

 2) FILS also checks if Extended Key ID can be used by both STAs and
    adds the KeyID KDE when it's used to the initial handshake without
    the normally required eapol handshake.

The latter seems to be closer to the intent of 802.11ai and since there
are no other implementations for Extended Key ID we could become
incompatible to this patch implements option 2) for now.

Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>

Now this is a very free interpretation of how to handle Extended Key ID
in combination with FILS. Technically it's the same issue as we have for
FT, so I'm using the same (arguable) solution here:

We bypass the 4-way handshake and Extended Key ID is therefore mostly
irrelevant. Neither FILS nor FT mention Extended Key ID but both have a
mechanism to hand over/get the GTK ID: Which of course could also handle
the (unicast) KeyID required for Extended Key ID support...

Now the patch series is rigorously sticking to the key install mode used
at the initial connect: When either the AP or the STA tries to use
anything else than for the initial connect we kill the connection. By
also adding the KeyID to the others KDEs these checks work basically out
of the box and the Extended Key ID flag in the RSN capabilities serves a

Alternatively we could relax the checks and accept that we either still
set the Extended Key ID bit in RSN but just assume the keyid is always
zero for the initial connect with FT or FILS or even drop the bit in the
RSN capabilities - creating a discrepancy to the beacon - and relax the
sanity checks for FILS and FT accordingly.

Since not Extended Key ID capable STAs won't care either way and
there are no other Extended Key ID implementations we have to stay
compatible with I decided to first try what I consider the cleanest way.

Therefore Unicast KeyIDs have been added to the frames transporting also
the GTK ID. Based on the feedback we either keep or change it.

 src/ap/wpa_auth.c    | 12 ++++++++++--
 src/ap/wpa_auth_ft.c |  6 +-----
 2 files changed, 11 insertions(+), 7 deletions(-)

diff mbox series

diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 6a1cd4f6a..67db61d6a 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -2685,6 +2685,15 @@  static struct wpabuf * fils_prepare_plainbuf(struct wpa_state_machine *sm,
 	wpabuf_put_u8(plain, WLAN_EID_EXT_KEY_DELIVERY);
 	wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN,
 			    wpabuf_put(plain, WPA_KEY_RSC_LEN));
+	hdr[1] = 0;
+	if (sm->use_extended_key_id) {
+		hdr[0] = sm->keyidx_active & 0x01;
+		tmp = wpabuf_put(plain, 0);
+		tmp2 = wpa_add_kde(tmp, RSN_KEY_DATA_KEYID, hdr, 2, NULL, 0);
+		wpabuf_put(plain, tmp2 - tmp);
+	}
 	/* GTK KDE */
 	gtk = gsm->GTK[gsm->GN - 1];
 	gtk_len = gsm->GTK_len;
@@ -2701,7 +2710,6 @@  static struct wpabuf * fils_prepare_plainbuf(struct wpa_state_machine *sm,
 		gtk = dummy_gtk;
 	hdr[0] = gsm->GN & 0x03;
-	hdr[1] = 0;
 	tmp = wpabuf_put(plain, 0);
 	tmp2 = wpa_add_kde(tmp, RSN_KEY_DATA_GROUPKEY, hdr, 2,
 			   gtk, gtk_len);
@@ -2756,7 +2764,7 @@  int fils_set_tk(struct wpa_state_machine *sm)
 	klen = wpa_cipher_key_len(sm->pairwise);
 	wpa_printf(MSG_DEBUG, "FILS: Configure TK to the driver");
-	if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
+	if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, sm->keyidx_active,
 			     sm->PTK.tk, klen, KEY_TYPE_PAIRWISE)) {
 		wpa_printf(MSG_DEBUG, "FILS: Failed to set TK to the driver");
 		return -1;
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index cf854a027..4a887e286 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -2785,8 +2785,7 @@  static int wpa_ft_set_key_mgmt(struct wpa_state_machine *sm,
 		return -1;
 	sm->pairwise = wpa_pick_pairwise_cipher(ciphers, 0);
-	return 0;
+	return handle_extended_key_id(sm, parse->capabilities);
@@ -2898,9 +2897,6 @@  static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
-	if (handle_extended_key_id(sm, parse.capabilities))
 	use_sha384 = wpa_key_mgmt_sha384(parse.key_mgmt);
 	pmk_r1_len = use_sha384 ? SHA384_MAC_LEN : PMK_LEN;