]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/wpa_supplicant/rebased-v2.6-0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch
netsnmp: Fix rootfile to build on other architectures
[ipfire-2.x.git] / src / patches / wpa_supplicant / rebased-v2.6-0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch
CommitLineData
d7d57745
MT
1From 927f891007c402fefd1ff384645b3f07597c3ede 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 | 116 ++++++++++++++++++++++++++++++------------------
16 src/rsn_supp/wpa_i.h | 4 ++
17 3 files changed, 87 insertions(+), 44 deletions(-)
18
19diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
20index af1d0f0..d200285 100644
21--- a/src/common/wpa_common.h
22+++ b/src/common/wpa_common.h
23@@ -217,6 +217,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 3c47879..95bd7be 100644
43--- a/src/rsn_supp/wpa.c
44+++ b/src/rsn_supp/wpa.c
45@@ -714,6 +714,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@@ -748,6 +757,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@@ -854,6 +866,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@@ -864,30 +918,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@@ -2307,7 +2345,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@@ -2333,11 +2371,11 @@ 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
172- if (clear_ptk) {
173+ if (clear_keys) {
174 /*
175 * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if
176 * this is not part of a Fast BSS Transition.
177@@ -2347,6 +2385,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid)
178 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
179 sm->tptk_set = 0;
180 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
181+ os_memset(&sm->gtk, 0, sizeof(sm->gtk));
182+#ifdef CONFIG_IEEE80211W
183+ os_memset(&sm->igtk, 0, sizeof(sm->igtk));
184+#endif /* CONFIG_IEEE80211W */
185 }
186
187 #ifdef CONFIG_TDLS
188@@ -2877,6 +2919,10 @@ void wpa_sm_drop_sa(struct wpa_sm *sm)
189 os_memset(sm->pmk, 0, sizeof(sm->pmk));
190 os_memset(&sm->ptk, 0, sizeof(sm->ptk));
191 os_memset(&sm->tptk, 0, sizeof(sm->tptk));
192+ os_memset(&sm->gtk, 0, sizeof(sm->gtk));
193+#ifdef CONFIG_IEEE80211W
194+ os_memset(&sm->igtk, 0, sizeof(sm->igtk));
195+#endif /* CONFIG_IEEE80211W */
196 #ifdef CONFIG_IEEE80211R
197 os_memset(sm->xxkey, 0, sizeof(sm->xxkey));
198 os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0));
199@@ -2949,29 +2995,11 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
200 os_memset(&gd, 0, sizeof(gd));
201 #ifdef CONFIG_IEEE80211W
202 } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) {
203- struct wpa_igtk_kde igd;
204- u16 keyidx;
205-
206- os_memset(&igd, 0, sizeof(igd));
207- keylen = wpa_cipher_key_len(sm->mgmt_group_cipher);
208- os_memcpy(igd.keyid, buf + 2, 2);
209- os_memcpy(igd.pn, buf + 4, 6);
210-
211- keyidx = WPA_GET_LE16(igd.keyid);
212- os_memcpy(igd.igtk, buf + 10, keylen);
213-
214- wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)",
215- igd.igtk, keylen);
216- if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher),
217- broadcast_ether_addr,
218- keyidx, 0, igd.pn, sizeof(igd.pn),
219- igd.igtk, keylen) < 0) {
220- wpa_printf(MSG_DEBUG, "Failed to install the IGTK in "
221- "WNM mode");
222- os_memset(&igd, 0, sizeof(igd));
223+ const struct wpa_igtk_kde *igtk;
224+
225+ igtk = (const struct wpa_igtk_kde *) (buf + 2);
226+ if (wpa_supplicant_install_igtk(sm, igtk) < 0)
227 return -1;
228- }
229- os_memset(&igd, 0, sizeof(igd));
230 #endif /* CONFIG_IEEE80211W */
231 } else {
232 wpa_printf(MSG_DEBUG, "Unknown element id");
233diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
234index f653ba6..afc9e37 100644
235--- a/src/rsn_supp/wpa_i.h
236+++ b/src/rsn_supp/wpa_i.h
237@@ -31,6 +31,10 @@ struct wpa_sm {
238 u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN];
239 int rx_replay_counter_set;
240 u8 request_counter[WPA_REPLAY_COUNTER_LEN];
241+ struct wpa_gtk gtk;
242+#ifdef CONFIG_IEEE80211W
243+ struct wpa_igtk igtk;
244+#endif /* CONFIG_IEEE80211W */
245
246 struct eapol_sm *eapol; /* EAPOL state machine from upper level code */
247
248--
2492.7.4
250