From 39acf9c4ddcf2b6d61ef45419fff60fd4dcb855d Mon Sep 17 00:00:00 2001 From: Hrudaynath Dhabe Date: Tue, 15 Oct 2019 13:56:07 +0530 Subject: [PATCH] wifi: Add PMK caching feature for station WPA2-enterprise 4. Pmksa cache expiry after dot11RSNAConfigPMKLifetime timeout. --- .../src/esp_supplicant/esp_wpa2.c | 13 +- .../src/esp_supplicant/esp_wpa_main.c | 6 - .../wpa_supplicant/src/rsn_supp/pmksa_cache.c | 626 +++++++++--------- .../wpa_supplicant/src/rsn_supp/pmksa_cache.h | 106 +-- components/wpa_supplicant/src/rsn_supp/wpa.c | 2 + components/wpa_supplicant/src/utils/common.c | 6 +- .../{include => src}/utils/common.h | 31 +- 7 files changed, 373 insertions(+), 417 deletions(-) rename components/wpa_supplicant/{include => src}/utils/common.h (91%) diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wpa2.c b/components/wpa_supplicant/src/esp_supplicant/esp_wpa2.c index 672955ef9b..6f8bd00aee 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wpa2.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wpa2.c @@ -666,16 +666,9 @@ static int wpa2_start_eapol_internal(void) return ESP_FAIL; } if (wpa_sta_is_cur_pmksa_set()) { - if (0) { - wpa_printf(MSG_DEBUG, - "RSN: Timeout on waiting for the AP to initiate 4-way handshake \ - for PMKSA caching or EAP authentication \ - - try to force it to start EAP authentication"); - } else { - wpa_printf(MSG_DEBUG, - "RSN: PMKSA caching - do not send EAPOL-Start"); - return -1; - } + wpa_printf(MSG_DEBUG, + "RSN: PMKSA caching - do not send EAPOL-Start"); + return ESP_FAIL; } ret = esp_wifi_get_assoc_bssid_internal(bssid); diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c b/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c index 74048a28a6..c576982213 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c @@ -109,14 +109,8 @@ void wpa_neg_complete() bool wpa_attach(void) { bool ret = true; -#ifndef IOT_SIP_MODE ret = wpa_sm_init(NULL, wpa_sendto_wrapper, wpa_config_assoc_ie, wpa_install_key, wpa_get_key, wpa_deauthenticate, wpa_neg_complete); -#else - u8 *payload = (u8 *)os_malloc(WPA_TX_MSG_BUFF_MAXLEN); - ret = wpa_sm_init(payload, wpa_sendto_wrapper, - wpa_config_assoc_ie, wpa_install_key, wpa_get_key, wpa_deauthenticate, wpa_neg_complete); -#endif if(ret) { ret = (esp_wifi_register_tx_cb_internal(eapol_txcb, WIFI_TXCB_EAPOL_ID) == ESP_OK); } diff --git a/components/wpa_supplicant/src/rsn_supp/pmksa_cache.c b/components/wpa_supplicant/src/rsn_supp/pmksa_cache.c index 6e09d07c19..a23233f2a7 100644 --- a/components/wpa_supplicant/src/rsn_supp/pmksa_cache.c +++ b/components/wpa_supplicant/src/rsn_supp/pmksa_cache.c @@ -13,92 +13,75 @@ #include "common/eapol_common.h" #include "common/ieee802_11_defs.h" #include "pmksa_cache.h" +#include "esp_timer.h" #ifdef IEEE8021X_EAPOL static const int pmksa_cache_max_entries = 10; +static const int dot11RSNAConfigPMKLifetime = 43200; +static const int dot11RSNAConfigPMKReauthThreshold = 70; struct rsn_pmksa_cache { - struct rsn_pmksa_cache_entry *pmksa; /* PMKSA cache */ - int pmksa_count; /* number of entries in PMKSA cache */ - struct wpa_sm *sm; /* TODO: get rid of this reference(?) */ + struct rsn_pmksa_cache_entry *pmksa; /* PMKSA cache */ + int pmksa_count; /* number of entries in PMKSA cache */ + struct wpa_sm *sm; /* TODO: get rid of this reference(?) */ + esp_timer_handle_t cache_timeout_timer; - void (*free_cb)(struct rsn_pmksa_cache_entry *entry, void *ctx, - enum pmksa_free_reason reason); - void *ctx; + void (*free_cb)(struct rsn_pmksa_cache_entry *entry, void *ctx, + enum pmksa_free_reason reason); + void *ctx; }; -//static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa); +static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa); static void _pmksa_cache_free_entry(struct rsn_pmksa_cache_entry *entry) { - bin_clear_free(entry, sizeof(*entry)); + wpa_bin_clear_free(entry, sizeof(*entry)); } static void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa, - struct rsn_pmksa_cache_entry *entry, - enum pmksa_free_reason reason) + struct rsn_pmksa_cache_entry *entry, + enum pmksa_free_reason reason) { - //wpa_sm_remove_pmkid(pmksa->sm, entry->aa, entry->pmkid); - pmksa->pmksa_count--; - pmksa->free_cb(entry, pmksa->ctx, reason); - _pmksa_cache_free_entry(entry); + pmksa->pmksa_count--; + pmksa->free_cb(entry, pmksa->ctx, reason); + _pmksa_cache_free_entry(entry); } -#if 0 -static void pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx) + +static void pmksa_cache_expire(void *eloop_ctx) { - struct rsn_pmksa_cache *pmksa = eloop_ctx; - struct os_reltime now; + struct rsn_pmksa_cache *pmksa = eloop_ctx; + int64_t now_sec = esp_timer_get_time() / 1e6; - os_get_reltime(&now); - while (pmksa->pmksa && pmksa->pmksa->expiration <= now.sec) { - struct rsn_pmksa_cache_entry *entry = pmksa->pmksa; - pmksa->pmksa = entry->next; - wpa_printf(MSG_DEBUG, "RSN: expired PMKSA cache entry for " - MACSTR, MAC2STR(entry->aa)); - pmksa_cache_free_entry(pmksa, entry, PMKSA_EXPIRE); - } + while (pmksa->pmksa && pmksa->pmksa->expiration <= now_sec) { + struct rsn_pmksa_cache_entry *entry = pmksa->pmksa; + pmksa->pmksa = entry->next; + wpa_printf(MSG_DEBUG, "RSN: expired PMKSA cache entry for " + MACSTR, MAC2STR(entry->aa)); + pmksa_cache_free_entry(pmksa, entry, PMKSA_EXPIRE); + } - pmksa_cache_set_expiration(pmksa); -} - -static void pmksa_cache_reauth(void *eloop_ctx, void *timeout_ctx) -{ - struct rsn_pmksa_cache *pmksa = eloop_ctx; - pmksa->sm->cur_pmksa = NULL; - eapol_sm_request_reauth(pmksa->sm->eapol); + pmksa_cache_set_expiration(pmksa); } static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa) { - int sec; - struct rsn_pmksa_cache_entry *entry; - struct os_reltime now; + int sec; + int64_t now_sec = esp_timer_get_time() / 1e6; - eloop_cancel_timeout(pmksa_cache_reauth, pmksa, NULL); - if (pmksa->pmksa == NULL) - return; - os_get_reltime(&now); - sec = pmksa->pmksa->expiration - now.sec; - if (sec < 0) - sec = 0; - eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, pmksa, NULL); + esp_timer_stop(pmksa->cache_timeout_timer); + if (pmksa->pmksa == NULL) + return; + sec = pmksa->pmksa->expiration - now_sec; + if (sec < 0) + sec = 0; - entry = pmksa->sm->cur_pmksa ? pmksa->sm->cur_pmksa : - pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL); - if (entry) { - sec = pmksa->pmksa->reauth_time - now.sec; - if (sec < 0) - sec = 0; - eloop_register_timeout(sec, 0, pmksa_cache_reauth, pmksa, - NULL); - } + esp_timer_start_once(pmksa->cache_timeout_timer, (sec + 1) * 1e6); } -#endif /** * pmksa_cache_add - Add a PMKSA cache entry @@ -120,122 +103,120 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa) */ struct rsn_pmksa_cache_entry * pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len, - const u8 *kck, size_t kck_len, - const u8 *aa, const u8 *spa, void *network_ctx, int akmp) + const u8 *kck, size_t kck_len, + const u8 *aa, const u8 *spa, void *network_ctx, int akmp) { - struct rsn_pmksa_cache_entry *entry, *pos, *prev; - //struct os_reltime now; + struct rsn_pmksa_cache_entry *entry, *pos, *prev; + int64_t now_sec = esp_timer_get_time() / 1e6; - if (pmk_len > PMK_LEN) - return NULL; + if (pmk_len > PMK_LEN) + return NULL; - if (wpa_key_mgmt_suite_b(akmp) && !kck) - return NULL; + if (wpa_key_mgmt_suite_b(akmp) && !kck) + return NULL; - entry = os_zalloc(sizeof(*entry)); - if (entry == NULL) - return NULL; - os_memcpy(entry->pmk, pmk, pmk_len); - entry->pmk_len = pmk_len; + entry = os_zalloc(sizeof(*entry)); + if (entry == NULL) + return NULL; + os_memcpy(entry->pmk, pmk, pmk_len); + entry->pmk_len = pmk_len; rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid, - wpa_key_mgmt_sha256(akmp)); - //os_get_reltime(&now); - //entry->expiration = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime; - /*entry->reauth_time = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime * - pmksa->sm->dot11RSNAConfigPMKReauthThreshold / 100;*/ - entry->akmp = akmp; - os_memcpy(entry->aa, aa, ETH_ALEN); - entry->network_ctx = network_ctx; + wpa_key_mgmt_sha256(akmp)); + entry->expiration = now_sec + dot11RSNAConfigPMKLifetime; + entry->reauth_time = now_sec + dot11RSNAConfigPMKLifetime * + dot11RSNAConfigPMKReauthThreshold / 100; + entry->akmp = akmp; + os_memcpy(entry->aa, aa, ETH_ALEN); + entry->network_ctx = network_ctx; - /* Replace an old entry for the same Authenticator (if found) with the - * new entry */ - pos = pmksa->pmksa; - prev = NULL; - while (pos) { - if (os_memcmp(aa, pos->aa, ETH_ALEN) == 0) { - if (pos->pmk_len == pmk_len && - os_memcmp_const(pos->pmk, pmk, pmk_len) == 0 && - os_memcmp_const(pos->pmkid, entry->pmkid, - PMKID_LEN) == 0) { - wpa_printf(MSG_DEBUG, "WPA: reusing previous " - "PMKSA entry"); - os_free(entry); - return pos; - } - if (prev == NULL) - pmksa->pmksa = pos->next; - else - prev->next = pos->next; + /* Replace an old entry for the same Authenticator (if found) with the + * new entry */ + pos = pmksa->pmksa; + prev = NULL; + while (pos) { + if (os_memcmp(aa, pos->aa, ETH_ALEN) == 0) { + if (pos->pmk_len == pmk_len && + os_memcmp_const(pos->pmk, pmk, pmk_len) == 0 && + os_memcmp_const(pos->pmkid, entry->pmkid, + PMKID_LEN) == 0) { + wpa_printf(MSG_DEBUG, "WPA: reusing previous " + "PMKSA entry"); + os_free(entry); + return pos; + } + if (prev == NULL) + pmksa->pmksa = pos->next; + else + prev->next = pos->next; - /* - * If OKC is used, there may be other PMKSA cache - * entries based on the same PMK. These needs to be - * flushed so that a new entry can be created based on - * the new PMK. Only clear other entries if they have a - * matching PMK and this PMK has been used successfully - * with the current AP, i.e., if opportunistic flag has - * been cleared in wpa_supplicant_key_neg_complete(). - */ - wpa_printf(MSG_DEBUG, "RSN: Replace PMKSA entry for " - "the current AP and any PMKSA cache entry " - "that was based on the old PMK"); - if (!pos->opportunistic) - pmksa_cache_flush(pmksa, network_ctx, pos->pmk, - pos->pmk_len); - pmksa_cache_free_entry(pmksa, pos, PMKSA_REPLACE); - break; - } - prev = pos; - pos = pos->next; - } + /* + * If OKC is used, there may be other PMKSA cache + * entries based on the same PMK. These needs to be + * flushed so that a new entry can be created based on + * the new PMK. Only clear other entries if they have a + * matching PMK and this PMK has been used successfully + * with the current AP, i.e., if opportunistic flag has + * been cleared in wpa_supplicant_key_neg_complete(). + */ + wpa_printf(MSG_DEBUG, "RSN: Replace PMKSA entry for " + "the current AP and any PMKSA cache entry " + "that was based on the old PMK"); + if (!pos->opportunistic) + pmksa_cache_flush(pmksa, network_ctx, pos->pmk, + pos->pmk_len); + pmksa_cache_free_entry(pmksa, pos, PMKSA_REPLACE); + break; + } + prev = pos; + pos = pos->next; + } - if (pmksa->pmksa_count >= pmksa_cache_max_entries && pmksa->pmksa) { - /* Remove the oldest entry to make room for the new entry */ - pos = pmksa->pmksa; + if (pmksa->pmksa_count >= pmksa_cache_max_entries && pmksa->pmksa) { + /* Remove the oldest entry to make room for the new entry */ + pos = pmksa->pmksa; - if (pos == pmksa->sm->cur_pmksa) { - /* - * Never remove the current PMKSA cache entry, since - * it's in use, and removing it triggers a needless - * deauthentication. - */ - pos = pos->next; - pmksa->pmksa->next = pos ? pos->next : NULL; - } else - pmksa->pmksa = pos->next; + if (pos == pmksa->sm->cur_pmksa) { + /* + * Never remove the current PMKSA cache entry, since + * it's in use, and removing it triggers a needless + * deauthentication. + */ + pos = pos->next; + pmksa->pmksa->next = pos ? pos->next : NULL; + } else + pmksa->pmksa = pos->next; - if (pos) { - wpa_printf(MSG_DEBUG, "RSN: removed the oldest idle " - "PMKSA cache entry (for " MACSTR ") to " - "make room for new one", - MAC2STR(pos->aa)); - pmksa_cache_free_entry(pmksa, pos, PMKSA_FREE); - } - } + if (pos) { + wpa_printf(MSG_DEBUG, "RSN: removed the oldest idle " + "PMKSA cache entry (for " MACSTR ") to " + "make room for new one", + MAC2STR(pos->aa)); + pmksa_cache_free_entry(pmksa, pos, PMKSA_FREE); + } + } - /* Add the new entry; order by expiration time */ - pos = pmksa->pmksa; - prev = NULL; - while (pos) { - if (pos->expiration > entry->expiration) - break; - prev = pos; - pos = pos->next; - } - if (prev == NULL) { - entry->next = pmksa->pmksa; - pmksa->pmksa = entry; - //pmksa_cache_set_expiration(pmksa); - } else { - entry->next = prev->next; - prev->next = entry; - } - pmksa->pmksa_count++; - wpa_printf(MSG_DEBUG, "RSN: Added PMKSA cache entry for " MACSTR - " network_ctx=%p", MAC2STR(entry->aa), network_ctx); - //wpa_sm_add_pmkid(pmksa->sm, entry->aa, entry->pmkid); + /* Add the new entry; order by expiration time */ + pos = pmksa->pmksa; + prev = NULL; + while (pos) { + if (pos->expiration > entry->expiration) + break; + prev = pos; + pos = pos->next; + } + if (prev == NULL) { + entry->next = pmksa->pmksa; + pmksa->pmksa = entry; + pmksa_cache_set_expiration(pmksa); + } else { + entry->next = prev->next; + prev->next = entry; + } + pmksa->pmksa_count++; + wpa_printf(MSG_DEBUG, "RSN: Added PMKSA cache entry for " MACSTR + " network_ctx=%p", MAC2STR(entry->aa), network_ctx); - return entry; + return entry; } @@ -247,35 +228,35 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len, * @pmk_len: PMK length */ void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx, - const u8 *pmk, size_t pmk_len) + const u8 *pmk, size_t pmk_len) { - struct rsn_pmksa_cache_entry *entry, *prev = NULL, *tmp; - int removed = 0; + struct rsn_pmksa_cache_entry *entry, *prev = NULL, *tmp; + int removed = 0; - entry = pmksa->pmksa; - while (entry) { - if ((entry->network_ctx == network_ctx || - network_ctx == NULL) && - (pmk == NULL || - (pmk_len == entry->pmk_len && - os_memcmp(pmk, entry->pmk, pmk_len) == 0))) { - wpa_printf(MSG_DEBUG, "RSN: Flush PMKSA cache entry " - "for " MACSTR, MAC2STR(entry->aa)); - if (prev) - prev->next = entry->next; - else - pmksa->pmksa = entry->next; - tmp = entry; - entry = entry->next; - pmksa_cache_free_entry(pmksa, tmp, PMKSA_FREE); - removed++; - } else { - prev = entry; - entry = entry->next; - } - } - /*if (removed) - pmksa_cache_set_expiration(pmksa);*/ + entry = pmksa->pmksa; + while (entry) { + if ((entry->network_ctx == network_ctx || + network_ctx == NULL) && + (pmk == NULL || + (pmk_len == entry->pmk_len && + os_memcmp(pmk, entry->pmk, pmk_len) == 0))) { + wpa_printf(MSG_DEBUG, "RSN: Flush PMKSA cache entry " + "for " MACSTR, MAC2STR(entry->aa)); + if (prev) + prev->next = entry->next; + else + pmksa->pmksa = entry->next; + tmp = entry; + entry = entry->next; + pmksa_cache_free_entry(pmksa, tmp, PMKSA_FREE); + removed++; + } else { + prev = entry; + entry = entry->next; + } + } + /*if (removed) + pmksa_cache_set_expiration(pmksa);*/ } @@ -285,20 +266,21 @@ void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx, */ void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa) { - struct rsn_pmksa_cache_entry *entry, *prev; + struct rsn_pmksa_cache_entry *entry, *prev; - if (pmksa == NULL) - return; + if (pmksa == NULL) + return; - entry = pmksa->pmksa; - pmksa->pmksa = NULL; - while (entry) { - prev = entry; - entry = entry->next; - os_free(prev); - } - //pmksa_cache_set_expiration(pmksa); - os_free(pmksa); + entry = pmksa->pmksa; + pmksa->pmksa = NULL; + while (entry) { + prev = entry; + entry = entry->next; + os_free(prev); + } + pmksa_cache_set_expiration(pmksa); + os_free(pmksa); + esp_timer_stop(pmksa->cache_timeout_timer); } @@ -311,41 +293,41 @@ void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa) * Returns: Pointer to PMKSA cache entry or %NULL if no match was found */ struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa, - const u8 *aa, const u8 *pmkid, - const void *network_ctx) + const u8 *aa, const u8 *pmkid, + const void *network_ctx) { - struct rsn_pmksa_cache_entry *entry = pmksa->pmksa; - while (entry) { - if ((aa == NULL || os_memcmp(entry->aa, aa, ETH_ALEN) == 0) && - (pmkid == NULL || - os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0) && - (network_ctx == NULL || network_ctx == entry->network_ctx)) - return entry; - entry = entry->next; - } - return NULL; + struct rsn_pmksa_cache_entry *entry = pmksa->pmksa; + while (entry) { + if ((aa == NULL || os_memcmp(entry->aa, aa, ETH_ALEN) == 0) && + (pmkid == NULL || + os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0) && + (network_ctx == NULL || network_ctx == entry->network_ctx)) + return entry; + entry = entry->next; + } + return NULL; } static struct rsn_pmksa_cache_entry * pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa, - const struct rsn_pmksa_cache_entry *old_entry, - const u8 *aa) + const struct rsn_pmksa_cache_entry *old_entry, + const u8 *aa) { - struct rsn_pmksa_cache_entry *new_entry; + struct rsn_pmksa_cache_entry *new_entry; - new_entry = pmksa_cache_add(pmksa, old_entry->pmk, old_entry->pmk_len, - NULL, 0, - aa, pmksa->sm->own_addr, - old_entry->network_ctx, old_entry->akmp); - if (new_entry == NULL) - return NULL; + new_entry = pmksa_cache_add(pmksa, old_entry->pmk, old_entry->pmk_len, + NULL, 0, + aa, pmksa->sm->own_addr, + old_entry->network_ctx, old_entry->akmp); + if (new_entry == NULL) + return NULL; - /* TODO: reorder entries based on expiration time? */ - new_entry->expiration = old_entry->expiration; - new_entry->opportunistic = 1; + /* TODO: reorder entries based on expiration time? */ + new_entry->expiration = old_entry->expiration; + new_entry->opportunistic = 1; - return new_entry; + return new_entry; } @@ -362,26 +344,26 @@ pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa, */ struct rsn_pmksa_cache_entry * pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa, void *network_ctx, - const u8 *aa) + const u8 *aa) { - struct rsn_pmksa_cache_entry *entry = pmksa->pmksa; + struct rsn_pmksa_cache_entry *entry = pmksa->pmksa; - wpa_printf(MSG_DEBUG, "RSN: Consider " MACSTR " for OKC", MAC2STR(aa)); - if (network_ctx == NULL) - return NULL; - while (entry) { - if (entry->network_ctx == network_ctx) { - entry = pmksa_cache_clone_entry(pmksa, entry, aa); - if (entry) { - wpa_printf(MSG_DEBUG, "RSN: added " - "opportunistic PMKSA cache entry " - "for " MACSTR, MAC2STR(aa)); - } - return entry; - } - entry = entry->next; - } - return NULL; + wpa_printf(MSG_DEBUG, "RSN: Consider " MACSTR " for OKC", MAC2STR(aa)); + if (network_ctx == NULL) + return NULL; + while (entry) { + if (entry->network_ctx == network_ctx) { + entry = pmksa_cache_clone_entry(pmksa, entry, aa); + if (entry) { + wpa_printf(MSG_DEBUG, "RSN: added " + "opportunistic PMKSA cache entry " + "for " MACSTR, MAC2STR(aa)); + } + return entry; + } + entry = entry->next; + } + return NULL; } @@ -392,9 +374,9 @@ pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa, void *network_ctx, */ struct rsn_pmksa_cache_entry * pmksa_cache_get_current(struct wpa_sm *sm) { - if (sm == NULL) - return NULL; - return sm->cur_pmksa; + if (sm == NULL) + return NULL; + return sm->cur_pmksa; } @@ -404,9 +386,9 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get_current(struct wpa_sm *sm) */ void pmksa_cache_clear_current(struct wpa_sm *sm) { - if (sm == NULL) - return; - sm->cur_pmksa = NULL; + if (sm == NULL) + return; + sm->cur_pmksa = NULL; } @@ -420,37 +402,37 @@ void pmksa_cache_clear_current(struct wpa_sm *sm) * Returns: 0 if PMKSA was found or -1 if no matching entry was found */ int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid, - const u8 *bssid, void *network_ctx, - int try_opportunistic) + const u8 *bssid, void *network_ctx, + int try_opportunistic) { - struct rsn_pmksa_cache *pmksa = sm->pmksa; - wpa_printf(MSG_DEBUG, "RSN: PMKSA cache search - network_ctx=%p " - "try_opportunistic=%d", network_ctx, try_opportunistic); - if (pmkid) - wpa_hexdump(MSG_DEBUG, "RSN: Search for PMKID", - pmkid, PMKID_LEN); - if (bssid) - wpa_printf(MSG_DEBUG, "RSN: Search for BSSID " MACSTR, - MAC2STR(bssid)); + struct rsn_pmksa_cache *pmksa = sm->pmksa; + wpa_printf(MSG_DEBUG, "RSN: PMKSA cache search - network_ctx=%p " + "try_opportunistic=%d", network_ctx, try_opportunistic); + if (pmkid) + wpa_hexdump(MSG_DEBUG, "RSN: Search for PMKID", + pmkid, PMKID_LEN); + if (bssid) + wpa_printf(MSG_DEBUG, "RSN: Search for BSSID " MACSTR, + MAC2STR(bssid)); - sm->cur_pmksa = NULL; - if (pmkid) - sm->cur_pmksa = pmksa_cache_get(pmksa, NULL, pmkid, - network_ctx); - if (sm->cur_pmksa == NULL && bssid) - sm->cur_pmksa = pmksa_cache_get(pmksa, bssid, NULL, - network_ctx); - if (sm->cur_pmksa == NULL && try_opportunistic && bssid) - sm->cur_pmksa = pmksa_cache_get_opportunistic(pmksa, - network_ctx, - bssid); - if (sm->cur_pmksa) { - wpa_hexdump(MSG_DEBUG, "RSN: PMKSA cache entry found - PMKID", - sm->cur_pmksa->pmkid, PMKID_LEN); - return 0; - } - wpa_printf(MSG_DEBUG, "RSN: No PMKSA cache entry found"); - return -1; + sm->cur_pmksa = NULL; + if (pmkid) + sm->cur_pmksa = pmksa_cache_get(pmksa, NULL, pmkid, + network_ctx); + if (sm->cur_pmksa == NULL && bssid) + sm->cur_pmksa = pmksa_cache_get(pmksa, bssid, NULL, + network_ctx); + if (sm->cur_pmksa == NULL && try_opportunistic && bssid) + sm->cur_pmksa = pmksa_cache_get_opportunistic(pmksa, + network_ctx, + bssid); + if (sm->cur_pmksa) { + wpa_hexdump(MSG_DEBUG, "RSN: PMKSA cache entry found - PMKID", + sm->cur_pmksa->pmkid, PMKID_LEN); + return 0; + } + wpa_printf(MSG_DEBUG, "RSN: No PMKSA cache entry found"); + return -1; } @@ -466,38 +448,36 @@ int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid, */ int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len) { - int i, ret; - char *pos = buf; - struct rsn_pmksa_cache_entry *entry; - //struct os_reltime now; - - //os_get_reltime(&now); - ret = os_snprintf(pos, buf + len - pos, - "Index / AA / PMKID / expiration (in seconds) / " - "opportunistic\n"); - if (os_snprintf_error(buf + len - pos, ret)) - return pos - buf; - pos += ret; - i = 0; - entry = pmksa->pmksa; - while (entry) { - i++; - ret = os_snprintf(pos, buf + len - pos, "%d " MACSTR " ", - i, MAC2STR(entry->aa)); - if (os_snprintf_error(buf + len - pos, ret)) - return pos - buf; - pos += ret; - pos += wpa_snprintf_hex(pos, buf + len - pos, entry->pmkid, - PMKID_LEN); - ret = os_snprintf(pos, buf + len - pos, " %d %d\n", - (int) (entry->expiration),// - now.sec), - entry->opportunistic); - if (os_snprintf_error(buf + len - pos, ret)) - return pos - buf; - pos += ret; - entry = entry->next; - } - return pos - buf; + int i, ret; + char *pos = buf; + struct rsn_pmksa_cache_entry *entry; + int64_t now_sec = esp_timer_get_time() / 1e6; + ret = os_snprintf(pos, buf + len - pos, + "Index / AA / PMKID / expiration (in seconds) / " + "opportunistic\n"); + if (os_snprintf_error(buf + len - pos, ret)) + return pos - buf; + pos += ret; + i = 0; + entry = pmksa->pmksa; + while (entry) { + i++; + ret = os_snprintf(pos, buf + len - pos, "%d " MACSTR " ", + i, MAC2STR(entry->aa)); + if (os_snprintf_error(buf + len - pos, ret)) + return pos - buf; + pos += ret; + pos += wpa_snprintf_hex(pos, buf + len - pos, entry->pmkid, + PMKID_LEN); + ret = os_snprintf(pos, buf + len - pos, " %d %d\n", + (int) (entry->expiration - now_sec), + entry->opportunistic); + if (os_snprintf_error(buf + len - pos, ret)) + return pos - buf; + pos += ret; + entry = entry->next; + } + return pos - buf; } @@ -510,19 +490,29 @@ int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len) */ struct rsn_pmksa_cache * pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry, - void *ctx, enum pmksa_free_reason reason), - void *ctx, struct wpa_sm *sm) + void *ctx, enum pmksa_free_reason reason), + void *ctx, struct wpa_sm *sm) { - struct rsn_pmksa_cache *pmksa; + struct rsn_pmksa_cache *pmksa; - pmksa = os_zalloc(sizeof(*pmksa)); - if (pmksa) { - pmksa->free_cb = free_cb; - pmksa->ctx = ctx; - pmksa->sm = sm; - } + pmksa = os_zalloc(sizeof(*pmksa)); + if (pmksa) { + pmksa->free_cb = free_cb; + pmksa->ctx = ctx; + pmksa->sm = sm; + pmksa->pmksa_count = 0; + pmksa->pmksa = NULL; - return pmksa; + esp_timer_create_args_t pmksa_cache_timeout_timer_create = { + .callback = &pmksa_cache_expire, + .arg = pmksa, + .dispatch_method = ESP_TIMER_TASK, + .name = "pmksa_timeout_timer" + }; + esp_timer_create(&pmksa_cache_timeout_timer_create, &(pmksa->cache_timeout_timer)); + } + + return pmksa; } #endif /* IEEE8021X_EAPOL */ diff --git a/components/wpa_supplicant/src/rsn_supp/pmksa_cache.h b/components/wpa_supplicant/src/rsn_supp/pmksa_cache.h index f8e040e067..6e314385ca 100644 --- a/components/wpa_supplicant/src/rsn_supp/pmksa_cache.h +++ b/components/wpa_supplicant/src/rsn_supp/pmksa_cache.h @@ -13,102 +13,102 @@ * struct rsn_pmksa_cache_entry - PMKSA cache entry */ struct rsn_pmksa_cache_entry { - struct rsn_pmksa_cache_entry *next; - u8 pmkid[PMKID_LEN]; - u8 pmk[PMK_LEN]; - size_t pmk_len; - os_time_t expiration; - int akmp; /* WPA_KEY_MGMT_* */ - u8 aa[ETH_ALEN]; + struct rsn_pmksa_cache_entry *next; + u8 pmkid[PMKID_LEN]; + u8 pmk[PMK_LEN]; + size_t pmk_len; + os_time_t expiration; + int akmp; /* WPA_KEY_MGMT_* */ + u8 aa[ETH_ALEN]; - os_time_t reauth_time; + os_time_t reauth_time; - /** - * network_ctx - Network configuration context - * - * This field is only used to match PMKSA cache entries to a specific - * network configuration (e.g., a specific SSID and security policy). - * This can be a pointer to the configuration entry, but PMKSA caching - * code does not dereference the value and this could be any kind of - * identifier. - */ - void *network_ctx; - int opportunistic; + /** + * network_ctx - Network configuration context + * + * This field is only used to match PMKSA cache entries to a specific + * network configuration (e.g., a specific SSID and security policy). + * This can be a pointer to the configuration entry, but PMKSA caching + * code does not dereference the value and this could be any kind of + * identifier. + */ + void *network_ctx; + int opportunistic; }; struct rsn_pmksa_cache; enum pmksa_free_reason { - PMKSA_FREE, - PMKSA_REPLACE, - PMKSA_EXPIRE, + PMKSA_FREE, + PMKSA_REPLACE, + PMKSA_EXPIRE, }; #ifdef IEEE8021X_EAPOL struct rsn_pmksa_cache * pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry, - void *ctx, enum pmksa_free_reason reason), - void *ctx, struct wpa_sm *sm); + void *ctx, enum pmksa_free_reason reason), + void *ctx, struct wpa_sm *sm); void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa); struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa, - const u8 *aa, const u8 *pmkid, - const void *network_ctx); + const u8 *aa, const u8 *pmkid, + const void *network_ctx); int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len); struct rsn_pmksa_cache_entry * pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len, - const u8 *kck, size_t kck_len, - const u8 *aa, const u8 *spa, void *network_ctx, int akmp); + const u8 *kck, size_t kck_len, + const u8 *aa, const u8 *spa, void *network_ctx, int akmp); struct rsn_pmksa_cache_entry * pmksa_cache_get_current(struct wpa_sm *sm); void pmksa_cache_clear_current(struct wpa_sm *sm); int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid, - const u8 *bssid, void *network_ctx, - int try_opportunistic); + const u8 *bssid, void *network_ctx, + int try_opportunistic); struct rsn_pmksa_cache_entry * pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa, - void *network_ctx, const u8 *aa); + void *network_ctx, const u8 *aa); void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx, - const u8 *pmk, size_t pmk_len); + const u8 *pmk, size_t pmk_len); #else /* IEEE8021X_EAPOL */ -static inline struct rsn_pmksa_cache * + static inline struct rsn_pmksa_cache * pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry, - void *ctx, enum pmksa_free_reason reason), - void *ctx, struct wpa_sm *sm) + void *ctx, enum pmksa_free_reason reason), + void *ctx, struct wpa_sm *sm) { - return (void *) -1; + return (void *) -1; } static inline void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa) { } -static inline struct rsn_pmksa_cache_entry * + static inline struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa, const u8 *aa, const u8 *pmkid, - const void *network_ctx) + const void *network_ctx) { - return NULL; + return NULL; } -static inline struct rsn_pmksa_cache_entry * + static inline struct rsn_pmksa_cache_entry * pmksa_cache_get_current(struct wpa_sm *sm) { - return NULL; + return NULL; } static inline int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, - size_t len) + size_t len) { - return -1; + return -1; } -static inline struct rsn_pmksa_cache_entry * + static inline struct rsn_pmksa_cache_entry * pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len, - const u8 *kck, size_t kck_len, - const u8 *aa, const u8 *spa, void *network_ctx, int akmp) + const u8 *kck, size_t kck_len, + const u8 *aa, const u8 *spa, void *network_ctx, int akmp) { - return NULL; + return NULL; } static inline void pmksa_cache_clear_current(struct wpa_sm *sm) @@ -116,16 +116,16 @@ static inline void pmksa_cache_clear_current(struct wpa_sm *sm) } static inline int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid, - const u8 *bssid, - void *network_ctx, - int try_opportunistic) + const u8 *bssid, + void *network_ctx, + int try_opportunistic) { - return -1; + return -1; } static inline void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, - void *network_ctx, - const u8 *pmk, size_t pmk_len) + void *network_ctx, + const u8 *pmk, size_t pmk_len) { } diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index c2d56e6a16..bc68cf2b2a 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -528,6 +528,8 @@ void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, if (res) goto failed; + pmksa_cache_set_current(sm, NULL, sm->bssid, 0, 0); + if (sm->renew_snonce) { if (os_get_random(sm->snonce, WPA_NONCE_LEN)) { #ifdef DEBUG_PRINT diff --git a/components/wpa_supplicant/src/utils/common.c b/components/wpa_supplicant/src/utils/common.c index 5b2f9d7758..12d703ec9f 100644 --- a/components/wpa_supplicant/src/utils/common.c +++ b/components/wpa_supplicant/src/utils/common.c @@ -286,7 +286,7 @@ char * wpa_config_parse_string(const char *value, size_t *len) } -int is_hex(const u8 *data, size_t len) +int wpa_is_hex(const u8 *data, size_t len) { size_t i; @@ -298,7 +298,7 @@ int is_hex(const u8 *data, size_t len) } -size_t merge_byte_arrays(u8 *res, size_t res_len, +size_t wpa_merge_byte_arrays(u8 *res, size_t res_len, const u8 *src1, size_t src1_len, const u8 *src2, size_t src2_len) { @@ -344,7 +344,7 @@ char * dup_binstr(const void *src, size_t len) return res; } -void bin_clear_free(void *bin, size_t len) +void wpa_bin_clear_free(void *bin, size_t len) { if (bin) { os_memset(bin, 0, len); diff --git a/components/wpa_supplicant/include/utils/common.h b/components/wpa_supplicant/src/utils/common.h similarity index 91% rename from components/wpa_supplicant/include/utils/common.h rename to components/wpa_supplicant/src/utils/common.h index c5674254ed..7a44beda8a 100644 --- a/components/wpa_supplicant/include/utils/common.h +++ b/components/wpa_supplicant/src/utils/common.h @@ -396,8 +396,8 @@ size_t printf_decode(u8 *buf, size_t maxlen, const char *str); const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len); char * wpa_config_parse_string(const char *value, size_t *len); -int is_hex(const u8 *data, size_t len); -size_t merge_byte_arrays(u8 *res, size_t res_len, +int wpa_is_hex(const u8 *data, size_t len); +size_t wpa_merge_byte_arrays(u8 *res, size_t res_len, const u8 *src1, size_t src1_len, const u8 *src2, size_t src2_len); char * dup_binstr(const void *src, size_t len); @@ -420,7 +420,7 @@ static inline int is_multicast_ether_addr(const u8 *a) #define broadcast_ether_addr (const u8 *) "\xff\xff\xff\xff\xff\xff" -#include "wpa_debug.h" +#include "utils/wpa_debug.h" struct wpa_freq_range_list { @@ -431,32 +431,9 @@ struct wpa_freq_range_list { unsigned int num; }; -int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value); -int freq_range_list_includes(const struct wpa_freq_range_list *list, - unsigned int freq); -char * freq_range_list_str(const struct wpa_freq_range_list *list); - -int int_array_len(const int *a); -void int_array_concat(int **res, const int *a); -void int_array_sort_unique(int *a); -void int_array_add_unique(int **res, int a); - #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -void str_clear_free(char *str); -void bin_clear_free(void *bin, size_t len); - -int random_mac_addr(u8 *addr); -int random_mac_addr_keep_oui(u8 *addr); - -const char * cstr_token(const char *str, const char *delim, const char **last); -char * str_token(char *str, const char *delim, char **context); -size_t utf8_escape(const char *inp, size_t in_size, - char *outp, size_t out_size); -size_t utf8_unescape(const char *inp, size_t in_size, - char *outp, size_t out_size); -int is_ctrl_char(char c); - +void wpa_bin_clear_free(void *bin, size_t len); /* * gcc 4.4 ends up generating strict-aliasing warnings about some very common