/[pkg-src]/trunk/wpa_supplicant/patches/0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch |
Annotation of /trunk/wpa_supplicant/patches/0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch
Parent Directory | Revision Log
Revision 2999 -
(hide 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 | niro | 2999 | 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 |