qcacmn: Beacon protection support
Changes to support Beacon protection. Additional key ix 6 and 7 support BIGTK. Update beacon template for Beacon protection support. CRs-Fixed: 2632290 Change-Id: Ic37d17f5076bb28d2e1f2430da039cc8b9f759b6
Bu işleme şunda yer alıyor:

işlemeyi yapan:
nshrivas

ebeveyn
a308b3e970
işleme
806b7c72df
@@ -49,6 +49,7 @@
|
||||
#define WLAN_CRYPTO_KEYIX_NONE ((uint16_t)-1)
|
||||
#define WLAN_CRYPTO_MAXKEYIDX (4)
|
||||
#define WLAN_CRYPTO_MAXIGTKKEYIDX (2)
|
||||
#define WLAN_CRYPTO_MAXBIGTKKEYIDX (2)
|
||||
#ifndef WLAN_CRYPTO_MAX_VLANKEYIX
|
||||
#define WLAN_CRYPTO_MAX_VLANKEYIX WLAN_CRYPTO_MAXKEYIDX
|
||||
#endif
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -427,9 +427,11 @@ struct wlan_crypto_mmie {
|
||||
* @crypto_params: crypto params for the peer
|
||||
* @key: key buffers for this peer
|
||||
* @igtk_key: igtk key buffer for this peer
|
||||
* @bigtk_key: bigtk key buffer for this peer
|
||||
* @igtk_key_type: igtk key type
|
||||
* @def_tx_keyid: default key used for this peer
|
||||
* @def_igtk_tx_keyid default igtk key used for this peer
|
||||
* @def_bigtk_tx_keyid default bigtk key used for this peer
|
||||
* @fils_aead_set fils params for this peer
|
||||
*
|
||||
*/
|
||||
@@ -437,9 +439,11 @@ struct wlan_crypto_comp_priv {
|
||||
struct wlan_crypto_params crypto_params;
|
||||
struct wlan_crypto_key *key[WLAN_CRYPTO_MAX_VLANKEYIX];
|
||||
struct wlan_crypto_key *igtk_key[WLAN_CRYPTO_MAXIGTKKEYIDX];
|
||||
struct wlan_crypto_key *bigtk_key[WLAN_CRYPTO_MAXBIGTKKEYIDX];
|
||||
uint32_t igtk_key_type;
|
||||
uint8_t def_tx_keyid;
|
||||
uint8_t def_igtk_tx_keyid;
|
||||
uint8_t def_bigtk_tx_keyid;
|
||||
uint8_t fils_aead_set;
|
||||
};
|
||||
|
||||
|
@@ -55,6 +55,36 @@ const struct wlan_crypto_cipher *wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX];
|
||||
WLAN_CRYPTO_ADDSELECTOR(frm,\
|
||||
wlan_crypto_rsn_keymgmt_to_suite(keymgmt))
|
||||
|
||||
static int is_valid_keyix(uint16_t keyix)
|
||||
{
|
||||
if (keyix >= (WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX
|
||||
+ WLAN_CRYPTO_MAXBIGTKKEYIDX))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int is_igtk(uint16_t keyix)
|
||||
{
|
||||
if (keyix < WLAN_CRYPTO_MAXKEYIDX)
|
||||
return 0;
|
||||
else if (keyix - WLAN_CRYPTO_MAXKEYIDX >= WLAN_CRYPTO_MAXIGTKKEYIDX)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int is_bigtk(uint16_t keyix)
|
||||
{
|
||||
if (keyix < (WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX))
|
||||
return 0;
|
||||
if (keyix - WLAN_CRYPTO_MAXKEYIDX - WLAN_CRYPTO_MAXIGTKKEYIDX
|
||||
>= WLAN_CRYPTO_MAXBIGTKKEYIDX)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_crypto_vdev_get_crypto_params - called by mlme to get crypto params
|
||||
* @vdev:vdev
|
||||
@@ -588,6 +618,7 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
|
||||
bool isbcast;
|
||||
enum QDF_OPMODE vdev_mode;
|
||||
uint8_t igtk_idx = 0;
|
||||
uint8_t bigtk_idx = 0;
|
||||
|
||||
if (!vdev || !req_key || req_key->keylen > (sizeof(req_key->keydata))) {
|
||||
crypto_err("Invalid params vdev%pK, req_key%pK", vdev, req_key);
|
||||
@@ -679,22 +710,40 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
|
||||
}
|
||||
|
||||
if (IS_MGMT_CIPHER(req_key->type)) {
|
||||
struct wlan_crypto_key *crypto_key = NULL;
|
||||
|
||||
igtk_idx = req_key->keyix - WLAN_CRYPTO_MAXKEYIDX;
|
||||
if (igtk_idx >= WLAN_CRYPTO_MAXIGTKKEYIDX) {
|
||||
crypto_err("igtk key invalid keyid %d",
|
||||
igtk_idx);
|
||||
bigtk_idx = igtk_idx - WLAN_CRYPTO_MAXIGTKKEYIDX;
|
||||
if (is_igtk(req_key->keyix)) {
|
||||
bigtk_idx = 0;
|
||||
} else if (is_bigtk(req_key->keyix)) {
|
||||
igtk_idx = 0;
|
||||
} else {
|
||||
crypto_err("igtk/bigtk key invalid keyid %d",
|
||||
req_key->keyix);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
key = qdf_mem_malloc(sizeof(struct wlan_crypto_key));
|
||||
if (!key)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
if (crypto_priv->igtk_key[igtk_idx])
|
||||
qdf_mem_free(crypto_priv->igtk_key[igtk_idx]);
|
||||
|
||||
crypto_priv->igtk_key[igtk_idx] = key;
|
||||
crypto_priv->igtk_key_type = req_key->type;
|
||||
crypto_priv->def_igtk_tx_keyid = igtk_idx;
|
||||
if (igtk_idx) {
|
||||
crypto_key = crypto_priv->igtk_key[igtk_idx];
|
||||
if (crypto_key)
|
||||
qdf_mem_free(crypto_key);
|
||||
|
||||
crypto_priv->igtk_key[igtk_idx] = key;
|
||||
crypto_priv->igtk_key_type = req_key->type;
|
||||
crypto_priv->def_igtk_tx_keyid = igtk_idx;
|
||||
} else {
|
||||
crypto_key = crypto_priv->bigtk_key[bigtk_idx];
|
||||
if (crypto_key)
|
||||
qdf_mem_free(crypto_key);
|
||||
|
||||
crypto_priv->bigtk_key[bigtk_idx] = key;
|
||||
crypto_priv->def_bigtk_tx_keyid = bigtk_idx;
|
||||
}
|
||||
} else {
|
||||
if (IS_FILS_CIPHER(req_key->type)) {
|
||||
crypto_err("FILS key is not for BroadCast pkt");
|
||||
@@ -720,6 +769,8 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
|
||||
crypto_err("peer NULL");
|
||||
if (IS_MGMT_CIPHER(req_key->type)) {
|
||||
crypto_priv->igtk_key[igtk_idx] = NULL;
|
||||
crypto_priv->bigtk_key[bigtk_idx]
|
||||
= NULL;
|
||||
crypto_priv->igtk_key_type
|
||||
= WLAN_CRYPTO_CIPHER_NONE;
|
||||
} else
|
||||
@@ -759,22 +810,39 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
if (IS_MGMT_CIPHER(req_key->type)) {
|
||||
struct wlan_crypto_key *crypto_key = NULL;
|
||||
|
||||
igtk_idx = req_key->keyix - WLAN_CRYPTO_MAXKEYIDX;
|
||||
if (igtk_idx >= WLAN_CRYPTO_MAXIGTKKEYIDX) {
|
||||
crypto_err("igtk key invalid keyid %d",
|
||||
igtk_idx);
|
||||
bigtk_idx = igtk_idx - WLAN_CRYPTO_MAXIGTKKEYIDX;
|
||||
if (is_igtk(req_key->keyix)) {
|
||||
bigtk_idx = 0;
|
||||
} else if (is_bigtk(req_key->keyix)) {
|
||||
igtk_idx = 0;
|
||||
} else {
|
||||
crypto_err("igtk/bigtk key invalid keyid %d",
|
||||
req_key->keyix);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
key = qdf_mem_malloc(sizeof(struct wlan_crypto_key));
|
||||
if (!key)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
if (crypto_priv->igtk_key[igtk_idx])
|
||||
qdf_mem_free(crypto_priv->igtk_key[igtk_idx]);
|
||||
if (igtk_idx) {
|
||||
crypto_key = crypto_priv->igtk_key[igtk_idx];
|
||||
if (crypto_key)
|
||||
qdf_mem_free(crypto_key);
|
||||
|
||||
crypto_priv->igtk_key[igtk_idx] = key;
|
||||
crypto_priv->igtk_key_type = req_key->type;
|
||||
crypto_priv->def_igtk_tx_keyid = igtk_idx;
|
||||
crypto_priv->igtk_key[igtk_idx] = key;
|
||||
crypto_priv->igtk_key_type = req_key->type;
|
||||
crypto_priv->def_igtk_tx_keyid = igtk_idx;
|
||||
} else {
|
||||
crypto_key = crypto_priv->bigtk_key[bigtk_idx];
|
||||
if (crypto_key)
|
||||
qdf_mem_free(crypto_key);
|
||||
|
||||
crypto_priv->bigtk_key[bigtk_idx] = key;
|
||||
crypto_priv->def_bigtk_tx_keyid = bigtk_idx;
|
||||
}
|
||||
} else {
|
||||
uint16_t kid = req_key->keyix;
|
||||
if (kid == WLAN_CRYPTO_KEYIX_NONE)
|
||||
@@ -853,7 +921,8 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
|
||||
key->valid = 1;
|
||||
if ((IS_MGMT_CIPHER(req_key->type))) {
|
||||
if (HAS_CIPHER_CAP(crypto_params,
|
||||
WLAN_CRYPTO_CAP_PMF_OFFLOAD)) {
|
||||
WLAN_CRYPTO_CAP_PMF_OFFLOAD) ||
|
||||
is_bigtk(req_key->keyix)) {
|
||||
if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) {
|
||||
WLAN_CRYPTO_TX_OPS_SETKEY(psoc)(vdev,
|
||||
key, macaddr, req_key->type);
|
||||
@@ -928,10 +997,13 @@ struct wlan_crypto_key *wlan_crypto_vdev_getkey(struct wlan_objmgr_vdev *vdev,
|
||||
* we return the default key, for all other keyix we return the
|
||||
* key accordingly.
|
||||
*/
|
||||
if (keyix == WLAN_CRYPTO_KEYIX_NONE ||
|
||||
keyix >= (WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX))
|
||||
if ((keyix == WLAN_CRYPTO_KEYIX_NONE) ||
|
||||
!is_valid_keyix(keyix))
|
||||
key = crypto_priv->key[crypto_priv->def_tx_keyid];
|
||||
else if (keyix >= WLAN_CRYPTO_MAXKEYIDX)
|
||||
else if (is_bigtk(keyix))
|
||||
key = crypto_priv->bigtk_key[keyix - WLAN_CRYPTO_MAXKEYIDX
|
||||
- WLAN_CRYPTO_MAXIGTKKEYIDX];
|
||||
else if (is_igtk(keyix))
|
||||
key = crypto_priv->igtk_key[keyix - WLAN_CRYPTO_MAXKEYIDX];
|
||||
else
|
||||
key = crypto_priv->key[keyix];
|
||||
@@ -970,9 +1042,12 @@ struct wlan_crypto_key *wlan_crypto_peer_getkey(struct wlan_objmgr_peer *peer,
|
||||
* key accordingly.
|
||||
*/
|
||||
if (keyix == WLAN_CRYPTO_KEYIX_NONE ||
|
||||
keyix >= (WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX))
|
||||
!is_valid_keyix(keyix))
|
||||
key = crypto_priv->key[crypto_priv->def_tx_keyid];
|
||||
else if (keyix >= WLAN_CRYPTO_MAXKEYIDX)
|
||||
else if (is_bigtk(keyix))
|
||||
key = crypto_priv->bigtk_key[keyix - WLAN_CRYPTO_MAXKEYIDX
|
||||
- WLAN_CRYPTO_MAXIGTKKEYIDX];
|
||||
else if (is_igtk(keyix))
|
||||
key = crypto_priv->igtk_key[keyix - WLAN_CRYPTO_MAXKEYIDX];
|
||||
else
|
||||
key = crypto_priv->key[keyix];
|
||||
@@ -1097,8 +1172,7 @@ QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev,
|
||||
uint8_t bssid_mac[QDF_MAC_ADDR_SIZE];
|
||||
|
||||
if (!vdev || !macaddr ||
|
||||
(key_idx >=
|
||||
(WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX))) {
|
||||
!is_valid_keyix(key_idx)) {
|
||||
crypto_err("Invalid param vdev %pK macaddr %pK keyidx %d",
|
||||
vdev, macaddr, key_idx);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
@@ -1147,12 +1221,23 @@ QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev,
|
||||
|
||||
if (key_idx >= WLAN_CRYPTO_MAXKEYIDX) {
|
||||
uint8_t igtk_idx = key_idx - WLAN_CRYPTO_MAXKEYIDX;
|
||||
if (igtk_idx >= WLAN_CRYPTO_MAXIGTKKEYIDX) {
|
||||
crypto_err("Igtk key invalid keyid %d", igtk_idx);
|
||||
uint8_t bigtk_idx = igtk_idx - WLAN_CRYPTO_MAXIGTKKEYIDX;
|
||||
|
||||
if (is_igtk(key_idx)) {
|
||||
bigtk_idx = 0;
|
||||
} else if (is_bigtk(key_idx)) {
|
||||
igtk_idx = 0;
|
||||
} else {
|
||||
crypto_err("igtk/bigtk key invalid keyid %d", key_idx);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
key = crypto_priv->igtk_key[igtk_idx];
|
||||
crypto_priv->igtk_key[igtk_idx] = NULL;
|
||||
if (igtk_idx) {
|
||||
key = crypto_priv->igtk_key[igtk_idx];
|
||||
crypto_priv->igtk_key[igtk_idx] = NULL;
|
||||
} else {
|
||||
key = crypto_priv->bigtk_key[bigtk_idx];
|
||||
crypto_priv->bigtk_key[bigtk_idx] = NULL;
|
||||
}
|
||||
if (key)
|
||||
key->valid = 0;
|
||||
} else {
|
||||
@@ -4114,7 +4199,7 @@ QDF_STATUS wlan_crypto_validate_key_params(enum wlan_crypto_cipher_type cipher,
|
||||
uint8_t key_index, uint8_t key_len,
|
||||
uint8_t seq_len)
|
||||
{
|
||||
if (key_index >= (WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX)) {
|
||||
if (!is_valid_keyix(key_index)) {
|
||||
crypto_err("Invalid Key index %d", key_index);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
@@ -4158,15 +4243,18 @@ QDF_STATUS wlan_crypto_save_key(struct wlan_objmgr_vdev *vdev,
|
||||
crypto_err("crypto_priv NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
if (key_index >= (WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX)) {
|
||||
if (!is_valid_keyix(key_index)) {
|
||||
crypto_err("Invalid Key index %d", key_index);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
if (key_index < WLAN_CRYPTO_MAXKEYIDX)
|
||||
crypto_priv->key[key_index] = crypto_key;
|
||||
else
|
||||
else if (is_igtk(key_index))
|
||||
crypto_priv->igtk_key[key_index - WLAN_CRYPTO_MAXKEYIDX] =
|
||||
crypto_key;
|
||||
else
|
||||
crypto_priv->bigtk_key[key_index - WLAN_CRYPTO_MAXKEYIDX
|
||||
- WLAN_CRYPTO_MAXIGTKKEYIDX] = crypto_key;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -4181,14 +4269,19 @@ struct wlan_crypto_key *wlan_crypto_get_key(struct wlan_objmgr_vdev *vdev,
|
||||
crypto_err("crypto_priv NULL");
|
||||
return NULL;
|
||||
}
|
||||
if (key_index >= (WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX)) {
|
||||
if (!is_valid_keyix(key_index)) {
|
||||
crypto_err("Invalid Key index %d", key_index);
|
||||
return NULL;
|
||||
}
|
||||
if (key_index < WLAN_CRYPTO_MAXKEYIDX)
|
||||
return crypto_priv->key[key_index];
|
||||
else if (is_igtk(key_index))
|
||||
return crypto_priv->igtk_key[key_index - WLAN_CRYPTO_MAXKEYIDX];
|
||||
else
|
||||
return crypto_priv->bigtk_key[key_index - WLAN_CRYPTO_MAXKEYIDX
|
||||
- WLAN_CRYPTO_MAXIGTKKEYIDX];
|
||||
|
||||
return crypto_priv->igtk_key[key_index - WLAN_CRYPTO_MAXKEYIDX];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QDF_STATUS wlan_crypto_set_key_req(struct wlan_objmgr_vdev *vdev,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -195,6 +195,13 @@ static void wlan_crypto_free_key(struct wlan_crypto_comp_priv *crypto_priv)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < WLAN_CRYPTO_MAXBIGTKKEYIDX; i++) {
|
||||
if (crypto_priv->bigtk_key[i]) {
|
||||
qdf_mem_free(crypto_priv->bigtk_key[i]);
|
||||
crypto_priv->bigtk_key[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static QDF_STATUS wlan_crypto_vdev_obj_destroy_handler(
|
||||
|
@@ -89,6 +89,9 @@
|
||||
#define WLAN_PDEV_F_MBSS_IE_ENABLE 0x20000000
|
||||
/* VDEV Peer delete all */
|
||||
#define WLAN_PDEV_F_DELETE_ALL_PEER 0x40000000
|
||||
/* PDEV BEacon Protection */
|
||||
#define WLAN_PDEV_F_BEACON_PROTECTION 0x80000000
|
||||
|
||||
|
||||
/* PDEV op flags */
|
||||
/* Enable htrate for wep and tkip */
|
||||
|
@@ -171,6 +171,7 @@ struct tbttoffset_params {
|
||||
* @ext_csa_switch_count_offset: ECSA switch count offset in beacon frame
|
||||
* @esp_ie_offset: ESP IE offset in beacon frame
|
||||
* @mu_edca_ie_offset: Mu EDCA IE offset in beacon frame
|
||||
* @enable_bigtk: enable bigtk or not
|
||||
* @frm: beacon template parameter
|
||||
*/
|
||||
struct beacon_tmpl_params {
|
||||
@@ -183,6 +184,7 @@ struct beacon_tmpl_params {
|
||||
uint32_t ext_csa_switch_count_offset;
|
||||
uint32_t esp_ie_offset;
|
||||
uint32_t mu_edca_ie_offset;
|
||||
bool enable_bigtk;
|
||||
uint8_t *frm;
|
||||
};
|
||||
|
||||
|
@@ -5120,6 +5120,7 @@ typedef enum {
|
||||
wmi_service_time_sync_ftm,
|
||||
wmi_service_nss_ratio_to_host_support,
|
||||
wmi_roam_scan_chan_list_to_host_support,
|
||||
wmi_beacon_protection_support,
|
||||
wmi_services_max,
|
||||
} wmi_conv_service_ids;
|
||||
#define WMI_SERVICE_UNAVAILABLE 0xFFFF
|
||||
|
@@ -2402,6 +2402,9 @@ static QDF_STATUS send_beacon_tmpl_send_cmd_tlv(wmi_unified_t wmi_handle,
|
||||
cmd->esp_ie_offset = param->esp_ie_offset;
|
||||
cmd->mu_edca_ie_offset = param->mu_edca_ie_offset;
|
||||
cmd->buf_len = param->tmpl_len;
|
||||
|
||||
WMI_BEACON_PROTECTION_EN_SET(cmd->feature_enable_bitmap,
|
||||
param->enable_bigtk);
|
||||
buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param);
|
||||
|
||||
bcn_prb_info = (wmi_bcn_prb_info *) buf_ptr;
|
||||
@@ -14436,6 +14439,8 @@ static void populate_tlv_service(uint32_t *wmi_service)
|
||||
WMI_SERVICE_NSS_RATIO_TO_HOST_SUPPORT;
|
||||
wmi_service[wmi_roam_scan_chan_list_to_host_support] =
|
||||
WMI_SERVICE_ROAM_SCAN_CHANNEL_LIST_TO_HOST_SUPPORT;
|
||||
wmi_service[wmi_beacon_protection_support] =
|
||||
WMI_SERVICE_BEACON_PROTECTION_SUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Yeni konuda referans
Bir kullanıcı engelle