Skip to content

Commit e152c74

Browse files
ajaykathatnoglitch
authored andcommitted
wilc1000: added WPA3 support for WILC1000
Added WPA3 security support for WILC1000. Signed-off-by: Ajay Singh <ajay.kathat@microchip.com> [nicolas.ferre@microchip.com: removed KERNEL_VERSION() dependent code] Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
1 parent 82c7248 commit e152c74

10 files changed

Lines changed: 322 additions & 44 deletions

File tree

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

Lines changed: 174 additions & 29 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,
@@ -352,6 +354,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
352354
int ret;
353355
u32 i;
354356
u8 security = WILC_FW_SEC_NO;
357+
enum mfptype mfp_type = WILC_FW_MFP_NONE;
355358
enum authtype auth_type = WILC_FW_AUTH_ANY;
356359
u32 cipher_group;
357360
struct cfg80211_bss *bss;
@@ -364,6 +367,13 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
364367
"Connecting to SSID [%s] on netdev [%p] host if [%x]\n",
365368
sme->ssid, dev, (u32)priv->hif_drv);
366369

370+
if (sme->auth_type == NL80211_AUTHTYPE_SAE &&
371+
vif->wilc->chip == WILC_3000){
372+
pr_err("WILC3000: WPA3 not supported\n");
373+
ret = -ENOTSUPP;
374+
goto out_error;
375+
}
376+
367377
if (vif->iftype == WILC_CLIENT_MODE)
368378
PRINT_INFO(vif->ndev, CFG80211_DBG,
369379
"Connected to Direct network,OBSS disabled\n");
@@ -428,6 +438,18 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
428438
auth_type = WILC_FW_AUTH_OPEN_SYSTEM;
429439
break;
430440

441+
case NL80211_AUTHTYPE_SAE:
442+
auth_type = WILC_FW_AUTH_SAE;
443+
if (sme->ssid_len) {
444+
memcpy(vif->auth.ssid.ssid, sme->ssid, sme->ssid_len);
445+
vif->auth.ssid.ssid_len = sme->ssid_len;
446+
}
447+
vif->auth.key_mgmt_suite = cpu_to_be32(sme->crypto.akm_suites[0]);
448+
ether_addr_copy(vif->auth.bssid, sme->bssid);
449+
pr_debug("%s: external SAE processing: bss=%pM action=%u akm=%u len[%d]\n",
450+
__func__, sme->bssid, vif->auth.action,
451+
vif->auth.key_mgmt_suite, sme->crypto.sae_pwd_len);
452+
break;
431453
default:
432454
PRINT_INFO(vif->ndev, CFG80211_DBG,
433455
"Automatic Authentication type= %d\n",
@@ -436,8 +458,18 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
436458
}
437459

438460
if (sme->crypto.n_akm_suites) {
439-
if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X)
461+
if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_8021X) {
462+
PRINT_INFO(vif->ndev, CFG80211_DBG, "AUTH IEEE802.1X\n");
440463
auth_type = WILC_FW_AUTH_IEEE8021;
464+
} else if (sme->crypto.akm_suites[0] ==
465+
WLAN_AKM_SUITE_PSK_SHA256) {
466+
PRINT_INFO(vif->ndev, CFG80211_DBG, "AUTH WPA-PSK-SHA256\n");
467+
auth_type = WILC_FW_AUTH_OPEN_SYSTEM_SHA256;
468+
} else if (sme->crypto.akm_suites[0] ==
469+
WLAN_AKM_SUITE_8021X_SHA256) {
470+
PRINT_INFO(vif->ndev, CFG80211_DBG, "AUTH IEEE802.1X-SHA256\n");
471+
auth_type = WILC_FW_AUTH_IEE8021X_SHA256;
472+
}
441473
}
442474

443475
if (wfi_drv->usr_scan_req.scan_result) {
@@ -458,6 +490,15 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
458490
ret = -EALREADY;
459491
goto out_put_bss;
460492
}
493+
PRINT_INFO(vif->ndev, CFG80211_DBG, "Set MFP Type %d", sme->mfp);
494+
495+
if (sme->mfp == NL80211_MFP_OPTIONAL) {
496+
PRINT_INFO(vif->ndev, CFG80211_DBG, "MFP Type Optional");
497+
mfp_type = WILC_FW_MFP_OPTIONAL;
498+
} else if (sme->mfp == NL80211_MFP_REQUIRED) {
499+
PRINT_INFO(vif->ndev, CFG80211_DBG, "MFP Type Required");
500+
mfp_type = WILC_FW_MFP_REQUIRED;
501+
}
461502

462503
join_params = wilc_parse_join_bss_param(bss, &sme->crypto);
463504
if (!join_params) {
@@ -481,6 +522,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
481522
wfi_drv->conn_info.conn_result = cfg_connect_result;
482523
wfi_drv->conn_info.arg = priv;
483524
wfi_drv->conn_info.param = join_params;
525+
wfi_drv->conn_info.mfp_type = mfp_type;
484526

485527
ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len);
486528
if (ret) {
@@ -558,6 +600,19 @@ static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
558600
return 0;
559601
}
560602

603+
static int wilc_wfi_cfg_allocate_wpa_igtk_entry(struct wilc_priv *priv, u8 idx)
604+
{
605+
idx -= 4;
606+
if (!priv->wilc_igtk[idx]) {
607+
priv->wilc_igtk[idx] = kzalloc(sizeof(*priv->wilc_igtk[idx]),
608+
GFP_KERNEL);
609+
if (!priv->wilc_igtk[idx])
610+
return -ENOMEM;
611+
}
612+
613+
return 0;
614+
}
615+
561616
static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
562617
struct key_params *params)
563618
{
@@ -587,13 +642,14 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
587642
bool pairwise, const u8 *mac_addr, struct key_params *params)
588643

589644
{
590-
int ret = 0, keylen = params->key_len;
645+
int ret = 0, keylen = params->key_len, seqlen = params->seq_len;
591646
const u8 *rx_mic = NULL;
592647
const u8 *tx_mic = NULL;
593648
u8 mode = WILC_FW_SEC_NO;
594649
u8 op_mode;
595650
struct wilc_vif *vif = netdev_priv(netdev);
596651
struct wilc_priv *priv = &vif->priv;
652+
struct wilc_wfi_key *key;
597653

598654
PRINT_INFO(vif->ndev, CFG80211_DBG,
599655
"Adding key with cipher suite = %x\n", params->cipher);
@@ -669,6 +725,28 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
669725

670726
break;
671727

728+
case WLAN_CIPHER_SUITE_AES_CMAC:
729+
ret = wilc_wfi_cfg_allocate_wpa_igtk_entry(priv, key_index);
730+
if (ret)
731+
return -ENOMEM;
732+
733+
key = priv->wilc_igtk[key_index - 4];
734+
735+
ret = wilc_wfi_cfg_copy_wpa_info(key, params);
736+
if (ret)
737+
return -ENOMEM;
738+
739+
if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
740+
priv->wdev.iftype == NL80211_IFTYPE_P2P_GO)
741+
op_mode = WILC_AP_MODE;
742+
else
743+
op_mode = WILC_STATION_MODE;
744+
745+
ret = wilc_add_igtk(vif, params->key, keylen, params->seq,
746+
seqlen, mac_addr, op_mode, key_index);
747+
748+
break;
749+
672750
default:
673751
netdev_err(netdev, "%s: Unsupported cipher\n", __func__);
674752
ret = -ENOTSUPP;
@@ -686,23 +764,34 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev,
686764
struct wilc_vif *vif = netdev_priv(netdev);
687765
struct wilc_priv *priv = &vif->priv;
688766

689-
if (priv->wilc_gtk[key_index]) {
690-
kfree(priv->wilc_gtk[key_index]->key);
691-
priv->wilc_gtk[key_index]->key = NULL;
692-
kfree(priv->wilc_gtk[key_index]->seq);
693-
priv->wilc_gtk[key_index]->seq = NULL;
694-
695-
kfree(priv->wilc_gtk[key_index]);
696-
priv->wilc_gtk[key_index] = NULL;
697-
}
767+
if (!pairwise && (key_index == 4 || key_index == 5)) {
768+
key_index -= 4;
769+
if (priv->wilc_igtk[key_index]) {
770+
kfree(priv->wilc_igtk[key_index]->key);
771+
priv->wilc_igtk[key_index]->key = NULL;
772+
kfree(priv->wilc_igtk[key_index]->seq);
773+
priv->wilc_igtk[key_index]->seq = NULL;
774+
kfree(priv->wilc_igtk[key_index]);
775+
priv->wilc_igtk[key_index] = NULL;
776+
}
777+
} else {
778+
if (priv->wilc_gtk[key_index]) {
779+
kfree(priv->wilc_gtk[key_index]->key);
780+
priv->wilc_gtk[key_index]->key = NULL;
781+
kfree(priv->wilc_gtk[key_index]->seq);
782+
priv->wilc_gtk[key_index]->seq = NULL;
783+
kfree(priv->wilc_gtk[key_index]);
784+
priv->wilc_gtk[key_index] = NULL;
785+
}
698786

699-
if (priv->wilc_ptk[key_index]) {
700-
kfree(priv->wilc_ptk[key_index]->key);
701-
priv->wilc_ptk[key_index]->key = NULL;
702-
kfree(priv->wilc_ptk[key_index]->seq);
703-
priv->wilc_ptk[key_index]->seq = NULL;
704-
kfree(priv->wilc_ptk[key_index]);
705-
priv->wilc_ptk[key_index] = NULL;
787+
if (priv->wilc_ptk[key_index]) {
788+
kfree(priv->wilc_ptk[key_index]->key);
789+
priv->wilc_ptk[key_index]->key = NULL;
790+
kfree(priv->wilc_ptk[key_index]->seq);
791+
priv->wilc_ptk[key_index]->seq = NULL;
792+
kfree(priv->wilc_ptk[key_index]);
793+
priv->wilc_ptk[key_index] = NULL;
794+
}
706795
}
707796

708797
return ret;
@@ -717,13 +806,25 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
717806
struct key_params key_params;
718807

719808
if (!pairwise) {
720-
PRINT_INFO(vif->ndev, CFG80211_DBG,
721-
"Getting group key idx: %x\n", key_index);
722-
key_params.key = priv->wilc_gtk[key_index]->key;
723-
key_params.cipher = priv->wilc_gtk[key_index]->cipher;
724-
key_params.key_len = priv->wilc_gtk[key_index]->key_len;
725-
key_params.seq = priv->wilc_gtk[key_index]->seq;
726-
key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
809+
if (key_index == 4 || key_index == 5) {
810+
PRINT_INFO(vif->ndev, CFG80211_DBG,
811+
"Getting integrity group key idx: %x\n",
812+
key_index);
813+
key_index -= 4;
814+
key_params.key = priv->wilc_igtk[key_index]->key;
815+
key_params.cipher = priv->wilc_igtk[key_index]->cipher;
816+
key_params.key_len = priv->wilc_igtk[key_index]->key_len;
817+
key_params.seq = priv->wilc_igtk[key_index]->seq;
818+
key_params.seq_len = priv->wilc_igtk[key_index]->seq_len;
819+
} else {
820+
PRINT_INFO(vif->ndev, CFG80211_DBG,
821+
"Getting group key idx: %x\n", key_index);
822+
key_params.key = priv->wilc_gtk[key_index]->key;
823+
key_params.cipher = priv->wilc_gtk[key_index]->cipher;
824+
key_params.key_len = priv->wilc_gtk[key_index]->key_len;
825+
key_params.seq = priv->wilc_gtk[key_index]->seq;
826+
key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
827+
}
727828
} else {
728829
PRINT_INFO(vif->ndev, CFG80211_DBG, "Getting pairwise key\n");
729830
key_params.key = priv->wilc_ptk[key_index]->key;
@@ -1048,6 +1149,20 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
10481149
}
10491150
}
10501151

1152+
bool wilc_wfi_mgmt_frame_rx(struct wilc_vif *vif, u8 *buff, u32 size)
1153+
{
1154+
struct wilc *wl = vif->wilc;
1155+
struct wilc_priv *priv = &vif->priv;
1156+
int freq, ret;
1157+
1158+
freq = ieee80211_channel_to_frequency(wl->op_ch, NL80211_BAND_2GHZ);
1159+
PRINT_D(vif->ndev, GENERIC_DBG, "%s Frame Type:%x\n", __func__,
1160+
((struct ieee80211_mgmt *)buff)->frame_control);
1161+
1162+
ret = cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
1163+
return ret;
1164+
}
1165+
10511166
bool wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
10521167
{
10531168
struct wilc *wl = vif->wilc;
@@ -1268,8 +1383,14 @@ static int mgmt_tx(struct wiphy *wiphy,
12681383
goto out_txq_add_pkt;
12691384
}
12701385

1271-
if (!ieee80211_is_public_action((struct ieee80211_hdr *)buf, len))
1386+
if (!ieee80211_is_public_action((struct ieee80211_hdr *)buf, len)) {
1387+
if (chan)
1388+
wilc_set_mac_chnl_num(vif, chan->hw_value);
1389+
else
1390+
wilc_set_mac_chnl_num(vif, vif->wilc->op_ch);
1391+
12721392
goto out_set_timeout;
1393+
}
12731394

12741395
PRINT_INFO(vif->ndev, GENERIC_DBG, "ACTION FRAME:%x\n",
12751396
(u16)mgmt->frame_control);
@@ -1355,6 +1476,7 @@ void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
13551476
struct wilc_vif *vif = netdev_priv(wdev->netdev);
13561477
u32 presp_bit = BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
13571478
u32 action_bit = BIT(IEEE80211_STYPE_ACTION >> 4);
1479+
u32 pauth_bit = BIT(IEEE80211_STYPE_AUTH >> 4);
13581480

13591481
if (wl->initialized) {
13601482
bool prev = vif->mgmt_reg_stypes & presp_bit;
@@ -1368,10 +1490,16 @@ void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy,
13681490

13691491
if (now != prev)
13701492
wilc_frame_register(vif, IEEE80211_STYPE_ACTION, now);
1493+
prev = vif->mgmt_reg_stypes & pauth_bit;
1494+
now = upd->interface_stypes & pauth_bit;
1495+
if (now != prev) {
1496+
pr_err("%s setup authframe\n", __func__);
1497+
wilc_frame_register(vif, IEEE80211_STYPE_AUTH, now);
1498+
}
13711499
}
13721500

13731501
vif->mgmt_reg_stypes =
1374-
upd->interface_stypes & (presp_bit | action_bit);
1502+
upd->interface_stypes & (presp_bit | action_bit | pauth_bit);
13751503
}
13761504

13771505
static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
@@ -1935,6 +2063,21 @@ static int set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
19352063
return ret;
19362064
}
19372065

2066+
static int external_auth(struct wiphy *wiphy, struct net_device *dev,
2067+
struct cfg80211_external_auth_params *auth)
2068+
{
2069+
int ret = 0;
2070+
struct wilc_vif *vif = netdev_priv(dev);
2071+
2072+
pr_debug("%s bssid: %pM", __func__, auth->bssid);
2073+
if (auth->status == WLAN_STATUS_SUCCESS)
2074+
wilc_set_external_auth_param(vif, auth);
2075+
else
2076+
pr_debug("%s status [%d]\n", __func__, auth->status);
2077+
2078+
return ret;
2079+
}
2080+
19382081
static const struct cfg80211_ops wilc_cfg80211_ops = {
19392082
.set_monitor_channel = set_channel,
19402083
.scan = scan,
@@ -1959,6 +2102,7 @@ static const struct cfg80211_ops wilc_cfg80211_ops = {
19592102
.change_bss = change_bss,
19602103
.set_wiphy_params = set_wiphy_params,
19612104

2105+
.external_auth = external_auth,
19622106
.set_pmksa = set_pmksa,
19632107
.del_pmksa = del_pmksa,
19642108
.flush_pmksa = flush_pmksa,
@@ -2124,6 +2268,7 @@ struct wilc *wilc_create_wiphy(struct device *dev)
21242268
BIT(NL80211_IFTYPE_P2P_GO) |
21252269
BIT(NL80211_IFTYPE_P2P_CLIENT);
21262270
wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2271+
wiphy->features |= NL80211_FEATURE_SAE;
21272272
pr_info("Max scan ids= %d,Max scan IE len= %d,Signal Type= %d,Interface Modes= %d\n",
21282273
wiphy->max_scan_ssids, wiphy->max_scan_ie_len,
21292274
wiphy->signal_type, wiphy->interface_modes);

drivers/net/wireless/microchip/wilc1000/fw.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ struct wilc_ap_wpa_ptk {
5454
u8 key[];
5555
} __packed;
5656

57+
struct wilc_wpa_igtk {
58+
u8 index;
59+
u8 pn_len;
60+
u8 pn[6];
61+
u8 key_len;
62+
u8 key[];
63+
} __packed;
64+
5765
struct wilc_gtk_key {
5866
u8 mac_addr[ETH_ALEN];
5967
u8 rsc[8];
@@ -110,4 +118,13 @@ struct wilc_join_bss_param {
110118
struct wilc_noa_opp_enable opp_en;
111119
};
112120
} __packed;
121+
122+
struct wilc_external_auth_param {
123+
u8 action;
124+
u8 bssid[ETH_ALEN];
125+
u8 ssid[IEEE80211_MAX_SSID_LEN];
126+
u8 ssid_len;
127+
__le32 key_mgmt_suites;
128+
__le16 status;
129+
} __packed;
113130
#endif

0 commit comments

Comments
 (0)