From de94be0acde87f727ab8482761127d24fae71a73 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 4 May 2019 19:17:45 +0300 Subject: [PATCH] Enforce that IEEE 802.1X EAPOL-Key Replay Counter increases While this should not happen in practical use cases, wpa_get_ntp_timestamp() could return the same value when called twice in a row quickly. Work around that case by enforcing a new Replay Counter value based on stored last value. Signed-off-by: Jouni Malinen --- src/ap/hostapd.h | 2 ++ src/ap/ieee802_1x.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 594699f3c..f573717d1 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -384,6 +384,8 @@ struct hostapd_data { unsigned int num_backlogged_sta; unsigned int airtime_weight; #endif /* CONFIG_AIRTIME_POLICY */ + + u8 last_1x_eapol_key_replay_counter[8]; }; diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c index 97f503f75..09ec16b8b 100644 --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c @@ -157,6 +157,21 @@ static void ieee802_1x_tx_key_one(struct hostapd_data *hapd, key->type = EAPOL_KEY_TYPE_RC4; WPA_PUT_BE16(key->key_length, key_len); wpa_get_ntp_timestamp(key->replay_counter); + if (os_memcmp(key->replay_counter, + hapd->last_1x_eapol_key_replay_counter, + IEEE8021X_REPLAY_COUNTER_LEN) <= 0) { + /* NTP timestamp did not increment from last EAPOL-Key frame; + * use previously used value + 1 instead. */ + inc_byte_array(hapd->last_1x_eapol_key_replay_counter, + IEEE8021X_REPLAY_COUNTER_LEN); + os_memcpy(key->replay_counter, + hapd->last_1x_eapol_key_replay_counter, + IEEE8021X_REPLAY_COUNTER_LEN); + } else { + os_memcpy(hapd->last_1x_eapol_key_replay_counter, + key->replay_counter, + IEEE8021X_REPLAY_COUNTER_LEN); + } if (random_get_bytes(key->key_iv, sizeof(key->key_iv))) { wpa_printf(MSG_ERROR, "Could not get random numbers");