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