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:
Gurumoorthi Gnanasambandhan
2020-03-13 19:32:50 +05:30
işlemeyi yapan: nshrivas
ebeveyn a308b3e970
işleme 806b7c72df
8 değiştirilmiş dosya ile 151 ekleme ve 35 silme

Dosyayı Görüntüle

@@ -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

Dosyayı Görüntüle

@@ -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;
};

Dosyayı Görüntüle

@@ -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,

Dosyayı Görüntüle

@@ -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(

Dosyayı Görüntüle

@@ -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 */

Dosyayı Görüntüle

@@ -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;
};

Dosyayı Görüntüle

@@ -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

Dosyayı Görüntüle

@@ -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;
}
/**