wpa-supplicant: import 2.6
[openembedded.git] / recipes / wpa-supplicant / wpa-supplicant-2.6 / key-replay-cve-multiple.patch
1 The WPA2 four-way handshake protocol is vulnerable to replay attacks which can
2 result in unauthenticated clients gaining access to the network.
3
4 Backport a number of patches from upstream to fix this.
5
6 CVE: CVE-2017-13077
7 CVE: CVE-2017-13078
8 CVE: CVE-2017-13079
9 CVE: CVE-2017-13080
10 CVE: CVE-2017-13081
11 CVE: CVE-2017-13082
12 CVE: CVE-2017-13086
13 CVE: CVE-2017-13087
14 CVE: CVE-2017-13088
15
16 Upstream-Status: Backport
17 Signed-off-by: Ross Burton <ross.burton@intel.com>
18
19 From cf4cab804c7afd5c45505528a8d16e46163243a2 Mon Sep 17 00:00:00 2001
20 From: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
21 Date: Fri, 14 Jul 2017 15:15:35 +0200
22 Subject: [PATCH 1/8] hostapd: Avoid key reinstallation in FT handshake
23
24 Do not reinstall TK to the driver during Reassociation Response frame
25 processing if the first attempt of setting the TK succeeded. This avoids
26 issues related to clearing the TX/RX PN that could result in reusing
27 same PN values for transmitted frames (e.g., due to CCM nonce reuse and
28 also hitting replay protection on the receiver) and accepting replayed
29 frames on RX side.
30
31 This issue was introduced by the commit
32 0e84c25434e6a1f283c7b4e62e483729085b78d2 ('FT: Fix PTK configuration in
33 authenticator') which allowed wpa_ft_install_ptk() to be called multiple
34 times with the same PTK. While the second configuration attempt is
35 needed with some drivers, it must be done only if the first attempt
36 failed.
37
38 Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
39 ---
40  src/ap/ieee802_11.c  | 16 +++++++++++++---
41  src/ap/wpa_auth.c    | 11 +++++++++++
42  src/ap/wpa_auth.h    |  3 ++-
43  src/ap/wpa_auth_ft.c | 10 ++++++++++
44  src/ap/wpa_auth_i.h  |  1 +
45  5 files changed, 37 insertions(+), 4 deletions(-)
46
47 diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
48 index 4e04169..333035f 100644
49 --- a/src/ap/ieee802_11.c
50 +++ b/src/ap/ieee802_11.c
51 @@ -1841,6 +1841,7 @@ static int add_associated_sta(struct hostapd_data *hapd,
52  {
53         struct ieee80211_ht_capabilities ht_cap;
54         struct ieee80211_vht_capabilities vht_cap;
55 +       int set = 1;
56  
57         /*
58          * Remove the STA entry to ensure the STA PS state gets cleared and
59 @@ -1848,9 +1849,18 @@ static int add_associated_sta(struct hostapd_data *hapd,
60          * FT-over-the-DS, where a station re-associates back to the same AP but
61          * skips the authentication flow, or if working with a driver that
62          * does not support full AP client state.
63 +        *
64 +        * Skip this if the STA has already completed FT reassociation and the
65 +        * TK has been configured since the TX/RX PN must not be reset to 0 for
66 +        * the same key.
67          */
68 -       if (!sta->added_unassoc)
69 +       if (!sta->added_unassoc &&
70 +           (!(sta->flags & WLAN_STA_AUTHORIZED) ||
71 +            !wpa_auth_sta_ft_tk_already_set(sta->wpa_sm))) {
72                 hostapd_drv_sta_remove(hapd, sta->addr);
73 +               wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED);
74 +               set = 0;
75 +       }
76  
77  #ifdef CONFIG_IEEE80211N
78         if (sta->flags & WLAN_STA_HT)
79 @@ -1873,11 +1883,11 @@ static int add_associated_sta(struct hostapd_data *hapd,
80                             sta->flags & WLAN_STA_VHT ? &vht_cap : NULL,
81                             sta->flags | WLAN_STA_ASSOC, sta->qosinfo,
82                             sta->vht_opmode, sta->p2p_ie ? 1 : 0,
83 -                           sta->added_unassoc)) {
84 +                           set)) {
85                 hostapd_logger(hapd, sta->addr,
86                                HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE,
87                                "Could not %s STA to kernel driver",
88 -                              sta->added_unassoc ? "set" : "add");
89 +                              set ? "set" : "add");
90  
91                 if (sta->added_unassoc) {
92                         hostapd_drv_sta_remove(hapd, sta->addr);
93 diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
94 index 3587086..707971d 100644
95 --- a/src/ap/wpa_auth.c
96 +++ b/src/ap/wpa_auth.c
97 @@ -1745,6 +1745,9 @@ int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event)
98  #else /* CONFIG_IEEE80211R */
99                 break;
100  #endif /* CONFIG_IEEE80211R */
101 +       case WPA_DRV_STA_REMOVED:
102 +               sm->tk_already_set = FALSE;
103 +               return 0;
104         }
105  
106  #ifdef CONFIG_IEEE80211R
107 @@ -3250,6 +3253,14 @@ int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm)
108  }
109  
110  
111 +int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm)
112 +{
113 +       if (!sm || !wpa_key_mgmt_ft(sm->wpa_key_mgmt))
114 +               return 0;
115 +       return sm->tk_already_set;
116 +}
117 +
118 +
119  int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
120                              struct rsn_pmksa_cache_entry *entry)
121  {
122 diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
123 index 0de8d97..97461b0 100644
124 --- a/src/ap/wpa_auth.h
125 +++ b/src/ap/wpa_auth.h
126 @@ -267,7 +267,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
127                  u8 *data, size_t data_len);
128  enum wpa_event {
129         WPA_AUTH, WPA_ASSOC, WPA_DISASSOC, WPA_DEAUTH, WPA_REAUTH,
130 -       WPA_REAUTH_EAPOL, WPA_ASSOC_FT
131 +       WPA_REAUTH_EAPOL, WPA_ASSOC_FT, WPA_DRV_STA_REMOVED
132  };
133  void wpa_remove_ptk(struct wpa_state_machine *sm);
134  int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event);
135 @@ -280,6 +280,7 @@ int wpa_auth_pairwise_set(struct wpa_state_machine *sm);
136  int wpa_auth_get_pairwise(struct wpa_state_machine *sm);
137  int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm);
138  int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm);
139 +int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm);
140  int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
141                              struct rsn_pmksa_cache_entry *entry);
142  struct rsn_pmksa_cache_entry *
143 diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
144 index 42242a5..e63b99a 100644
145 --- a/src/ap/wpa_auth_ft.c
146 +++ b/src/ap/wpa_auth_ft.c
147 @@ -780,6 +780,14 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm)
148                 return;
149         }
150  
151 +       if (sm->tk_already_set) {
152 +               /* Must avoid TK reconfiguration to prevent clearing of TX/RX
153 +                * PN in the driver */
154 +               wpa_printf(MSG_DEBUG,
155 +                          "FT: Do not re-install same PTK to the driver");
156 +               return;
157 +       }
158 +
159         /* FIX: add STA entry to kernel/driver here? The set_key will fail
160          * most likely without this.. At the moment, STA entry is added only
161          * after association has been completed. This function will be called
162 @@ -792,6 +800,7 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm)
163  
164         /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
165         sm->pairwise_set = TRUE;
166 +       sm->tk_already_set = TRUE;
167  }
168  
169  
170 @@ -898,6 +907,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
171  
172         sm->pairwise = pairwise;
173         sm->PTK_valid = TRUE;
174 +       sm->tk_already_set = FALSE;
175         wpa_ft_install_ptk(sm);
176  
177         buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +
178 diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h
179 index 72b7eb3..7fd8f05 100644
180 --- a/src/ap/wpa_auth_i.h
181 +++ b/src/ap/wpa_auth_i.h
182 @@ -65,6 +65,7 @@ struct wpa_state_machine {
183         struct wpa_ptk PTK;
184         Boolean PTK_valid;
185         Boolean pairwise_set;
186 +       Boolean tk_already_set;
187         int keycount;
188         Boolean Pair;
189         struct wpa_key_replay_counter {
190 -- 
191 2.7.4
192
193 From 927f891007c402fefd1ff384645b3f07597c3ede Mon Sep 17 00:00:00 2001
194 From: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
195 Date: Wed, 12 Jul 2017 16:03:24 +0200
196 Subject: [PATCH 2/8] Prevent reinstallation of an already in-use group key
197
198 Track the current GTK and IGTK that is in use and when receiving a
199 (possibly retransmitted) Group Message 1 or WNM-Sleep Mode Response, do
200 not install the given key if it is already in use. This prevents an
201 attacker from trying to trick the client into resetting or lowering the
202 sequence counter associated to the group key.
203
204 Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
205 ---
206  src/common/wpa_common.h |  11 +++++
207  src/rsn_supp/wpa.c      | 116 ++++++++++++++++++++++++++++++------------------
208  src/rsn_supp/wpa_i.h    |   4 ++
209  3 files changed, 87 insertions(+), 44 deletions(-)
210
211 diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
212 index af1d0f0..d200285 100644
213 --- a/src/common/wpa_common.h
214 +++ b/src/common/wpa_common.h
215 @@ -217,6 +217,17 @@ struct wpa_ptk {
216         size_t tk_len;
217  };
218  
219 +struct wpa_gtk {
220 +       u8 gtk[WPA_GTK_MAX_LEN];
221 +       size_t gtk_len;
222 +};
223 +
224 +#ifdef CONFIG_IEEE80211W
225 +struct wpa_igtk {
226 +       u8 igtk[WPA_IGTK_MAX_LEN];
227 +       size_t igtk_len;
228 +};
229 +#endif /* CONFIG_IEEE80211W */
230  
231  /* WPA IE version 1
232   * 00-50-f2:1 (OUI:OUI type)
233 diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
234 index 3c47879..95bd7be 100644
235 --- a/src/rsn_supp/wpa.c
236 +++ b/src/rsn_supp/wpa.c
237 @@ -714,6 +714,15 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
238         const u8 *_gtk = gd->gtk;
239         u8 gtk_buf[32];
240  
241 +       /* Detect possible key reinstallation */
242 +       if (sm->gtk.gtk_len == (size_t) gd->gtk_len &&
243 +           os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) {
244 +               wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
245 +                       "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)",
246 +                       gd->keyidx, gd->tx, gd->gtk_len);
247 +               return 0;
248 +       }
249 +
250         wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
251         wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
252                 "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)",
253 @@ -748,6 +757,9 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
254         }
255         os_memset(gtk_buf, 0, sizeof(gtk_buf));
256  
257 +       sm->gtk.gtk_len = gd->gtk_len;
258 +       os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len);
259 +
260         return 0;
261  }
262  
263 @@ -854,6 +866,48 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
264  }
265  
266  
267 +#ifdef CONFIG_IEEE80211W
268 +static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
269 +                                      const struct wpa_igtk_kde *igtk)
270 +{
271 +       size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher);
272 +       u16 keyidx = WPA_GET_LE16(igtk->keyid);
273 +
274 +       /* Detect possible key reinstallation */
275 +       if (sm->igtk.igtk_len == len &&
276 +           os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) {
277 +               wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
278 +                       "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)",
279 +                       keyidx);
280 +               return  0;
281 +       }
282 +
283 +       wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
284 +               "WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x",
285 +               keyidx, MAC2STR(igtk->pn));
286 +       wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len);
287 +       if (keyidx > 4095) {
288 +               wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
289 +                       "WPA: Invalid IGTK KeyID %d", keyidx);
290 +               return -1;
291 +       }
292 +       if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
293 +                          broadcast_ether_addr,
294 +                          keyidx, 0, igtk->pn, sizeof(igtk->pn),
295 +                          igtk->igtk, len) < 0) {
296 +               wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
297 +                       "WPA: Failed to configure IGTK to the driver");
298 +               return -1;
299 +       }
300 +
301 +       sm->igtk.igtk_len = len;
302 +       os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len);
303 +
304 +       return 0;
305 +}
306 +#endif /* CONFIG_IEEE80211W */
307 +
308 +
309  static int ieee80211w_set_keys(struct wpa_sm *sm,
310                                struct wpa_eapol_ie_parse *ie)
311  {
312 @@ -864,30 +918,14 @@ static int ieee80211w_set_keys(struct wpa_sm *sm,
313         if (ie->igtk) {
314                 size_t len;
315                 const struct wpa_igtk_kde *igtk;
316 -               u16 keyidx;
317 +
318                 len = wpa_cipher_key_len(sm->mgmt_group_cipher);
319                 if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len)
320                         return -1;
321 +
322                 igtk = (const struct wpa_igtk_kde *) ie->igtk;
323 -               keyidx = WPA_GET_LE16(igtk->keyid);
324 -               wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d "
325 -                       "pn %02x%02x%02x%02x%02x%02x",
326 -                       keyidx, MAC2STR(igtk->pn));
327 -               wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK",
328 -                               igtk->igtk, len);
329 -               if (keyidx > 4095) {
330 -                       wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
331 -                               "WPA: Invalid IGTK KeyID %d", keyidx);
332 -                       return -1;
333 -               }
334 -               if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
335 -                                  broadcast_ether_addr,
336 -                                  keyidx, 0, igtk->pn, sizeof(igtk->pn),
337 -                                  igtk->igtk, len) < 0) {
338 -                       wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
339 -                               "WPA: Failed to configure IGTK to the driver");
340 +               if (wpa_supplicant_install_igtk(sm, igtk) < 0)
341                         return -1;
342 -               }
343         }
344  
345         return 0;
346 @@ -2307,7 +2345,7 @@ void wpa_sm_deinit(struct wpa_sm *sm)
347   */
348  void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
349  {
350 -       int clear_ptk = 1;
351 +       int clear_keys = 1;
352  
353         if (sm == NULL)
354                 return;
355 @@ -2333,11 +2371,11 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
356                 /* Prepare for the next transition */
357                 wpa_ft_prepare_auth_request(sm, NULL);
358  
359 -               clear_ptk = 0;
360 +               clear_keys = 0;
361         }
362  #endif /* CONFIG_IEEE80211R */
363  
364 -       if (clear_ptk) {
365 +       if (clear_keys) {
366                 /*
367                  * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if
368                  * this is not part of a Fast BSS Transition.
369 @@ -2347,6 +2385,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
370                 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
371                 sm->tptk_set = 0;
372                 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
373 +               os_memset(&sm->gtk, 0, sizeof(sm->gtk));
374 +#ifdef CONFIG_IEEE80211W
375 +               os_memset(&sm->igtk, 0, sizeof(sm->igtk));
376 +#endif /* CONFIG_IEEE80211W */
377         }
378  
379  #ifdef CONFIG_TDLS
380 @@ -2877,6 +2919,10 @@ void wpa_sm_drop_sa(struct wpa_sm *sm)
381         os_memset(sm->pmk, 0, sizeof(sm->pmk));
382         os_memset(&sm->ptk, 0, sizeof(sm->ptk));
383         os_memset(&sm->tptk, 0, sizeof(sm->tptk));
384 +       os_memset(&sm->gtk, 0, sizeof(sm->gtk));
385 +#ifdef CONFIG_IEEE80211W
386 +       os_memset(&sm->igtk, 0, sizeof(sm->igtk));
387 +#endif /* CONFIG_IEEE80211W */
388  #ifdef CONFIG_IEEE80211R
389         os_memset(sm->xxkey, 0, sizeof(sm->xxkey));
390         os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0));
391 @@ -2949,29 +2995,11 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
392                 os_memset(&gd, 0, sizeof(gd));
393  #ifdef CONFIG_IEEE80211W
394         } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
395 -               struct wpa_igtk_kde igd;
396 -               u16 keyidx;
397 -
398 -               os_memset(&igd, 0, sizeof(igd));
399 -               keylen = wpa_cipher_key_len(sm->mgmt_group_cipher);
400 -               os_memcpy(igd.keyid, buf + 2, 2);
401 -               os_memcpy(igd.pn, buf + 4, 6);
402 -
403 -               keyidx = WPA_GET_LE16(igd.keyid);
404 -               os_memcpy(igd.igtk, buf + 10, keylen);
405 -
406 -               wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)",
407 -                               igd.igtk, keylen);
408 -               if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
409 -                                  broadcast_ether_addr,
410 -                                  keyidx, 0, igd.pn, sizeof(igd.pn),
411 -                                  igd.igtk, keylen) < 0) {
412 -                       wpa_printf(MSG_DEBUG, "Failed to install the IGTK in "
413 -                                  "WNM mode");
414 -                       os_memset(&igd, 0, sizeof(igd));
415 +               const struct wpa_igtk_kde *igtk;
416 +
417 +               igtk = (const struct wpa_igtk_kde *) (buf + 2);
418 +               if (wpa_supplicant_install_igtk(sm, igtk) < 0)
419                         return -1;
420 -               }
421 -               os_memset(&igd, 0, sizeof(igd));
422  #endif /* CONFIG_IEEE80211W */
423         } else {
424                 wpa_printf(MSG_DEBUG, "Unknown element id");
425 diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
426 index f653ba6..afc9e37 100644
427 --- a/src/rsn_supp/wpa_i.h
428 +++ b/src/rsn_supp/wpa_i.h
429 @@ -31,6 +31,10 @@ struct wpa_sm {
430         u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN];
431         int rx_replay_counter_set;
432         u8 request_counter[WPA_REPLAY_COUNTER_LEN];
433 +       struct wpa_gtk gtk;
434 +#ifdef CONFIG_IEEE80211W
435 +       struct wpa_igtk igtk;
436 +#endif /* CONFIG_IEEE80211W */
437  
438         struct eapol_sm *eapol; /* EAPOL state machine from upper level code */
439  
440 -- 
441 2.7.4
442
443 From 8280294e74846ea342389a0cd17215050fa5afe8 Mon Sep 17 00:00:00 2001
444 From: Jouni Malinen <j@w1.fi>
445 Date: Sun, 1 Oct 2017 12:12:24 +0300
446 Subject: [PATCH 3/8] Extend protection of GTK/IGTK reinstallation of WNM-Sleep
447  Mode cases
448
449 This extends the protection to track last configured GTK/IGTK value
450 separately from EAPOL-Key frames and WNM-Sleep Mode frames to cover a
451 corner case where these two different mechanisms may get used when the
452 GTK/IGTK has changed and tracking a single value is not sufficient to
453 detect a possible key reconfiguration.
454
455 Signed-off-by: Jouni Malinen <j@w1.fi>
456 ---
457  src/rsn_supp/wpa.c   | 53 +++++++++++++++++++++++++++++++++++++---------------
458  src/rsn_supp/wpa_i.h |  2 ++
459  2 files changed, 40 insertions(+), 15 deletions(-)
460
461 diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
462 index 95bd7be..7a2c68d 100644
463 --- a/src/rsn_supp/wpa.c
464 +++ b/src/rsn_supp/wpa.c
465 @@ -709,14 +709,17 @@ struct wpa_gtk_data {
466  
467  static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
468                                       const struct wpa_gtk_data *gd,
469 -                                     const u8 *key_rsc)
470 +                                     const u8 *key_rsc, int wnm_sleep)
471  {
472         const u8 *_gtk = gd->gtk;
473         u8 gtk_buf[32];
474  
475         /* Detect possible key reinstallation */
476 -       if (sm->gtk.gtk_len == (size_t) gd->gtk_len &&
477 -           os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) {
478 +       if ((sm->gtk.gtk_len == (size_t) gd->gtk_len &&
479 +            os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) ||
480 +           (sm->gtk_wnm_sleep.gtk_len == (size_t) gd->gtk_len &&
481 +            os_memcmp(sm->gtk_wnm_sleep.gtk, gd->gtk,
482 +                      sm->gtk_wnm_sleep.gtk_len) == 0)) {
483                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
484                         "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)",
485                         gd->keyidx, gd->tx, gd->gtk_len);
486 @@ -757,8 +760,14 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
487         }
488         os_memset(gtk_buf, 0, sizeof(gtk_buf));
489  
490 -       sm->gtk.gtk_len = gd->gtk_len;
491 -       os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len);
492 +       if (wnm_sleep) {
493 +               sm->gtk_wnm_sleep.gtk_len = gd->gtk_len;
494 +               os_memcpy(sm->gtk_wnm_sleep.gtk, gd->gtk,
495 +                         sm->gtk_wnm_sleep.gtk_len);
496 +       } else {
497 +               sm->gtk.gtk_len = gd->gtk_len;
498 +               os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len);
499 +       }
500  
501         return 0;
502  }
503 @@ -852,7 +861,7 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
504             (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
505                                                gtk_len, gtk_len,
506                                                &gd.key_rsc_len, &gd.alg) ||
507 -            wpa_supplicant_install_gtk(sm, &gd, key_rsc))) {
508 +            wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0))) {
509                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
510                         "RSN: Failed to install GTK");
511                 os_memset(&gd, 0, sizeof(gd));
512 @@ -868,14 +877,18 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
513  
514  #ifdef CONFIG_IEEE80211W
515  static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
516 -                                      const struct wpa_igtk_kde *igtk)
517 +                                      const struct wpa_igtk_kde *igtk,
518 +                                      int wnm_sleep)
519  {
520         size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher);
521         u16 keyidx = WPA_GET_LE16(igtk->keyid);
522  
523         /* Detect possible key reinstallation */
524 -       if (sm->igtk.igtk_len == len &&
525 -           os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) {
526 +       if ((sm->igtk.igtk_len == len &&
527 +            os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) ||
528 +           (sm->igtk_wnm_sleep.igtk_len == len &&
529 +            os_memcmp(sm->igtk_wnm_sleep.igtk, igtk->igtk,
530 +                      sm->igtk_wnm_sleep.igtk_len) == 0)) {
531                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
532                         "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)",
533                         keyidx);
534 @@ -900,8 +913,14 @@ static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
535                 return -1;
536         }
537  
538 -       sm->igtk.igtk_len = len;
539 -       os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len);
540 +       if (wnm_sleep) {
541 +               sm->igtk_wnm_sleep.igtk_len = len;
542 +               os_memcpy(sm->igtk_wnm_sleep.igtk, igtk->igtk,
543 +                         sm->igtk_wnm_sleep.igtk_len);
544 +       } else {
545 +               sm->igtk.igtk_len = len;
546 +               os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len);
547 +       }
548  
549         return 0;
550  }
551 @@ -924,7 +943,7 @@ static int ieee80211w_set_keys(struct wpa_sm *sm,
552                         return -1;
553  
554                 igtk = (const struct wpa_igtk_kde *) ie->igtk;
555 -               if (wpa_supplicant_install_igtk(sm, igtk) < 0)
556 +               if (wpa_supplicant_install_igtk(sm, igtk, 0) < 0)
557                         return -1;
558         }
559  
560 @@ -1574,7 +1593,7 @@ static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm,
561         if (wpa_supplicant_rsc_relaxation(sm, key->key_rsc))
562                 key_rsc = null_rsc;
563  
564 -       if (wpa_supplicant_install_gtk(sm, &gd, key_rsc) ||
565 +       if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0) ||
566             wpa_supplicant_send_2_of_2(sm, key, ver, key_info) < 0)
567                 goto failed;
568         os_memset(&gd, 0, sizeof(gd));
569 @@ -2386,8 +2405,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
570                 sm->tptk_set = 0;
571                 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
572                 os_memset(&sm->gtk, 0, sizeof(sm->gtk));
573 +               os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep));
574  #ifdef CONFIG_IEEE80211W
575                 os_memset(&sm->igtk, 0, sizeof(sm->igtk));
576 +               os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep));
577  #endif /* CONFIG_IEEE80211W */
578         }
579  
580 @@ -2920,8 +2941,10 @@ void wpa_sm_drop_sa(struct wpa_sm *sm)
581         os_memset(&sm->ptk, 0, sizeof(sm->ptk));
582         os_memset(&sm->tptk, 0, sizeof(sm->tptk));
583         os_memset(&sm->gtk, 0, sizeof(sm->gtk));
584 +       os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep));
585  #ifdef CONFIG_IEEE80211W
586         os_memset(&sm->igtk, 0, sizeof(sm->igtk));
587 +       os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep));
588  #endif /* CONFIG_IEEE80211W */
589  #ifdef CONFIG_IEEE80211R
590         os_memset(sm->xxkey, 0, sizeof(sm->xxkey));
591 @@ -2986,7 +3009,7 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
592  
593                 wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)",
594                                 gd.gtk, gd.gtk_len);
595 -               if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) {
596 +               if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 1)) {
597                         os_memset(&gd, 0, sizeof(gd));
598                         wpa_printf(MSG_DEBUG, "Failed to install the GTK in "
599                                    "WNM mode");
600 @@ -2998,7 +3021,7 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
601                 const struct wpa_igtk_kde *igtk;
602  
603                 igtk = (const struct wpa_igtk_kde *) (buf + 2);
604 -               if (wpa_supplicant_install_igtk(sm, igtk) < 0)
605 +               if (wpa_supplicant_install_igtk(sm, igtk, 1) < 0)
606                         return -1;
607  #endif /* CONFIG_IEEE80211W */
608         } else {
609 diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
610 index afc9e37..9a54631 100644
611 --- a/src/rsn_supp/wpa_i.h
612 +++ b/src/rsn_supp/wpa_i.h
613 @@ -32,8 +32,10 @@ struct wpa_sm {
614         int rx_replay_counter_set;
615         u8 request_counter[WPA_REPLAY_COUNTER_LEN];
616         struct wpa_gtk gtk;
617 +       struct wpa_gtk gtk_wnm_sleep;
618  #ifdef CONFIG_IEEE80211W
619         struct wpa_igtk igtk;
620 +       struct wpa_igtk igtk_wnm_sleep;
621  #endif /* CONFIG_IEEE80211W */
622  
623         struct eapol_sm *eapol; /* EAPOL state machine from upper level code */
624 -- 
625 2.7.4
626
627 From 8f82bc94e8697a9d47fa8774dfdaaede1084912c Mon Sep 17 00:00:00 2001
628 From: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
629 Date: Fri, 29 Sep 2017 04:22:51 +0200
630 Subject: [PATCH 4/8] Prevent installation of an all-zero TK
631
632 Properly track whether a PTK has already been installed to the driver
633 and the TK part cleared from memory. This prevents an attacker from
634 trying to trick the client into installing an all-zero TK.
635
636 This fixes the earlier fix in commit
637 ad00d64e7d8827b3cebd665a0ceb08adabf15e1e ('Fix TK configuration to the
638 driver in EAPOL-Key 3/4 retry case') which did not take into account
639 possibility of an extra message 1/4 showing up between retries of
640 message 3/4.
641
642 Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
643 ---
644  src/common/wpa_common.h | 1 +
645  src/rsn_supp/wpa.c      | 5 ++---
646  src/rsn_supp/wpa_i.h    | 1 -
647  3 files changed, 3 insertions(+), 4 deletions(-)
648
649 diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
650 index d200285..1021ccb 100644
651 --- a/src/common/wpa_common.h
652 +++ b/src/common/wpa_common.h
653 @@ -215,6 +215,7 @@ struct wpa_ptk {
654         size_t kck_len;
655         size_t kek_len;
656         size_t tk_len;
657 +       int installed; /* 1 if key has already been installed to driver */
658  };
659  
660  struct wpa_gtk {
661 diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
662 index 7a2c68d..0550a41 100644
663 --- a/src/rsn_supp/wpa.c
664 +++ b/src/rsn_supp/wpa.c
665 @@ -510,7 +510,6 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
666                 os_memset(buf, 0, sizeof(buf));
667         }
668         sm->tptk_set = 1;
669 -       sm->tk_to_set = 1;
670  
671         kde = sm->assoc_wpa_ie;
672         kde_len = sm->assoc_wpa_ie_len;
673 @@ -615,7 +614,7 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
674         enum wpa_alg alg;
675         const u8 *key_rsc;
676  
677 -       if (!sm->tk_to_set) {
678 +       if (sm->ptk.installed) {
679                 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
680                         "WPA: Do not re-install same PTK to the driver");
681                 return 0;
682 @@ -659,7 +658,7 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
683  
684         /* TK is not needed anymore in supplicant */
685         os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
686 -       sm->tk_to_set = 0;
687 +       sm->ptk.installed = 1;
688  
689         if (sm->wpa_ptk_rekey) {
690                 eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
691 diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
692 index 9a54631..41f371f 100644
693 --- a/src/rsn_supp/wpa_i.h
694 +++ b/src/rsn_supp/wpa_i.h
695 @@ -24,7 +24,6 @@ struct wpa_sm {
696         struct wpa_ptk ptk, tptk;
697         int ptk_set, tptk_set;
698         unsigned int msg_3_of_4_ok:1;
699 -       unsigned int tk_to_set:1;
700         u8 snonce[WPA_NONCE_LEN];
701         u8 anonce[WPA_NONCE_LEN]; /* ANonce from the last 1/4 msg */
702         int renew_snonce;
703 -- 
704 2.7.4
705
706 From 12fac09b437a1dc8a0f253e265934a8aaf4d2f8b Mon Sep 17 00:00:00 2001
707 From: Jouni Malinen <j@w1.fi>
708 Date: Sun, 1 Oct 2017 12:32:57 +0300
709 Subject: [PATCH 5/8] Fix PTK rekeying to generate a new ANonce
710
711 The Authenticator state machine path for PTK rekeying ended up bypassing
712 the AUTHENTICATION2 state where a new ANonce is generated when going
713 directly to the PTKSTART state since there is no need to try to
714 determine the PMK again in such a case. This is far from ideal since the
715 new PTK would depend on a new nonce only from the supplicant.
716
717 Fix this by generating a new ANonce when moving to the PTKSTART state
718 for the purpose of starting new 4-way handshake to rekey PTK.
719
720 Signed-off-by: Jouni Malinen <j@w1.fi>
721 ---
722  src/ap/wpa_auth.c | 24 +++++++++++++++++++++---
723  1 file changed, 21 insertions(+), 3 deletions(-)
724
725 diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
726 index 707971d..bf10cc1 100644
727 --- a/src/ap/wpa_auth.c
728 +++ b/src/ap/wpa_auth.c
729 @@ -1901,6 +1901,21 @@ SM_STATE(WPA_PTK, AUTHENTICATION2)
730  }
731  
732  
733 +static int wpa_auth_sm_ptk_update(struct wpa_state_machine *sm)
734 +{
735 +       if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
736 +               wpa_printf(MSG_ERROR,
737 +                          "WPA: Failed to get random data for ANonce");
738 +               sm->Disconnect = TRUE;
739 +               return -1;
740 +       }
741 +       wpa_hexdump(MSG_DEBUG, "WPA: Assign new ANonce", sm->ANonce,
742 +                   WPA_NONCE_LEN);
743 +       sm->TimeoutCtr = 0;
744 +       return 0;
745 +}
746 +
747 +
748  SM_STATE(WPA_PTK, INITPMK)
749  {
750         u8 msk[2 * PMK_LEN];
751 @@ -2458,9 +2473,12 @@ SM_STEP(WPA_PTK)
752                 SM_ENTER(WPA_PTK, AUTHENTICATION);
753         else if (sm->ReAuthenticationRequest)
754                 SM_ENTER(WPA_PTK, AUTHENTICATION2);
755 -       else if (sm->PTKRequest)
756 -               SM_ENTER(WPA_PTK, PTKSTART);
757 -       else switch (sm->wpa_ptk_state) {
758 +       else if (sm->PTKRequest) {
759 +               if (wpa_auth_sm_ptk_update(sm) < 0)
760 +                       SM_ENTER(WPA_PTK, DISCONNECTED);
761 +               else
762 +                       SM_ENTER(WPA_PTK, PTKSTART);
763 +       } else switch (sm->wpa_ptk_state) {
764         case WPA_PTK_INITIALIZE:
765                 break;
766         case WPA_PTK_DISCONNECT:
767 -- 
768 2.7.4
769
770 From 6c4bed4f47d1960ec04981a9d50e5076aea5223d Mon Sep 17 00:00:00 2001
771 From: Jouni Malinen <j@w1.fi>
772 Date: Fri, 22 Sep 2017 11:03:15 +0300
773 Subject: [PATCH 6/8] TDLS: Reject TPK-TK reconfiguration
774
775 Do not try to reconfigure the same TPK-TK to the driver after it has
776 been successfully configured. This is an explicit check to avoid issues
777 related to resetting the TX/RX packet number. There was already a check
778 for this for TPK M2 (retries of that message are ignored completely), so
779 that behavior does not get modified.
780
781 For TPK M3, the TPK-TK could have been reconfigured, but that was
782 followed by immediate teardown of the link due to an issue in updating
783 the STA entry. Furthermore, for TDLS with any real security (i.e.,
784 ignoring open/WEP), the TPK message exchange is protected on the AP path
785 and simple replay attacks are not feasible.
786
787 As an additional corner case, make sure the local nonce gets updated if
788 the peer uses a very unlikely "random nonce" of all zeros.
789
790 Signed-off-by: Jouni Malinen <j@w1.fi>
791 ---
792  src/rsn_supp/tdls.c | 38 ++++++++++++++++++++++++++++++++++++--
793  1 file changed, 36 insertions(+), 2 deletions(-)
794
795 diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
796 index e424168..9eb9738 100644
797 --- a/src/rsn_supp/tdls.c
798 +++ b/src/rsn_supp/tdls.c
799 @@ -112,6 +112,7 @@ struct wpa_tdls_peer {
800                 u8 tk[16]; /* TPK-TK; assuming only CCMP will be used */
801         } tpk;
802         int tpk_set;
803 +       int tk_set; /* TPK-TK configured to the driver */
804         int tpk_success;
805         int tpk_in_progress;
806  
807 @@ -192,6 +193,20 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
808         u8 rsc[6];
809         enum wpa_alg alg;
810  
811 +       if (peer->tk_set) {
812 +               /*
813 +                * This same TPK-TK has already been configured to the driver
814 +                * and this new configuration attempt (likely due to an
815 +                * unexpected retransmitted frame) would result in clearing
816 +                * the TX/RX sequence number which can break security, so must
817 +                * not allow that to happen.
818 +                */
819 +               wpa_printf(MSG_INFO, "TDLS: TPK-TK for the peer " MACSTR
820 +                          " has already been configured to the driver - do not reconfigure",
821 +                          MAC2STR(peer->addr));
822 +               return -1;
823 +       }
824 +
825         os_memset(rsc, 0, 6);
826  
827         switch (peer->cipher) {
828 @@ -209,12 +224,15 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
829                 return -1;
830         }
831  
832 +       wpa_printf(MSG_DEBUG, "TDLS: Configure pairwise key for peer " MACSTR,
833 +                  MAC2STR(peer->addr));
834         if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1,
835                            rsc, sizeof(rsc), peer->tpk.tk, key_len) < 0) {
836                 wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the "
837                            "driver");
838                 return -1;
839         }
840 +       peer->tk_set = 1;
841         return 0;
842  }
843  
844 @@ -696,7 +714,7 @@ static void wpa_tdls_peer_clear(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
845         peer->cipher = 0;
846         peer->qos_info = 0;
847         peer->wmm_capable = 0;
848 -       peer->tpk_set = peer->tpk_success = 0;
849 +       peer->tk_set = peer->tpk_set = peer->tpk_success = 0;
850         peer->chan_switch_enabled = 0;
851         os_memset(&peer->tpk, 0, sizeof(peer->tpk));
852         os_memset(peer->inonce, 0, WPA_NONCE_LEN);
853 @@ -1159,6 +1177,7 @@ skip_rsnie:
854                 wpa_tdls_peer_free(sm, peer);
855                 return -1;
856         }
857 +       peer->tk_set = 0; /* A new nonce results in a new TK */
858         wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake",
859                     peer->inonce, WPA_NONCE_LEN);
860         os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
861 @@ -1751,6 +1770,19 @@ static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer,
862  }
863  
864  
865 +static int tdls_nonce_set(const u8 *nonce)
866 +{
867 +       int i;
868 +
869 +       for (i = 0; i < WPA_NONCE_LEN; i++) {
870 +               if (nonce[i])
871 +                       return 1;
872 +       }
873 +
874 +       return 0;
875 +}
876 +
877 +
878  static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
879                                    const u8 *buf, size_t len)
880  {
881 @@ -2004,7 +2036,8 @@ skip_rsn:
882         peer->rsnie_i_len = kde.rsn_ie_len;
883         peer->cipher = cipher;
884  
885 -       if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0) {
886 +       if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0 ||
887 +           !tdls_nonce_set(peer->inonce)) {
888                 /*
889                  * There is no point in updating the RNonce for every obtained
890                  * TPK M1 frame (e.g., retransmission due to timeout) with the
891 @@ -2020,6 +2053,7 @@ skip_rsn:
892                                 "TDLS: Failed to get random data for responder nonce");
893                         goto error;
894                 }
895 +               peer->tk_set = 0; /* A new nonce results in a new TK */
896         }
897  
898  #if 0
899 -- 
900 2.7.4
901
902 From 53c5eb58e95004f86e65ee9fbfccbc291b139057 Mon Sep 17 00:00:00 2001
903 From: Jouni Malinen <j@w1.fi>
904 Date: Fri, 22 Sep 2017 11:25:02 +0300
905 Subject: [PATCH 7/8] WNM: Ignore WNM-Sleep Mode Response without pending
906  request
907
908 Commit 03ed0a52393710be6bdae657d1b36efa146520e5 ('WNM: Ignore WNM-Sleep
909 Mode Response if WNM-Sleep Mode has not been used') started ignoring the
910 response when no WNM-Sleep Mode Request had been used during the
911 association. This can be made tighter by clearing the used flag when
912 successfully processing a response. This adds an additional layer of
913 protection against unexpected retransmissions of the response frame.
914
915 Signed-off-by: Jouni Malinen <j@w1.fi>
916 ---
917  wpa_supplicant/wnm_sta.c | 4 +++-
918  1 file changed, 3 insertions(+), 1 deletion(-)
919
920 diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
921 index 1b3409c..67a07ff 100644
922 --- a/wpa_supplicant/wnm_sta.c
923 +++ b/wpa_supplicant/wnm_sta.c
924 @@ -260,7 +260,7 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s,
925  
926         if (!wpa_s->wnmsleep_used) {
927                 wpa_printf(MSG_DEBUG,
928 -                          "WNM: Ignore WNM-Sleep Mode Response frame since WNM-Sleep Mode has not been used in this association");
929 +                          "WNM: Ignore WNM-Sleep Mode Response frame since WNM-Sleep Mode operation has not been requested");
930                 return;
931         }
932  
933 @@ -299,6 +299,8 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s,
934                 return;
935         }
936  
937 +       wpa_s->wnmsleep_used = 0;
938 +
939         if (wnmsleep_ie->status == WNM_STATUS_SLEEP_ACCEPT ||
940             wnmsleep_ie->status == WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE) {
941                 wpa_printf(MSG_DEBUG, "Successfully recv WNM-Sleep Response "
942 -- 
943 2.7.4
944
945 From b372ab0b7daea719749194dc554b26e6367603f2 Mon Sep 17 00:00:00 2001
946 From: Jouni Malinen <j@w1.fi>
947 Date: Fri, 22 Sep 2017 12:06:37 +0300
948 Subject: [PATCH 8/8] FT: Do not allow multiple Reassociation Response frames
949
950 The driver is expected to not report a second association event without
951 the station having explicitly request a new association. As such, this
952 case should not be reachable. However, since reconfiguring the same
953 pairwise or group keys to the driver could result in nonce reuse issues,
954 be extra careful here and do an additional state check to avoid this
955 even if the local driver ends up somehow accepting an unexpected
956 Reassociation Response frame.
957
958 Signed-off-by: Jouni Malinen <j@w1.fi>
959 ---
960  src/rsn_supp/wpa.c    | 3 +++
961  src/rsn_supp/wpa_ft.c | 8 ++++++++
962  src/rsn_supp/wpa_i.h  | 1 +
963  3 files changed, 12 insertions(+)
964
965 diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
966 index 0550a41..2a53c6f 100644
967 --- a/src/rsn_supp/wpa.c
968 +++ b/src/rsn_supp/wpa.c
969 @@ -2440,6 +2440,9 @@ void wpa_sm_notify_disassoc(struct wpa_sm *sm)
970  #ifdef CONFIG_TDLS
971         wpa_tdls_disassoc(sm);
972  #endif /* CONFIG_TDLS */
973 +#ifdef CONFIG_IEEE80211R
974 +       sm->ft_reassoc_completed = 0;
975 +#endif /* CONFIG_IEEE80211R */
976  
977         /* Keys are not needed in the WPA state machine anymore */
978         wpa_sm_drop_sa(sm);
979 diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c
980 index 205793e..d45bb45 100644
981 --- a/src/rsn_supp/wpa_ft.c
982 +++ b/src/rsn_supp/wpa_ft.c
983 @@ -153,6 +153,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
984         u16 capab;
985  
986         sm->ft_completed = 0;
987 +       sm->ft_reassoc_completed = 0;
988  
989         buf_len = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +
990                 2 + sm->r0kh_id_len + ric_ies_len + 100;
991 @@ -681,6 +682,11 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
992                 return -1;
993         }
994  
995 +       if (sm->ft_reassoc_completed) {
996 +               wpa_printf(MSG_DEBUG, "FT: Reassociation has already been completed for this FT protocol instance - ignore unexpected retransmission");
997 +               return 0;
998 +       }
999 +
1000         if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) {
1001                 wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs");
1002                 return -1;
1003 @@ -781,6 +787,8 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
1004                 return -1;
1005         }
1006  
1007 +       sm->ft_reassoc_completed = 1;
1008 +
1009         if (wpa_ft_process_gtk_subelem(sm, parse.gtk, parse.gtk_len) < 0)
1010                 return -1;
1011  
1012 diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
1013 index 41f371f..56f88dc 100644
1014 --- a/src/rsn_supp/wpa_i.h
1015 +++ b/src/rsn_supp/wpa_i.h
1016 @@ -128,6 +128,7 @@ struct wpa_sm {
1017         size_t r0kh_id_len;
1018         u8 r1kh_id[FT_R1KH_ID_LEN];
1019         int ft_completed;
1020 +       int ft_reassoc_completed;
1021         int over_the_ds_in_progress;
1022         u8 target_ap[ETH_ALEN]; /* over-the-DS target AP */
1023         int set_ptk_after_assoc;
1024 -- 
1025 2.7.4