diff options
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.patch | 305 |
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 + |