]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Enable use of PMKSA caching independent of RSN supplicant state machine
authorVinay Gannevaram <quic_vganneva@quicinc.com>
Sun, 18 Sep 2022 18:01:51 +0000 (23:31 +0530)
committerJouni Malinen <j@w1.fi>
Thu, 3 Nov 2022 22:19:14 +0000 (00:19 +0200)
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>
src/rsn_supp/pmksa_cache.c

index 0cd5159821bb2e5c5f195d869c0490970d7ade2f..07f731cca68c2d67600ff9ad188c30308e6f56fc 100644 (file)
@@ -45,12 +45,14 @@ static void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa,
                                   struct rsn_pmksa_cache_entry *entry,
                                   enum pmksa_free_reason reason)
 {
-       wpa_sm_remove_pmkid(pmksa->sm, entry->network_ctx, entry->aa,
-                           entry->pmkid,
-                           entry->fils_cache_id_set ? entry->fils_cache_id :
-                           NULL);
+       if (pmksa->sm)
+               wpa_sm_remove_pmkid(pmksa->sm, entry->network_ctx, entry->aa,
+                                   entry->pmkid,
+                                   entry->fils_cache_id_set ?
+                                   entry->fils_cache_id : NULL);
        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);
 }
 
@@ -64,7 +66,7 @@ static void pmksa_cache_expire(void *eloop_ctx, void *timeout_ctx)
 
        os_get_reltime(&now);
        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)) {
                        /* Do not expire the currently used PMKSA entry for SAE
                         * 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)
 {
        struct rsn_pmksa_cache *pmksa = eloop_ctx;
+
+       if (!pmksa->sm)
+               return;
+
        pmksa->sm->cur_pmksa = NULL;
        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) {
                sec = 0;
                if (wpa_key_mgmt_sae(pmksa->pmksa->akmp) &&
+                   pmksa->is_current_cb &&
                    pmksa->is_current_cb(pmksa->pmksa, pmksa->ctx)) {
                        /* Do not continue polling for the current PMKSA entry
                         * 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);
 
+       if (!pmksa->sm)
+               return;
+
        entry = pmksa->sm->cur_pmksa ? pmksa->sm->cur_pmksa :
                pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL, 0);
        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 os_reltime now;
+       unsigned int pmk_lifetime = 43200;
+       unsigned int pmk_reauth_threshold = 70;
 
        if (pmk_len > PMK_LEN_MAX)
                return NULL;
@@ -198,9 +210,14 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
        else
                rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid, akmp);
        os_get_reltime(&now);
-       entry->expiration = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime;
-       entry->reauth_time = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime *
-               pmksa->sm->dot11RSNAConfigPMKReauthThreshold / 100;
+       if (pmksa->sm) {
+               pmk_lifetime = pmksa->sm->dot11RSNAConfigPMKLifetime;
+               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;
        if (cache_id) {
                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 */
                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
                         * 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
                   " network_ctx=%p akmp=0x%x", MAC2STR(entry->aa),
                   entry->network_ctx, entry->akmp);
+
+       if (!pmksa->sm)
+               return entry;
+
        wpa_sm_add_pmkid(pmksa->sm, entry->network_ctx, entry->aa, entry->pmkid,
                         entry->fils_cache_id_set ? entry->fils_cache_id : NULL,
                         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;
        const u8 *pmkid = NULL;
 
+       if (!pmksa->sm)
+               return NULL;
+
        if (wpa_key_mgmt_sae(old_entry->akmp) ||
            wpa_key_mgmt_fils(old_entry->akmp))
                pmkid = old_entry->pmkid;