Commit 787fb926 authored by Chung-Hsien Hsu's avatar Chung-Hsien Hsu Committed by Kalle Valo

brcmfmac: support 4-way handshake offloading for WPA/WPA2-PSK in AP mode

Firmware may have authenticator code built-in. This is detected by the
driver and indicated in the wiphy features flags. User space can use
this flag to determine whether or not to provide the pre-shared key
material in the nl80211 start AP command to offload the 4-way handshake
in AP mode.
Signed-off-by: default avatarChung-Hsien Hsu <stanley.hsu@cypress.com>
Signed-off-by: default avatarChi-Hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200817073316.33402-3-stanley.hsu@cypress.com
parent 5a6bd84f
...@@ -4679,6 +4679,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, ...@@ -4679,6 +4679,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_pub *drvr = cfg->pub; struct brcmf_pub *drvr = cfg->pub;
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct cfg80211_crypto_settings *crypto = &settings->crypto;
const struct brcmf_tlv *ssid_ie; const struct brcmf_tlv *ssid_ie;
const struct brcmf_tlv *country_ie; const struct brcmf_tlv *country_ie;
struct brcmf_ssid_le ssid_le; struct brcmf_ssid_le ssid_le;
...@@ -4818,6 +4820,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, ...@@ -4818,6 +4820,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
goto exit; goto exit;
} }
if (crypto->psk) {
brcmf_dbg(INFO, "using PSK offload\n");
profile->use_fwauth |= BIT(BRCMF_PROFILE_FWAUTH_PSK);
err = brcmf_set_pmk(ifp, crypto->psk,
BRCMF_WSEC_MAX_PSK_LEN);
if (err < 0)
goto exit;
}
if (profile->use_fwauth == 0)
profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE);
err = brcmf_parse_configure_security(ifp, settings, err = brcmf_parse_configure_security(ifp, settings,
NL80211_IFTYPE_AP); NL80211_IFTYPE_AP);
if (err < 0) { if (err < 0) {
...@@ -4904,6 +4917,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) ...@@ -4904,6 +4917,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_pub *drvr = cfg->pub; struct brcmf_pub *drvr = cfg->pub;
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
s32 err; s32 err;
struct brcmf_fil_bss_enable_le bss_enable; struct brcmf_fil_bss_enable_le bss_enable;
struct brcmf_join_params join_params; struct brcmf_join_params join_params;
...@@ -4915,6 +4929,12 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) ...@@ -4915,6 +4929,12 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
/* first to make sure they get processed by fw. */ /* first to make sure they get processed by fw. */
msleep(400); msleep(400);
if (profile->use_fwauth != BIT(BRCMF_PROFILE_FWAUTH_NONE)) {
if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_PSK))
brcmf_set_pmk(ifp, NULL, 0);
profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE);
}
if (ifp->vif->mbss) { if (ifp->vif->mbss) {
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1); err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
return err; return err;
...@@ -7063,6 +7083,9 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) ...@@ -7063,6 +7083,9 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
wiphy_ext_feature_set(wiphy, wiphy_ext_feature_set(wiphy,
NL80211_EXT_FEATURE_SAE_OFFLOAD); NL80211_EXT_FEATURE_SAE_OFFLOAD);
} }
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWAUTH))
wiphy_ext_feature_set(wiphy,
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK);
wiphy->mgmt_stypes = brcmf_txrx_stypes; wiphy->mgmt_stypes = brcmf_txrx_stypes;
wiphy->max_remain_on_channel_duration = 5000; wiphy->max_remain_on_channel_duration = 5000;
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) { if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
......
...@@ -128,6 +128,17 @@ enum brcmf_profile_fwsup { ...@@ -128,6 +128,17 @@ enum brcmf_profile_fwsup {
BRCMF_PROFILE_FWSUP_SAE BRCMF_PROFILE_FWSUP_SAE
}; };
/**
* enum brcmf_profile_fwauth - firmware authenticator profile
*
* @BRCMF_PROFILE_FWAUTH_NONE: no firmware authenticator
* @BRCMF_PROFILE_FWAUTH_PSK: authenticator for WPA/WPA2-PSK
*/
enum brcmf_profile_fwauth {
BRCMF_PROFILE_FWAUTH_NONE,
BRCMF_PROFILE_FWAUTH_PSK
};
/** /**
* struct brcmf_cfg80211_profile - profile information. * struct brcmf_cfg80211_profile - profile information.
* *
...@@ -140,6 +151,7 @@ struct brcmf_cfg80211_profile { ...@@ -140,6 +151,7 @@ struct brcmf_cfg80211_profile {
struct brcmf_cfg80211_security sec; struct brcmf_cfg80211_security sec;
struct brcmf_wsec_key key[BRCMF_MAX_DEFAULT_KEYS]; struct brcmf_wsec_key key[BRCMF_MAX_DEFAULT_KEYS];
enum brcmf_profile_fwsup use_fwsup; enum brcmf_profile_fwsup use_fwsup;
u16 use_fwauth;
bool is_ft; bool is_ft;
}; };
......
...@@ -42,6 +42,7 @@ static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = { ...@@ -42,6 +42,7 @@ static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
{ BRCMF_FEAT_MONITOR_FMT_RADIOTAP, "rtap" }, { BRCMF_FEAT_MONITOR_FMT_RADIOTAP, "rtap" },
{ BRCMF_FEAT_DOT11H, "802.11h" }, { BRCMF_FEAT_DOT11H, "802.11h" },
{ BRCMF_FEAT_SAE, "sae" }, { BRCMF_FEAT_SAE, "sae" },
{ BRCMF_FEAT_FWAUTH, "idauth" },
}; };
#ifdef DEBUG #ifdef DEBUG
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
* MONITOR_FMT_HW_RX_HDR: firmware provides monitor packets with hw/ucode header * MONITOR_FMT_HW_RX_HDR: firmware provides monitor packets with hw/ucode header
* DOT11H: firmware supports 802.11h * DOT11H: firmware supports 802.11h
* SAE: simultaneous authentication of equals * SAE: simultaneous authentication of equals
* FWAUTH: Firmware authenticator
*/ */
#define BRCMF_FEAT_LIST \ #define BRCMF_FEAT_LIST \
BRCMF_FEAT_DEF(MBSS) \ BRCMF_FEAT_DEF(MBSS) \
...@@ -49,7 +50,8 @@ ...@@ -49,7 +50,8 @@
BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) \ BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) \
BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) \ BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) \
BRCMF_FEAT_DEF(DOT11H) \ BRCMF_FEAT_DEF(DOT11H) \
BRCMF_FEAT_DEF(SAE) BRCMF_FEAT_DEF(SAE) \
BRCMF_FEAT_DEF(FWAUTH)
/* /*
* Quirks: * Quirks:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment