aboutsummaryrefslogtreecommitdiffstats
path: root/hostapd/wpa.c
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 /hostapd/wpa.c
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.
Diffstat (limited to 'hostapd/wpa.c')
-rw-r--r--hostapd/wpa.c21
1 files changed, 21 insertions, 0 deletions
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);