]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/wpa_supplicant/0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch
netsnmp: Fix rootfile to build on other architectures
[people/pmueller/ipfire-2.x.git] / src / patches / wpa_supplicant / 0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch
CommitLineData
d7d57745
MT
1From cf62cadcadc68377d72e2238a0f06b21c0777f90 Mon Sep 17 00:00:00 2001
2From: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
3Date: Wed, 12 Jul 2017 16:03:24 +0200
4Subject: [PATCH 2/8] Prevent reinstallation of an already in-use group key
5
6Track the current GTK and IGTK that is in use and when receiving a
7(possibly retransmitted) Group Message 1 or WNM-Sleep Mode Response, do
8not install the given key if it is already in use. This prevents an
9attacker from trying to trick the client into resetting or lowering the
10sequence counter associated to the group key.
11
12Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
13---
14 src/common/wpa_common.h | 11 +++++
15 src/rsn_supp/wpa.c | 118 ++++++++++++++++++++++++++++++------------------
16 src/rsn_supp/wpa_i.h | 4 ++
17 3 files changed, 88 insertions(+), 45 deletions(-)
18
19diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
20index cc8edf8..0872b12 100644
21--- a/src/common/wpa_common.h
22+++ b/src/common/wpa_common.h
23@@ -221,6 +221,17 @@ struct wpa_ptk {
24 size_t tk_len;
25 };
26
27+struct wpa_gtk {
28+ u8 gtk[WPA_GTK_MAX_LEN];
29+ size_t gtk_len;
30+};
31+
32+#ifdef CONFIG_IEEE80211W
33+struct wpa_igtk {
34+ u8 igtk[WPA_IGTK_MAX_LEN];
35+ size_t igtk_len;
36+};
37+#endif /* CONFIG_IEEE80211W */
38
39 /* WPA IE version 1
40 * 00-50-f2:1 (OUI:OUI type)
41diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
42index 739689d..5e5fb2a 100644
43--- a/src/rsn_supp/wpa.c
44+++ b/src/rsn_supp/wpa.c
45@@ -800,6 +800,15 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
46 const u8 *_gtk = gd->gtk;
47 u8 gtk_buf[32];
48
49+ /* Detect possible key reinstallation */
50+ if (sm->gtk.gtk_len == (size_t) gd->gtk_len &&
51+ os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) {
52+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
53+ "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)",
54+ gd->keyidx, gd->tx, gd->gtk_len);
55+ return 0;
56+ }
57+
58 wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
59 wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
60 "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)",
61@@ -834,6 +843,9 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm,
62 }
63 os_memset(gtk_buf, 0, sizeof(gtk_buf));
64
65+ sm->gtk.gtk_len = gd->gtk_len;
66+ os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len);
67+
68 return 0;
69 }
70
71@@ -940,6 +952,48 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
72 }
73
74
75+#ifdef CONFIG_IEEE80211W
76+static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
77+ const struct wpa_igtk_kde *igtk)
78+{
79+ size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher);
80+ u16 keyidx = WPA_GET_LE16(igtk->keyid);
81+
82+ /* Detect possible key reinstallation */
83+ if (sm->igtk.igtk_len == len &&
84+ os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) {
85+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
86+ "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)",
87+ keyidx);
88+ return 0;
89+ }
90+
91+ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
92+ "WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x",
93+ keyidx, MAC2STR(igtk->pn));
94+ wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len);
95+ if (keyidx > 4095) {
96+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
97+ "WPA: Invalid IGTK KeyID %d", keyidx);
98+ return -1;
99+ }
100+ if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
101+ broadcast_ether_addr,
102+ keyidx, 0, igtk->pn, sizeof(igtk->pn),
103+ igtk->igtk, len) < 0) {
104+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
105+ "WPA: Failed to configure IGTK to the driver");
106+ return -1;
107+ }
108+
109+ sm->igtk.igtk_len = len;
110+ os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len);
111+
112+ return 0;
113+}
114+#endif /* CONFIG_IEEE80211W */
115+
116+
117 static int ieee80211w_set_keys(struct wpa_sm *sm,
118 struct wpa_eapol_ie_parse *ie)
119 {
120@@ -950,30 +1004,14 @@ static int ieee80211w_set_keys(struct wpa_sm *sm,
121 if (ie->igtk) {
122 size_t len;
123 const struct wpa_igtk_kde *igtk;
124- u16 keyidx;
125+
126 len = wpa_cipher_key_len(sm->mgmt_group_cipher);
127 if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len)
128 return -1;
129+
130 igtk = (const struct wpa_igtk_kde *) ie->igtk;
131- keyidx = WPA_GET_LE16(igtk->keyid);
132- wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d "
133- "pn %02x%02x%02x%02x%02x%02x",
134- keyidx, MAC2STR(igtk->pn));
135- wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK",
136- igtk->igtk, len);
137- if (keyidx > 4095) {
138- wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
139- "WPA: Invalid IGTK KeyID %d", keyidx);
140- return -1;
141- }
142- if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
143- broadcast_ether_addr,
144- keyidx, 0, igtk->pn, sizeof(igtk->pn),
145- igtk->igtk, len) < 0) {
146- wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
147- "WPA: Failed to configure IGTK to the driver");
148+ if (wpa_supplicant_install_igtk(sm, igtk) < 0)
149 return -1;
150- }
151 }
152
153 return 0;
154@@ -2491,7 +2529,7 @@ void wpa_sm_deinit(struct wpa_sm *sm)
155 */
156 void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
157 {
158- int clear_ptk = 1;
159+ int clear_keys = 1;
160
161 if (sm == NULL)
162 return;
163@@ -2517,7 +2555,7 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
164 /* Prepare for the next transition */
165 wpa_ft_prepare_auth_request(sm, NULL);
166
167- clear_ptk = 0;
168+ clear_keys = 0;
169 }
170 #endif /* CONFIG_IEEE80211R */
171 #ifdef CONFIG_FILS
172@@ -2527,11 +2565,11 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
173 * AUTHENTICATED state to get the EAPOL port Authorized.
174 */
175 wpa_supplicant_key_neg_complete(sm, sm->bssid, 1);
176- clear_ptk = 0;
177+ clear_keys = 0;
178 }
179 #endif /* CONFIG_FILS */
180
181- if (clear_ptk) {
182+ if (clear_keys) {
183 /*
184 * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if
185 * this is not part of a Fast BSS Transition.
186@@ -2541,6 +2579,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
187 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
188 sm->tptk_set = 0;
189 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
190+ os_memset(&sm->gtk, 0, sizeof(sm->gtk));
191+#ifdef CONFIG_IEEE80211W
192+ os_memset(&sm->igtk, 0, sizeof(sm->igtk));
193+#endif /* CONFIG_IEEE80211W */
194 }
195
196 #ifdef CONFIG_TDLS
197@@ -3117,6 +3159,10 @@ void wpa_sm_drop_sa(struct wpa_sm *sm)
198 os_memset(sm->pmk, 0, sizeof(sm->pmk));
199 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
200 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
201+ os_memset(&sm->gtk, 0, sizeof(sm->gtk));
202+#ifdef CONFIG_IEEE80211W
203+ os_memset(&sm->igtk, 0, sizeof(sm->igtk));
204+#endif /* CONFIG_IEEE80211W */
205 #ifdef CONFIG_IEEE80211R
206 os_memset(sm->xxkey, 0, sizeof(sm->xxkey));
207 os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0));
208@@ -3189,29 +3235,11 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
209 os_memset(&gd, 0, sizeof(gd));
210 #ifdef CONFIG_IEEE80211W
211 } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
212- struct wpa_igtk_kde igd;
213- u16 keyidx;
214-
215- os_memset(&igd, 0, sizeof(igd));
216- keylen = wpa_cipher_key_len(sm->mgmt_group_cipher);
217- os_memcpy(igd.keyid, buf + 2, 2);
218- os_memcpy(igd.pn, buf + 4, 6);
219-
220- keyidx = WPA_GET_LE16(igd.keyid);
221- os_memcpy(igd.igtk, buf + 10, keylen);
222-
223- wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)",
224- igd.igtk, keylen);
225- if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
226- broadcast_ether_addr,
227- keyidx, 0, igd.pn, sizeof(igd.pn),
228- igd.igtk, keylen) < 0) {
229- wpa_printf(MSG_DEBUG, "Failed to install the IGTK in "
230- "WNM mode");
231- os_memset(&igd, 0, sizeof(igd));
232+ const struct wpa_igtk_kde *igtk;
233+
234+ igtk = (const struct wpa_igtk_kde *) (buf + 2);
235+ if (wpa_supplicant_install_igtk(sm, igtk) < 0)
236 return -1;
237- }
238- os_memset(&igd, 0, sizeof(igd));
239 #endif /* CONFIG_IEEE80211W */
240 } else {
241 wpa_printf(MSG_DEBUG, "Unknown element id");
242diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
243index 82e1941..2827ed6 100644
244--- a/src/rsn_supp/wpa_i.h
245+++ b/src/rsn_supp/wpa_i.h
246@@ -31,6 +31,10 @@ struct wpa_sm {
247 u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN];
248 int rx_replay_counter_set;
249 u8 request_counter[WPA_REPLAY_COUNTER_LEN];
250+ struct wpa_gtk gtk;
251+#ifdef CONFIG_IEEE80211W
252+ struct wpa_igtk igtk;
253+#endif /* CONFIG_IEEE80211W */
254
255 struct eapol_sm *eapol; /* EAPOL state machine from upper level code */
256
257--
2582.7.4
259