/[pkg-src]/trunk/wpa_supplicant/patches/0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch |
Contents of /trunk/wpa_supplicant/patches/0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch
Parent Directory | Revision Log
Revision 2999 -
(show annotations)
(download)
Tue Oct 17 10:55:21 2017 UTC (6 years, 11 months ago) by niro
File size: 7883 byte(s)
Tue Oct 17 10:55:21 2017 UTC (6 years, 11 months ago) by niro
File size: 7883 byte(s)
-krackattack patches
1 | From 927f891007c402fefd1ff384645b3f07597c3ede Mon Sep 17 00:00:00 2001 |
2 | From: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be> |
3 | Date: Wed, 12 Jul 2017 16:03:24 +0200 |
4 | Subject: [PATCH 2/8] Prevent reinstallation of an already in-use group key |
5 | |
6 | Track 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 |
8 | not install the given key if it is already in use. This prevents an |
9 | attacker from trying to trick the client into resetting or lowering the |
10 | sequence counter associated to the group key. |
11 | |
12 | Signed-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 | |
19 | diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h |
20 | index 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) |
41 | diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c |
42 | index 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"); |
233 | diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h |
234 | index 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 | -- |
249 | 2.7.4 |
250 |