Enable use of PMKSA caching independent of RSN supplicant state machine
Allow PMKSA caching functionality to be used even if sm, current_cb, and free_cb are uninitialized. This makes RSN supplicant state machine independent PMKSA caching possible for other modules, enabling functional reuse. Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
parent
1d0ee1908b
commit
10e455c44a
1 changed files with 34 additions and 10 deletions
|
@ -45,12 +45,14 @@ static void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa,
|
||||||
struct rsn_pmksa_cache_entry *entry,
|
struct rsn_pmksa_cache_entry *entry,
|
||||||
enum pmksa_free_reason reason)
|
enum pmksa_free_reason reason)
|
||||||
{
|
{
|
||||||
wpa_sm_remove_pmkid(pmksa->sm, entry->network_ctx, entry->aa,
|
if (pmksa->sm)
|
||||||
entry->pmkid,
|
wpa_sm_remove_pmkid(pmksa->sm, entry->network_ctx, entry->aa,
|
||||||
entry->fils_cache_id_set ? entry->fils_cache_id :
|
entry->pmkid,
|
||||||
NULL);
|
entry->fils_cache_id_set ?
|
||||||
|
entry->fils_cache_id : NULL);
|
||||||
pmksa->pmksa_count--;
|
pmksa->pmksa_count--;
|
||||||
pmksa->free_cb(entry, pmksa->ctx, reason);
|
if (pmksa->free_cb)
|
||||||
|
pmksa->free_cb(entry, pmksa->ctx, reason);
|
||||||
_pmksa_cache_free_entry(entry);
|
_pmksa_cache_free_entry(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +66,7 @@ static void pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
|
||||||
|
|
||||||
os_get_reltime(&now);
|
os_get_reltime(&now);
|
||||||
while (entry && entry->expiration <= now.sec) {
|
while (entry && entry->expiration <= now.sec) {
|
||||||
if (wpa_key_mgmt_sae(entry->akmp) &&
|
if (wpa_key_mgmt_sae(entry->akmp) && pmksa->is_current_cb &&
|
||||||
pmksa->is_current_cb(entry, pmksa->ctx)) {
|
pmksa->is_current_cb(entry, pmksa->ctx)) {
|
||||||
/* Do not expire the currently used PMKSA entry for SAE
|
/* Do not expire the currently used PMKSA entry for SAE
|
||||||
* since there is no convenient mechanism for
|
* since there is no convenient mechanism for
|
||||||
|
@ -97,6 +99,10 @@ static void pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
|
||||||
static void pmksa_cache_reauth(void *eloop_ctx, void *timeout_ctx)
|
static void pmksa_cache_reauth(void *eloop_ctx, void *timeout_ctx)
|
||||||
{
|
{
|
||||||
struct rsn_pmksa_cache *pmksa = eloop_ctx;
|
struct rsn_pmksa_cache *pmksa = eloop_ctx;
|
||||||
|
|
||||||
|
if (!pmksa->sm)
|
||||||
|
return;
|
||||||
|
|
||||||
pmksa->sm->cur_pmksa = NULL;
|
pmksa->sm->cur_pmksa = NULL;
|
||||||
eapol_sm_request_reauth(pmksa->sm->eapol);
|
eapol_sm_request_reauth(pmksa->sm->eapol);
|
||||||
}
|
}
|
||||||
|
@ -117,6 +123,7 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa)
|
||||||
if (sec < 0) {
|
if (sec < 0) {
|
||||||
sec = 0;
|
sec = 0;
|
||||||
if (wpa_key_mgmt_sae(pmksa->pmksa->akmp) &&
|
if (wpa_key_mgmt_sae(pmksa->pmksa->akmp) &&
|
||||||
|
pmksa->is_current_cb &&
|
||||||
pmksa->is_current_cb(pmksa->pmksa, pmksa->ctx)) {
|
pmksa->is_current_cb(pmksa->pmksa, pmksa->ctx)) {
|
||||||
/* Do not continue polling for the current PMKSA entry
|
/* Do not continue polling for the current PMKSA entry
|
||||||
* from SAE to expire every second. Use the expiration
|
* from SAE to expire every second. Use the expiration
|
||||||
|
@ -137,6 +144,9 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa)
|
||||||
}
|
}
|
||||||
eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, pmksa, NULL);
|
eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, pmksa, NULL);
|
||||||
|
|
||||||
|
if (!pmksa->sm)
|
||||||
|
return;
|
||||||
|
|
||||||
entry = pmksa->sm->cur_pmksa ? pmksa->sm->cur_pmksa :
|
entry = pmksa->sm->cur_pmksa ? pmksa->sm->cur_pmksa :
|
||||||
pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL, 0);
|
pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL, 0);
|
||||||
if (entry && !wpa_key_mgmt_sae(entry->akmp)) {
|
if (entry && !wpa_key_mgmt_sae(entry->akmp)) {
|
||||||
|
@ -177,6 +187,8 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
||||||
{
|
{
|
||||||
struct rsn_pmksa_cache_entry *entry;
|
struct rsn_pmksa_cache_entry *entry;
|
||||||
struct os_reltime now;
|
struct os_reltime now;
|
||||||
|
unsigned int pmk_lifetime = 43200;
|
||||||
|
unsigned int pmk_reauth_threshold = 70;
|
||||||
|
|
||||||
if (pmk_len > PMK_LEN_MAX)
|
if (pmk_len > PMK_LEN_MAX)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -198,9 +210,14 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
||||||
else
|
else
|
||||||
rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid, akmp);
|
rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid, akmp);
|
||||||
os_get_reltime(&now);
|
os_get_reltime(&now);
|
||||||
entry->expiration = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime;
|
if (pmksa->sm) {
|
||||||
entry->reauth_time = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime *
|
pmk_lifetime = pmksa->sm->dot11RSNAConfigPMKLifetime;
|
||||||
pmksa->sm->dot11RSNAConfigPMKReauthThreshold / 100;
|
pmk_reauth_threshold =
|
||||||
|
pmksa->sm->dot11RSNAConfigPMKReauthThreshold;
|
||||||
|
}
|
||||||
|
entry->expiration = now.sec + pmk_lifetime;
|
||||||
|
entry->reauth_time = now.sec +
|
||||||
|
pmk_lifetime * pmk_reauth_threshold / 100;
|
||||||
entry->akmp = akmp;
|
entry->akmp = akmp;
|
||||||
if (cache_id) {
|
if (cache_id) {
|
||||||
entry->fils_cache_id_set = 1;
|
entry->fils_cache_id_set = 1;
|
||||||
|
@ -267,7 +284,7 @@ pmksa_cache_add_entry(struct rsn_pmksa_cache *pmksa,
|
||||||
/* Remove the oldest entry to make room for the new entry */
|
/* Remove the oldest entry to make room for the new entry */
|
||||||
pos = pmksa->pmksa;
|
pos = pmksa->pmksa;
|
||||||
|
|
||||||
if (pos == pmksa->sm->cur_pmksa) {
|
if (pmksa->sm && pos == pmksa->sm->cur_pmksa) {
|
||||||
/*
|
/*
|
||||||
* Never remove the current PMKSA cache entry, since
|
* Never remove the current PMKSA cache entry, since
|
||||||
* it's in use, and removing it triggers a needless
|
* it's in use, and removing it triggers a needless
|
||||||
|
@ -308,6 +325,10 @@ pmksa_cache_add_entry(struct rsn_pmksa_cache *pmksa,
|
||||||
wpa_printf(MSG_DEBUG, "RSN: Added PMKSA cache entry for " MACSTR
|
wpa_printf(MSG_DEBUG, "RSN: Added PMKSA cache entry for " MACSTR
|
||||||
" network_ctx=%p akmp=0x%x", MAC2STR(entry->aa),
|
" network_ctx=%p akmp=0x%x", MAC2STR(entry->aa),
|
||||||
entry->network_ctx, entry->akmp);
|
entry->network_ctx, entry->akmp);
|
||||||
|
|
||||||
|
if (!pmksa->sm)
|
||||||
|
return entry;
|
||||||
|
|
||||||
wpa_sm_add_pmkid(pmksa->sm, entry->network_ctx, entry->aa, entry->pmkid,
|
wpa_sm_add_pmkid(pmksa->sm, entry->network_ctx, entry->aa, entry->pmkid,
|
||||||
entry->fils_cache_id_set ? entry->fils_cache_id : NULL,
|
entry->fils_cache_id_set ? entry->fils_cache_id : NULL,
|
||||||
entry->pmk, entry->pmk_len,
|
entry->pmk, entry->pmk_len,
|
||||||
|
@ -423,6 +444,9 @@ pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa,
|
||||||
os_time_t old_reauth_time = old_entry->reauth_time;
|
os_time_t old_reauth_time = old_entry->reauth_time;
|
||||||
const u8 *pmkid = NULL;
|
const u8 *pmkid = NULL;
|
||||||
|
|
||||||
|
if (!pmksa->sm)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (wpa_key_mgmt_sae(old_entry->akmp) ||
|
if (wpa_key_mgmt_sae(old_entry->akmp) ||
|
||||||
wpa_key_mgmt_fils(old_entry->akmp))
|
wpa_key_mgmt_fils(old_entry->akmp))
|
||||||
pmkid = old_entry->pmkid;
|
pmkid = old_entry->pmkid;
|
||||||
|
|
Loading…
Add table
Reference in a new issue