Added support for enforcing frequent PTK rekeying
Added a new configuration option, wpa_ptk_rekey, that can be used to enforce frequent PTK rekeying, e.g., to mitigate some attacks against TKIP deficiencies. This can be set either by the Authenticator (to initiate periodic 4-way handshake to rekey PTK) or by the Supplicant (to request Authenticator to rekey PTK). With both wpa_ptk_rekey and wpa_group_rekey (in hostapd) set to 600, TKIP keys will not be used for more than 10 minutes which may make some attacks against TKIP more difficult to implement.
This commit is contained in:
parent
81eec387dd
commit
581a8cde77
15 changed files with 83 additions and 2 deletions
|
@ -1,5 +1,10 @@
|
|||
ChangeLog for hostapd
|
||||
|
||||
????-??-?? - v0.6.6
|
||||
* added a new configuration option, wpa_ptk_rekey, that can be used to
|
||||
enforce frequent PTK rekeying, e.g., to mitigate some attacks against
|
||||
TKIP deficiencies
|
||||
|
||||
2008-11-01 - v0.6.5
|
||||
* added support for SHA-256 as X.509 certificate digest when using the
|
||||
internal X.509/TLSv1 implementation
|
||||
|
|
|
@ -1697,6 +1697,8 @@ struct hostapd_config * hostapd_config_read(const char *fname)
|
|||
bss->wpa_strict_rekey = atoi(pos);
|
||||
} else if (os_strcmp(buf, "wpa_gmk_rekey") == 0) {
|
||||
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_passphrase") == 0) {
|
||||
int len = os_strlen(pos);
|
||||
if (len < 8 || len > 63) {
|
||||
|
|
|
@ -223,6 +223,7 @@ struct hostapd_bss_config {
|
|||
int wpa_group_rekey;
|
||||
int wpa_strict_rekey;
|
||||
int wpa_gmk_rekey;
|
||||
int wpa_ptk_rekey;
|
||||
int rsn_pairwise;
|
||||
int rsn_preauth;
|
||||
char *rsn_preauth_interfaces;
|
||||
|
|
|
@ -293,6 +293,7 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
|
|||
wconf->wpa_group_rekey = conf->wpa_group_rekey;
|
||||
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->rsn_pairwise = conf->rsn_pairwise;
|
||||
wconf->rsn_preauth = conf->rsn_preauth;
|
||||
wconf->eapol_version = conf->eapol_version;
|
||||
|
|
|
@ -710,6 +710,10 @@ own_ip_addr=127.0.0.1
|
|||
# (in seconds).
|
||||
#wpa_gmk_rekey=86400
|
||||
|
||||
# Maximum lifetime for PTK in seconds. This can be used to enforce rekeying of
|
||||
# PTK to mitigate some attacks against TKIP deficiencies.
|
||||
#wpa_ptk_rekey=600
|
||||
|
||||
# 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.
|
||||
|
|
|
@ -43,6 +43,7 @@ static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len);
|
|||
static void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx);
|
||||
static void wpa_group_sm_step(struct wpa_authenticator *wpa_auth,
|
||||
struct wpa_group *group);
|
||||
static void wpa_request_new_ptk(struct wpa_state_machine *sm);
|
||||
|
||||
/* Default timeouts are 100 ms, but this seems to be a bit too fast for most
|
||||
* WPA Supplicants, so use a bit longer timeout. */
|
||||
|
@ -260,6 +261,17 @@ static void wpa_rekey_gtk(void *eloop_ctx, void *timeout_ctx)
|
|||
}
|
||||
|
||||
|
||||
static void wpa_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
|
||||
{
|
||||
struct wpa_authenticator *wpa_auth = eloop_ctx;
|
||||
struct wpa_state_machine *sm = timeout_ctx;
|
||||
|
||||
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "rekeying PTK");
|
||||
wpa_request_new_ptk(sm);
|
||||
wpa_sm_step(sm);
|
||||
}
|
||||
|
||||
|
||||
static int wpa_auth_pmksa_clear_cb(struct wpa_state_machine *sm, void *ctx)
|
||||
{
|
||||
if (sm->pmksa == ctx)
|
||||
|
@ -528,6 +540,7 @@ void wpa_auth_sta_deinit(struct wpa_state_machine *sm)
|
|||
|
||||
eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm);
|
||||
eloop_cancel_timeout(wpa_sm_call_step, sm, NULL);
|
||||
eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm);
|
||||
if (sm->in_step_loop) {
|
||||
/* Must not free state machine while wpa_sm_step() is running.
|
||||
* Freeing will be completed in the end of wpa_sm_step(). */
|
||||
|
@ -1086,6 +1099,7 @@ void wpa_remove_ptk(struct wpa_state_machine *sm)
|
|||
os_memset(&sm->PTK, 0, sizeof(sm->PTK));
|
||||
wpa_auth_set_key(sm->wpa_auth, 0, "none", sm->addr, 0, (u8 *) "", 0);
|
||||
sm->pairwise_set = FALSE;
|
||||
eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1553,6 +1567,13 @@ SM_STATE(WPA_PTK, PTKINITDONE)
|
|||
/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
|
||||
sm->pairwise_set = TRUE;
|
||||
|
||||
if (sm->wpa_auth->conf.wpa_ptk_rekey) {
|
||||
eloop_cancel_timeout(wpa_rekey_ptk, sm->wpa_auth, sm);
|
||||
eloop_register_timeout(sm->wpa_auth->conf.
|
||||
wpa_ptk_rekey, 0, wpa_rekey_ptk,
|
||||
sm->wpa_auth, sm);
|
||||
}
|
||||
|
||||
if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
|
||||
wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
|
||||
WPA_EAPOL_authorized, 1);
|
||||
|
|
|
@ -136,6 +136,7 @@ struct wpa_auth_config {
|
|||
int wpa_group_rekey;
|
||||
int wpa_strict_rekey;
|
||||
int wpa_gmk_rekey;
|
||||
int wpa_ptk_rekey;
|
||||
int rsn_pairwise;
|
||||
int rsn_preauth;
|
||||
int eapol_version;
|
||||
|
|
|
@ -133,7 +133,6 @@ void wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck,
|
|||
* @sm: Pointer to WPA state machine data from wpa_sm_init()
|
||||
* @error: Indicate whether this is an Michael MIC error report
|
||||
* @pairwise: 1 = error report for pairwise packet, 0 = for group packet
|
||||
* Returns: Pointer to the current network structure or %NULL on failure
|
||||
*
|
||||
* Send an EAPOL-Key Request to the current authenticator. This function is
|
||||
* used to request rekeying and it is usually called when a local Michael MIC
|
||||
|
@ -489,6 +488,14 @@ static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
|
|||
}
|
||||
|
||||
|
||||
static void wpa_sm_rekey_ptk(void *eloop_ctx, void *timeout_ctx)
|
||||
{
|
||||
struct wpa_sm *sm = eloop_ctx;
|
||||
wpa_printf(MSG_DEBUG, "WPA: Request PTK rekeying");
|
||||
wpa_sm_key_request(sm, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
|
||||
const struct wpa_eapol_key *key)
|
||||
{
|
||||
|
@ -533,6 +540,13 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
|
|||
"driver.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sm->wpa_ptk_rekey) {
|
||||
eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
|
||||
eloop_register_timeout(sm->wpa_ptk_rekey, 0, wpa_sm_rekey_ptk,
|
||||
sm, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1849,6 +1863,7 @@ void wpa_sm_deinit(struct wpa_sm *sm)
|
|||
return;
|
||||
pmksa_cache_deinit(sm->pmksa);
|
||||
eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
|
||||
eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
|
||||
os_free(sm->assoc_wpa_ie);
|
||||
os_free(sm->ap_wpa_ie);
|
||||
os_free(sm->ap_rsn_ie);
|
||||
|
@ -2018,6 +2033,7 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
|
|||
sm->ssid_len = config->ssid_len;
|
||||
} else
|
||||
sm->ssid_len = 0;
|
||||
sm->wpa_ptk_rekey = config->wpa_ptk_rekey;
|
||||
} else {
|
||||
sm->network_ctx = NULL;
|
||||
sm->peerkey_enabled = 0;
|
||||
|
@ -2026,6 +2042,7 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
|
|||
sm->eap_workaround = 0;
|
||||
sm->eap_conf_ctx = NULL;
|
||||
sm->ssid_len = 0;
|
||||
sm->wpa_ptk_rekey = 0;
|
||||
}
|
||||
if (config == NULL || config->network_ctx != sm->network_ctx)
|
||||
pmksa_cache_notify_reconfig(sm->pmksa);
|
||||
|
|
|
@ -85,6 +85,7 @@ struct rsn_supp_config {
|
|||
void *eap_conf_ctx;
|
||||
const u8 *ssid;
|
||||
size_t ssid_len;
|
||||
int wpa_ptk_rekey;
|
||||
};
|
||||
|
||||
#ifndef CONFIG_NO_WPA
|
||||
|
|
|
@ -60,6 +60,7 @@ struct wpa_sm {
|
|||
void *eap_conf_ctx;
|
||||
u8 ssid[32];
|
||||
size_t ssid_len;
|
||||
int wpa_ptk_rekey;
|
||||
|
||||
u8 own_addr[ETH_ALEN];
|
||||
const char *ifname;
|
||||
|
|
|
@ -5,6 +5,9 @@ ChangeLog for wpa_supplicant
|
|||
(can be used to simulate test SIM/USIM card with a known private key;
|
||||
enable with CONFIG_SIM_SIMULATOR=y/CONFIG_USIM_SIMULATOR=y in .config
|
||||
and password="Ki:OPc"/password="Ki:OPc:SQN" in network configuration)
|
||||
* added a new network configuration option, wpa_ptk_rekey, that can be
|
||||
used to enforce frequent PTK rekeying, e.g., to mitigate some attacks
|
||||
against TKIP deficiencies
|
||||
|
||||
2008-11-01 - v0.6.5
|
||||
* added support for SHA-256 as X.509 certificate digest when using the
|
||||
|
|
|
@ -1357,7 +1357,8 @@ static const struct parse_data ssid_fields[] = {
|
|||
#endif /* CONFIG_IEEE80211W */
|
||||
{ INT_RANGE(peerkey, 0, 1) },
|
||||
{ INT_RANGE(mixed_cell, 0, 1) },
|
||||
{ INT_RANGE(frequency, 0, 10000) }
|
||||
{ INT_RANGE(frequency, 0, 10000) },
|
||||
{ INT(wpa_ptk_rekey) }
|
||||
};
|
||||
|
||||
#undef OFFSET
|
||||
|
|
|
@ -334,6 +334,14 @@ struct wpa_ssid {
|
|||
* will be used instead of this configured value.
|
||||
*/
|
||||
int frequency;
|
||||
|
||||
/**
|
||||
* wpa_ptk_rekey - Maximum lifetime for PTK in seconds
|
||||
*
|
||||
* This value can be used to enforce rekeying of PTK to mitigate some
|
||||
* attacks against TKIP deficiencies.
|
||||
*/
|
||||
int wpa_ptk_rekey;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_SSID_H */
|
||||
|
|
|
@ -276,6 +276,9 @@ fast_reauth=1
|
|||
# 1 = enabled
|
||||
#peerkey=1
|
||||
#
|
||||
# wpa_ptk_rekey: Maximum lifetime for PTK in seconds. This can be used to
|
||||
# enforce rekeying of PTK to mitigate some attacks against TKIP deficiencies.
|
||||
#
|
||||
# Following fields are only used with internal EAP implementation.
|
||||
# eap: space-separated list of accepted EAP methods
|
||||
# MD5 = EAP-MD5 (unsecure and does not generate keying material ->
|
||||
|
@ -475,6 +478,17 @@ network={
|
|||
priority=2
|
||||
}
|
||||
|
||||
# WPA-Personal(PSK) with TKIP and enforcement for frequent PTK rekeying
|
||||
network={
|
||||
ssid="example"
|
||||
proto=WPA
|
||||
key_mgmt=WPA-PSK
|
||||
pairwise=TKIP
|
||||
group=TKIP
|
||||
psk="not so secure passphrase"
|
||||
wpa_ptk_rekey=600
|
||||
}
|
||||
|
||||
# Only WPA-EAP is used. Both CCMP and TKIP is accepted. An AP that used WEP104
|
||||
# or WEP40 as the group cipher will not be accepted.
|
||||
network={
|
||||
|
|
|
@ -626,6 +626,7 @@ void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
|
|||
#endif /* IEEE8021X_EAPOL */
|
||||
conf.ssid = ssid->ssid;
|
||||
conf.ssid_len = ssid->ssid_len;
|
||||
conf.wpa_ptk_rekey = ssid->wpa_ptk_rekey;
|
||||
}
|
||||
wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue