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)