[PATCH 11/15] netdev: add support to use PMKSA over SAE if available

James Prestwood
2024-11-22T15:16:12Z

This was quite simple and only requiring caching the PMKSA after a
successful handshake, and using the correct authentication type
for connections if we have a prior PMKSA cached.

This is only being added for initial SAE associations for now since
this is where we gain the biggest improvement, in addition to the
requirement by the WiFi alliance to label products as "WPA3 capable"
---
src/netdev.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)

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;
--
2.34.1