wifi: wilc1000: add IGTK support
Add support to handle IGTK keys which are required for MFP to FW. Index ID 4 and 5 are used to store the IGTK key. Signed-off-by: Ajay Singh <ajay.kathat@microchip.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20220524120606.9675-4-ajay.kathat@microchip.com
This commit is contained in:
parent
c5b331d4f5
commit
0e703de3ef
@ -307,6 +307,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
int ret;
|
||||
u32 i;
|
||||
u8 security = WILC_FW_SEC_NO;
|
||||
enum mfptype mfp_type = WILC_FW_MFP_NONE;
|
||||
enum authtype auth_type = WILC_FW_AUTH_ANY;
|
||||
u32 cipher_group;
|
||||
struct cfg80211_bss *bss;
|
||||
@ -416,6 +417,13 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
wfi_drv->conn_info.arg = priv;
|
||||
wfi_drv->conn_info.param = join_params;
|
||||
|
||||
if (sme->mfp == NL80211_MFP_OPTIONAL)
|
||||
mfp_type = WILC_FW_MFP_OPTIONAL;
|
||||
else if (sme->mfp == NL80211_MFP_REQUIRED)
|
||||
mfp_type = WILC_FW_MFP_REQUIRED;
|
||||
|
||||
wfi_drv->conn_info.mfp_type = mfp_type;
|
||||
|
||||
ret = wilc_set_join_req(vif, bss->bssid, sme->ie, sme->ie_len);
|
||||
if (ret) {
|
||||
netdev_err(dev, "wilc_set_join_req(): Error\n");
|
||||
@ -495,6 +503,18 @@ static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wilc_wfi_cfg_allocate_wpa_igtk_entry(struct wilc_priv *priv, u8 idx)
|
||||
{
|
||||
idx -= 4;
|
||||
if (!priv->wilc_igtk[idx]) {
|
||||
priv->wilc_igtk[idx] = kzalloc(sizeof(*priv->wilc_igtk[idx]),
|
||||
GFP_KERNEL);
|
||||
if (!priv->wilc_igtk[idx])
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wilc_wfi_cfg_copy_wpa_info(struct wilc_wfi_key *key_info,
|
||||
struct key_params *params)
|
||||
{
|
||||
@ -531,6 +551,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
|
||||
u8 op_mode;
|
||||
struct wilc_vif *vif = netdev_priv(netdev);
|
||||
struct wilc_priv *priv = &vif->priv;
|
||||
struct wilc_wfi_key *key;
|
||||
|
||||
switch (params->cipher) {
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
@ -594,6 +615,26 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
|
||||
key_index);
|
||||
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||
ret = wilc_wfi_cfg_allocate_wpa_igtk_entry(priv, key_index);
|
||||
if (ret)
|
||||
return -ENOMEM;
|
||||
|
||||
key = priv->wilc_igtk[key_index - 4];
|
||||
ret = wilc_wfi_cfg_copy_wpa_info(key, params);
|
||||
if (ret)
|
||||
return -ENOMEM;
|
||||
|
||||
if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
|
||||
priv->wdev.iftype == NL80211_IFTYPE_P2P_GO)
|
||||
op_mode = WILC_AP_MODE;
|
||||
else
|
||||
op_mode = WILC_STATION_MODE;
|
||||
|
||||
ret = wilc_add_igtk(vif, params->key, keylen, params->seq,
|
||||
params->seq_len, mac_addr, op_mode,
|
||||
key_index);
|
||||
break;
|
||||
|
||||
default:
|
||||
netdev_err(netdev, "%s: Unsupported cipher\n", __func__);
|
||||
@ -611,23 +652,34 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
struct wilc_vif *vif = netdev_priv(netdev);
|
||||
struct wilc_priv *priv = &vif->priv;
|
||||
|
||||
if (priv->wilc_gtk[key_index]) {
|
||||
kfree(priv->wilc_gtk[key_index]->key);
|
||||
priv->wilc_gtk[key_index]->key = NULL;
|
||||
kfree(priv->wilc_gtk[key_index]->seq);
|
||||
priv->wilc_gtk[key_index]->seq = NULL;
|
||||
if (!pairwise && (key_index == 4 || key_index == 5)) {
|
||||
key_index -= 4;
|
||||
if (priv->wilc_igtk[key_index]) {
|
||||
kfree(priv->wilc_igtk[key_index]->key);
|
||||
priv->wilc_igtk[key_index]->key = NULL;
|
||||
kfree(priv->wilc_igtk[key_index]->seq);
|
||||
priv->wilc_igtk[key_index]->seq = NULL;
|
||||
kfree(priv->wilc_igtk[key_index]);
|
||||
priv->wilc_igtk[key_index] = NULL;
|
||||
}
|
||||
} else {
|
||||
if (priv->wilc_gtk[key_index]) {
|
||||
kfree(priv->wilc_gtk[key_index]->key);
|
||||
priv->wilc_gtk[key_index]->key = NULL;
|
||||
kfree(priv->wilc_gtk[key_index]->seq);
|
||||
priv->wilc_gtk[key_index]->seq = NULL;
|
||||
|
||||
kfree(priv->wilc_gtk[key_index]);
|
||||
priv->wilc_gtk[key_index] = NULL;
|
||||
}
|
||||
|
||||
if (priv->wilc_ptk[key_index]) {
|
||||
kfree(priv->wilc_ptk[key_index]->key);
|
||||
priv->wilc_ptk[key_index]->key = NULL;
|
||||
kfree(priv->wilc_ptk[key_index]->seq);
|
||||
priv->wilc_ptk[key_index]->seq = NULL;
|
||||
kfree(priv->wilc_ptk[key_index]);
|
||||
priv->wilc_ptk[key_index] = NULL;
|
||||
kfree(priv->wilc_gtk[key_index]);
|
||||
priv->wilc_gtk[key_index] = NULL;
|
||||
}
|
||||
if (priv->wilc_ptk[key_index]) {
|
||||
kfree(priv->wilc_ptk[key_index]->key);
|
||||
priv->wilc_ptk[key_index]->key = NULL;
|
||||
kfree(priv->wilc_ptk[key_index]->seq);
|
||||
priv->wilc_ptk[key_index]->seq = NULL;
|
||||
kfree(priv->wilc_ptk[key_index]);
|
||||
priv->wilc_ptk[key_index] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -642,11 +694,20 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
|
||||
struct key_params key_params;
|
||||
|
||||
if (!pairwise) {
|
||||
key_params.key = priv->wilc_gtk[key_index]->key;
|
||||
key_params.cipher = priv->wilc_gtk[key_index]->cipher;
|
||||
key_params.key_len = priv->wilc_gtk[key_index]->key_len;
|
||||
key_params.seq = priv->wilc_gtk[key_index]->seq;
|
||||
key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
|
||||
if (key_index == 4 || key_index == 5) {
|
||||
key_index -= 4;
|
||||
key_params.key = priv->wilc_igtk[key_index]->key;
|
||||
key_params.cipher = priv->wilc_igtk[key_index]->cipher;
|
||||
key_params.key_len = priv->wilc_igtk[key_index]->key_len;
|
||||
key_params.seq = priv->wilc_igtk[key_index]->seq;
|
||||
key_params.seq_len = priv->wilc_igtk[key_index]->seq_len;
|
||||
} else {
|
||||
key_params.key = priv->wilc_gtk[key_index]->key;
|
||||
key_params.cipher = priv->wilc_gtk[key_index]->cipher;
|
||||
key_params.key_len = priv->wilc_gtk[key_index]->key_len;
|
||||
key_params.seq = priv->wilc_gtk[key_index]->seq;
|
||||
key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
|
||||
}
|
||||
} else {
|
||||
key_params.key = priv->wilc_ptk[key_index]->key;
|
||||
key_params.cipher = priv->wilc_ptk[key_index]->cipher;
|
||||
@ -667,6 +728,14 @@ static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
u8 key_index)
|
||||
{
|
||||
struct wilc_vif *vif = netdev_priv(netdev);
|
||||
|
||||
return wilc_set_default_mgmt_key_index(vif, key_index);
|
||||
}
|
||||
|
||||
static int get_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *mac, struct station_info *sinfo)
|
||||
{
|
||||
@ -1626,6 +1695,7 @@ static const struct cfg80211_ops wilc_cfg80211_ops = {
|
||||
.del_key = del_key,
|
||||
.get_key = get_key,
|
||||
.set_default_key = set_default_key,
|
||||
.set_default_mgmt_key = set_default_mgmt_key,
|
||||
.add_virtual_intf = add_virtual_intf,
|
||||
.del_virtual_intf = del_virtual_intf,
|
||||
.change_virtual_intf = change_virtual_intf,
|
||||
|
@ -54,6 +54,14 @@ struct wilc_ap_wpa_ptk {
|
||||
u8 key[];
|
||||
} __packed;
|
||||
|
||||
struct wilc_wpa_igtk {
|
||||
u8 index;
|
||||
u8 pn_len;
|
||||
u8 pn[6];
|
||||
u8 key_len;
|
||||
u8 key[];
|
||||
} __packed;
|
||||
|
||||
struct wilc_gtk_key {
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 rsc[8];
|
||||
|
@ -271,12 +271,19 @@ error:
|
||||
static int wilc_send_connect_wid(struct wilc_vif *vif)
|
||||
{
|
||||
int result = 0;
|
||||
struct wid wid_list[4];
|
||||
struct wid wid_list[5];
|
||||
u32 wid_cnt = 0;
|
||||
struct host_if_drv *hif_drv = vif->hif_drv;
|
||||
struct wilc_conn_info *conn_attr = &hif_drv->conn_info;
|
||||
struct wilc_join_bss_param *bss_param = conn_attr->param;
|
||||
|
||||
|
||||
wid_list[wid_cnt].id = WID_SET_MFP;
|
||||
wid_list[wid_cnt].type = WID_CHAR;
|
||||
wid_list[wid_cnt].size = sizeof(char);
|
||||
wid_list[wid_cnt].val = (s8 *)&conn_attr->mfp_type;
|
||||
wid_cnt++;
|
||||
|
||||
wid_list[wid_cnt].id = WID_INFO_ELEMENT_ASSOCIATE;
|
||||
wid_list[wid_cnt].type = WID_BIN_DATA;
|
||||
wid_list[wid_cnt].val = conn_attr->req_ies;
|
||||
@ -1143,6 +1150,36 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
|
||||
return result;
|
||||
}
|
||||
|
||||
int wilc_add_igtk(struct wilc_vif *vif, const u8 *igtk, u8 igtk_key_len,
|
||||
const u8 *pn, u8 pn_len, const u8 *mac_addr, u8 mode, u8 index)
|
||||
{
|
||||
int result = 0;
|
||||
u8 t_key_len = igtk_key_len;
|
||||
struct wid wid;
|
||||
struct wilc_wpa_igtk *key_buf;
|
||||
|
||||
key_buf = kzalloc(sizeof(*key_buf) + t_key_len, GFP_KERNEL);
|
||||
if (!key_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
key_buf->index = index;
|
||||
|
||||
memcpy(&key_buf->pn[0], pn, pn_len);
|
||||
key_buf->pn_len = pn_len;
|
||||
|
||||
memcpy(&key_buf->key[0], igtk, igtk_key_len);
|
||||
key_buf->key_len = t_key_len;
|
||||
|
||||
wid.id = WID_ADD_IGTK;
|
||||
wid.type = WID_STR;
|
||||
wid.size = sizeof(*key_buf) + t_key_len;
|
||||
wid.val = (s8 *)key_buf;
|
||||
result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
|
||||
kfree(key_buf);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
|
||||
u8 index, u32 key_rsc_len, const u8 *key_rsc,
|
||||
const u8 *rx_mic, const u8 *tx_mic, u8 mode,
|
||||
@ -1932,3 +1969,20 @@ int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
|
||||
|
||||
return wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
|
||||
}
|
||||
|
||||
int wilc_set_default_mgmt_key_index(struct wilc_vif *vif, u8 index)
|
||||
{
|
||||
struct wid wid;
|
||||
int result;
|
||||
|
||||
wid.id = WID_DEFAULT_MGMT_KEY_ID;
|
||||
wid.type = WID_CHAR;
|
||||
wid.size = sizeof(char);
|
||||
wid.val = &index;
|
||||
result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
|
||||
if (result)
|
||||
netdev_err(vif->ndev,
|
||||
"Failed to send default mgmt key index\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -108,6 +108,7 @@ struct wilc_conn_info {
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 security;
|
||||
enum authtype auth_type;
|
||||
enum mfptype mfp_type;
|
||||
u8 ch;
|
||||
u8 *req_ies;
|
||||
size_t req_ies_len;
|
||||
@ -155,6 +156,9 @@ struct wilc_vif;
|
||||
int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
|
||||
const u8 *mac_addr, const u8 *rx_mic, const u8 *tx_mic,
|
||||
u8 mode, u8 cipher_mode, u8 index);
|
||||
int wilc_add_igtk(struct wilc_vif *vif, const u8 *igtk, u8 igtk_key_len,
|
||||
const u8 *pn, u8 pn_len, const u8 *mac_addr, u8 mode,
|
||||
u8 index);
|
||||
s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
|
||||
u32 *out_val);
|
||||
int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
|
||||
@ -210,4 +214,5 @@ void wilc_network_info_received(struct wilc *wilc, u8 *buffer, u32 length);
|
||||
void wilc_gnrl_async_info_received(struct wilc *wilc, u8 *buffer, u32 length);
|
||||
void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
|
||||
struct cfg80211_crypto_settings *crypto);
|
||||
int wilc_set_default_mgmt_key_index(struct wilc_vif *vif, u8 index);
|
||||
#endif
|
||||
|
@ -129,6 +129,7 @@ struct wilc_priv {
|
||||
struct net_device *real_ndev;
|
||||
struct wilc_wfi_key *wilc_gtk[WILC_MAX_NUM_STA];
|
||||
struct wilc_wfi_key *wilc_ptk[WILC_MAX_NUM_STA];
|
||||
struct wilc_wfi_key *wilc_igtk[2];
|
||||
u8 wilc_groupkey;
|
||||
|
||||
/* mutexes */
|
||||
|
@ -91,6 +91,12 @@ enum authtype {
|
||||
WILC_FW_AUTH_OPEN_SYSTEM_SHA256 = 13
|
||||
};
|
||||
|
||||
enum mfptype {
|
||||
WILC_FW_MFP_NONE = 0x0,
|
||||
WILC_FW_MFP_OPTIONAL = 0x1,
|
||||
WILC_FW_MFP_REQUIRED = 0x2
|
||||
};
|
||||
|
||||
enum site_survey {
|
||||
WILC_FW_SITE_SURVEY_1CH = 0,
|
||||
WILC_FW_SITE_SURVEY_ALL_CH = 1,
|
||||
@ -661,6 +667,9 @@ enum {
|
||||
WID_LOG_TERMINAL_SWITCH = 0x00CD,
|
||||
WID_TX_POWER = 0x00CE,
|
||||
WID_WOWLAN_TRIGGER = 0X00CF,
|
||||
WID_SET_MFP = 0x00D0,
|
||||
|
||||
WID_DEFAULT_MGMT_KEY_ID = 0x00D2,
|
||||
/* EMAC Short WID list */
|
||||
/* RTS Threshold */
|
||||
/*
|
||||
@ -750,6 +759,7 @@ enum {
|
||||
WID_REMOVE_KEY = 0x301E,
|
||||
WID_ASSOC_REQ_INFO = 0x301F,
|
||||
WID_ASSOC_RES_INFO = 0x3020,
|
||||
WID_ADD_IGTK = 0x3022,
|
||||
WID_MANUFACTURER = 0x3026, /* Added for CAPI tool */
|
||||
WID_MODEL_NAME = 0x3027, /* Added for CAPI tool */
|
||||
WID_MODEL_NUM = 0x3028, /* Added for CAPI tool */
|
||||
|
Loading…
x
Reference in New Issue
Block a user