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