@@ -56,6 +56,7 @@
#define RSN_AKM_PSK 2 /* Pre-shared Key */
#define RSN_AKM_SHA256_1X 5 /* SHA256, 802.1X */
#define RSN_AKM_SHA256_PSK 6 /* SHA256, Pre-shared Key */
+#define RSN_AKM_SAE 8 /* SAE */
#define RSN_CAP_LEN 2 /* Length of RSN capabilities */
#define RSN_CAP_PTK_REPLAY_CNTR_MASK (BIT(2) | BIT(3))
#define RSN_CAP_MFPR_MASK BIT(6)
@@ -4236,6 +4237,10 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
wpa_auth |= WPA2_AUTH_1X_SHA256;
break;
+ case RSN_AKM_SAE:
+ brcmf_dbg(TRACE, "RSN_AKM_SAE\n");
+ wpa_auth |= WPA3_AUTH_SAE_PSK;
+ break;
default:
bphy_err(drvr, "Invalid key mgmt info\n");
}
@@ -4253,11 +4258,12 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
brcmf_dbg(TRACE, "MFP Required\n");
mfp = BRCMF_MFP_REQUIRED;
/* Firmware only supports mfp required in
- * combination with WPA2_AUTH_PSK_SHA256 or
- * WPA2_AUTH_1X_SHA256.
+ * combination with WPA2_AUTH_PSK_SHA256,
+ * WPA2_AUTH_1X_SHA256, or WPA3_AUTH_SAE_PSK.
*/
if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
- WPA2_AUTH_1X_SHA256))) {
+ WPA2_AUTH_1X_SHA256 |
+ WPA3_AUTH_SAE_PSK))) {
err = -EINVAL;
goto exit;
}
@@ -4822,6 +4828,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
if (err < 0)
goto exit;
}
+ if (crypto->sae_pwd) {
+ brcmf_dbg(INFO, "using SAE offload\n");
+ profile->use_fwauth |= BIT(BRCMF_PROFILE_FWAUTH_SAE);
+ err = brcmf_set_sae_password(ifp, crypto->sae_pwd,
+ crypto->sae_pwd_len);
+ if (err < 0)
+ goto exit;
+ }
if (profile->use_fwauth == 0)
profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE);
@@ -4924,6 +4938,8 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
if (profile->use_fwauth != BIT(BRCMF_PROFILE_FWAUTH_NONE)) {
if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_PSK))
brcmf_set_pmk(ifp, NULL, 0);
+ if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_SAE))
+ brcmf_set_sae_password(ifp, NULL, 0);
profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE);
}
@@ -7066,9 +7082,13 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
wiphy_ext_feature_set(wiphy,
NL80211_EXT_FEATURE_SAE_OFFLOAD);
}
- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWAUTH))
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWAUTH)) {
wiphy_ext_feature_set(wiphy,
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK);
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE))
+ wiphy_ext_feature_set(wiphy,
+ NL80211_EXT_FEATURE_SAE_OFFLOAD);
+ }
wiphy->mgmt_stypes = brcmf_txrx_stypes;
wiphy->max_remain_on_channel_duration = 5000;
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
@@ -133,10 +133,12 @@ enum brcmf_profile_fwsup {
*
* @BRCMF_PROFILE_FWAUTH_NONE: no firmware authenticator
* @BRCMF_PROFILE_FWAUTH_PSK: authenticator for WPA/WPA2-PSK
+ * @BRCMF_PROFILE_FWAUTH_PSK: authenticator for SAE
*/
enum brcmf_profile_fwauth {
BRCMF_PROFILE_FWAUTH_NONE,
- BRCMF_PROFILE_FWAUTH_PSK
+ BRCMF_PROFILE_FWAUTH_PSK,
+ BRCMF_PROFILE_FWAUTH_SAE
};
/**