aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2008-11-06 17:57:21 (GMT)
committerJouni Malinen <j@w1.fi>2008-11-06 17:57:21 (GMT)
commit581a8cde77670ba7de2cce57f4a723ba435df9b7 (patch)
treed06cf58048193c7a10dc8e6de59fc414124fffcc
parent81eec387dd7c1f4521822e48023e950dfa7b5a52 (diff)
downloadhostap-06-581a8cde77670ba7de2cce57f4a723ba435df9b7.zip
hostap-06-581a8cde77670ba7de2cce57f4a723ba435df9b7.tar.gz
hostap-06-581a8cde77670ba7de2cce57f4a723ba435df9b7.tar.bz2
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.
-rw-r--r--hostapd/ChangeLog5
-rw-r--r--hostapd/config.c2
-rw-r--r--hostapd/config.h1
-rw-r--r--hostapd/hostapd.c1
-rw-r--r--hostapd/hostapd.conf4
-rw-r--r--hostapd/wpa.c21
-rw-r--r--hostapd/wpa.h1
-rw-r--r--src/rsn_supp/wpa.c19
-rw-r--r--src/rsn_supp/wpa.h1
-rw-r--r--src/rsn_supp/wpa_i.h1
-rw-r--r--wpa_supplicant/ChangeLog3
-rw-r--r--wpa_supplicant/config.c3
-rw-r--r--wpa_supplicant/config_ssid.h8
-rw-r--r--wpa_supplicant/wpa_supplicant.conf14
-rw-r--r--wpa_supplicant/wpas_glue.c1
15 files changed, 83 insertions, 2 deletions
diff --git a/hostapd/ChangeLog b/hostapd/ChangeLog
index a8e7f4e..b2cfb5b 100644
--- a/hostapd/ChangeLog
+++ b/hostapd/ChangeLog
@@ -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
diff --git a/hostapd/config.c b/hostapd/config.c
index 7fceacb..d10d64f 100644
--- a/hostapd/config.c
+++ b/hostapd/config.c
@@ -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) {
diff --git a/hostapd/config.h b/hostapd/config.h
index 5c7d040..212e099 100644
--- a/hostapd/config.h
+++ b/hostapd/config.h
@@ -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;
diff --git a/hostapd/hostapd.c b/hostapd/hostapd.c
index e80446a..889f81e 100644
--- a/hostapd/hostapd.c
+++ b/hostapd/hostapd.c
@@ -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;
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 898a3a3..599d7f1 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -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.
diff --git a/hostapd/wpa.c b/hostapd/wpa.c
index c7bcac8..cc01f02 100644
--- a/hostapd/wpa.c
+++ b/hostapd/wpa.c
@@ -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);
diff --git a/hostapd/wpa.h b/hostapd/wpa.h
index 567a8bf..153106e 100644
--- a/hostapd/wpa.h
+++ b/hostapd/wpa.h
@@ -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;
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 5ec1dab..1da54f2 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -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);
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 650e75f..bdf7785 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -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
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index 1505155..95348da 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -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;
diff --git a/wpa_supplicant/ChangeLog b/wpa_supplicant/ChangeLog
index 251e95a..4f213fa 100644
--- a/wpa_supplicant/ChangeLog
+++ b/wpa_supplicant/ChangeLog
@@ -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
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index fc64be1..70b02c4 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -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
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 5e57bc1..5510639 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -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 */
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index b639d39..44dc3a1 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -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={
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index f0c1cda..d5e31eb 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -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);
}