[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

KRACK update for wheezy



Hi,

I have looked at backporting the "KRACK" patches down into wheezy. I'm a
little concerned about the results: I don't have a good grasp of WPA2
and particularly of the wpa_supplicant codebase. I don't even know if
wheezy is actually vulnerable, I went under the assumption that it was
vulnerable and carried on.

Obviously, I don't have a full WPA stack to test this with here either:
my laptop is not running wheezy and I couldn't find a quick way to test
this directly, let alone mount a full attack to try and reproduce the
issue or confirm it is fixed.

So I uploaded a test package to my usual repository:

https://people.debian.org/~anarcat/debian/wheezy-lts/

WARNING: I didn't test this in any way. I tried to make the patch
meaningful and the code compiled, but that's about it.

A patch is attached for your perusal, but I am concerned about some bits
of the patchset, and I wonder if the version in wheezy might not be
vulnerable to even *more* issues. It's kind of scary to think that
wpa_supplicant is running, as root, on so many machines out there...

But more specifically, I'm concerned about the following hunks:

@@ -861,6 +870,7 @@ static u16 wpa_ft_process_auth_req(struc
 	wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
 
 	sm->pairwise = pairwise;
+        sm->tk_already_set = FALSE;
 	wpa_ft_install_ptk(sm);
 
 	buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +

The code in jessie also had a "sm->PTK_valid = TRUE;" assignment there,
I didn't look to see what that does exactly.

In the second patch, in wpa_sm_notify_assoc there are more os_memset()
calls in jessie that were not present in the wheezy version. For
example, those two:

 		os_memset(&sm->ptk, 0, sizeof(sm->tptk));
 		os_memset(&sm->tptk, 0, sizeof(sm->tptk));

Again PTK stuff...

Patch #5 is also worrisome: in wheezy, we *always* reset the nonce in
TDLS. So the last part of the hunk isn't relevant at all, because we
don't check if peer->inonce is set at all in wheezy. So I'm worried the
fix is incomplete, or even worse, that there are *other* vulnerabilities
in wheezy.

Patches 6-8 were completely discarded: they all refer to non-existent
code about WNM sleep support, which doesn't seem to be implemented in
wheezy. Hopefully that is not an issue either.

So that's about it, hopefully some more experienced wifi people can take
a look at this. Otherwise I can dig deeper in the protocol and try to
figure out what's going on, but it definitely seems sketchy...

Thank you for your time.

-- 
It is a miracle that curiosity survives formal education
                        - Albert Einstein
>From c2fcc12029d96c3a5030857ce2980b48d0159b06 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Antoine=20Beaupr=C3=A9?= <anarcat@debian.org>
Date: Mon, 23 Oct 2017 19:35:56 -0400
Subject: [PATCH] KRACK issues patchset, 1.0-3+deb7u5

---
 debian/changelog                                   |   9 +
 ...-Avoid-key-reinstallation-in-FT-handshake.patch |  97 ++++++++++
 ...nstallation-of-an-already-in-use-group-ke.patch | 213 +++++++++++++++++++++
 ...ection-of-GTK-IGTK-reinstallation-of-WNM-.patch | 111 +++++++++++
 ...Fix-PTK-rekeying-to-generate-a-new-ANonce.patch |  64 +++++++
 .../0005-TDLS-Reject-TPK-TK-reconfiguration.patch  | 117 +++++++++++
 ...Key-Data-in-WNM-Sleep-Mode-Response-frame.patch |  35 ++++
 ...WNM-Sleep-Mode-Response-if-WNM-Sleep-Mode.patch |  85 ++++++++
 ...WNM-Sleep-Mode-Response-without-pending-r.patch |  43 +++++
 ...llow-multiple-Reassociation-Response-fram.patch |  82 ++++++++
 ...nore-incoming-TDLS-Setup-Response-retries.patch |  32 ++++
 debian/patches/series                              |   7 +
 12 files changed, 895 insertions(+)
 create mode 100644 debian/patches/2017-1/0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch
 create mode 100644 debian/patches/2017-1/0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch
 create mode 100644 debian/patches/2017-1/0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch
 create mode 100644 debian/patches/2017-1/0004-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch
 create mode 100644 debian/patches/2017-1/0005-TDLS-Reject-TPK-TK-reconfiguration.patch
 create mode 100644 debian/patches/2017-1/0006-WNM-Ignore-Key-Data-in-WNM-Sleep-Mode-Response-frame.patch
 create mode 100644 debian/patches/2017-1/0007-WNM-Ignore-WNM-Sleep-Mode-Response-if-WNM-Sleep-Mode.patch
 create mode 100644 debian/patches/2017-1/0008-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch
 create mode 100644 debian/patches/2017-1/0009-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch
 create mode 100644 debian/patches/2017-1/0010-TDLS-Ignore-incoming-TDLS-Setup-Response-retries.patch

diff --git a/debian/changelog b/debian/changelog
index e830c0d..5175dbd 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+wpa (1.0-3+deb7u5) UNRELEASED; urgency=medium
+
+  * Non-maintainer upload by the LTS Security Team.
+  * Fix multiple issues in WPA protocol (CVE-2017-13077, CVE-2017-13078,
+    CVE-2017-13079, CVE-2017-13080, CVE-2017-13081, CVE-2017-13082,
+    CVE-2017-13086, CVE-2017-13087, CVE-2017-13088)
+
+ -- Antoine Beaupré <anarcat@debian.org>  Mon, 23 Oct 2017 17:09:19 -0400
+
 wpa (1.0-3+deb7u4) wheezy-security; urgency=high
 
   * Non-maintainer upload by the LTS team.
diff --git a/debian/patches/2017-1/0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch b/debian/patches/2017-1/0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch
new file mode 100644
index 0000000..1a72412
--- /dev/null
+++ b/debian/patches/2017-1/0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch
@@ -0,0 +1,97 @@
+From fae4ceb757da370ebd1870762fd38fb39ee3d0a2 Mon Sep 17 00:00:00 2001
+From: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
+Date: Fri, 14 Jul 2017 15:15:35 +0200
+Subject: [PATCH 01/10] hostapd: Avoid key reinstallation in FT handshake
+
+Do not reinstall TK to the driver during Reassociation Response frame
+processing if the first attempt of setting the TK succeeded. This avoids
+issues related to clearing the TX/RX PN that could result in reusing
+same PN values for transmitted frames (e.g., due to CCM nonce reuse and
+also hitting replay protection on the receiver) and accepting replayed
+frames on RX side.
+
+This issue was introduced by the commit
+0e84c25434e6a1f283c7b4e62e483729085b78d2 ('FT: Fix PTK configuration in
+authenticator') which allowed wpa_ft_install_ptk() to be called multiple
+times with the same PTK. While the second configuration attempt is
+needed with some drivers, it must be done only if the first attempt
+failed.
+
+Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
+---
+ src/ap/wpa_auth.c    |  8 ++++++++
+ src/ap/wpa_auth.h    |  1 +
+ src/ap/wpa_auth_ft.c | 10 ++++++++++
+ src/ap/wpa_auth_i.h  |  1 +
+ 4 files changed, 20 insertions(+)
+
+--- a/src/ap/wpa_auth.c
++++ b/src/ap/wpa_auth.c
+@@ -2756,6 +2756,14 @@ int wpa_auth_sta_wpa_version(struct wpa_
+ }
+ 
+ 
++int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm)
++{
++	if (!sm || !wpa_key_mgmt_ft(sm->wpa_key_mgmt))
++		return 0;
++	return sm->tk_already_set;
++}
++
++
+ int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
+ 			     struct rsn_pmksa_cache_entry *entry)
+ {
+--- a/src/ap/wpa_auth.h
++++ b/src/ap/wpa_auth.h
+@@ -249,6 +249,7 @@ int wpa_auth_pairwise_set(struct wpa_sta
+ int wpa_auth_get_pairwise(struct wpa_state_machine *sm);
+ int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm);
+ int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm);
++int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm);
+ int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
+ 			     struct rsn_pmksa_cache_entry *entry);
+ struct rsn_pmksa_cache_entry *
+--- a/src/ap/wpa_auth_ft.c
++++ b/src/ap/wpa_auth_ft.c
+@@ -736,6 +736,14 @@ void wpa_ft_install_ptk(struct wpa_state
+ 		return;
+ 	}
+ 
++	if (sm->tk_already_set) {
++		/* Must avoid TK reconfiguration to prevent clearing of TX/RX
++		 * PN in the driver */
++		wpa_printf(MSG_DEBUG,
++			   "FT: Do not re-install same PTK to the driver");
++		return;
++	}
++
+ 	/* FIX: add STA entry to kernel/driver here? The set_key will fail
+ 	 * most likely without this.. At the moment, STA entry is added only
+ 	 * after association has been completed. This function will be called
+@@ -748,6 +756,7 @@ void wpa_ft_install_ptk(struct wpa_state
+ 
+ 	/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
+ 	sm->pairwise_set = TRUE;
++	sm->tk_already_set = TRUE;
+ }
+ 
+ 
+@@ -861,6 +870,7 @@ static u16 wpa_ft_process_auth_req(struc
+ 	wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
+ 
+ 	sm->pairwise = pairwise;
++        sm->tk_already_set = FALSE;
+ 	wpa_ft_install_ptk(sm);
+ 
+ 	buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +
+--- a/src/ap/wpa_auth_i.h
++++ b/src/ap/wpa_auth_i.h
+@@ -67,6 +67,7 @@ struct wpa_state_machine {
+ 	struct wpa_ptk PTK;
+ 	Boolean PTK_valid;
+ 	Boolean pairwise_set;
++	Boolean tk_already_set;
+ 	int keycount;
+ 	Boolean Pair;
+ 	struct {
diff --git a/debian/patches/2017-1/0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch b/debian/patches/2017-1/0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch
new file mode 100644
index 0000000..da14380
--- /dev/null
+++ b/debian/patches/2017-1/0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch
@@ -0,0 +1,213 @@
+From d703108d74fb1bc98f48490c513c7061dd8fbe9e Mon Sep 17 00:00:00 2001
+From: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
+Date: Wed, 12 Jul 2017 16:03:24 +0200
+Subject: [PATCH 02/10] Prevent reinstallation of an already in-use group key
+
+Track the current GTK and IGTK that is in use and when receiving a
+(possibly retransmitted) Group Message 1 or WNM-Sleep Mode Response, do
+not install the given key if it is already in use. This prevents an
+attacker from trying to trick the client into resetting or lowering the
+sequence counter associated to the group key.
+
+Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
+---
+ src/common/wpa_common.h |  11 +++++
+ src/rsn_supp/wpa.c      | 116 ++++++++++++++++++++++++++++++------------------
+ src/rsn_supp/wpa_i.h    |   4 ++
+ 3 files changed, 87 insertions(+), 44 deletions(-)
+
+--- a/src/common/wpa_common.h
++++ b/src/common/wpa_common.h
+@@ -107,6 +107,7 @@
+ 
+ #ifdef CONFIG_IEEE80211W
+ #define WPA_IGTK_LEN 16
++#define WPA_IGTK_MAX_LEN 32
+ #endif /* CONFIG_IEEE80211W */
+ 
+ 
+@@ -185,6 +186,17 @@ struct wpa_ptk {
+ 	} u;
+ } STRUCT_PACKED;
+ 
++struct wpa_gtk {
++	u8 gtk[WPA_GTK_MAX_LEN];
++	size_t gtk_len;
++};
++
++#ifdef CONFIG_IEEE80211W
++struct wpa_igtk {
++	u8 igtk[WPA_IGTK_MAX_LEN];
++	size_t igtk_len;
++};
++#endif /* CONFIG_IEEE80211W */
+ 
+ /* WPA IE version 1
+  * 00-50-f2:1 (OUI:OUI type)
+--- a/src/rsn_supp/wpa.c
++++ b/src/rsn_supp/wpa.c
+@@ -639,6 +639,15 @@ static int wpa_supplicant_install_gtk(st
+ 	const u8 *_gtk = gd->gtk;
+ 	u8 gtk_buf[32];
+ 
++	/* Detect possible key reinstallation */
++	if (sm->gtk.gtk_len == (size_t) gd->gtk_len &&
++	    os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) {
++		wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
++			"WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)",
++			gd->keyidx, gd->tx, gd->gtk_len);
++		return 0;
++	}
++
+ 	wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
+ 	wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ 		"WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)",
+@@ -670,6 +679,9 @@ static int wpa_supplicant_install_gtk(st
+ 		return -1;
+ 	}
+ 
++	sm->gtk.gtk_len = gd->gtk_len;
++	os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len);
++
+ 	return 0;
+ }
+ 
+@@ -742,6 +754,48 @@ static int wpa_supplicant_pairwise_gtk(s
+ }
+ 
+ 
++#ifdef CONFIG_IEEE80211W
++static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
++				       const struct wpa_igtk_kde *igtk)
++{
++	size_t len = WPA_IGTK_LEN;
++	u16 keyidx = WPA_GET_LE16(igtk->keyid);
++
++	/* Detect possible key reinstallation */
++	if (sm->igtk.igtk_len == len &&
++	    os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) {
++		wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
++			"WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)",
++			keyidx);
++		return  0;
++	}
++
++	wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
++		"WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x",
++		keyidx, MAC2STR(igtk->pn));
++	wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len);
++	if (keyidx > 4095) {
++		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
++			"WPA: Invalid IGTK KeyID %d", keyidx);
++		return -1;
++	}
++	if (wpa_sm_set_key(sm, WPA_ALG_IGTK,
++			   broadcast_ether_addr,
++			   keyidx, 0, igtk->pn, sizeof(igtk->pn),
++			   igtk->igtk, len) < 0) {
++		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
++			"WPA: Failed to configure IGTK to the driver");
++		return -1;
++	}
++
++	sm->igtk.igtk_len = len;
++	os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len);
++
++	return 0;
++}
++#endif /* CONFIG_IEEE80211W */
++
++
+ static int ieee80211w_set_keys(struct wpa_sm *sm,
+ 			       struct wpa_eapol_ie_parse *ie)
+ {
+@@ -751,28 +805,12 @@ static int ieee80211w_set_keys(struct wp
+ 
+ 	if (ie->igtk) {
+ 		const struct wpa_igtk_kde *igtk;
+-		u16 keyidx;
++
+ 		if (ie->igtk_len != sizeof(*igtk))
+ 			return -1;
+ 		igtk = (const struct wpa_igtk_kde *) ie->igtk;
+-		keyidx = WPA_GET_LE16(igtk->keyid);
+-		wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d "
+-			"pn %02x%02x%02x%02x%02x%02x",
+-			keyidx, MAC2STR(igtk->pn));
+-		wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK",
+-				igtk->igtk, WPA_IGTK_LEN);
+-		if (keyidx > 4095) {
+-			wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+-				"WPA: Invalid IGTK KeyID %d", keyidx);
+-			return -1;
+-		}
+-		if (wpa_sm_set_key(sm, WPA_ALG_IGTK, broadcast_ether_addr,
+-				   keyidx, 0, igtk->pn, sizeof(igtk->pn),
+-				   igtk->igtk, WPA_IGTK_LEN) < 0) {
+-			wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+-				"WPA: Failed to configure IGTK to the driver");
+-			return -1;
+-		}
++		if (wpa_supplicant_install_igtk(sm, igtk) < 0)
++ 			return -1;
+ 	}
+ 
+ 	return 0;
+@@ -2098,7 +2136,7 @@ void wpa_sm_deinit(struct wpa_sm *sm)
+  */
+ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
+ {
+-	int clear_ptk = 1;
++	int clear_keys = 1;
+ 
+ 	if (sm == NULL)
+ 		return;
+@@ -2124,11 +2162,11 @@ void wpa_sm_notify_assoc(struct wpa_sm *
+ 		/* Prepare for the next transition */
+ 		wpa_ft_prepare_auth_request(sm, NULL);
+ 
+-		clear_ptk = 0;
++		clear_keys = 0;
+ 	}
+ #endif /* CONFIG_IEEE80211R */
+ 
+-	if (clear_ptk) {
++	if (clear_keys) {
+ 		/*
+ 		 * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if
+ 		 * this is not part of a Fast BSS Transition.
+@@ -2136,6 +2174,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *
+ 		wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Clear old PTK");
+ 		sm->ptk_set = 0;
+ 		sm->tptk_set = 0;
++		os_memset(&sm->gtk, 0, sizeof(sm->gtk));
++#ifdef CONFIG_IEEE80211W
++		os_memset(&sm->igtk, 0, sizeof(sm->igtk));
++#endif /* CONFIG_IEEE80211W */
+ 	}
+ 
+ #ifdef CONFIG_TDLS
+@@ -2640,6 +2682,10 @@ void wpa_sm_drop_sa(struct wpa_sm *sm)
+ 	os_memset(sm->pmk, 0, sizeof(sm->pmk));
+ 	os_memset(&sm->ptk, 0, sizeof(sm->ptk));
+ 	os_memset(&sm->tptk, 0, sizeof(sm->tptk));
++	os_memset(&sm->gtk, 0, sizeof(sm->gtk));
++#ifdef CONFIG_IEEE80211W
++	os_memset(&sm->igtk, 0, sizeof(sm->igtk));
++#endif /* CONFIG_IEEE80211W */
+ }
+ 
+ 
+--- a/src/rsn_supp/wpa_i.h
++++ b/src/rsn_supp/wpa_i.h
+@@ -35,6 +35,10 @@ struct wpa_sm {
+ 	u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN];
+ 	int rx_replay_counter_set;
+ 	u8 request_counter[WPA_REPLAY_COUNTER_LEN];
++	struct wpa_gtk gtk;
++#ifdef CONFIG_IEEE80211W
++	struct wpa_igtk igtk;
++#endif /* CONFIG_IEEE80211W */
+ 
+ 	struct eapol_sm *eapol; /* EAPOL state machine from upper level code */
+ 
diff --git a/debian/patches/2017-1/0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch b/debian/patches/2017-1/0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch
new file mode 100644
index 0000000..9037a83
--- /dev/null
+++ b/debian/patches/2017-1/0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch
@@ -0,0 +1,111 @@
+From 6dddf40742b318e6668a3645993193b06a0fa795 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Sun, 1 Oct 2017 12:12:24 +0300
+Subject: [PATCH 03/10] Extend protection of GTK/IGTK reinstallation of
+ WNM-Sleep Mode cases
+
+This extends the protection to track last configured GTK/IGTK value
+separately from EAPOL-Key frames and WNM-Sleep Mode frames to cover a
+corner case where these two different mechanisms may get used when the
+GTK/IGTK has changed and tracking a single value is not sufficient to
+detect a possible key reconfiguration.
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ src/rsn_supp/wpa.c   | 53 +++++++++++++++++++++++++++++++++++++---------------
+ src/rsn_supp/wpa_i.h |  2 ++
+ 2 files changed, 40 insertions(+), 15 deletions(-)
+
+--- a/src/rsn_supp/wpa.c
++++ b/src/rsn_supp/wpa.c
+@@ -634,14 +634,17 @@ struct wpa_gtk_data {
+ 
+ static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
+ 				      const struct wpa_gtk_data *gd,
+-				      const u8 *key_rsc)
++				      const u8 *key_rsc, int wnm_sleep)
+ {
+ 	const u8 *_gtk = gd->gtk;
+ 	u8 gtk_buf[32];
+ 
+ 	/* Detect possible key reinstallation */
+-	if (sm->gtk.gtk_len == (size_t) gd->gtk_len &&
+-	    os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) {
++	if ((sm->gtk.gtk_len == (size_t) gd->gtk_len &&
++	     os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) ||
++	    (sm->gtk_wnm_sleep.gtk_len == (size_t) gd->gtk_len &&
++	     os_memcmp(sm->gtk_wnm_sleep.gtk, gd->gtk,
++		       sm->gtk_wnm_sleep.gtk_len) == 0)) {
+ 		wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ 			"WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)",
+ 			gd->keyidx, gd->tx, gd->gtk_len);
+@@ -679,8 +682,14 @@ static int wpa_supplicant_install_gtk(st
+ 		return -1;
+ 	}
+ 
+-	sm->gtk.gtk_len = gd->gtk_len;
+-	os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len);
++	if (wnm_sleep) {
++		sm->gtk_wnm_sleep.gtk_len = gd->gtk_len;
++		os_memcpy(sm->gtk_wnm_sleep.gtk, gd->gtk,
++			  sm->gtk_wnm_sleep.gtk_len);
++	} else {
++		sm->gtk.gtk_len = gd->gtk_len;
++		os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len);
++	}
+ 
+ 	return 0;
+ }
+@@ -739,7 +748,7 @@ static int wpa_supplicant_pairwise_gtk(s
+ 	if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
+ 					      gtk_len, gtk_len,
+ 					      &gd.key_rsc_len, &gd.alg) ||
+-	    wpa_supplicant_install_gtk(sm, &gd, key->key_rsc)) {
++	    wpa_supplicant_install_gtk(sm, &gd, key->key_rsc, 0)) {
+ 		wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
+ 			"RSN: Failed to install GTK");
+ 		return -1;
+@@ -1425,7 +1434,7 @@ static void wpa_supplicant_process_1_of_
+ 	if (ret)
+ 		goto failed;
+ 
+-	if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc) ||
++	if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc, 0) ||
+ 	    wpa_supplicant_send_2_of_2(sm, key, ver, key_info))
+ 		goto failed;
+ 
+@@ -2175,8 +2184,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *
+ 		sm->ptk_set = 0;
+ 		sm->tptk_set = 0;
+ 		os_memset(&sm->gtk, 0, sizeof(sm->gtk));
++		os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep));
+ #ifdef CONFIG_IEEE80211W
+ 		os_memset(&sm->igtk, 0, sizeof(sm->igtk));
++		os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep));
+ #endif /* CONFIG_IEEE80211W */
+ 	}
+ 
+@@ -2683,8 +2694,10 @@ void wpa_sm_drop_sa(struct wpa_sm *sm)
+ 	os_memset(&sm->ptk, 0, sizeof(sm->ptk));
+ 	os_memset(&sm->tptk, 0, sizeof(sm->tptk));
+ 	os_memset(&sm->gtk, 0, sizeof(sm->gtk));
++	os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep));
+ #ifdef CONFIG_IEEE80211W
+ 	os_memset(&sm->igtk, 0, sizeof(sm->igtk));
++	os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep));
+ #endif /* CONFIG_IEEE80211W */
+ }
+ 
+--- a/src/rsn_supp/wpa_i.h
++++ b/src/rsn_supp/wpa_i.h
+@@ -36,8 +36,10 @@ struct wpa_sm {
+ 	int rx_replay_counter_set;
+ 	u8 request_counter[WPA_REPLAY_COUNTER_LEN];
+ 	struct wpa_gtk gtk;
++	struct wpa_gtk gtk_wnm_sleep;
+ #ifdef CONFIG_IEEE80211W
+ 	struct wpa_igtk igtk;
++	struct wpa_igtk igtk_wnm_sleep;
+ #endif /* CONFIG_IEEE80211W */
+ 
+ 	struct eapol_sm *eapol; /* EAPOL state machine from upper level code */
diff --git a/debian/patches/2017-1/0004-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch b/debian/patches/2017-1/0004-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch
new file mode 100644
index 0000000..374c06d
--- /dev/null
+++ b/debian/patches/2017-1/0004-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch
@@ -0,0 +1,64 @@
+From dd1900d11c28a968cfc0d1f92153b2789bcbd686 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Sun, 1 Oct 2017 12:32:57 +0300
+Subject: [PATCH 04/10] Fix PTK rekeying to generate a new ANonce
+
+The Authenticator state machine path for PTK rekeying ended up bypassing
+the AUTHENTICATION2 state where a new ANonce is generated when going
+directly to the PTKSTART state since there is no need to try to
+determine the PMK again in such a case. This is far from ideal since the
+new PTK would depend on a new nonce only from the supplicant.
+
+Fix this by generating a new ANonce when moving to the PTKSTART state
+for the purpose of starting new 4-way handshake to rekey PTK.
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ src/ap/wpa_auth.c | 24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
+index c2ba9a0..26b224a 100644
+--- a/src/ap/wpa_auth.c
++++ b/src/ap/wpa_auth.c
+@@ -1710,6 +1710,21 @@ SM_STATE(WPA_PTK, AUTHENTICATION2)
+ }
+ 
+ 
++static int wpa_auth_sm_ptk_update(struct wpa_state_machine *sm)
++{
++	if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
++		wpa_printf(MSG_ERROR,
++			   "WPA: Failed to get random data for ANonce");
++		sm->Disconnect = TRUE;
++		return -1;
++	}
++	wpa_hexdump(MSG_DEBUG, "WPA: Assign new ANonce", sm->ANonce,
++		    WPA_NONCE_LEN);
++	sm->TimeoutCtr = 0;
++	return 0;
++}
++
++
+ SM_STATE(WPA_PTK, INITPMK)
+ {
+ 	u8 msk[2 * PMK_LEN];
+@@ -2221,9 +2236,12 @@ SM_STEP(WPA_PTK)
+ 		SM_ENTER(WPA_PTK, AUTHENTICATION);
+ 	else if (sm->ReAuthenticationRequest)
+ 		SM_ENTER(WPA_PTK, AUTHENTICATION2);
+-	else if (sm->PTKRequest)
+-		SM_ENTER(WPA_PTK, PTKSTART);
+-	else switch (sm->wpa_ptk_state) {
++	else if (sm->PTKRequest) {
++		if (wpa_auth_sm_ptk_update(sm) < 0)
++			SM_ENTER(WPA_PTK, DISCONNECTED);
++		else
++			SM_ENTER(WPA_PTK, PTKSTART);
++	} else switch (sm->wpa_ptk_state) {
+ 	case WPA_PTK_INITIALIZE:
+ 		break;
+ 	case WPA_PTK_DISCONNECT:
+-- 
+2.7.4
+
diff --git a/debian/patches/2017-1/0005-TDLS-Reject-TPK-TK-reconfiguration.patch b/debian/patches/2017-1/0005-TDLS-Reject-TPK-TK-reconfiguration.patch
new file mode 100644
index 0000000..9fb70be
--- /dev/null
+++ b/debian/patches/2017-1/0005-TDLS-Reject-TPK-TK-reconfiguration.patch
@@ -0,0 +1,117 @@
+From ce152bef7ea0a6a5ccbff073564bc0499d5b5dfb Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Fri, 22 Sep 2017 11:03:15 +0300
+Subject: [PATCH 05/10] TDLS: Reject TPK-TK reconfiguration
+
+Do not try to reconfigure the same TPK-TK to the driver after it has
+been successfully configured. This is an explicit check to avoid issues
+related to resetting the TX/RX packet number. There was already a check
+for this for TPK M2 (retries of that message are ignored completely), so
+that behavior does not get modified.
+
+For TPK M3, the TPK-TK could have been reconfigured, but that was
+followed by immediate teardown of the link due to an issue in updating
+the STA entry. Furthermore, for TDLS with any real security (i.e.,
+ignoring open/WEP), the TPK message exchange is protected on the AP path
+and simple replay attacks are not feasible.
+
+As an additional corner case, make sure the local nonce gets updated if
+the peer uses a very unlikely "random nonce" of all zeros.
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ src/rsn_supp/tdls.c | 38 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 36 insertions(+), 2 deletions(-)
+
+--- a/src/rsn_supp/tdls.c
++++ b/src/rsn_supp/tdls.c
+@@ -109,6 +109,7 @@ struct wpa_tdls_peer {
+ 		u8 tk[16]; /* TPK-TK; assuming only CCMP will be used */
+ 	} tpk;
+ 	int tpk_set;
++	int tk_set; /* TPK-TK configured to the driver */
+ 	int tpk_success;
+ 
+ 	struct tpk_timer {
+@@ -166,6 +167,20 @@ static int wpa_tdls_set_key(struct wpa_s
+ 	u8 rsc[6];
+ 	enum wpa_alg alg;
+ 
++	if (peer->tk_set) {
++		/*
++		 * This same TPK-TK has already been configured to the driver
++		 * and this new configuration attempt (likely due to an
++		 * unexpected retransmitted frame) would result in clearing
++		 * the TX/RX sequence number which can break security, so must
++		 * not allow that to happen.
++		 */
++		wpa_printf(MSG_INFO, "TDLS: TPK-TK for the peer " MACSTR
++			   " has already been configured to the driver - do not reconfigure",
++			   MAC2STR(peer->addr));
++		return -1;
++	}
++
+ 	os_memset(rsc, 0, 6);
+ 
+ 	switch (peer->cipher) {
+@@ -183,12 +198,15 @@ static int wpa_tdls_set_key(struct wpa_s
+ 		return -1;
+ 	}
+ 
++	wpa_printf(MSG_DEBUG, "TDLS: Configure pairwise key for peer " MACSTR,
++		   MAC2STR(peer->addr));
+ 	if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1,
+ 			   rsc, sizeof(rsc), peer->tpk.tk, key_len) < 0) {
+ 		wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the "
+ 			   "driver");
+ 		return -1;
+ 	}
++	peer->tk_set = 1;
+ 	return 0;
+ }
+ 
+@@ -619,7 +637,7 @@ static void wpa_tdls_peer_free(struct wp
+ 	peer->sm_tmr.buf = NULL;
+ 	peer->rsnie_i_len = peer->rsnie_p_len = 0;
+ 	peer->cipher = 0;
+-	peer->tpk_set = peer->tpk_success = 0;
++	peer->tk_set = peer->tpk_set = peer->tpk_success = 0;
+ 	os_memset(&peer->tpk, 0, sizeof(peer->tpk));
+ 	os_memset(peer->inonce, 0, WPA_NONCE_LEN);
+ 	os_memset(peer->rnonce, 0, WPA_NONCE_LEN);
+@@ -1008,6 +1026,7 @@ skip_rsnie:
+ 		wpa_tdls_peer_free(sm, peer);
+ 		return -1;
+ 	}
++	peer->tk_set = 0; /* A new nonce results in a new TK */
+ 	wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake",
+ 		    peer->inonce, WPA_NONCE_LEN);
+ 	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
+@@ -1334,6 +1353,19 @@ static int copy_supp_rates(const struct
+ }
+ 
+ 
++static int tdls_nonce_set(const u8 *nonce)
++{
++	int i;
++
++	for (i = 0; i < WPA_NONCE_LEN; i++) {
++		if (nonce[i])
++			return 1;
++	}
++
++	return 0;
++}
++
++
+ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
+ 				   const u8 *buf, size_t len)
+ {
+@@ -1564,6 +1596,7 @@ skip_rsn:
+ 			 */
+ 			goto skip_rsn_check;
+ 		}
++		peer->tk_set = 0; /* A new nonce results in a new TK */
+ 	}
+ #endif /* CONFIG_TDLS_TESTING */
+ 
diff --git a/debian/patches/2017-1/0006-WNM-Ignore-Key-Data-in-WNM-Sleep-Mode-Response-frame.patch b/debian/patches/2017-1/0006-WNM-Ignore-Key-Data-in-WNM-Sleep-Mode-Response-frame.patch
new file mode 100644
index 0000000..f2f5fbf
--- /dev/null
+++ b/debian/patches/2017-1/0006-WNM-Ignore-Key-Data-in-WNM-Sleep-Mode-Response-frame.patch
@@ -0,0 +1,35 @@
+From 8d2f7096afc87ad6af4a83670d9f399b40d3d57e Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Sun, 25 Oct 2015 15:45:50 +0200
+Subject: [PATCH 06/10] WNM: Ignore Key Data in WNM Sleep Mode Response frame
+ if no PMF in use
+
+WNM Sleep Mode Response frame is used to update GTK/IGTK only if PMF is
+enabled. Verify that PMF is in use before using this field on station
+side to avoid accepting unauthenticated key updates. (CVE-2015-5310)
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ wpa_supplicant/wnm_sta.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
+index 4a792c4..e08480a 100644
+--- a/wpa_supplicant/wnm_sta.c
++++ b/wpa_supplicant/wnm_sta.c
+@@ -186,6 +186,12 @@ static void wnm_sleep_mode_exit_success(struct wpa_supplicant *wpa_s,
+ 	end = ptr + key_len_total;
+ 	wpa_hexdump_key(MSG_DEBUG, "WNM: Key Data", ptr, key_len_total);
+ 
++	if (key_len_total && !wpa_sm_pmf_enabled(wpa_s->wpa)) {
++		wpa_msg(wpa_s, MSG_INFO,
++			"WNM: Ignore Key Data in WNM-Sleep Mode Response - PMF not enabled");
++		return;
++	}
++
+ 	while (ptr + 1 < end) {
+ 		if (ptr + 2 + ptr[1] > end) {
+ 			wpa_printf(MSG_DEBUG, "WNM: Invalid Key Data element "
+-- 
+2.7.4
+
diff --git a/debian/patches/2017-1/0007-WNM-Ignore-WNM-Sleep-Mode-Response-if-WNM-Sleep-Mode.patch b/debian/patches/2017-1/0007-WNM-Ignore-WNM-Sleep-Mode-Response-if-WNM-Sleep-Mode.patch
new file mode 100644
index 0000000..9e726cd
--- /dev/null
+++ b/debian/patches/2017-1/0007-WNM-Ignore-WNM-Sleep-Mode-Response-if-WNM-Sleep-Mode.patch
@@ -0,0 +1,85 @@
+From 622cd8c05af5391e5cf83191fdf29608c08a1e87 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Sun, 25 Oct 2015 23:02:14 +0200
+Subject: [PATCH 07/10] WNM: Ignore WNM-Sleep Mode Response if WNM-Sleep Mode
+ has not been used
+
+The AP is not expected to send out a WNM-Sleep Mode Response frame
+without the STA trying to use WNM-Sleep Mode. Drop such unexpected
+responses to reduce unnecessary processing of the frame.
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ wpa_supplicant/ctrl_iface.c       | 2 ++
+ wpa_supplicant/events.c           | 2 ++
+ wpa_supplicant/wnm_sta.c          | 8 ++++++++
+ wpa_supplicant/wpa_supplicant_i.h | 1 +
+ 4 files changed, 13 insertions(+)
+
+diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
+index 98d3ce4..b343370 100644
+--- a/wpa_supplicant/ctrl_iface.c
++++ b/wpa_supplicant/ctrl_iface.c
+@@ -5794,6 +5794,8 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
+ #endif /* CONFIG_INTERWORKING */
+ 
+ 	wpa_s->ext_mgmt_frame_handling = 0;
++
++	wpa_s->wnmsleep_used = 0;
+ }
+ 
+ 
+diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
+index 2d17aba..05b036a 100644
+--- a/wpa_supplicant/events.c
++++ b/wpa_supplicant/events.c
+@@ -225,6 +225,8 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
+ 	wpa_s->current_ssid = NULL;
+ 	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
+ 	wpa_s->key_mgmt = 0;
++
++	wpa_s->wnmsleep_used = 0;
+ }
+ 
+ 
+diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
+index e08480a..23eabb8 100644
+--- a/wpa_supplicant/wnm_sta.c
++++ b/wpa_supplicant/wnm_sta.c
+@@ -136,6 +136,8 @@ int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s,
+ 	if (res < 0)
+ 		wpa_printf(MSG_DEBUG, "Failed to send WNM-Sleep Request "
+ 			   "(action=%d, intval=%d)", action, intval);
++	else
++		wpa_s->wnmsleep_used = 1;
+ 
+ 	os_free(wnmsleep_ie);
+ 	os_free(wnmtfs_ie);
+@@ -251,6 +253,12 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s,
+ 	u8 *tfsresp_ie_start = NULL;
+ 	u8 *tfsresp_ie_end = NULL;
+ 
++	if (!wpa_s->wnmsleep_used) {
++		wpa_printf(MSG_DEBUG,
++			   "WNM: Ignore WNM-Sleep Mode Response frame since WNM-Sleep Mode has not been used in this association");
++		return;
++	}
++
+ 	if (len < 3)
+ 		return;
+ 	key_len_total = WPA_GET_LE16(frm + 1);
+diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
+index cbe3e49..2dae4c9 100644
+--- a/wpa_supplicant/wpa_supplicant_i.h
++++ b/wpa_supplicant/wpa_supplicant_i.h
+@@ -608,6 +608,7 @@ struct wpa_supplicant {
+ 	unsigned int eap_expected_failure:1;
+ 	unsigned int reattach:1; /* reassociation to the same BSS requested */
+ 	unsigned int mac_addr_changed:1;
++	unsigned int wnmsleep_used:1;
+ 
+ 	struct os_reltime last_mac_addr_change;
+ 	int last_mac_addr_style;
+-- 
+2.7.4
+
diff --git a/debian/patches/2017-1/0008-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch b/debian/patches/2017-1/0008-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch
new file mode 100644
index 0000000..c685915
--- /dev/null
+++ b/debian/patches/2017-1/0008-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch
@@ -0,0 +1,43 @@
+From cef25ff15a62b3b7f2d788adcdf3aae9a9cb218d Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Fri, 22 Sep 2017 11:25:02 +0300
+Subject: [PATCH 08/10] WNM: Ignore WNM-Sleep Mode Response without pending
+ request
+
+Commit 03ed0a52393710be6bdae657d1b36efa146520e5 ('WNM: Ignore WNM-Sleep
+Mode Response if WNM-Sleep Mode has not been used') started ignoring the
+response when no WNM-Sleep Mode Request had been used during the
+association. This can be made tighter by clearing the used flag when
+successfully processing a response. This adds an additional layer of
+protection against unexpected retransmissions of the response frame.
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ wpa_supplicant/wnm_sta.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
+index 23eabb8..4c2fa85 100644
+--- a/wpa_supplicant/wnm_sta.c
++++ b/wpa_supplicant/wnm_sta.c
+@@ -255,7 +255,7 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s,
+ 
+ 	if (!wpa_s->wnmsleep_used) {
+ 		wpa_printf(MSG_DEBUG,
+-			   "WNM: Ignore WNM-Sleep Mode Response frame since WNM-Sleep Mode has not been used in this association");
++			   "WNM: Ignore WNM-Sleep Mode Response frame since WNM-Sleep Mode operation has not been requested");
+ 		return;
+ 	}
+ 
+@@ -293,6 +293,8 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s,
+ 		return;
+ 	}
+ 
++	wpa_s->wnmsleep_used = 0;
++
+ 	if (wnmsleep_ie->status == WNM_STATUS_SLEEP_ACCEPT ||
+ 	    wnmsleep_ie->status == WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE) {
+ 		wpa_printf(MSG_DEBUG, "Successfully recv WNM-Sleep Response "
+-- 
+2.7.4
+
diff --git a/debian/patches/2017-1/0009-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch b/debian/patches/2017-1/0009-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch
new file mode 100644
index 0000000..4ecfeee
--- /dev/null
+++ b/debian/patches/2017-1/0009-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch
@@ -0,0 +1,82 @@
+From dda06c8255d189bc951d81c67d29c6a378a705ba Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Fri, 22 Sep 2017 12:06:37 +0300
+Subject: [PATCH 09/10] FT: Do not allow multiple Reassociation Response frames
+
+The driver is expected to not report a second association event without
+the station having explicitly request a new association. As such, this
+case should not be reachable. However, since reconfiguring the same
+pairwise or group keys to the driver could result in nonce reuse issues,
+be extra careful here and do an additional state check to avoid this
+even if the local driver ends up somehow accepting an unexpected
+Reassociation Response frame.
+
+Signed-off-by: Jouni Malinen <j@w1.fi>
+---
+ src/rsn_supp/wpa.c    | 3 +++
+ src/rsn_supp/wpa_ft.c | 8 ++++++++
+ src/rsn_supp/wpa_i.h  | 1 +
+ 3 files changed, 12 insertions(+)
+
+diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
+index 1c80bf7..6df5a5f 100644
+--- a/src/rsn_supp/wpa.c
++++ b/src/rsn_supp/wpa.c
+@@ -2236,6 +2236,9 @@ void wpa_sm_notify_disassoc(struct wpa_sm *sm)
+ #ifdef CONFIG_TDLS
+ 	wpa_tdls_disassoc(sm);
+ #endif /* CONFIG_TDLS */
++#ifdef CONFIG_IEEE80211R
++	sm->ft_reassoc_completed = 0;
++#endif /* CONFIG_IEEE80211R */
+ }
+ 
+ 
+diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c
+index 3b3c9d0..6d6dfab 100644
+--- a/src/rsn_supp/wpa_ft.c
++++ b/src/rsn_supp/wpa_ft.c
+@@ -156,6 +156,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
+ 	u16 capab;
+ 
+ 	sm->ft_completed = 0;
++	sm->ft_reassoc_completed = 0;
+ 
+ 	buf_len = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +
+ 		2 + sm->r0kh_id_len + ric_ies_len + 100;
+@@ -687,6 +688,11 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
+ 		return -1;
+ 	}
+ 
++	if (sm->ft_reassoc_completed) {
++		wpa_printf(MSG_DEBUG, "FT: Reassociation has already been completed for this FT protocol instance - ignore unexpected retransmission");
++		return 0;
++	}
++
+ 	if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
+ 		wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs");
+ 		return -1;
+@@ -787,6 +793,8 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
+ 		return -1;
+ 	}
+ 
++	sm->ft_reassoc_completed = 1;
++
+ 	if (wpa_ft_process_gtk_subelem(sm, parse.gtk, parse.gtk_len) < 0)
+ 		return -1;
+ 
+diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
+index b4885de..269e4df 100644
+--- a/src/rsn_supp/wpa_i.h
++++ b/src/rsn_supp/wpa_i.h
+@@ -122,6 +122,7 @@ struct wpa_sm {
+ 	size_t r0kh_id_len;
+ 	u8 r1kh_id[FT_R1KH_ID_LEN];
+ 	int ft_completed;
++	int ft_reassoc_completed;
+ 	int over_the_ds_in_progress;
+ 	u8 target_ap[ETH_ALEN]; /* over-the-DS target AP */
+ 	int set_ptk_after_assoc;
+-- 
+2.7.4
+
diff --git a/debian/patches/2017-1/0010-TDLS-Ignore-incoming-TDLS-Setup-Response-retries.patch b/debian/patches/2017-1/0010-TDLS-Ignore-incoming-TDLS-Setup-Response-retries.patch
new file mode 100644
index 0000000..f4b52b1
--- /dev/null
+++ b/debian/patches/2017-1/0010-TDLS-Ignore-incoming-TDLS-Setup-Response-retries.patch
@@ -0,0 +1,32 @@
+From a035d6e3ca1f502f0e26b36afb9966c29f052821 Mon Sep 17 00:00:00 2001
+From: Arik Nemtsov <arik@wizery.com>
+Date: Thu, 10 Dec 2015 12:56:07 +0200
+Subject: [PATCH 10/10] TDLS: Ignore incoming TDLS Setup Response retries
+
+The Setup Response timer is relatively fast (500 ms) and there are
+instances where it fires on the responder side after the initiator has
+already sent out the TDLS Setup Confirm frame. Prevent the processing of
+this stale TDLS Setup Response frame on the initiator side.
+
+Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
+---
+ src/rsn_supp/tdls.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/src/rsn_supp/tdls.c
++++ b/src/rsn_supp/tdls.c
+@@ -1749,6 +1749,14 @@ static int wpa_tdls_process_tpk_m2(struc
+ 			   "TPK M2: " MACSTR, MAC2STR(src_addr));
+ 		return -1;
+ 	}
++
++	if (peer->tpk_success) {
++		wpa_printf(MSG_INFO, "TDLS: Ignore incoming TPK M2 retry, from "
++			   MACSTR " as TPK M3 was already sent",
++			   MAC2STR(src_addr));
++		return 0;
++	}
++
+ 	wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_REQUEST);
+ 
+ 	if (len < 3 + 2 + 1)
diff --git a/debian/patches/series b/debian/patches/series
index 0d462fc..9fc1e4a 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -20,3 +20,10 @@ CVE-2016-4476.patch
 CVE-2016-4477-part1.patch
 CVE-2016-4477-part2.patch
 CVE-2016-4476-and-CVE-2016-4477.patch
+2017-1/0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch
+2017-1/0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch
+2017-1/0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch
+2017-1/0004-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch
+2017-1/0005-TDLS-Reject-TPK-TK-reconfiguration.patch
+2017-1/0009-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch
+2017-1/0010-TDLS-Ignore-incoming-TDLS-Setup-Response-retries.patch
-- 
2.11.0


Reply to: