summaryrefslogtreecommitdiff
path: root/package/network/services/hostapd/patches/013-Add-hostapd-options-wpa_group_update_count-and-wpa_p.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/network/services/hostapd/patches/013-Add-hostapd-options-wpa_group_update_count-and-wpa_p.patch')
-rw-r--r--package/network/services/hostapd/patches/013-Add-hostapd-options-wpa_group_update_count-and-wpa_p.patch305
1 files changed, 305 insertions, 0 deletions
diff --git a/package/network/services/hostapd/patches/013-Add-hostapd-options-wpa_group_update_count-and-wpa_p.patch b/package/network/services/hostapd/patches/013-Add-hostapd-options-wpa_group_update_count-and-wpa_p.patch
new file mode 100644
index 0000000..623c2be
--- /dev/null
+++ b/package/network/services/hostapd/patches/013-Add-hostapd-options-wpa_group_update_count-and-wpa_p.patch
@@ -0,0 +1,305 @@
+From 41f140d38617e1fd3fa88c1667c1bce0cad79224 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?G=C3=BCnther=20Kelleter?= <guenther.kelleter@devolo.de>
+Date: Thu, 5 Jan 2017 17:00:33 +0100
+Subject: [PATCH] Add hostapd options wpa_group_update_count and
+ wpa_pairwise_update_count
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+wpa_group_update_count and wpa_pairwise_update_count can now be used to
+set the GTK and PTK rekey retry limits (dot11RSNAConfigGroupUpdateCount
+and dot11RSNAConfigPairwiseUpdateCount). Defaults set to current
+hardcoded value (4).
+
+Some stations may suffer from frequent deauthentications due to GTK
+rekey failures: EAPOL 1/2 frame is not answered during the total timeout
+period of currently ~3.5 seconds. For example, a Galaxy S6 with Android
+6.0.1 appears to go into power save mode for up to 5 seconds. Increasing
+wpa_group_update_count to 6 fixed this issue.
+
+Signed-off-by: Günther Kelleter <guenther.kelleter@devolo.de>
+---
+ hostapd/config_file.c | 22 ++++++++++++++++++++++
+ hostapd/hostapd.conf | 11 +++++++++++
+ src/ap/ap_config.c | 2 ++
+ src/ap/ap_config.h | 2 ++
+ src/ap/wpa_auth.c | 37 ++++++++++++++++++-------------------
+ src/ap/wpa_auth.h | 2 ++
+ src/ap/wpa_auth_glue.c | 2 ++
+ src/ap/wpa_auth_i.h | 4 ++--
+ wpa_supplicant/ibss_rsn.c | 2 ++
+ wpa_supplicant/mesh_rsn.c | 2 ++
+ 10 files changed, 65 insertions(+), 21 deletions(-)
+
+diff --git a/hostapd/config_file.c b/hostapd/config_file.c
+index 8cfa198c3..02693a5b1 100644
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -2489,6 +2489,28 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ bss->wpa_gmk_rekey = atoi(pos);
+ } else if (os_strcmp(buf, "wpa_ptk_rekey") == 0) {
+ bss->wpa_ptk_rekey = atoi(pos);
++ } else if (os_strcmp(buf, "wpa_group_update_count") == 0) {
++ char *endp;
++ unsigned long val = strtoul(pos, &endp, 0);
++
++ if (*endp || val < 1 || val > (u32) -1) {
++ wpa_printf(MSG_ERROR,
++ "Line %d: Invalid wpa_group_update_count=%lu; allowed range 1..4294967295",
++ line, val);
++ return 1;
++ }
++ bss->wpa_group_update_count = (u32) val;
++ } else if (os_strcmp(buf, "wpa_pairwise_update_count") == 0) {
++ char *endp;
++ unsigned long val = strtoul(pos, &endp, 0);
++
++ if (*endp || val < 1 || val > (u32) -1) {
++ wpa_printf(MSG_ERROR,
++ "Line %d: Invalid wpa_pairwise_update_count=%lu; allowed range 1..4294967295",
++ line, val);
++ return 1;
++ }
++ bss->wpa_pairwise_update_count = (u32) val;
+ } else if (os_strcmp(buf, "wpa_passphrase") == 0) {
+ int len = os_strlen(pos);
+ if (len < 8 || len > 63) {
+diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
+index 314f3842b..1fb1bd987 100644
+--- a/hostapd/hostapd.conf
++++ b/hostapd/hostapd.conf
+@@ -1221,6 +1221,11 @@ own_ip_addr=127.0.0.1
+ # (dot11RSNAConfigGroupRekeyStrict)
+ #wpa_strict_rekey=1
+
++# The number of times EAPOL-Key Message 1/2 in the RSN Group Key Handshake is
++#retried per GTK Handshake attempt. (dot11RSNAConfigGroupUpdateCount)
++# Range 1..4294967295; default: 4
++#wpa_group_update_count=4
++
+ # Time interval for rekeying GMK (master key used internally to generate GTKs
+ # (in seconds).
+ #wpa_gmk_rekey=86400
+@@ -1229,6 +1234,12 @@ own_ip_addr=127.0.0.1
+ # PTK to mitigate some attacks against TKIP deficiencies.
+ #wpa_ptk_rekey=600
+
++# The number of times EAPOL-Key Message 1/4 and Message 3/4 in the RSN 4-Way
++# Handshake are retried per 4-Way Handshake attempt.
++# (dot11RSNAConfigPairwiseUpdateCount)
++# Range 1..4294967295; default: 4
++#wpa_pairwise_update_count=4
++
+ # Enable IEEE 802.11i/RSN/WPA2 pre-authentication. This is used to speed up
+ # roaming be pre-authenticating IEEE 802.1X/EAP part of the full RSN
+ # authentication and key handshake before actually associating with a new AP.
+diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
+index c2b80ad97..9abcab7fb 100644
+--- a/src/ap/ap_config.c
++++ b/src/ap/ap_config.c
+@@ -56,6 +56,8 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
+
+ bss->wpa_group_rekey = 600;
+ bss->wpa_gmk_rekey = 86400;
++ bss->wpa_group_update_count = 4;
++ bss->wpa_pairwise_update_count = 4;
+ bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
+ bss->wpa_pairwise = WPA_CIPHER_TKIP;
+ bss->wpa_group = WPA_CIPHER_TKIP;
+diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
+index 31b1e7762..7495dc96f 100644
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
+@@ -330,6 +330,8 @@ struct hostapd_bss_config {
+ int wpa_strict_rekey;
+ int wpa_gmk_rekey;
+ int wpa_ptk_rekey;
++ u32 wpa_group_update_count;
++ u32 wpa_pairwise_update_count;
+ int rsn_pairwise;
+ int rsn_preauth;
+ char *rsn_preauth_interfaces;
+diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
+index 0bd901fbf..8c082f426 100644
+--- a/src/ap/wpa_auth.c
++++ b/src/ap/wpa_auth.c
+@@ -60,8 +60,6 @@ static void wpa_group_put(struct wpa_authenticator *wpa_auth,
+ struct wpa_group *group);
+ static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos);
+
+-static const u32 dot11RSNAConfigGroupUpdateCount = 4;
+-static const u32 dot11RSNAConfigPairwiseUpdateCount = 4;
+ static const u32 eapol_key_timeout_first = 100; /* ms */
+ static const u32 eapol_key_timeout_subseq = 1000; /* ms */
+ static const u32 eapol_key_timeout_first_group = 500; /* ms */
+@@ -1623,7 +1621,7 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
+ {
+ int timeout_ms;
+ int pairwise = key_info & WPA_KEY_INFO_KEY_TYPE;
+- int ctr;
++ u32 ctr;
+
+ if (sm == NULL)
+ return;
+@@ -1640,7 +1638,7 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
+ if (pairwise && ctr == 1 && !(key_info & WPA_KEY_INFO_MIC))
+ sm->pending_1_of_4_timeout = 1;
+ wpa_printf(MSG_DEBUG, "WPA: Use EAPOL-Key timeout of %u ms (retry "
+- "counter %d)", timeout_ms, ctr);
++ "counter %u)", timeout_ms, ctr);
+ eloop_register_timeout(timeout_ms / 1000, (timeout_ms % 1000) * 1000,
+ wpa_send_eapol_timeout, wpa_auth, sm);
+ }
+@@ -2002,7 +2000,7 @@ SM_STATE(WPA_PTK, PTKSTART)
+ sm->alt_snonce_valid = FALSE;
+
+ sm->TimeoutCtr++;
+- if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) {
++ if (sm->TimeoutCtr > sm->wpa_auth->conf.wpa_pairwise_update_count) {
+ /* No point in sending the EAPOL-Key - we will disconnect
+ * immediately following this. */
+ return;
+@@ -2693,7 +2691,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
+ sm->TimeoutEvt = FALSE;
+
+ sm->TimeoutCtr++;
+- if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) {
++ if (sm->TimeoutCtr > sm->wpa_auth->conf.wpa_pairwise_update_count) {
+ /* No point in sending the EAPOL-Key - we will disconnect
+ * immediately following this. */
+ return;
+@@ -2988,11 +2986,12 @@ SM_STEP(WPA_PTK)
+ sm->EAPOLKeyPairwise)
+ SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING);
+ else if (sm->TimeoutCtr >
+- (int) dot11RSNAConfigPairwiseUpdateCount) {
++ sm->wpa_auth->conf.wpa_pairwise_update_count) {
+ wpa_auth->dot11RSNA4WayHandshakeFailures++;
+- wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
+- "PTKSTART: Retry limit %d reached",
+- dot11RSNAConfigPairwiseUpdateCount);
++ wpa_auth_vlogger(
++ sm->wpa_auth, sm->addr, LOGGER_DEBUG,
++ "PTKSTART: Retry limit %u reached",
++ sm->wpa_auth->conf.wpa_pairwise_update_count);
+ SM_ENTER(WPA_PTK, DISCONNECT);
+ } else if (sm->TimeoutEvt)
+ SM_ENTER(WPA_PTK, PTKSTART);
+@@ -3016,12 +3015,12 @@ SM_STEP(WPA_PTK)
+ sm->EAPOLKeyPairwise && sm->MICVerified)
+ SM_ENTER(WPA_PTK, PTKINITDONE);
+ else if (sm->TimeoutCtr >
+- (int) dot11RSNAConfigPairwiseUpdateCount) {
++ sm->wpa_auth->conf.wpa_pairwise_update_count) {
+ wpa_auth->dot11RSNA4WayHandshakeFailures++;
+- wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
+- "PTKINITNEGOTIATING: Retry limit %d "
+- "reached",
+- dot11RSNAConfigPairwiseUpdateCount);
++ wpa_auth_vlogger(
++ sm->wpa_auth, sm->addr, LOGGER_DEBUG,
++ "PTKINITNEGOTIATING: Retry limit %u reached",
++ sm->wpa_auth->conf.wpa_pairwise_update_count);
+ SM_ENTER(WPA_PTK, DISCONNECT);
+ } else if (sm->TimeoutEvt)
+ SM_ENTER(WPA_PTK, PTKINITNEGOTIATING);
+@@ -3056,7 +3055,7 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
+ SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group);
+
+ sm->GTimeoutCtr++;
+- if (sm->GTimeoutCtr > (int) dot11RSNAConfigGroupUpdateCount) {
++ if (sm->GTimeoutCtr > sm->wpa_auth->conf.wpa_group_update_count) {
+ /* No point in sending the EAPOL-Key - we will disconnect
+ * immediately following this. */
+ return;
+@@ -3154,7 +3153,7 @@ SM_STEP(WPA_PTK_GROUP)
+ !sm->EAPOLKeyPairwise && sm->MICVerified)
+ SM_ENTER(WPA_PTK_GROUP, REKEYESTABLISHED);
+ else if (sm->GTimeoutCtr >
+- (int) dot11RSNAConfigGroupUpdateCount)
++ sm->wpa_auth->conf.wpa_group_update_count)
+ SM_ENTER(WPA_PTK_GROUP, KEYERROR);
+ else if (sm->TimeoutEvt)
+ SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING);
+@@ -3614,8 +3613,8 @@ int wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen)
+ "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n",
+ RSN_VERSION,
+ !!wpa_auth->conf.wpa_strict_rekey,
+- dot11RSNAConfigGroupUpdateCount,
+- dot11RSNAConfigPairwiseUpdateCount,
++ wpa_auth->conf.wpa_group_update_count,
++ wpa_auth->conf.wpa_pairwise_update_count,
+ wpa_cipher_key_len(wpa_auth->conf.wpa_group) * 8,
+ dot11RSNAConfigPMKLifetime,
+ dot11RSNAConfigPMKReauthThreshold,
+diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
+index 9cbe3889b..0920a169d 100644
+--- a/src/ap/wpa_auth.h
++++ b/src/ap/wpa_auth.h
+@@ -144,6 +144,8 @@ struct wpa_auth_config {
+ int wpa_strict_rekey;
+ int wpa_gmk_rekey;
+ int wpa_ptk_rekey;
++ u32 wpa_group_update_count;
++ u32 wpa_pairwise_update_count;
+ int rsn_pairwise;
+ int rsn_preauth;
+ int eapol_version;
+diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
+index 22518a1f1..394f77a66 100644
+--- a/src/ap/wpa_auth_glue.c
++++ b/src/ap/wpa_auth_glue.c
+@@ -41,6 +41,8 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
+ wconf->wpa_strict_rekey = conf->wpa_strict_rekey;
+ wconf->wpa_gmk_rekey = conf->wpa_gmk_rekey;
+ wconf->wpa_ptk_rekey = conf->wpa_ptk_rekey;
++ wconf->wpa_group_update_count = conf->wpa_group_update_count;
++ wconf->wpa_pairwise_update_count = conf->wpa_pairwise_update_count;
+ wconf->rsn_pairwise = conf->rsn_pairwise;
+ wconf->rsn_preauth = conf->rsn_preauth;
+ wconf->eapol_version = conf->eapol_version;
+diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h
+index 065a624ad..cda2c5065 100644
+--- a/src/ap/wpa_auth_i.h
++++ b/src/ap/wpa_auth_i.h
+@@ -48,8 +48,8 @@ struct wpa_state_machine {
+ Boolean AuthenticationRequest;
+ Boolean ReAuthenticationRequest;
+ Boolean Disconnect;
+- int TimeoutCtr;
+- int GTimeoutCtr;
++ u32 TimeoutCtr;
++ u32 GTimeoutCtr;
+ Boolean TimeoutEvt;
+ Boolean EAPOLKeyReceived;
+ Boolean EAPOLKeyPairwise;
+diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
+index 521a692ba..954061ae4 100644
+--- a/wpa_supplicant/ibss_rsn.c
++++ b/wpa_supplicant/ibss_rsn.c
+@@ -428,6 +428,8 @@ static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn,
+ conf.wpa_group = WPA_CIPHER_CCMP;
+ conf.eapol_version = 2;
+ conf.wpa_group_rekey = ssid->group_rekey ? ssid->group_rekey : 600;
++ conf.wpa_group_update_count = 4;
++ conf.wpa_pairwise_update_count = 4;
+
+ ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb, ibss_rsn);
+ if (ibss_rsn->auth_group == NULL) {
+diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
+index 33040f30b..628382cbf 100644
+--- a/wpa_supplicant/mesh_rsn.c
++++ b/wpa_supplicant/mesh_rsn.c
+@@ -158,6 +158,8 @@ static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr,
+ conf.wpa_group = rsn->group_cipher;
+ conf.eapol_version = 0;
+ conf.wpa_group_rekey = -1;
++ conf.wpa_group_update_count = 4;
++ conf.wpa_pairwise_update_count = 4;
+ #ifdef CONFIG_IEEE80211W
+ conf.ieee80211w = ieee80211w;
+ if (ieee80211w != NO_MGMT_FRAME_PROTECTION)
+--
+2.13.6
+