Skip to content

Commit ab56846

Browse files
committed
wilc1000: added WPA3 support for WILC1000
Added WPA3 security support for WILC1000. Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
1 parent 718b41e commit ab56846

10 files changed

Lines changed: 341 additions & 46 deletions

File tree

drivers/net/wireless/microchip/wilc1000/cfg80211.c

Lines changed: 185 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
static const struct ieee80211_txrx_stypes
2222
wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
2323
[NL80211_IFTYPE_STATION] = {
24-
.tx = 0xffff,
24+
.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
25+
BIT(IEEE80211_STYPE_AUTH >> 4),
2526
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
26-
BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
27+
BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
28+
BIT(IEEE80211_STYPE_AUTH >> 4),
2729
},
2830
[NL80211_IFTYPE_AP] = {
2931
.tx = 0xffff,
@@ -382,6 +384,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
382384
int ret;
383385
u32 i;
384386
u8 security = WILC_FW_SEC_NO;
387+
enum mfptype mfp_type = WILC_FW_MFP_NONE;
385388
enum authtype auth_type = WILC_FW_AUTH_ANY;
386389
u32 cipher_group;
387390
struct cfg80211_bss *bss;
@@ -394,6 +397,13 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
394397
"Connecting to SSID [%s] on netdev [%p] host if [%x]\n",
395398
sme->ssid, dev, (u32)priv->hif_drv);
396399

400+
if (sme->auth_type == NL80211_AUTHTYPE_SAE &&
401+
vif->wilc->chip == WILC_3000){
402+
pr_err("WILC3000: WPA3 not supported\n");
403+
ret = -ENOTSUPP;
404+
goto out_error;
405+
}
406+
397407
if (vif->iftype == WILC_CLIENT_MODE)
398408
PRINT_INFO(vif->ndev, CFG80211_DBG,
399409
"Connected to Direct network,OBSS disabled\n");
@@ -458,6 +468,18 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
458468
auth_type = WILC_FW_AUTH_OPEN_SYSTEM;
459469
break;
460470

471+
case NL80211_AUTHTYPE_SAE:
472+
auth_type = WILC_FW_AUTH_SAE;
473+
if (sme->ssid_len) {
474+
memcpy(vif->auth.ssid.ssid, sme->ssid, sme->ssid_len);
475+
vif->auth.ssid.ssid_len = sme->ssid_len;
476+
}
477+
vif->auth.key_mgmt_suite = cpu_to_be32(sme->crypto.akm_suites[0]);
478+
ether_addr_copy(vif->auth.bssid, sme->bssid);
479+
pr_debug("%s: external SAE processing: bss=%pM action=%u akm=%u len[%d]\n",
480+
__func__, sme->bssid, vif->auth.action,
481+
vif->auth.key_mgmt_suite, sme->crypto.sae_pwd_len);
482+
break;
461483
default:
462484
PRINT_INFO(vif->ndev, CFG80211_DBG,
463485
"Automatic Authentication type= %d\n",
@@ -466,8 +488,18 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
466488
}
467489

468490
if (sme->crypto.n_akm_suites) {
469-
if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
491+
if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X) {
492+
PRINT_INFO(vif->ndev, CFG80211_DBG, "AUTH IEEE802.1X\n");
470493
auth_type = WILC_FW_AUTH_IEEE8021;
494+
} else if (sme->crypto.akm_suites[0] ==
495+
WLAN_AKM_SUITE_PSK_SHA256) {
496+
PRINT_INFO(vif->ndev, CFG80211_DBG, "AUTH WPA-PSK-SHA256\n");
497+
auth_type = WILC_FW_AUTH_OPEN_SYSTEM_SHA256;
498+
} else if (sme->crypto.akm_suites[0] ==
499+
WLAN_AKM_SUITE_8021X_SHA256) {
500+
PRINT_INFO(vif->ndev, CFG80211_DBG, "AUTH IEEE802.1X-SHA256\n");
501+
auth_type = WILC_FW_AUTH_IEE8021X_SHA256;
502+
}
471503
}
472504

473505
if (wfi_drv->usr_scan_req.scan_result) {
@@ -494,6 +526,15 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
494526
ret = -EALREADY;
495527
goto out_put_bss;
496528
}
529+
PRINT_INFO(vif->ndev, CFG80211_DBG, "Set MFP Type %d", sme->mfp);
530+
531+
if (sme->mfp == NL80211_MFP_OPTIONAL) {
532+
PRINT_INFO(vif->ndev, CFG80211_DBG, "MFP Type Optional");
533+
mfp_type = WILC_FW_MFP_OPTIONAL;
534+
} else if (sme->mfp == NL80211_MFP_REQUIRED) {
535+
PRINT_INFO(vif->ndev, CFG80211_DBG, "MFP Type Required");
536+
mfp_type = WILC_FW_MFP_REQUIRED;
537+
}
497538

498539
join_params = wilc_parse_join_bss_param(bss, &sme->crypto);
499540
if (!join_params) {
@@ -517,6 +558,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
517558
wfi_drv->conn_info.conn_result = cfg_connect_result;
518559
wfi_drv->conn_info.arg = priv;
519560
wfi_drv->conn_info.param = join_params;
561+
wfi_drv->conn_info.mfp_type = mfp_type;
520562

521563
ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len);
522564
if (ret) {
@@ -594,6 +636,19 @@ static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
594636
return 0;
595637
}
596638

639+
static int wilc_wfi_cfg_allocate_wpa_igtk_entry(struct wilc_priv *priv, u8 idx)
640+
{
641+
idx -= 4;
642+
if (!priv->wilc_igtk[idx]) {
643+
priv->wilc_igtk[idx] = kzalloc(sizeof(*priv->wilc_igtk[idx]),
644+
GFP_KERNEL);
645+
if (!priv->wilc_igtk[idx])
646+
return -ENOMEM;
647+
}
648+
649+
return 0;
650+
}
651+
597652
static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
598653
struct key_params *params)
599654
{
@@ -623,13 +678,14 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
623678
bool pairwise, const u8 *mac_addr, struct key_params *params)
624679

625680
{
626-
int ret = 0, keylen = params->key_len;
681+
int ret = 0, keylen = params->key_len, seqlen = params->seq_len;
627682
const u8 *rx_mic = NULL;
628683
const u8 *tx_mic = NULL;
629684
u8 mode = WILC_FW_SEC_NO;
630685
u8 op_mode;
631686
struct wilc_vif *vif = netdev_priv(netdev);
632687
struct wilc_priv *priv = &vif->priv;
688+
struct wilc_wfi_key *key;
633689

634690
PRINT_INFO(vif->ndev, CFG80211_DBG,
635691
"Adding key with cipher suite = %x\n", params->cipher);
@@ -705,6 +761,28 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
705761

706762
break;
707763

764+
case WLAN_CIPHER_SUITE_AES_CMAC:
765+
ret = wilc_wfi_cfg_allocate_wpa_igtk_entry(priv, key_index);
766+
if (ret)
767+
return -ENOMEM;
768+
769+
key = priv->wilc_igtk[key_index - 4];
770+
771+
ret = wilc_wfi_cfg_copy_wpa_info(key, params);
772+
if (ret)
773+
return -ENOMEM;
774+
775+
if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
776+
priv->wdev.iftype == NL80211_IFTYPE_P2P_GO)
777+
op_mode = WILC_AP_MODE;
778+
else
779+
op_mode = WILC_STATION_MODE;
780+
781+
ret = wilc_add_igtk(vif, params->key, keylen, params->seq,
782+
seqlen, mac_addr, op_mode, key_index);
783+
784+
break;
785+
708786
default:
709787
netdev_err(netdev, "%s: Unsupported cipher\n", __func__);
710788
ret = -ENOTSUPP;
@@ -722,23 +800,34 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev,
722800
struct wilc_vif *vif = netdev_priv(netdev);
723801
struct wilc_priv *priv = &vif->priv;
724802

725-
if (priv->wilc_gtk[key_index]) {
726-
kfree(priv->wilc_gtk[key_index]->key);
727-
priv->wilc_gtk[key_index]->key = NULL;
728-
kfree(priv->wilc_gtk[key_index]->seq);
729-
priv->wilc_gtk[key_index]->seq = NULL;
730-
731-
kfree(priv->wilc_gtk[key_index]);
732-
priv->wilc_gtk[key_index] = NULL;
733-
}
803+
if (!pairwise && (key_index == 4 || key_index == 5)) {
804+
key_index -= 4;
805+
if (priv->wilc_igtk[key_index]) {
806+
kfree(priv->wilc_igtk[key_index]->key);
807+
priv->wilc_igtk[key_index]->key = NULL;
808+
kfree(priv->wilc_igtk[key_index]->seq);
809+
priv->wilc_igtk[key_index]->seq = NULL;
810+
kfree(priv->wilc_igtk[key_index]);
811+
priv->wilc_igtk[key_index] = NULL;
812+
}
813+
} else {
814+
if (priv->wilc_gtk[key_index]) {
815+
kfree(priv->wilc_gtk[key_index]->key);
816+
priv->wilc_gtk[key_index]->key = NULL;
817+
kfree(priv->wilc_gtk[key_index]->seq);
818+
priv->wilc_gtk[key_index]->seq = NULL;
819+
kfree(priv->wilc_gtk[key_index]);
820+
priv->wilc_gtk[key_index] = NULL;
821+
}
734822

735-
if (priv->wilc_ptk[key_index]) {
736-
kfree(priv->wilc_ptk[key_index]->key);
737-
priv->wilc_ptk[key_index]->key = NULL;
738-
kfree(priv->wilc_ptk[key_index]->seq);
739-
priv->wilc_ptk[key_index]->seq = NULL;
740-
kfree(priv->wilc_ptk[key_index]);
741-
priv->wilc_ptk[key_index] = NULL;
823+
if (priv->wilc_ptk[key_index]) {
824+
kfree(priv->wilc_ptk[key_index]->key);
825+
priv->wilc_ptk[key_index]->key = NULL;
826+
kfree(priv->wilc_ptk[key_index]->seq);
827+
priv->wilc_ptk[key_index]->seq = NULL;
828+
kfree(priv->wilc_ptk[key_index]);
829+
priv->wilc_ptk[key_index] = NULL;
830+
}
742831
}
743832

744833
return ret;
@@ -753,13 +842,25 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
753842
struct key_params key_params;
754843

755844
if (!pairwise) {
756-
PRINT_INFO(vif->ndev, CFG80211_DBG,
757-
"Getting group key idx: %x\n", key_index);
758-
key_params.key = priv->wilc_gtk[key_index]->key;
759-
key_params.cipher = priv->wilc_gtk[key_index]->cipher;
760-
key_params.key_len = priv->wilc_gtk[key_index]->key_len;
761-
key_params.seq = priv->wilc_gtk[key_index]->seq;
762-
key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
845+
if (key_index == 4 || key_index == 5) {
846+
PRINT_INFO(vif->ndev, CFG80211_DBG,
847+
"Getting integrity group key idx: %x\n",
848+
key_index);
849+
key_index -= 4;
850+
key_params.key = priv->wilc_igtk[key_index]->key;
851+
key_params.cipher = priv->wilc_igtk[key_index]->cipher;
852+
key_params.key_len = priv->wilc_igtk[key_index]->key_len;
853+
key_params.seq = priv->wilc_igtk[key_index]->seq;
854+
key_params.seq_len = priv->wilc_igtk[key_index]->seq_len;
855+
} else {
856+
PRINT_INFO(vif->ndev, CFG80211_DBG,
857+
"Getting group key idx: %x\n", key_index);
858+
key_params.key = priv->wilc_gtk[key_index]->key;
859+
key_params.cipher = priv->wilc_gtk[key_index]->cipher;
860+
key_params.key_len = priv->wilc_gtk[key_index]->key_len;
861+
key_params.seq = priv->wilc_gtk[key_index]->seq;
862+
key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
863+
}
763864
} else {
764865
PRINT_INFO(vif->ndev, CFG80211_DBG, "Getting pairwise key\n");
765866
key_params.key = priv->wilc_ptk[key_index]->key;
@@ -1099,6 +1200,24 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
10991200
}
11001201
}
11011202

1203+
bool wilc_wfi_mgmt_frame_rx(struct wilc_vif *vif, u8 *buff, u32 size)
1204+
{
1205+
struct wilc *wl = vif->wilc;
1206+
struct wilc_priv *priv = &vif->priv;
1207+
int freq, ret;
1208+
1209+
#if KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE
1210+
freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ);
1211+
#else
1212+
freq = ieee80211_channel_to_frequency(wl->op_ch, IEEE80211_BAND_2GHZ);
1213+
#endif
1214+
PRINT_D(vif->ndev, GENERIC_DBG, "%s Frame Type:%x\n", __func__,
1215+
((struct ieee80211_mgmt *)buff)->frame_control);
1216+
1217+
ret = cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
1218+
return ret;
1219+
}
1220+
11021221
bool wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
11031222
{
11041223
struct wilc *wl = vif->wilc;
@@ -1336,8 +1455,14 @@ static int mgmt_tx(struct wiphy *wiphy,
13361455
goto out_txq_add_pkt;
13371456
}
13381457

1339-
if (!ieee80211_is_public_action((struct ieee80211_hdr *)buf, len))
1458+
if (!ieee80211_is_public_action((struct ieee80211_hdr *)buf, len)) {
1459+
if (chan)
1460+
wilc_set_mac_chnl_num(vif, chan->hw_value);
1461+
else
1462+
wilc_set_mac_chnl_num(vif, vif->wilc->op_ch);
1463+
13401464
goto out_set_timeout;
1465+
}
13411466

13421467
PRINT_INFO(vif->ndev, GENERIC_DBG, "ACTION FRAME:%x\n",
13431468
(u16)mgmt->frame_control);
@@ -1424,6 +1549,7 @@ void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
14241549
struct wilc_vif *vif = netdev_priv(wdev->netdev);
14251550
u32 presp_bit = BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
14261551
u32 action_bit = BIT(IEEE80211_STYPE_ACTION >> 4);
1552+
u32 pauth_bit = BIT(IEEE80211_STYPE_AUTH >> 4);
14271553

14281554
if (wl->initialized) {
14291555
bool prev = vif->mgmt_reg_stypes & presp_bit;
@@ -1437,10 +1563,16 @@ void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
14371563

14381564
if (now != prev)
14391565
wilc_frame_register(vif, IEEE80211_STYPE_ACTION, now);
1566+
prev = vif->mgmt_reg_stypes & pauth_bit;
1567+
now = upd->interface_stypes & pauth_bit;
1568+
if (now != prev) {
1569+
pr_err("%s setup authframe\n", __func__);
1570+
wilc_frame_register(vif, IEEE80211_STYPE_AUTH, now);
1571+
}
14401572
}
14411573

14421574
vif->mgmt_reg_stypes =
1443-
upd->interface_stypes & (presp_bit | action_bit);
1575+
upd->interface_stypes & (presp_bit | action_bit | pauth_bit);
14441576
}
14451577
#else
14461578
void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
@@ -1453,8 +1585,9 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
14531585
return;
14541586

14551587
PRINT_D(vif->ndev, GENERIC_DBG,
1456-
"Frame registering Frame Type: %x: Boolean: %d\n",
1457-
frame_type, reg);
1588+
"Frame registering Frame Type: %x: Boolean: %d\n", frame_type,
1589+
reg);
1590+
14581591
switch (frame_type) {
14591592
case IEEE80211_STYPE_PROBE_REQ:
14601593
vif->frame_reg[0].type = frame_type;
@@ -1465,6 +1598,10 @@ void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
14651598
vif->frame_reg[1].type = frame_type;
14661599
vif->frame_reg[1].reg = reg;
14671600
break;
1601+
case IEEE80211_STYPE_AUTH:
1602+
vif->frame_reg[2].type = frame_type;
1603+
vif->frame_reg[2].reg = reg;
1604+
break;
14681605

14691606
default:
14701607
break;
@@ -2091,6 +2228,21 @@ static int set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
20912228
return ret;
20922229
}
20932230

2231+
static int external_auth(struct wiphy *wiphy, struct net_device *dev,
2232+
struct cfg80211_external_auth_params *auth)
2233+
{
2234+
int ret = 0;
2235+
struct wilc_vif *vif = netdev_priv(dev);
2236+
2237+
pr_debug("%s bssid: %pM", __func__, auth->bssid);
2238+
if (auth->status == WLAN_STATUS_SUCCESS)
2239+
wilc_set_external_auth_param(vif, auth);
2240+
else
2241+
pr_err("%s failed [%d]\n", __func__, auth->status);
2242+
2243+
return ret;
2244+
}
2245+
20942246
static const struct cfg80211_ops wilc_cfg80211_ops = {
20952247
.set_monitor_channel = set_channel,
20962248
.scan = scan,
@@ -2115,6 +2267,7 @@ static const struct cfg80211_ops wilc_cfg80211_ops = {
21152267
.change_bss = change_bss,
21162268
.set_wiphy_params = set_wiphy_params,
21172269

2270+
.external_auth = external_auth,
21182271
.set_pmksa = set_pmksa,
21192272
.del_pmksa = del_pmksa,
21202273
.flush_pmksa = flush_pmksa,
@@ -2292,6 +2445,7 @@ struct wilc *wilc_create_wiphy(struct device *dev)
22922445
BIT(NL80211_IFTYPE_P2P_GO) |
22932446
BIT(NL80211_IFTYPE_P2P_CLIENT);
22942447
wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2448+
wiphy->features |= NL80211_FEATURE_SAE;
22952449
pr_info("Max scan ids= %d,Max scan IE len= %d,Signal Type= %d,Interface Modes= %d\n",
22962450
wiphy->max_scan_ssids, wiphy->max_scan_ie_len,
22972451
wiphy->signal_type, wiphy->interface_modes);

0 commit comments

Comments
 (0)