mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-18 05:27:17 +07:00
brcmfmac: add support for SAE authentication offload
The firmware may have SAE authentication 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 password material for SAE authentication in the nl80211 CONNECT command. Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com> Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
f4268729eb
commit
3b1e0a7bdf
@ -1282,6 +1282,31 @@ static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int brcmf_set_sae_password(struct brcmf_if *ifp, const u8 *pwd_data,
|
||||
u16 pwd_len)
|
||||
{
|
||||
struct brcmf_pub *drvr = ifp->drvr;
|
||||
struct brcmf_wsec_sae_pwd_le sae_pwd;
|
||||
int err;
|
||||
|
||||
if (pwd_len > BRCMF_WSEC_MAX_SAE_PASSWORD_LEN) {
|
||||
bphy_err(drvr, "sae_password must be less than %d\n",
|
||||
BRCMF_WSEC_MAX_SAE_PASSWORD_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sae_pwd.key_len = cpu_to_le16(pwd_len);
|
||||
memcpy(sae_pwd.key, pwd_data, pwd_len);
|
||||
|
||||
err = brcmf_fil_iovar_data_set(ifp, "sae_password", &sae_pwd,
|
||||
sizeof(sae_pwd));
|
||||
if (err < 0)
|
||||
bphy_err(drvr, "failed to set SAE password in firmware (len=%u)\n",
|
||||
pwd_len);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
|
||||
@ -1505,6 +1530,8 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
|
||||
val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
|
||||
else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
|
||||
val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
|
||||
else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_3)
|
||||
val = WPA3_AUTH_SAE_PSK;
|
||||
else
|
||||
val = WPA_AUTH_DISABLED;
|
||||
brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
|
||||
@ -1537,6 +1564,10 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
|
||||
val = 1;
|
||||
brcmf_dbg(CONN, "shared key\n");
|
||||
break;
|
||||
case NL80211_AUTHTYPE_SAE:
|
||||
val = 3;
|
||||
brcmf_dbg(CONN, "SAE authentication\n");
|
||||
break;
|
||||
default:
|
||||
val = 2;
|
||||
brcmf_dbg(CONN, "automatic, auth type (%d)\n", sme->auth_type);
|
||||
@ -1705,6 +1736,16 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
|
||||
sme->crypto.cipher_group);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (val & WPA3_AUTH_SAE_PSK) {
|
||||
switch (sme->crypto.akm_suites[0]) {
|
||||
case WLAN_AKM_SUITE_SAE:
|
||||
val = WPA3_AUTH_SAE_PSK;
|
||||
break;
|
||||
default:
|
||||
bphy_err(drvr, "invalid cipher group (%d)\n",
|
||||
sme->crypto.cipher_group);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X)
|
||||
@ -1776,7 +1817,8 @@ brcmf_set_sharedkey(struct net_device *ndev,
|
||||
brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
|
||||
sec->wpa_versions, sec->cipher_pairwise);
|
||||
|
||||
if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
|
||||
if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2 |
|
||||
NL80211_WPA_VERSION_3))
|
||||
return 0;
|
||||
|
||||
if (!(sec->cipher_pairwise &
|
||||
@ -1983,7 +2025,13 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (sme->crypto.psk) {
|
||||
if (sme->crypto.sae_pwd) {
|
||||
brcmf_dbg(INFO, "using SAE offload\n");
|
||||
profile->use_fwsup = BRCMF_PROFILE_FWSUP_SAE;
|
||||
}
|
||||
|
||||
if (sme->crypto.psk &&
|
||||
profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) {
|
||||
if (WARN_ON(profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE)) {
|
||||
err = -EINVAL;
|
||||
goto done;
|
||||
@ -2001,12 +2049,23 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
|
||||
}
|
||||
}
|
||||
|
||||
if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK) {
|
||||
if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK)
|
||||
err = brcmf_set_pmk(ifp, sme->crypto.psk,
|
||||
BRCMF_WSEC_MAX_PSK_LEN);
|
||||
if (err)
|
||||
else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) {
|
||||
/* clean up user-space RSNE */
|
||||
if (brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0)) {
|
||||
bphy_err(drvr, "failed to clean up user-space RSNE\n");
|
||||
goto done;
|
||||
}
|
||||
err = brcmf_set_sae_password(ifp, sme->crypto.sae_pwd,
|
||||
sme->crypto.sae_pwd_len);
|
||||
if (!err && sme->crypto.psk)
|
||||
err = brcmf_set_pmk(ifp, sme->crypto.psk,
|
||||
BRCMF_WSEC_MAX_PSK_LEN);
|
||||
}
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
/* Join with specific BSSID and cached SSID
|
||||
* If SSID is zero join based on BSSID only
|
||||
@ -5362,7 +5421,8 @@ static bool brcmf_is_linkup(struct brcmf_cfg80211_vif *vif,
|
||||
if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
|
||||
brcmf_dbg(CONN, "Processing set ssid\n");
|
||||
memcpy(vif->profile.bssid, e->addr, ETH_ALEN);
|
||||
if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_PSK)
|
||||
if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_PSK &&
|
||||
vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_SAE)
|
||||
return true;
|
||||
|
||||
set_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
|
||||
@ -6672,6 +6732,9 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
|
||||
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK);
|
||||
wiphy_ext_feature_set(wiphy,
|
||||
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X);
|
||||
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;
|
||||
|
@ -107,7 +107,8 @@ struct brcmf_cfg80211_security {
|
||||
enum brcmf_profile_fwsup {
|
||||
BRCMF_PROFILE_FWSUP_NONE,
|
||||
BRCMF_PROFILE_FWSUP_PSK,
|
||||
BRCMF_PROFILE_FWSUP_1X
|
||||
BRCMF_PROFILE_FWSUP_1X,
|
||||
BRCMF_PROFILE_FWSUP_SAE
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -39,7 +39,8 @@ static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
|
||||
{ BRCMF_FEAT_P2P, "p2p" },
|
||||
{ BRCMF_FEAT_MONITOR, "monitor" },
|
||||
{ BRCMF_FEAT_MONITOR_FMT_RADIOTAP, "rtap" },
|
||||
{ BRCMF_FEAT_DOT11H, "802.11h" }
|
||||
{ BRCMF_FEAT_DOT11H, "802.11h" },
|
||||
{ BRCMF_FEAT_SAE, "sae" },
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -26,6 +26,7 @@
|
||||
* MONITOR_FMT_RADIOTAP: firmware provides monitor packets with radiotap header
|
||||
* MONITOR_FMT_HW_RX_HDR: firmware provides monitor packets with hw/ucode header
|
||||
* DOT11H: firmware supports 802.11h
|
||||
* SAE: simultaneous authentication of equals
|
||||
*/
|
||||
#define BRCMF_FEAT_LIST \
|
||||
BRCMF_FEAT_DEF(MBSS) \
|
||||
@ -45,7 +46,8 @@
|
||||
BRCMF_FEAT_DEF(MONITOR) \
|
||||
BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) \
|
||||
BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) \
|
||||
BRCMF_FEAT_DEF(DOT11H)
|
||||
BRCMF_FEAT_DEF(DOT11H) \
|
||||
BRCMF_FEAT_DEF(SAE)
|
||||
|
||||
/*
|
||||
* Quirks:
|
||||
|
@ -61,6 +61,8 @@
|
||||
#define BRCMF_WSEC_MAX_PSK_LEN 32
|
||||
#define BRCMF_WSEC_PASSPHRASE BIT(0)
|
||||
|
||||
#define BRCMF_WSEC_MAX_SAE_PASSWORD_LEN 128
|
||||
|
||||
/* primary (ie tx) key */
|
||||
#define BRCMF_PRIMARY_KEY (1 << 1)
|
||||
#define DOT11_BSSTYPE_ANY 2
|
||||
@ -518,6 +520,17 @@ struct brcmf_wsec_pmk_le {
|
||||
u8 key[2 * BRCMF_WSEC_MAX_PSK_LEN + 1];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_wsec_sae_pwd_le - firmware SAE password material.
|
||||
*
|
||||
* @key_len: number of octets in key materials.
|
||||
* @key: SAE password material.
|
||||
*/
|
||||
struct brcmf_wsec_sae_pwd_le {
|
||||
__le16 key_len;
|
||||
u8 key[BRCMF_WSEC_MAX_SAE_PASSWORD_LEN];
|
||||
};
|
||||
|
||||
/* Used to get specific STA parameters */
|
||||
struct brcmf_scb_val_le {
|
||||
__le32 val;
|
||||
|
@ -231,6 +231,8 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
|
||||
#define WPA2_AUTH_FT 0x4000 /* Fast BSS Transition */
|
||||
#define WPA2_AUTH_PSK_SHA256 0x8000 /* PSK with SHA256 key derivation */
|
||||
|
||||
#define WPA3_AUTH_SAE_PSK 0x40000 /* SAE with 4-way handshake */
|
||||
|
||||
#define DOT11_DEFAULT_RTS_LEN 2347
|
||||
#define DOT11_DEFAULT_FRAG_LEN 2346
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user