From 4fbfa76fc58fbdfae84a964511c6b8c7f474371f Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Thu, 13 Aug 2020 14:27:14 -0500 Subject: [PATCH] wiphy: Fix not attempting WPA3 connections for APs in transition mode Fix a logic error which prevented iwd from using SAE/WPA3 when attempting to connect to APs that are in transition mode. The SAE/WPA3 check incorrectly required mfpr bit to be set, which is true for APs in WPA3-Personal only mode, but is set to 0 for APs in WPA3-Personal transition mode. This patch also adds a bit more diagnostic output to help diagnose causes for connections where WPA3 is not attempted even when advertised by the AP. --- src/ie.c | 27 +++++++++++++++++++++++++++ src/ie.h | 1 + src/wiphy.c | 38 +++++++++++++++++++++++++++++--------- 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/ie.c b/src/ie.c index 4b2e3780..633f8015 100644 --- a/src/ie.c +++ b/src/ie.c @@ -1175,6 +1175,33 @@ bool ie_build_rsne(const struct ie_rsn_info *info, uint8_t *to) return true; } +bool ie_rsne_is_wpa3_personal(const struct ie_rsn_info *info) +{ + bool is_transition = info->akm_suites & IE_RSN_AKM_SUITE_PSK; + /* + * WPA3 Specification, Version 2 + * + * Section 2.2 WPA3-Personal only Mode: + * 1. An AP shall enable at least AKM suite selector 00-0F-AC:8 in + * the BSS + * 3. An AP shall not enable AKM suite selector: 00-0F-AC:2, 00-0F-AC:6 + * 5. an AP shall set MFPC to 1, MFPR to 1 + * + * Section 2.3 WPA3-Personal transition Mode: + * 1. an AP shall enable at least AKM suite selectors 00-0F-AC:2 and + * 00-0F-AC:8 in the BSS + * 3. an AP should enable AKM suite selector: 00-0F-AC:6 + * 5. an AP shall set MFPC to 1, MFPR to 0 + */ + if (!(info->akm_suites & IE_RSN_AKM_SUITE_SAE_SHA256)) + return false; + + if (!info->mfpc) + return false; + + return is_transition || info->mfpr; +} + bool ie_build_osen(const struct ie_rsn_info *info, uint8_t *to) { unsigned int pos; diff --git a/src/ie.h b/src/ie.h index 47dc9eff..995f0e4f 100644 --- a/src/ie.h +++ b/src/ie.h @@ -453,6 +453,7 @@ int ie_parse_rsne(struct ie_tlv_iter *iter, struct ie_rsn_info *info); int ie_parse_rsne_from_data(const uint8_t *data, size_t len, struct ie_rsn_info *info); bool ie_build_rsne(const struct ie_rsn_info *info, uint8_t *to); +bool ie_rsne_is_wpa3_personal(const struct ie_rsn_info *info); int ie_parse_wpa(struct ie_tlv_iter *iter, struct ie_rsn_info *out_info); int ie_parse_wpa_from_data(const uint8_t *data, size_t len, diff --git a/src/wiphy.c b/src/wiphy.c index 47be2c85..3adc5669 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -173,22 +173,42 @@ enum ie_rsn_akm_suite wiphy_select_akm(struct wiphy *wiphy, } else if (security == SECURITY_PSK) { /* * Prefer connecting to SAE/WPA3 network, but only if SAE is - * supported, we are MFP capable, and the AP has set the MFPR - * bit. If any of these conditions are not met, we can fallback - * to WPA2 (if the AKM is present). + * supported, we are MFP capable, and the AP has set the + * MFPR/MFPC bits correctly. If any of these conditions are not + * met, we can fallback to WPA2 (if the AKM is present). */ - if (wiphy->supported_ciphers & IE_RSN_CIPHER_SUITE_BIP && - wiphy_has_feature(wiphy, NL80211_FEATURE_SAE) && - info.mfpr) { - if ((info.akm_suites & - IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256) && - wiphy->support_cmds_auth_assoc) + if (ie_rsne_is_wpa3_personal(&info)) { + l_debug("Network is WPA3-Personal..."); + + if (!(wiphy->supported_ciphers & + IE_RSN_CIPHER_SUITE_BIP)) { + l_debug("HW not MFP capable, trying WPA2"); + goto wpa2_personal; + } + + /* + * TODO: Only SoftMAC (mac80211) drivers are currently + * capable of SAE since it requires ability to send + * Authenticate and Associate frames (which is given by + * support_cmds_auth_assoc). FullMAC drivers require + * SAE offload which we do not support nor supported + * in any upstream driver as of this time. + */ + if (!wiphy_has_feature(wiphy, NL80211_FEATURE_SAE) || + !wiphy->support_cmds_auth_assoc) { + l_debug("No HW WPA3 support, trying WPA2"); + goto wpa2_personal; + } + + if (info.akm_suites & + IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256) return IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256; if (info.akm_suites & IE_RSN_AKM_SUITE_SAE_SHA256) return IE_RSN_AKM_SUITE_SAE_SHA256; } +wpa2_personal: if ((info.akm_suites & IE_RSN_AKM_SUITE_FT_USING_PSK) && bss->rsne && bss->mde_present && wiphy->support_cmds_auth_assoc)