diff --git a/src/netdev.c b/src/netdev.c index 4dccb78a..02496c92 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -65,6 +65,7 @@ #include "src/frame-xchg.h" #include "src/diagnostic.h" #include "src/band.h" +#include "src/pmksa.h" #ifndef ENOTSUPP #define ENOTSUPP 524 @@ -1517,6 +1518,8 @@ static void try_handshake_complete(struct netdev_handshake_state *nhs) l_debug("Invoking handshake_event()"); + handshake_state_cache_pmksa(&nhs->super); + if (handshake_event(&nhs->super, HANDSHAKE_EVENT_COMPLETE)) return; @@ -2458,7 +2461,19 @@ static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev, { struct netdev_handshake_state *nhs = l_container_of(hs, struct netdev_handshake_state, super); - uint32_t auth_type = IE_AKM_IS_SAE(hs->akm_suite) ? + /* + * Choose Open system auth type if PMKSA caching is used for an SAE AKM: + * + * IEEE 802.11-2020 Table 9-151 + * - SAE authentication: + * 3 (SAE) for SAE Authentication + * 0 (open) for PMKSA caching + * - FT authentication over SAE: + * 3 (SAE) for FT Initial Mobility Domain Association + * 0 (open) for FT Initial Mobility Domain Association over + * PMKSA caching + */ + uint32_t auth_type = IE_AKM_IS_SAE(hs->akm_suite) && !hs->have_pmksa ? NL80211_AUTHTYPE_SAE : NL80211_AUTHTYPE_OPEN_SYSTEM; enum mpdu_management_subtype subtype = prev_bssid ? @@ -4027,6 +4042,15 @@ static void netdev_connect_common(struct netdev *netdev, goto done; } + /* + * If SAE, and we have a valid PMKSA cache we can skip the entire SAE + * protocol and authenticate using the cached keys. + */ + if (IE_AKM_IS_SAE(hs->akm_suite) && hs->have_pmksa) { + l_debug("Skipping SAE by using PMKSA cache"); + goto build_cmd_connect; + } + if (!IE_AKM_IS_SAE(hs->akm_suite) || nhs->type == CONNECTION_TYPE_SAE_OFFLOAD) goto build_cmd_connect;