qcacmn: Add support for SET KEY convergence

Make changes to the cmn driver to support SET KEY
convergence feature

Change-Id: I17b5f368a1f735eb394ea70f9b61cc033c3eb20a
CRs-Fixed: 2358796
This commit is contained in:
Kiran Kumar Lokere
2018-09-19 13:48:48 -07:00
committed by nshrivas
parent ec27e10c2a
commit 25531c4717
17 changed files with 1014 additions and 40 deletions

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2019 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
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: declares crypto functions interfacing with linux kernel
*/
#ifndef _WLAN_CFG80211_CRYPTO_H_
#define _WLAN_CFG80211_CRYPTO_H_
#include <net/cfg80211.h>
#ifdef CONFIG_CRYPTO_COMPONENT
/**
* wlan_cfg80211_set_default_key() - to set the default key to be used
* @vdev: VDEV Object pointer
* @key_index: Index to be set as the default
* @bssid: BSSID for which the key is to be set
*
* Return: Zero for success and negative for failure.
*/
int wlan_cfg80211_set_default_key(struct wlan_objmgr_vdev *vdev,
uint8_t key_index,
struct qdf_mac_addr *bssid);
#else
static inline int wlan_cfg80211_set_default_key(struct wlan_objmgr_vdev *vdev,
uint8_t key_index,
struct qdf_mac_addr *bssid)
{
return 0;
}
#endif
/**
* wlan_cfg80211_store_key() - Store the key
* @vdev: VDEV Object pointer
* @key_index: Index to be set as the default
* @pairwise: denotes if the key is pairwise or group key
* @mac_addr: BSSID for which the key is to be set
* @key_params: Params received from the kernel
*
* Return: Zero for success and negative for failure.
*/
int wlan_cfg80211_store_key(struct wlan_objmgr_vdev *vdev,
uint8_t key_index, bool pairwise,
const u8 *mac_addr, struct key_params *params);
/**
* wlan_cfg80211_crypto_add_key() - Add key for the specified vdev
* @vdev: vdev object
* @pairwise: denotes if the add key request is for pairwise or group key
* @key_index: Index of the key that needs to be added
*
* Return: Zero on Success, negative value on failure
*/
int wlan_cfg80211_crypto_add_key(struct wlan_objmgr_vdev *vdev, bool pairwise,
uint8_t key_index);
#endif

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2019 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -52,6 +52,16 @@ int osif_nl_to_crypto_akm_type(u32 key_mgmt);
* set the crypto cipher type for corresponding cipher type received * set the crypto cipher type for corresponding cipher type received
* from NL. * from NL.
* *
* Return: crypto cipher type, negative value for failure * Return: crypto cipher type
*/ */
int osif_nl_to_crypto_cipher_type(u32 cipher); enum wlan_crypto_cipher_type osif_nl_to_crypto_cipher_type(u32 cipher);
/**
* osif_nl_to_crypto_cipher_len() - return the cipher length
* @cipher: NL cipher type
*
* Check the cipher type and return the corresponding length
*
* Return: crypto cipher length, negative value for failure
*/
int osif_nl_to_crypto_cipher_len(u32 cipher);

View File

@@ -0,0 +1,138 @@
/*
* Copyright (c) 2019 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
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: defines crypto driver functions interfacing with linux kernel
*/
#include <wlan_crypto_global_def.h>
#include <wlan_crypto_global_api.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_crypto_main_i.h>
#include <net/cfg80211.h>
#include <wlan_nl_to_crypto_params.h>
#include "wlan_cfg80211_crypto.h"
#include <wlan_cfg80211.h>
static void wlan_cfg80211_translate_key(uint8_t key_index, bool pairwise,
const u8 *mac_addr,
struct key_params *params,
struct wlan_crypto_key *crypto_key)
{
static const struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
qdf_mem_zero(crypto_key, sizeof(*crypto_key));
crypto_key->keylen = params->key_len;
crypto_key->keyix = key_index;
qdf_mem_copy(&crypto_key->keyval[0], params->key, params->key_len);
qdf_mem_copy(&crypto_key->keyrsc[0], params->seq, params->seq_len);
crypto_key->cipher_type = osif_nl_to_crypto_cipher_type(params->cipher);
if (pairwise) {
crypto_key->flags |= PAIRWISE_USAGE;
qdf_mem_copy(&crypto_key->macaddr, mac_addr,
QDF_MAC_ADDR_SIZE);
} else {
crypto_key->flags |= GROUP_USAGE;
qdf_mem_copy(&crypto_key->macaddr, &bcast_mac,
QDF_MAC_ADDR_SIZE);
}
}
int wlan_cfg80211_store_key(struct wlan_objmgr_vdev *vdev,
uint8_t key_index, bool pairwise,
const u8 *mac_addr, struct key_params *params)
{
struct wlan_crypto_key *crypto_key = NULL;
enum wlan_crypto_cipher_type cipher;
int cipher_len;
QDF_STATUS status;
if (!vdev) {
cfg80211_err("vdev is NULL");
return -EINVAL;
}
if (!params) {
cfg80211_err("Key params is NULL");
return -EINVAL;
}
if (pairwise && !mac_addr) {
cfg80211_err("mac_addr is NULL for pairwise Key");
return -EINVAL;
}
cipher_len = osif_nl_to_crypto_cipher_len(params->cipher);
if (cipher_len < 0 || params->key_len < cipher_len) {
cfg80211_err("cipher length %d less than reqd len %d",
params->key_len, cipher_len);
return -EINVAL;
}
cipher = osif_nl_to_crypto_cipher_type(params->cipher);
status = wlan_crypto_validate_key_params(cipher, key_index,
params->key_len,
params->seq_len);
if (QDF_IS_STATUS_ERROR(status)) {
cfg80211_err("Invalid key params");
return -EINVAL;
}
/*
* key may already exist at times and may be retrieved only to
* update it.
*/
crypto_key = wlan_crypto_get_key(vdev, key_index);
if (!crypto_key) {
crypto_key = qdf_mem_malloc(sizeof(*crypto_key));
if (!crypto_key)
return -EINVAL;
status = wlan_crypto_save_key(vdev, key_index, crypto_key);
if (QDF_IS_STATUS_ERROR(status)) {
cfg80211_err("Failed to save key");
qdf_mem_free(crypto_key);
return -EINVAL;
}
}
wlan_cfg80211_translate_key(key_index, pairwise, mac_addr,
params, crypto_key);
return 0;
}
int wlan_cfg80211_crypto_add_key(struct wlan_objmgr_vdev *vdev, bool pairwise,
uint8_t key_index)
{
struct wlan_crypto_key *crypto_key;
QDF_STATUS status;
crypto_key = wlan_crypto_get_key(vdev, key_index);
if (!crypto_key) {
cfg80211_err("Crypto KEY is NULL");
return -EINVAL;
}
status = ucfg_crypto_set_key_req(vdev, crypto_key, pairwise);
return qdf_status_to_os_return(status);
}
#ifdef CONFIG_CRYPTO_COMPONENT
int wlan_cfg80211_set_default_key(struct wlan_objmgr_vdev *vdev,
uint8_t key_index, struct qdf_mac_addr *bssid)
{
return wlan_crypto_default_key(vdev, (uint8_t *)bssid,
key_index, true);
}
#endif

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2019 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -55,12 +55,14 @@ struct osif_akm_type_crypto_mapping {
* to internal crypto cipher type * to internal crypto cipher type
* @cipher_suite: NL cipher type * @cipher_suite: NL cipher type
* @cipher_crypto: cipher crypto type * @cipher_crypto: cipher crypto type
* @cipher_len: Length of the cipher
* *
* mapping cipher type received from NL to internal crypto cipher type * mapping cipher type received from NL to internal crypto cipher type
*/ */
struct osif_cipher_crypto_mapping { struct osif_cipher_crypto_mapping {
u32 cipher_suite; u32 cipher_suite;
wlan_crypto_cipher_type cipher_crypto; wlan_crypto_cipher_type cipher_crypto;
u32 cipher_len;
}; };
/** /**
@@ -160,57 +162,70 @@ static const struct osif_cipher_crypto_mapping
{ {
.cipher_suite = IW_AUTH_CIPHER_NONE, .cipher_suite = IW_AUTH_CIPHER_NONE,
.cipher_crypto = WLAN_CRYPTO_CIPHER_NONE, .cipher_crypto = WLAN_CRYPTO_CIPHER_NONE,
.cipher_len = 0,
}, },
{ {
.cipher_suite = WLAN_CIPHER_SUITE_WEP40, .cipher_suite = WLAN_CIPHER_SUITE_WEP40,
.cipher_crypto = WLAN_CRYPTO_CIPHER_WEP_40, .cipher_crypto = WLAN_CRYPTO_CIPHER_WEP_40,
.cipher_len = WLAN_CRYPTO_KEY_WEP40_LEN,
}, },
{ {
.cipher_suite = WLAN_CIPHER_SUITE_TKIP, .cipher_suite = WLAN_CIPHER_SUITE_TKIP,
.cipher_crypto = WLAN_CRYPTO_CIPHER_TKIP, .cipher_crypto = WLAN_CRYPTO_CIPHER_TKIP,
.cipher_len = WLAN_CRYPTO_KEY_TKIP_LEN,
}, },
{ {
.cipher_suite = WLAN_CIPHER_SUITE_CCMP, .cipher_suite = WLAN_CIPHER_SUITE_CCMP,
.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CCM, .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CCM,
.cipher_len = WLAN_CRYPTO_KEY_CCMP_LEN,
}, },
{ {
.cipher_suite = WLAN_CIPHER_SUITE_WEP104, .cipher_suite = WLAN_CIPHER_SUITE_WEP104,
.cipher_crypto = WLAN_CRYPTO_CIPHER_WEP_104, .cipher_crypto = WLAN_CRYPTO_CIPHER_WEP_104,
.cipher_len = WLAN_CRYPTO_KEY_WEP104_LEN,
}, },
{ {
.cipher_suite = WLAN_CIPHER_SUITE_GCMP, .cipher_suite = WLAN_CIPHER_SUITE_GCMP,
.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GCM, .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GCM,
.cipher_len = WLAN_CRYPTO_KEY_GCMP_LEN,
}, },
{ {
.cipher_suite = WLAN_CIPHER_SUITE_GCMP_256, .cipher_suite = WLAN_CIPHER_SUITE_GCMP_256,
.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GCM_256, .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GCM_256,
.cipher_len = WLAN_CRYPTO_KEY_GCMP_256_LEN,
}, },
{ {
.cipher_suite = WLAN_CIPHER_SUITE_CCMP_256, .cipher_suite = WLAN_CIPHER_SUITE_CCMP_256,
.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CCM_256, .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CCM_256,
.cipher_len = WLAN_CRYPTO_KEY_CCMP_256_LEN,
}, },
{ {
.cipher_suite = WLAN_CIPHER_SUITE_AES_CMAC, .cipher_suite = WLAN_CIPHER_SUITE_AES_CMAC,
.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CMAC, .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CMAC,
.cipher_len = WLAN_CRYPTO_KEY_CCMP_LEN,
}, },
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
{ {
.cipher_suite = WLAN_CIPHER_SUITE_BIP_GMAC_128, .cipher_suite = WLAN_CIPHER_SUITE_BIP_GMAC_128,
.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GMAC, .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GMAC,
.cipher_len = WLAN_CRYPTO_KEY_GMAC_LEN,
}, },
{ {
.cipher_suite = WLAN_CIPHER_SUITE_BIP_GMAC_256, .cipher_suite = WLAN_CIPHER_SUITE_BIP_GMAC_256,
.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GMAC_256, .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_GMAC_256,
.cipher_len = WLAN_CRYPTO_KEY_GMAC_256_LEN,
}, },
{ {
.cipher_suite = WLAN_CIPHER_SUITE_BIP_CMAC_256, .cipher_suite = WLAN_CIPHER_SUITE_BIP_CMAC_256,
.cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CMAC_256, .cipher_crypto = WLAN_CRYPTO_CIPHER_AES_CMAC_256,
.cipher_len = WLAN_CRYPTO_KEY_CCMP_256_LEN,
}, },
#endif #endif
#ifdef FEATURE_WLAN_WAPI #ifdef FEATURE_WLAN_WAPI
{ {
.cipher_suite = WLAN_CIPHER_SUITE_SMS4, .cipher_suite = WLAN_CIPHER_SUITE_SMS4,
.cipher_crypto = WLAN_CRYPTO_CIPHER_WAPI_SMS4, .cipher_crypto = WLAN_CRYPTO_CIPHER_WAPI_SMS4,
.cipher_len = WLAN_CRYPTO_KEY_WAPI_LEN,
}, },
#endif #endif
}; };
@@ -257,13 +272,13 @@ int osif_nl_to_crypto_akm_type(u32 key_mgmt)
return crypto_akm_type; return crypto_akm_type;
} }
int osif_nl_to_crypto_cipher_type(u32 cipher) enum wlan_crypto_cipher_type osif_nl_to_crypto_cipher_type(u32 cipher)
{ {
uint8_t index; uint8_t index;
bool cipher_crypto_exist = false; bool cipher_crypto_exist = false;
wlan_crypto_cipher_type crypto_cipher_type = WLAN_CRYPTO_CIPHER_NONE; wlan_crypto_cipher_type crypto_cipher_type = WLAN_CRYPTO_CIPHER_NONE;
for (index = 0; index < QDF_ARRAY_SIZE(osif_auth_type_crypto_mapping); for (index = 0; index < QDF_ARRAY_SIZE(osif_cipher_crypto_mapping);
index++) { index++) {
if (osif_cipher_crypto_mapping[index].cipher_suite == cipher) { if (osif_cipher_crypto_mapping[index].cipher_suite == cipher) {
crypto_cipher_type = osif_cipher_crypto_mapping[index]. crypto_cipher_type = osif_cipher_crypto_mapping[index].
@@ -275,10 +290,24 @@ int osif_nl_to_crypto_cipher_type(u32 cipher)
if (!cipher_crypto_exist) { if (!cipher_crypto_exist) {
QDF_TRACE_ERROR(QDF_MODULE_ID_OS_IF, "Unknown type: %d", QDF_TRACE_ERROR(QDF_MODULE_ID_OS_IF, "Unknown type: %d",
cipher); cipher);
return -EINVAL; return WLAN_CRYPTO_CIPHER_INVALID;
} }
QDF_TRACE_DEBUG(QDF_MODULE_ID_OS_IF, "Cipher suite, NL: %d, crypto: %d", QDF_TRACE_DEBUG(QDF_MODULE_ID_OS_IF, "Cipher suite, NL: %d, crypto: %d",
cipher, crypto_cipher_type); cipher, crypto_cipher_type);
return crypto_cipher_type; return crypto_cipher_type;
} }
int osif_nl_to_crypto_cipher_len(u32 cipher)
{
uint8_t index;
for (index = 0; index < QDF_ARRAY_SIZE(osif_cipher_crypto_mapping);
index++) {
if (osif_cipher_crypto_mapping[index].cipher_suite == cipher)
return osif_cipher_crypto_mapping[index].cipher_len;
}
return -EINVAL;
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -72,6 +72,9 @@
#include "qdf_module.h" #include "qdf_module.h"
#include <target_if_cp_stats.h> #include <target_if_cp_stats.h>
#ifdef CRYPTO_SET_KEY_CONVERGED
#include <target_if_crypto.h>
#endif
static struct target_if_ctx *g_target_if_ctx; static struct target_if_ctx *g_target_if_ctx;
@@ -313,6 +316,18 @@ static QDF_STATUS target_if_green_ap_tx_ops_register(
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
#endif /* WLAN_SUPPORT_GREEN_AP */ #endif /* WLAN_SUPPORT_GREEN_AP */
#if defined(WLAN_CONV_CRYPTO_SUPPORTED) && defined(CRYPTO_SET_KEY_CONVERGED)
static void target_if_crypto_tx_ops_register(
struct wlan_lmac_if_tx_ops *tx_ops)
{
target_if_crypto_register_tx_ops(tx_ops);
}
#else
static inline void target_if_crypto_tx_ops_register(
struct wlan_lmac_if_tx_ops *tx_ops)
{
}
#endif
static void target_if_target_tx_ops_register( static void target_if_target_tx_ops_register(
struct wlan_lmac_if_tx_ops *tx_ops) struct wlan_lmac_if_tx_ops *tx_ops)
@@ -402,6 +417,8 @@ QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
target_if_cp_stats_tx_ops_register(tx_ops); target_if_cp_stats_tx_ops_register(tx_ops);
target_if_crypto_tx_ops_register(tx_ops);
/* Converged UMAC components to register their TX-ops here */ /* Converged UMAC components to register their TX-ops here */
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2019 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
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: declares crypto functions interfacing with the target
*/
#ifndef __TARGET_IF_CRYPTO_H__
#define __TARGET_IF_CRYPTO_H__
#include <wlan_lmac_if_def.h>
/**
* target_if_crypto_register_tx_ops() - lmac handler to register
* crypto tx_ops callback functions
* @tx_ops: wlan_lmac_if_tx_ops object
*
* Return: QDF_STATUS
*/
QDF_STATUS target_if_crypto_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops);
/**
* target_if_crypto_set_key() - lmac handler to set key
* @vdev: VDEV object pointer
* @req: Key parameters that are required to install the key
* @key_type: Pairwise or Group Key type
*
* Return: QDF_STATUS
*/
QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *req,
enum wlan_crypto_key_type key_type);
#endif

View File

@@ -0,0 +1,224 @@
/*
* Copyright (c) 2019 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
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: offload lmac interface APIs definitions for crypto
*/
#include <qdf_mem.h>
#include <qdf_status.h>
#include <target_if_crypto.h>
#include <wmi_unified_priv.h>
#include <wmi_unified_param.h>
#include <wlan_objmgr_psoc_obj.h>
#include <target_if.h>
#include <wlan_crypto_global_def.h>
#include <wlan_crypto_global_api.h>
#include <wlan_objmgr_vdev_obj.h>
#include <cdp_txrx_cmn_struct.h>
#include <cds_api.h>
#include <cdp_txrx_cmn.h>
#include <wmi_unified_api.h>
#include <cdp_txrx_peer_ops.h>
#ifdef FEATURE_WLAN_WAPI
static void wlan_crypto_set_wapi_key(struct wlan_objmgr_vdev *vdev,
bool pairwise,
enum wlan_crypto_cipher_type cipher_type,
struct set_key_params *params)
{
static const unsigned char tx_iv[16] = {0x36, 0x5c, 0x36, 0x5c, 0x36,
0x5c, 0x36, 0x5c, 0x36, 0x5c,
0x36, 0x5c, 0x36, 0x5c, 0x36,
0x5c};
static const unsigned char rx_iv[16] = {0x5c, 0x36, 0x5c, 0x36, 0x5c,
0x36, 0x5c, 0x36, 0x5c, 0x36,
0x5c, 0x36, 0x5c, 0x36, 0x5c,
0x37};
if (cipher_type != WLAN_CRYPTO_CIPHER_WAPI_SMS4 ||
cipher_type != WLAN_CRYPTO_CIPHER_WAPI_GCM4)
return;
qdf_mem_copy(&params->rx_iv, &rx_iv,
WLAN_CRYPTO_WAPI_IV_SIZE);
qdf_mem_copy(&params->tx_iv, &tx_iv,
WLAN_CRYPTO_WAPI_IV_SIZE);
if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE) {
if (pairwise)
params->tx_iv[0] = 0x37;
params->rx_iv[WLAN_CRYPTO_WAPI_IV_SIZE - 1] = 0x36;
} else {
if (!pairwise)
params->rx_iv[WLAN_CRYPTO_WAPI_IV_SIZE - 1] = 0x36;
}
params->key_txmic_len = WLAN_CRYPTO_MIC_LEN;
params->key_rxmic_len = WLAN_CRYPTO_MIC_LEN;
}
#else
static inline void wlan_crypto_set_wapi_key(struct wlan_objmgr_vdev *vdev,
bool pairwise,
enum wlan_crypto_cipher_type cipher,
struct set_key_params *params)
{
}
#endif /* FEATURE_WLAN_WAPI */
#ifdef BIG_ENDIAN_HOST
static void wlan_crypto_endianness_conversion(uint8_t *dest, uint8_t *src,
uint32_t keylen)
{
int8_t i;
for (i = 0; i < roundup(keylen, sizeof(uint32_t)) / 4; i++) {
*dest = le32_to_cpu(*src);
dest++;
src++;
}
}
#else
static void wlan_crypto_endianness_conversion(uint8_t *dest, uint8_t *src,
uint32_t keylen)
{
qdf_mem_copy(dest, src, keylen);
}
#endif
QDF_STATUS target_if_crypto_set_key(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *req,
enum wlan_crypto_key_type key_type)
{
struct set_key_params params = {0};
struct wlan_objmgr_psoc *psoc;
struct wlan_objmgr_pdev *pdev;
enum cdp_sec_type sec_type = cdp_sec_type_none;
void *soc = cds_get_context(QDF_MODULE_ID_SOC);
struct cdp_pdev *txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
struct cdp_vdev *txrx_vdev;
uint32_t pn[4] = {0, 0, 0, 0};
struct cdp_peer *peer = NULL;
uint8_t peer_id;
uint8_t def_tx_idx;
void *pdev_wmi_handle;
bool pairwise = false;
QDF_STATUS status;
pdev = wlan_vdev_get_pdev(vdev);
if (!pdev) {
target_if_err("Invalid PDEV");
return QDF_STATUS_E_FAILURE;
}
psoc = wlan_vdev_get_psoc(vdev);
if (!psoc) {
target_if_err("Invalid PSOC");
return QDF_STATUS_E_FAILURE;
}
soc = wlan_psoc_get_dp_handle(psoc);
if (!soc) {
target_if_err("Invalid DP Handle");
return QDF_STATUS_E_FAILURE;
}
params.vdev_id = wlan_vdev_get_id(vdev);
params.key_idx = req->keyix;
qdf_mem_copy(params.peer_mac, req->macaddr, IEEE80211_ADDR_LEN);
pdev_wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
if (!pdev_wmi_handle) {
target_if_err("Invalid PDEV WMI handle");
return QDF_STATUS_E_FAILURE;
}
if (key_type != WLAN_CRYPTO_KEY_TYPE_UNICAST)
pairwise = false;
qdf_mem_copy(&params.key_rsc_ctr,
&req->keyrsc[0], sizeof(uint64_t));
params.key_flags = req->flags;
txrx_vdev = (struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
(struct cdp_pdev *)txrx_pdev, params.vdev_id);
peer = cdp_peer_find_by_addr(soc, txrx_pdev, req->macaddr, &peer_id);
if (!txrx_vdev) {
target_if_err("Invalid txrx vdev");
return QDF_STATUS_E_FAILURE;
}
if (!peer) {
target_if_err("Invalid peer");
return QDF_STATUS_E_FAILURE;
}
params.key_cipher = wlan_crypto_cipher_to_wmi_cipher(req->cipher_type);
sec_type = wlan_crypto_cipher_to_cdp_sec_type(req->cipher_type);
wlan_crypto_set_wapi_key(vdev, pairwise, req->cipher_type, &params);
switch (req->cipher_type) {
case WLAN_CRYPTO_CIPHER_WEP:
def_tx_idx = wlan_crypto_get_default_key_idx(vdev, false);
if (pairwise && params.key_idx == def_tx_idx)
params.key_flags |= TX_USAGE;
else if ((vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE) &&
(params.key_idx == def_tx_idx))
params.key_flags |= TX_USAGE;
break;
case WLAN_CRYPTO_CIPHER_TKIP:
params.key_txmic_len = WLAN_CRYPTO_MIC_LEN;
params.key_rxmic_len = WLAN_CRYPTO_MIC_LEN;
break;
default:
break;
}
wlan_crypto_endianness_conversion(&params.key_data[0],
&req->keyval[0],
req->keylen);
params.key_len = req->keylen;
/* Set PN check & security type in data path */
cdp_set_pn_check(soc, txrx_vdev, peer, sec_type, pn);
cdp_set_key(soc, peer, pairwise,
(uint32_t *)(req->keyval +
WLAN_CRYPTO_IV_SIZE +
WLAN_CRYPTO_MIC_LEN));
target_if_debug("vdev_id:%d, key: idx:%d,len:%d", params.vdev_id,
params.key_idx, params.key_len);
target_if_debug("peer mac %pM", params.peer_mac);
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_CRYPTO, QDF_TRACE_LEVEL_DEBUG,
&params.key_rsc_ctr, sizeof(uint64_t));
status = wmi_unified_setup_install_key_cmd(pdev_wmi_handle, &params);
return status;
}
QDF_STATUS target_if_crypto_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
{
struct wlan_lmac_if_crypto_tx_ops *crypto;
if (!tx_ops) {
target_if_err("txops NULL");
return QDF_STATUS_E_FAILURE;
}
crypto = &tx_ops->crypto_tx_ops;
crypto->set_key = target_if_crypto_set_key;
return QDF_STATUS_SUCCESS;
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -23,7 +23,6 @@
#define _WLAN_CRYPTO_GLOBAL_API_H_ #define _WLAN_CRYPTO_GLOBAL_API_H_
#include "wlan_crypto_global_def.h" #include "wlan_crypto_global_def.h"
/** /**
* wlan_crypto_set_vdev_param - called by ucfg to set crypto param * wlan_crypto_set_vdev_param - called by ucfg to set crypto param
* @vdev: vdev * @vdev: vdev
@@ -679,4 +678,126 @@ static inline int omac1_aes_256(const uint8_t *key, const uint8_t *data,
} }
#endif #endif
/**
* ucfg_crypto_set_key_req() - Set key request to UCFG
* @vdev: vdev object
* @req: key request information
* @pairwise: indicates the type of key to be set, unicast or group key
*
* Return: None
*/
QDF_STATUS ucfg_crypto_set_key_req(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *req, bool pairwise);
/**
* wlan_crypto_get_default_key_idx() - Get the default key index
* @vdev: vdev object
* @igtk: denotes if the request is for igtk key type or not
*
* Return: Index of the requested key
*/
int8_t wlan_crypto_get_default_key_idx(struct wlan_objmgr_vdev *vdev,
bool igtk);
/**
* wlan_crypto_get_cipher() - Get the cipher type for the vdev
* @vdev: vdev object
* @pairwise: denotes if the request is for pairwise cipher or not
* @key_index: Index of the key whose cipher type has to be returned
*
* Return: enum wlan_crypto_cipher_type
*/
enum wlan_crypto_cipher_type
wlan_crypto_get_cipher(struct wlan_objmgr_vdev *vdev,
bool pairwise, uint8_t key_index);
#ifdef CRYPTO_SET_KEY_CONVERGED
/**
* wlan_crypto_update_set_key_peer() - Update the peer for set key
* @vdev: vdev object
* @pairwise: denotes if the request is for pairwise cipher or not
* @key_index: Index of the key whose peer has to be set
* @peer_mac: MAC address of the peer
*
* Return: None
*/
void wlan_crypto_update_set_key_peer(struct wlan_objmgr_vdev *vdev,
bool pairwise, uint8_t key_index,
struct qdf_mac_addr *peer_mac);
/**
* wlan_crypto_validate_key_params() - validates key parameters
* @cipher: cipher type
* @key_index: the index of the key
* @key_len: key length
* @seq_len: sequence counter length
*
* Return: QDF_STATUS
*/
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);
/**
* wlan_crypto_save_key() - Allocate memory for storing key
* @vdev: vdev object
* @key_index: the index of the key that needs to be allocated
* @crypto_key: Pointer to crypto key
*
* Return: QDF_STATUS
*/
QDF_STATUS wlan_crypto_save_key(struct wlan_objmgr_vdev *vdev,
uint8_t key_index,
struct wlan_crypto_key *crypto_key);
/**
* wlan_crypto_get_key() - Get the stored key information
* @vdev: vdev object
* @key_index: the index of the key that needs to be retrieved
*
* Return: Key material
*/
struct wlan_crypto_key *wlan_crypto_get_key(struct wlan_objmgr_vdev *vdev,
uint8_t key_index);
/**
* wlan_crypto_set_key_req() - Set key request
* @vdev: vdev object
* @req: key request information
* @pairwise: indicates the type of key to be set, unicast or group key
*
* Return: QDF status
*/
QDF_STATUS wlan_crypto_set_key_req(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *req, bool pairwise);
#else
static inline void wlan_crypto_update_set_key_peer(
struct wlan_objmgr_vdev *vdev,
bool pairwise,
uint8_t key_index,
struct qdf_mac_addr *peer_mac)
{
}
static inline QDF_STATUS
wlan_crypto_save_key(struct wlan_objmgr_vdev *vdev, uint8_t key_index,
struct wlan_crypto_key *crypto_key)
{
return QDF_STATUS_SUCCESS;
}
static inline struct wlan_crypto_key *
wlan_crypto_get_key(struct wlan_objmgr_vdev *vdev, uint8_t key_index)
{
return NULL;
}
static inline QDF_STATUS wlan_crypto_set_key_req(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *req,
bool pairwise)
{
return QDF_STATUS_SUCCESS;
}
#endif /* CRYPTO_SET_KEY_CONVERGED */
#endif /* end of _WLAN_CRYPTO_GLOBAL_API_H_ */ #endif /* end of _WLAN_CRYPTO_GLOBAL_API_H_ */

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -27,11 +27,14 @@
#ifdef WLAN_CRYPTO_SUPPORT_FILS #ifdef WLAN_CRYPTO_SUPPORT_FILS
#include "wlan_crypto_fils_def.h" #include "wlan_crypto_fils_def.h"
#endif #endif
#include <wlan_objmgr_cmn.h>
#define WLAN_CRYPTO_TID_SIZE (17) #define WLAN_CRYPTO_TID_SIZE (17)
#define WLAN_CRYPTO_RSC_SIZE (16)
#define WLAN_CRYPTO_KEYBUF_SIZE (32) #define WLAN_CRYPTO_KEYBUF_SIZE (32)
#define WLAN_CRYPTO_MICBUF_SIZE (16) #define WLAN_CRYPTO_MICBUF_SIZE (16)
#define WLAN_CRYPTO_MIC_LEN (8) #define WLAN_CRYPTO_MIC_LEN (8)
#define WLAN_CRYPTO_IV_SIZE (16)
#define WLAN_CRYPTO_MIC256_LEN (16) #define WLAN_CRYPTO_MIC256_LEN (16)
#define WLAN_CRYPTO_TXMIC_OFFSET (0) #define WLAN_CRYPTO_TXMIC_OFFSET (0)
#define WLAN_CRYPTO_RXMIC_OFFSET (WLAN_CRYPTO_TXMIC_OFFSET + \ #define WLAN_CRYPTO_RXMIC_OFFSET (WLAN_CRYPTO_TXMIC_OFFSET + \
@@ -53,6 +56,14 @@
/* 128 bit wep key len */ /* 128 bit wep key len */
#define WLAN_CRYPTO_KEY_WEP128_LEN (16) #define WLAN_CRYPTO_KEY_WEP128_LEN (16)
#define WLAN_CRYPTO_KEY_TKIP_LEN (32)
#define WLAN_CRYPTO_KEY_CCMP_LEN (16)
#define WLAN_CRYPTO_KEY_CCMP_256_LEN (32)
#define WLAN_CRYPTO_KEY_GCMP_LEN (16)
#define WLAN_CRYPTO_KEY_GCMP_256_LEN (32)
#define WLAN_CRYPTO_KEY_WAPI_LEN (32)
#define WLAN_CRYPTO_KEY_GMAC_LEN (16)
#define WLAN_CRYPTO_KEY_GMAC_256_LEN (32)
#define WLAN_CRYPTO_WPI_SMS4_IVLEN (16) #define WLAN_CRYPTO_WPI_SMS4_IVLEN (16)
#define WLAN_CRYPTO_WPI_SMS4_KIDLEN (1) #define WLAN_CRYPTO_WPI_SMS4_KIDLEN (1)
#define WLAN_CRYPTO_WPI_SMS4_PADLEN (1) #define WLAN_CRYPTO_WPI_SMS4_PADLEN (1)
@@ -113,6 +124,7 @@ typedef enum wlan_crypto_cipher_type {
WLAN_CRYPTO_CIPHER_WEP_104 = 16, WLAN_CRYPTO_CIPHER_WEP_104 = 16,
WLAN_CRYPTO_CIPHER_NONE = 17, WLAN_CRYPTO_CIPHER_NONE = 17,
WLAN_CRYPTO_CIPHER_MAX = WLAN_CRYPTO_CIPHER_NONE, WLAN_CRYPTO_CIPHER_MAX = WLAN_CRYPTO_CIPHER_NONE,
WLAN_CRYPTO_CIPHER_INVALID,
} wlan_crypto_cipher_type; } wlan_crypto_cipher_type;
/* Auth types */ /* Auth types */
@@ -188,6 +200,11 @@ typedef enum wlan_crypto_key_mgmt {
WLAN_CRYPTO_KEY_MGMT_MAX = WLAN_CRYPTO_KEY_MGMT_DPP, WLAN_CRYPTO_KEY_MGMT_MAX = WLAN_CRYPTO_KEY_MGMT_DPP,
} wlan_crypto_key_mgmt; } wlan_crypto_key_mgmt;
enum wlan_crypto_key_type {
WLAN_CRYPTO_KEY_TYPE_UNICAST,
WLAN_CRYPTO_KEY_TYPE_GROUP,
};
/** /**
* struct wlan_crypto_params - holds crypto params * struct wlan_crypto_params - holds crypto params
* @authmodeset: authentication mode * @authmodeset: authentication mode
@@ -226,6 +243,8 @@ typedef enum wlan_crypto_param_type {
* @valid: is key valid or not * @valid: is key valid or not
* @flags: key flags * @flags: key flags
* @keyix: key id * @keyix: key id
* @cipher_type: cipher type being used for this key
* @mac_addr: MAC address of the peer
* @cipher_table: table which stores cipher related info * @cipher_table: table which stores cipher related info
* @private: private pointer to save cipher context * @private: private pointer to save cipher context
* @keylock: spin lock * @keylock: spin lock
@@ -245,6 +264,8 @@ struct wlan_crypto_key {
bool valid; bool valid;
uint16_t flags; uint16_t flags;
uint16_t keyix; uint16_t keyix;
enum wlan_crypto_cipher_type cipher_type;
uint8_t macaddr[QDF_MAC_ADDR_SIZE];
void *cipher_table; void *cipher_table;
void *private; void *private;
qdf_spinlock_t keylock; qdf_spinlock_t keylock;
@@ -303,23 +324,26 @@ struct wlan_crypto_req_key {
* @setkey: function pointer to setkey in hw * @setkey: function pointer to setkey in hw
* @delkey: function pointer to delkey in hw * @delkey: function pointer to delkey in hw
* @defaultkey: function pointer to set default key * @defaultkey: function pointer to set default key
* @set_key: converged function pointer to set key in hw
*/ */
struct wlan_lmac_if_crypto_tx_ops { struct wlan_lmac_if_crypto_tx_ops {
QDF_STATUS(*allockey)(struct wlan_objmgr_vdev *vdev, QDF_STATUS (*allockey)(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *key, struct wlan_crypto_key *key,
uint8_t *macaddr, uint32_t key_type); uint8_t *macaddr, uint32_t key_type);
QDF_STATUS(*setkey)(struct wlan_objmgr_vdev *vdev, QDF_STATUS (*setkey)(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *key, struct wlan_crypto_key *key,
uint8_t *macaddr, uint32_t key_type); uint8_t *macaddr, uint32_t key_type);
QDF_STATUS(*delkey)(struct wlan_objmgr_vdev *vdev, QDF_STATUS (*delkey)(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *key, struct wlan_crypto_key *key,
uint8_t *macaddr, uint32_t key_type); uint8_t *macaddr, uint32_t key_type);
QDF_STATUS(*defaultkey)(struct wlan_objmgr_vdev *vdev, QDF_STATUS (*defaultkey)(struct wlan_objmgr_vdev *vdev,
uint8_t keyix, uint8_t *macaddr); uint8_t keyix, uint8_t *macaddr);
QDF_STATUS (*set_key)(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *key,
enum wlan_crypto_key_type key_type);
}; };
/** /**
* struct wlan_lmac_if_crypto_rx_ops - structure of crypto rx function * struct wlan_lmac_if_crypto_rx_ops - structure of crypto rx function
* pointers * pointers

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -169,6 +169,8 @@ static inline void wlan_crypto_put_be64(u8 *a, u64 val)
(psoc->soc_cb.tx_ops.crypto_tx_ops.delkey) (psoc->soc_cb.tx_ops.crypto_tx_ops.delkey)
#define WLAN_CRYPTO_TX_OPS_DEFAULTKEY(psoc) \ #define WLAN_CRYPTO_TX_OPS_DEFAULTKEY(psoc) \
(psoc->soc_cb.tx_ops.crypto_tx_ops.defaultkey) (psoc->soc_cb.tx_ops.crypto_tx_ops.defaultkey)
#define WLAN_CRYPTO_TX_OPS_SET_KEY(psoc) \
((psoc)->soc_cb.tx_ops.crypto_tx_ops.set_key)
/* unalligned little endian access */ /* unalligned little endian access */
#ifndef LE_READ_2 #ifndef LE_READ_2

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -35,10 +35,8 @@
#include "wlan_crypto_def_i.h" #include "wlan_crypto_def_i.h"
#include "wlan_crypto_param_handling_i.h" #include "wlan_crypto_param_handling_i.h"
#include "wlan_crypto_obj_mgr_i.h" #include "wlan_crypto_obj_mgr_i.h"
#include <qdf_module.h> #include <qdf_module.h>
const struct wlan_crypto_cipher *wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX]; const struct wlan_crypto_cipher *wlan_crypto_cipher_ops[WLAN_CRYPTO_CIPHER_MAX];
#define WPA_ADD_CIPHER_TO_SUITE(frm, cipher) \ #define WPA_ADD_CIPHER_TO_SUITE(frm, cipher) \
@@ -954,6 +952,32 @@ QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev,
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
#ifdef CRYPTO_SET_KEY_CONVERGED
static QDF_STATUS wlan_crypto_set_default_key(struct wlan_objmgr_vdev *vdev,
uint8_t key_idx, uint8_t *macaddr)
{
return QDF_STATUS_SUCCESS;
}
#else
static QDF_STATUS wlan_crypto_set_default_key(struct wlan_objmgr_vdev *vdev,
uint8_t key_idx, uint8_t *macaddr)
{
struct wlan_objmgr_psoc *psoc;
psoc = wlan_vdev_get_psoc(vdev);
if (!psoc) {
crypto_err("psoc is NULL");
return QDF_STATUS_E_INVAL;
}
if (WLAN_CRYPTO_TX_OPS_DEFAULTKEY(psoc)) {
WLAN_CRYPTO_TX_OPS_DEFAULTKEY(psoc)(vdev, key_idx,
macaddr);
}
return QDF_STATUS_SUCCESS;
}
#endif
/** /**
* wlan_crypto_default_key - called by ucfg to set default tx key * wlan_crypto_default_key - called by ucfg to set default tx key
* @vdev: vdev * @vdev: vdev
@@ -1035,10 +1059,9 @@ QDF_STATUS wlan_crypto_default_key(struct wlan_objmgr_vdev *vdev,
if (!key->valid) if (!key->valid)
return QDF_STATUS_E_INVAL; return QDF_STATUS_E_INVAL;
if (WLAN_CRYPTO_TX_OPS_DEFAULTKEY(psoc)) { if (wlan_crypto_set_default_key(vdev, key_idx, macaddr) !=
WLAN_CRYPTO_TX_OPS_DEFAULTKEY(psoc)(vdev, key_idx, QDF_STATUS_SUCCESS)
macaddr); return QDF_STATUS_E_INVAL;
}
crypto_priv->def_tx_keyid = key_idx; crypto_priv->def_tx_keyid = key_idx;
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
@@ -3682,3 +3705,146 @@ QDF_STATUS wlan_set_vdev_crypto_prarams_from_ie(struct wlan_objmgr_vdev *vdev,
return send_fail ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS; return send_fail ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS;
} }
int8_t wlan_crypto_get_default_key_idx(struct wlan_objmgr_vdev *vdev, bool igtk)
{
struct wlan_crypto_comp_priv *crypto_priv;
crypto_priv = wlan_get_vdev_crypto_obj(vdev);
if (!crypto_priv) {
crypto_err("crypto_priv NULL");
return QDF_STATUS_E_FAILURE;
}
if (igtk)
return crypto_priv->def_igtk_tx_keyid;
else
return crypto_priv->def_tx_keyid;
}
enum wlan_crypto_cipher_type
wlan_crypto_get_cipher(struct wlan_objmgr_vdev *vdev,
bool pairwise, uint8_t key_index)
{
struct wlan_crypto_key *crypto_key;
crypto_key = wlan_crypto_get_key(vdev, key_index);
if (crypto_key)
return crypto_key->cipher_type;
else
return WLAN_CRYPTO_CIPHER_INVALID;
}
#ifdef CRYPTO_SET_KEY_CONVERGED
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)) {
crypto_err("Invalid Key index %d", key_index);
return QDF_STATUS_E_INVAL;
}
if (cipher == WLAN_CRYPTO_CIPHER_INVALID) {
crypto_err("Invalid Cipher %d", cipher);
return QDF_STATUS_E_INVAL;
}
if ((!(cipher == WLAN_CRYPTO_CIPHER_AES_CMAC ||
cipher == WLAN_CRYPTO_CIPHER_AES_CMAC_256 ||
cipher == WLAN_CRYPTO_CIPHER_AES_GMAC ||
cipher == WLAN_CRYPTO_CIPHER_AES_GMAC_256)) &&
(key_index >= WLAN_CRYPTO_MAXKEYIDX)) {
crypto_err("Invalid key index %d for cipher %d",
key_index, cipher);
return QDF_STATUS_E_INVAL;
}
if (key_len > (WLAN_CRYPTO_KEYBUF_SIZE + WLAN_CRYPTO_MICBUF_SIZE)) {
crypto_err("Invalid key length %d", key_len);
return QDF_STATUS_E_INVAL;
}
if (seq_len > WLAN_CRYPTO_RSC_SIZE) {
crypto_err("Invalid seq length %d", seq_len);
return QDF_STATUS_E_INVAL;
}
crypto_debug("key: idx:%d, len:%d, seq len:%d",
key_index, key_len, seq_len);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS wlan_crypto_save_key(struct wlan_objmgr_vdev *vdev,
uint8_t key_index,
struct wlan_crypto_key *crypto_key)
{
struct wlan_crypto_comp_priv *crypto_priv;
crypto_priv = wlan_get_vdev_crypto_obj(vdev);
if (!crypto_priv) {
crypto_err("crypto_priv NULL");
return QDF_STATUS_E_FAILURE;
}
if (key_index >= (WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX)) {
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
crypto_priv->igtk_key[key_index - WLAN_CRYPTO_MAXKEYIDX] =
crypto_key;
return QDF_STATUS_SUCCESS;
}
struct wlan_crypto_key *wlan_crypto_get_key(struct wlan_objmgr_vdev *vdev,
uint8_t key_index)
{
struct wlan_crypto_comp_priv *crypto_priv;
crypto_priv = wlan_get_vdev_crypto_obj(vdev);
if (!crypto_priv) {
crypto_err("crypto_priv NULL");
return NULL;
}
if (key_index >= (WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX)) {
crypto_err("Invalid Key index %d", key_index);
return NULL;
}
if (key_index < WLAN_CRYPTO_MAXKEYIDX)
return crypto_priv->key[key_index];
return crypto_priv->igtk_key[key_index - WLAN_CRYPTO_MAXKEYIDX];
}
QDF_STATUS wlan_crypto_set_key_req(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *req,
bool pairwise)
{
struct wlan_objmgr_psoc *psoc;
psoc = wlan_vdev_get_psoc(vdev);
if (psoc && WLAN_CRYPTO_TX_OPS_SET_KEY(psoc))
WLAN_CRYPTO_TX_OPS_SET_KEY(psoc)(vdev, req, pairwise);
else
return QDF_STATUS_E_FAILURE;
return QDF_STATUS_SUCCESS;
}
void wlan_crypto_update_set_key_peer(struct wlan_objmgr_vdev *vdev,
bool pairwise, uint8_t key_index,
struct qdf_mac_addr *peer_mac)
{
struct wlan_crypto_key *crypto_key;
crypto_key = wlan_crypto_get_key(vdev, key_index);
if (!crypto_key) {
crypto_err("crypto_key not present for key_idx %d", key_index);
return;
}
qdf_mem_copy(crypto_key->macaddr, peer_mac, QDF_MAC_ADDR_SIZE);
}
#endif

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -40,6 +40,8 @@ cipher2cap(int cipher)
{ {
switch (cipher) { switch (cipher) {
case WLAN_CRYPTO_CIPHER_WEP: return WLAN_CRYPTO_CAP_WEP; case WLAN_CRYPTO_CIPHER_WEP: return WLAN_CRYPTO_CAP_WEP;
case WLAN_CRYPTO_CIPHER_WEP_40: return WLAN_CRYPTO_CAP_WEP;
case WLAN_CRYPTO_CIPHER_WEP_104: return WLAN_CRYPTO_CAP_WEP;
case WLAN_CRYPTO_CIPHER_AES_OCB: return WLAN_CRYPTO_CAP_AES; case WLAN_CRYPTO_CIPHER_AES_OCB: return WLAN_CRYPTO_CAP_AES;
case WLAN_CRYPTO_CIPHER_AES_CCM: return WLAN_CRYPTO_CAP_AES; case WLAN_CRYPTO_CIPHER_AES_CCM: return WLAN_CRYPTO_CAP_AES;
case WLAN_CRYPTO_CIPHER_AES_CCM_256: return WLAN_CRYPTO_CAP_AES; case WLAN_CRYPTO_CIPHER_AES_CCM_256: return WLAN_CRYPTO_CAP_AES;

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2019 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
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* DOC: contains crypto north bound interface definitions
*/
#include <qdf_types.h>
#include <wlan_crypto_global_def.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_crypto_global_api.h>
QDF_STATUS ucfg_crypto_set_key_req(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_key *req, bool pairwise)
{
/*
* It is the job of dispatcher to decide whether the
* request has to be sent to scheduler or should be
* sent as a offload request or process directly.
*
* Current requirement is to process set key request
* as run to completion without posting any messages.
* Hence the request handler is directly called from
* here.
*/
return wlan_crypto_set_key_req(vdev, req, pairwise);
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -1682,4 +1682,24 @@ QDF_STATUS wmi_unified_send_obss_color_collision_cfg_cmd(void *wmi_hdl,
QDF_STATUS wmi_unified_extract_obss_color_collision_info(void *wmi_hdl, QDF_STATUS wmi_unified_extract_obss_color_collision_info(void *wmi_hdl,
uint8_t *data, struct wmi_obss_color_collision_info *info); uint8_t *data, struct wmi_obss_color_collision_info *info);
#ifdef CRYPTO_SET_KEY_CONVERGED
/**
* wlan_crypto_cipher_to_wmi_cipher() - Convert crypto cipher to WMI cipher
* @crypto_cipher: cipher type in crypto format
*
* Return: cipher type in WMI cipher type
*/
uint8_t wlan_crypto_cipher_to_wmi_cipher(
enum wlan_crypto_cipher_type crypto_cipher);
/**
* wlan_crypto_cipher_to_cdp_sec_type() - Convert crypto cipher to CDP type
* @crypto_cipher: cipher type in crypto format
*
* Return: security type in cdp_sec_type data format type
*/
enum cdp_sec_type wlan_crypto_cipher_to_cdp_sec_type(
enum wlan_crypto_cipher_type crypto_cipher);
#endif
#endif /* _WMI_UNIFIED_API_H_ */ #endif /* _WMI_UNIFIED_API_H_ */

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -1747,6 +1747,8 @@ struct wmi_probe_resp_params {
* @key_rxmic_len: rx mic length * @key_rxmic_len: rx mic length
* @key_tsc_counter: key tx sc counter * @key_tsc_counter: key tx sc counter
* @key_rsc_counter: key rx sc counter * @key_rsc_counter: key rx sc counter
* @key_rsc_ctr: key rx sc counter (stack variable, unnecessary heap alloc for
* key_rsc_counter should be cleaned up eventually)
* @rx_iv: receive IV, applicable only in case of WAPI * @rx_iv: receive IV, applicable only in case of WAPI
* @tx_iv: transmit IV, applicable only in case of WAPI * @tx_iv: transmit IV, applicable only in case of WAPI
* @key_data: key data * @key_data: key data
@@ -1762,6 +1764,7 @@ struct set_key_params {
uint32_t key_rxmic_len; uint32_t key_rxmic_len;
uint64_t key_tsc_counter; uint64_t key_tsc_counter;
uint64_t *key_rsc_counter; uint64_t *key_rsc_counter;
uint64_t key_rsc_ctr;
#if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI) #if defined(ATH_SUPPORT_WAPI) || defined(FEATURE_WLAN_WAPI)
uint8_t rx_iv[16]; uint8_t rx_iv[16];
uint8_t tx_iv[16]; uint8_t tx_iv[16];

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -19,6 +19,7 @@
#include "wmi_unified_priv.h" #include "wmi_unified_priv.h"
#include "wmi_unified_param.h" #include "wmi_unified_param.h"
#include "qdf_module.h" #include "qdf_module.h"
#include "cdp_txrx_cmn_struct.h"
static const wmi_host_channel_width mode_to_width[WMI_HOST_MODE_MAX] = { static const wmi_host_channel_width mode_to_width[WMI_HOST_MODE_MAX] = {
[WMI_HOST_MODE_11A] = WMI_HOST_CHAN_WIDTH_20, [WMI_HOST_MODE_11A] = WMI_HOST_CHAN_WIDTH_20,
@@ -4466,6 +4467,63 @@ wmi_unified_send_roam_scan_stats_cmd(void *wmi_hdl,
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
#ifdef CRYPTO_SET_KEY_CONVERGED
uint8_t wlan_crypto_cipher_to_wmi_cipher(
enum wlan_crypto_cipher_type crypto_cipher)
{
switch (crypto_cipher) {
case WLAN_CRYPTO_CIPHER_NONE:
return WMI_CIPHER_NONE;
case WLAN_CRYPTO_CIPHER_WEP:
return WMI_CIPHER_WEP;
case WLAN_CRYPTO_CIPHER_TKIP:
return WMI_CIPHER_TKIP;
case WLAN_CRYPTO_CIPHER_WAPI_SMS4:
case WLAN_CRYPTO_CIPHER_WAPI_GCM4:
return WMI_CIPHER_WAPI;
case WLAN_CRYPTO_CIPHER_AES_CCM:
case WLAN_CRYPTO_CIPHER_AES_CCM_256:
return WMI_CIPHER_AES_CCM;
case WLAN_CRYPTO_CIPHER_AES_CMAC:
return WMI_CIPHER_AES_CMAC;
case WLAN_CRYPTO_CIPHER_AES_GMAC:
case WLAN_CRYPTO_CIPHER_AES_GMAC_256:
return WMI_CIPHER_AES_GMAC;
case WLAN_CRYPTO_CIPHER_AES_GCM:
case WLAN_CRYPTO_CIPHER_AES_GCM_256:
return WMI_CIPHER_AES_GCM;
default:
return 0;
}
}
enum cdp_sec_type wlan_crypto_cipher_to_cdp_sec_type(
enum wlan_crypto_cipher_type crypto_cipher)
{
switch (crypto_cipher) {
case WLAN_CRYPTO_CIPHER_NONE:
return cdp_sec_type_none;
case WLAN_CRYPTO_CIPHER_WEP:
return cdp_sec_type_wep104;
case WLAN_CRYPTO_CIPHER_TKIP:
return cdp_sec_type_tkip;
case WLAN_CRYPTO_CIPHER_WAPI_SMS4:
case WLAN_CRYPTO_CIPHER_WAPI_GCM4:
return cdp_sec_type_wapi;
case WLAN_CRYPTO_CIPHER_AES_CCM:
return cdp_sec_type_aes_ccmp;
case WLAN_CRYPTO_CIPHER_AES_CCM_256:
return cdp_sec_type_aes_ccmp_256;
case WLAN_CRYPTO_CIPHER_AES_GCM:
return cdp_sec_type_aes_gcmp;
case WLAN_CRYPTO_CIPHER_AES_GCM_256:
return cdp_sec_type_aes_gcmp_256;
default:
return cdp_sec_type_none;
}
}
#endif /* CRYPTO_SET_KEY_CONVERGED */
QDF_STATUS QDF_STATUS
wmi_extract_roam_scan_stats_res_evt(wmi_unified_t wmi, void *evt_buf, wmi_extract_roam_scan_stats_res_evt(wmi_unified_t wmi, void *evt_buf,
uint32_t *vdev_id, uint32_t *vdev_id,

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -3996,9 +3996,8 @@ static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle,
key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); key_data = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
qdf_mem_copy((void *)key_data, qdf_mem_copy((void *)key_data,
(const void *)key_params->key_data, key_params->key_len); (const void *)key_params->key_data, key_params->key_len);
if (key_params->key_rsc_counter) qdf_mem_copy(&cmd->key_rsc_counter, &key_params->key_rsc_ctr,
qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter, sizeof(wmi_key_seq_counter));
sizeof(wmi_key_seq_counter));
cmd->key_len = key_params->key_len; cmd->key_len = key_params->key_len;
wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0); wmi_mtrace(WMI_VDEV_INSTALL_KEY_CMDID, cmd->vdev_id, 0);
@@ -4646,7 +4645,6 @@ static QDF_STATUS send_process_ll_stats_clear_cmd_tlv(wmi_unified_t wmi_handle,
WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask); WMI_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask);
/* WMI_LOGD("Peer MAC Addr : %pM", /* WMI_LOGD("Peer MAC Addr : %pM",
cmd->peer_macaddr); */ cmd->peer_macaddr); */
wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0); wmi_mtrace(WMI_CLEAR_LINK_STATS_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len, ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_CLEAR_LINK_STATS_CMDID); WMI_CLEAR_LINK_STATS_CMDID);