Bump version to v1.5 and start work on adding 4.19 kernel suppot
[librecmc/librecmc.git] / package / network / services / hostapd / patches / 013-Add-hostapd-options-wpa_group_update_count-and-wpa_p.patch
1 From 41f140d38617e1fd3fa88c1667c1bce0cad79224 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?G=C3=BCnther=20Kelleter?= <guenther.kelleter@devolo.de>
3 Date: Thu, 5 Jan 2017 17:00:33 +0100
4 Subject: [PATCH] Add hostapd options wpa_group_update_count and
5  wpa_pairwise_update_count
6 MIME-Version: 1.0
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
9
10 wpa_group_update_count and wpa_pairwise_update_count can now be used to
11 set the GTK and PTK rekey retry limits (dot11RSNAConfigGroupUpdateCount
12 and dot11RSNAConfigPairwiseUpdateCount). Defaults set to current
13 hardcoded value (4).
14
15 Some stations may suffer from frequent deauthentications due to GTK
16 rekey failures: EAPOL 1/2 frame is not answered during the total timeout
17 period of currently ~3.5 seconds. For example, a Galaxy S6 with Android
18 6.0.1 appears to go into power save mode for up to 5 seconds. Increasing
19 wpa_group_update_count to 6 fixed this issue.
20
21 Signed-off-by: Günther Kelleter <guenther.kelleter@devolo.de>
22 ---
23  hostapd/config_file.c     | 22 ++++++++++++++++++++++
24  hostapd/hostapd.conf      | 11 +++++++++++
25  src/ap/ap_config.c        |  2 ++
26  src/ap/ap_config.h        |  2 ++
27  src/ap/wpa_auth.c         | 37 ++++++++++++++++++-------------------
28  src/ap/wpa_auth.h         |  2 ++
29  src/ap/wpa_auth_glue.c    |  2 ++
30  src/ap/wpa_auth_i.h       |  4 ++--
31  wpa_supplicant/ibss_rsn.c |  2 ++
32  wpa_supplicant/mesh_rsn.c |  2 ++
33  10 files changed, 65 insertions(+), 21 deletions(-)
34
35 diff --git a/hostapd/config_file.c b/hostapd/config_file.c
36 index 8cfa198c3..02693a5b1 100644
37 --- a/hostapd/config_file.c
38 +++ b/hostapd/config_file.c
39 @@ -2489,6 +2489,28 @@ static int hostapd_config_fill(struct hostapd_config *conf,
40                 bss->wpa_gmk_rekey = atoi(pos);
41         } else if (os_strcmp(buf, "wpa_ptk_rekey") == 0) {
42                 bss->wpa_ptk_rekey = atoi(pos);
43 +       } else if (os_strcmp(buf, "wpa_group_update_count") == 0) {
44 +               char *endp;
45 +               unsigned long val = strtoul(pos, &endp, 0);
46 +
47 +               if (*endp || val < 1 || val > (u32) -1) {
48 +                       wpa_printf(MSG_ERROR,
49 +                                  "Line %d: Invalid wpa_group_update_count=%lu; allowed range 1..4294967295",
50 +                                  line, val);
51 +                       return 1;
52 +               }
53 +               bss->wpa_group_update_count = (u32) val;
54 +       } else if (os_strcmp(buf, "wpa_pairwise_update_count") == 0) {
55 +               char *endp;
56 +               unsigned long val = strtoul(pos, &endp, 0);
57 +
58 +               if (*endp || val < 1 || val > (u32) -1) {
59 +                       wpa_printf(MSG_ERROR,
60 +                                  "Line %d: Invalid wpa_pairwise_update_count=%lu; allowed range 1..4294967295",
61 +                                  line, val);
62 +                       return 1;
63 +               }
64 +               bss->wpa_pairwise_update_count = (u32) val;
65         } else if (os_strcmp(buf, "wpa_passphrase") == 0) {
66                 int len = os_strlen(pos);
67                 if (len < 8 || len > 63) {
68 diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
69 index 314f3842b..1fb1bd987 100644
70 --- a/hostapd/hostapd.conf
71 +++ b/hostapd/hostapd.conf
72 @@ -1221,6 +1221,11 @@ own_ip_addr=127.0.0.1
73  # (dot11RSNAConfigGroupRekeyStrict)
74  #wpa_strict_rekey=1
75  
76 +# The number of times EAPOL-Key Message 1/2 in the RSN Group Key Handshake is
77 +#retried per GTK Handshake attempt. (dot11RSNAConfigGroupUpdateCount)
78 +# Range 1..4294967295; default: 4
79 +#wpa_group_update_count=4
80 +
81  # Time interval for rekeying GMK (master key used internally to generate GTKs
82  # (in seconds).
83  #wpa_gmk_rekey=86400
84 @@ -1229,6 +1234,12 @@ own_ip_addr=127.0.0.1
85  # PTK to mitigate some attacks against TKIP deficiencies.
86  #wpa_ptk_rekey=600
87  
88 +# The number of times EAPOL-Key Message 1/4 and Message 3/4 in the RSN 4-Way
89 +# Handshake are retried per 4-Way Handshake attempt.
90 +# (dot11RSNAConfigPairwiseUpdateCount)
91 +# Range 1..4294967295; default: 4
92 +#wpa_pairwise_update_count=4
93 +
94  # Enable IEEE 802.11i/RSN/WPA2 pre-authentication. This is used to speed up
95  # roaming be pre-authenticating IEEE 802.1X/EAP part of the full RSN
96  # authentication and key handshake before actually associating with a new AP.
97 diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
98 index c2b80ad97..9abcab7fb 100644
99 --- a/src/ap/ap_config.c
100 +++ b/src/ap/ap_config.c
101 @@ -56,6 +56,8 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
102  
103         bss->wpa_group_rekey = 600;
104         bss->wpa_gmk_rekey = 86400;
105 +       bss->wpa_group_update_count = 4;
106 +       bss->wpa_pairwise_update_count = 4;
107         bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
108         bss->wpa_pairwise = WPA_CIPHER_TKIP;
109         bss->wpa_group = WPA_CIPHER_TKIP;
110 diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
111 index 31b1e7762..7495dc96f 100644
112 --- a/src/ap/ap_config.h
113 +++ b/src/ap/ap_config.h
114 @@ -330,6 +330,8 @@ struct hostapd_bss_config {
115         int wpa_strict_rekey;
116         int wpa_gmk_rekey;
117         int wpa_ptk_rekey;
118 +       u32 wpa_group_update_count;
119 +       u32 wpa_pairwise_update_count;
120         int rsn_pairwise;
121         int rsn_preauth;
122         char *rsn_preauth_interfaces;
123 diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
124 index 0bd901fbf..8c082f426 100644
125 --- a/src/ap/wpa_auth.c
126 +++ b/src/ap/wpa_auth.c
127 @@ -60,8 +60,6 @@ static void wpa_group_put(struct wpa_authenticator *wpa_auth,
128                           struct wpa_group *group);
129  static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos);
130  
131 -static const u32 dot11RSNAConfigGroupUpdateCount = 4;
132 -static const u32 dot11RSNAConfigPairwiseUpdateCount = 4;
133  static const u32 eapol_key_timeout_first = 100; /* ms */
134  static const u32 eapol_key_timeout_subseq = 1000; /* ms */
135  static const u32 eapol_key_timeout_first_group = 500; /* ms */
136 @@ -1623,7 +1621,7 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
137  {
138         int timeout_ms;
139         int pairwise = key_info & WPA_KEY_INFO_KEY_TYPE;
140 -       int ctr;
141 +       u32 ctr;
142  
143         if (sm == NULL)
144                 return;
145 @@ -1640,7 +1638,7 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
146         if (pairwise && ctr == 1 && !(key_info & WPA_KEY_INFO_MIC))
147                 sm->pending_1_of_4_timeout = 1;
148         wpa_printf(MSG_DEBUG, "WPA: Use EAPOL-Key timeout of %u ms (retry "
149 -                  "counter %d)", timeout_ms, ctr);
150 +                  "counter %u)", timeout_ms, ctr);
151         eloop_register_timeout(timeout_ms / 1000, (timeout_ms % 1000) * 1000,
152                                wpa_send_eapol_timeout, wpa_auth, sm);
153  }
154 @@ -2002,7 +2000,7 @@ SM_STATE(WPA_PTK, PTKSTART)
155         sm->alt_snonce_valid = FALSE;
156  
157         sm->TimeoutCtr++;
158 -       if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) {
159 +       if (sm->TimeoutCtr > sm->wpa_auth->conf.wpa_pairwise_update_count) {
160                 /* No point in sending the EAPOL-Key - we will disconnect
161                  * immediately following this. */
162                 return;
163 @@ -2693,7 +2691,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
164         sm->TimeoutEvt = FALSE;
165  
166         sm->TimeoutCtr++;
167 -       if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) {
168 +       if (sm->TimeoutCtr > sm->wpa_auth->conf.wpa_pairwise_update_count) {
169                 /* No point in sending the EAPOL-Key - we will disconnect
170                  * immediately following this. */
171                 return;
172 @@ -2988,11 +2986,12 @@ SM_STEP(WPA_PTK)
173                     sm->EAPOLKeyPairwise)
174                         SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING);
175                 else if (sm->TimeoutCtr >
176 -                        (int) dot11RSNAConfigPairwiseUpdateCount) {
177 +                        sm->wpa_auth->conf.wpa_pairwise_update_count) {
178                         wpa_auth->dot11RSNA4WayHandshakeFailures++;
179 -                       wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
180 -                                        "PTKSTART: Retry limit %d reached",
181 -                                        dot11RSNAConfigPairwiseUpdateCount);
182 +                       wpa_auth_vlogger(
183 +                               sm->wpa_auth, sm->addr, LOGGER_DEBUG,
184 +                               "PTKSTART: Retry limit %u reached",
185 +                               sm->wpa_auth->conf.wpa_pairwise_update_count);
186                         SM_ENTER(WPA_PTK, DISCONNECT);
187                 } else if (sm->TimeoutEvt)
188                         SM_ENTER(WPA_PTK, PTKSTART);
189 @@ -3016,12 +3015,12 @@ SM_STEP(WPA_PTK)
190                          sm->EAPOLKeyPairwise && sm->MICVerified)
191                         SM_ENTER(WPA_PTK, PTKINITDONE);
192                 else if (sm->TimeoutCtr >
193 -                        (int) dot11RSNAConfigPairwiseUpdateCount) {
194 +                        sm->wpa_auth->conf.wpa_pairwise_update_count) {
195                         wpa_auth->dot11RSNA4WayHandshakeFailures++;
196 -                       wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
197 -                                        "PTKINITNEGOTIATING: Retry limit %d "
198 -                                        "reached",
199 -                                        dot11RSNAConfigPairwiseUpdateCount);
200 +                       wpa_auth_vlogger(
201 +                               sm->wpa_auth, sm->addr, LOGGER_DEBUG,
202 +                               "PTKINITNEGOTIATING: Retry limit %u reached",
203 +                               sm->wpa_auth->conf.wpa_pairwise_update_count);
204                         SM_ENTER(WPA_PTK, DISCONNECT);
205                 } else if (sm->TimeoutEvt)
206                         SM_ENTER(WPA_PTK, PTKINITNEGOTIATING);
207 @@ -3056,7 +3055,7 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
208         SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group);
209  
210         sm->GTimeoutCtr++;
211 -       if (sm->GTimeoutCtr > (int) dot11RSNAConfigGroupUpdateCount) {
212 +       if (sm->GTimeoutCtr > sm->wpa_auth->conf.wpa_group_update_count) {
213                 /* No point in sending the EAPOL-Key - we will disconnect
214                  * immediately following this. */
215                 return;
216 @@ -3154,7 +3153,7 @@ SM_STEP(WPA_PTK_GROUP)
217                     !sm->EAPOLKeyPairwise && sm->MICVerified)
218                         SM_ENTER(WPA_PTK_GROUP, REKEYESTABLISHED);
219                 else if (sm->GTimeoutCtr >
220 -                        (int) dot11RSNAConfigGroupUpdateCount)
221 +                        sm->wpa_auth->conf.wpa_group_update_count)
222                         SM_ENTER(WPA_PTK_GROUP, KEYERROR);
223                 else if (sm->TimeoutEvt)
224                         SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING);
225 @@ -3614,8 +3613,8 @@ int wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen)
226                 "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n",
227                 RSN_VERSION,
228                 !!wpa_auth->conf.wpa_strict_rekey,
229 -               dot11RSNAConfigGroupUpdateCount,
230 -               dot11RSNAConfigPairwiseUpdateCount,
231 +               wpa_auth->conf.wpa_group_update_count,
232 +               wpa_auth->conf.wpa_pairwise_update_count,
233                 wpa_cipher_key_len(wpa_auth->conf.wpa_group) * 8,
234                 dot11RSNAConfigPMKLifetime,
235                 dot11RSNAConfigPMKReauthThreshold,
236 diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
237 index 9cbe3889b..0920a169d 100644
238 --- a/src/ap/wpa_auth.h
239 +++ b/src/ap/wpa_auth.h
240 @@ -144,6 +144,8 @@ struct wpa_auth_config {
241         int wpa_strict_rekey;
242         int wpa_gmk_rekey;
243         int wpa_ptk_rekey;
244 +       u32 wpa_group_update_count;
245 +       u32 wpa_pairwise_update_count;
246         int rsn_pairwise;
247         int rsn_preauth;
248         int eapol_version;
249 diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
250 index 22518a1f1..394f77a66 100644
251 --- a/src/ap/wpa_auth_glue.c
252 +++ b/src/ap/wpa_auth_glue.c
253 @@ -41,6 +41,8 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
254         wconf->wpa_strict_rekey = conf->wpa_strict_rekey;
255         wconf->wpa_gmk_rekey = conf->wpa_gmk_rekey;
256         wconf->wpa_ptk_rekey = conf->wpa_ptk_rekey;
257 +       wconf->wpa_group_update_count = conf->wpa_group_update_count;
258 +       wconf->wpa_pairwise_update_count = conf->wpa_pairwise_update_count;
259         wconf->rsn_pairwise = conf->rsn_pairwise;
260         wconf->rsn_preauth = conf->rsn_preauth;
261         wconf->eapol_version = conf->eapol_version;
262 diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h
263 index 065a624ad..cda2c5065 100644
264 --- a/src/ap/wpa_auth_i.h
265 +++ b/src/ap/wpa_auth_i.h
266 @@ -48,8 +48,8 @@ struct wpa_state_machine {
267         Boolean AuthenticationRequest;
268         Boolean ReAuthenticationRequest;
269         Boolean Disconnect;
270 -       int TimeoutCtr;
271 -       int GTimeoutCtr;
272 +       u32 TimeoutCtr;
273 +       u32 GTimeoutCtr;
274         Boolean TimeoutEvt;
275         Boolean EAPOLKeyReceived;
276         Boolean EAPOLKeyPairwise;
277 diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
278 index 521a692ba..954061ae4 100644
279 --- a/wpa_supplicant/ibss_rsn.c
280 +++ b/wpa_supplicant/ibss_rsn.c
281 @@ -428,6 +428,8 @@ static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn,
282         conf.wpa_group = WPA_CIPHER_CCMP;
283         conf.eapol_version = 2;
284         conf.wpa_group_rekey = ssid->group_rekey ? ssid->group_rekey : 600;
285 +       conf.wpa_group_update_count = 4;
286 +       conf.wpa_pairwise_update_count = 4;
287  
288         ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb, ibss_rsn);
289         if (ibss_rsn->auth_group == NULL) {
290 diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
291 index 33040f30b..628382cbf 100644
292 --- a/wpa_supplicant/mesh_rsn.c
293 +++ b/wpa_supplicant/mesh_rsn.c
294 @@ -158,6 +158,8 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr,
295         conf.wpa_group = rsn->group_cipher;
296         conf.eapol_version = 0;
297         conf.wpa_group_rekey = -1;
298 +       conf.wpa_group_update_count = 4;
299 +       conf.wpa_pairwise_update_count = 4;
300  #ifdef CONFIG_IEEE80211W
301         conf.ieee80211w = ieee80211w;
302         if (ieee80211w != NO_MGMT_FRAME_PROTECTION)
303 -- 
304 2.13.6
305