qcacld-3.0: Add support for GMAC cipher suite

Add changes to support GMAC group management cipher suite

Change-Id: Ic4855b77268464a1ed61efcf213f76a2d99ff0c4
CRs-Fixed: 2164828
This commit is contained in:
Padma, Santhosh Kumar 2017-12-20 17:39:33 +05:30 • committed by snandini
commit 4117d7a59c
9 changed files with 186 additions and 23 deletions

View file

@ -199,6 +199,10 @@ static const u32 hdd_cipher_suites[] = {
#endif
#ifdef WLAN_FEATURE_11W
WLAN_CIPHER_SUITE_AES_CMAC,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
WLAN_CIPHER_SUITE_BIP_GMAC_128,
WLAN_CIPHER_SUITE_BIP_GMAC_256,
#endif
#endif
WLAN_CIPHER_SUITE_GCMP,
WLAN_CIPHER_SUITE_GCMP_256,
@ -15121,6 +15125,14 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
case WLAN_CIPHER_SUITE_AES_CMAC:
setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
break;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
case WLAN_CIPHER_SUITE_BIP_GMAC_128:
setKey.encType = eCSR_ENCRYPT_TYPE_AES_GMAC_128;
break;
case WLAN_CIPHER_SUITE_BIP_GMAC_256:
setKey.encType = eCSR_ENCRYPT_TYPE_AES_GMAC_256;
break;
#endif
#endif
case WLAN_CIPHER_SUITE_GCMP:
setKey.encType = eCSR_ENCRYPT_TYPE_AES_GCMP;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
* Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@ -96,6 +96,8 @@ typedef enum eAniEdType {
/* Firmware uses key length to find GCMP 128 or 256 */
eSIR_ED_GCMP,
eSIR_ED_GCMP_256,
eSIR_ED_AES_GMAC_128,
eSIR_ED_AES_GMAC_256,
eSIR_ED_NOT_IMPLEMENTED = SIR_MAX_ENUM_SIZE
} tAniEdType;

View file

@ -1999,6 +1999,8 @@ lim_process_mlm_set_keys_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
case eSIR_ED_GCMP_256:
#ifdef WLAN_FEATURE_11W
case eSIR_ED_AES_128_CMAC:
case eSIR_ED_AES_GMAC_128:
case eSIR_ED_AES_GMAC_256:
#endif
sta_idx = session->staId;
break;

View file

@ -1766,7 +1766,10 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
/* Record if management frames need to be protected */
#ifdef WLAN_FEATURE_11W
if (eSIR_ED_AES_128_CMAC == sme_join_req->MgmtEncryptionType)
if ((eSIR_ED_AES_128_CMAC ==
sme_join_req->MgmtEncryptionType) ||
(eSIR_ED_AES_GMAC_128 == sme_join_req->MgmtEncryptionType) ||
(eSIR_ED_AES_GMAC_256 == sme_join_req->MgmtEncryptionType))
session->limRmfEnabled = 1;
else
session->limRmfEnabled = 0;

View file

@ -94,10 +94,9 @@ typedef enum {
#endif /* FEATURE_WLAN_WAPI */
eCSR_ENCRYPT_TYPE_KRK,
eCSR_ENCRYPT_TYPE_BTK,
#ifdef WLAN_FEATURE_11W
/* 11w BIP */
eCSR_ENCRYPT_TYPE_AES_CMAC,
#endif
eCSR_ENCRYPT_TYPE_AES_GMAC_128,
eCSR_ENCRYPT_TYPE_AES_GMAC_256,
eCSR_ENCRYPT_TYPE_AES_GCMP,
eCSR_ENCRYPT_TYPE_AES_GCMP_256,
eCSR_ENCRYPT_TYPE_ANY,
@ -228,6 +227,8 @@ typedef enum {
#define CSR_AES_KEY_LEN 16
#define CSR_AES_GCMP_KEY_LEN 16
#define CSR_AES_GCMP_256_KEY_LEN 32
#define CSR_AES_GMAC_128_KEY_LEN 16
#define CSR_AES_GMAC_256_KEY_LEN 32
#define CSR_MAX_TX_POWER (WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX)
#define CSR_MAX_RSC_LEN 16
#ifdef FEATURE_WLAN_WAPI
@ -931,6 +932,7 @@ typedef struct csr_roam_profile {
uint8_t MFPRequired;
uint8_t MFPCapable;
#endif
tAniEdType mgmt_encryption_type;
tCsrKeys Keys;
tCsrChannelInfo ChannelInfo;
uint8_t operationChannel;

View file

@ -10616,6 +10616,33 @@ csr_update_key_cmd(tpAniSirGlobal mac_ctx, struct csr_roam_session *session,
CSR_AES_KEY_LEN);
*is_key_valid = true;
break;
case eCSR_ENCRYPT_TYPE_AES_GMAC_128:
if (set_key->keyLength < CSR_AES_GMAC_128_KEY_LEN) {
sme_warn("Invalid AES GMAC 128 keylength [= %d]",
set_key->keyLength);
*is_key_valid = false;
return QDF_STATUS_E_INVAL;
}
set_key_cmd->keyLength = CSR_AES_GMAC_128_KEY_LEN;
qdf_mem_copy(set_key_cmd->Key, set_key->Key,
CSR_AES_GMAC_128_KEY_LEN);
*is_key_valid = true;
break;
case eCSR_ENCRYPT_TYPE_AES_GMAC_256:
if (set_key->keyLength < CSR_AES_GMAC_256_KEY_LEN) {
sme_warn("Invalid AES GMAC 256 keylength [= %d]",
set_key->keyLength);
*is_key_valid = false;
return QDF_STATUS_E_INVAL;
}
set_key_cmd->keyLength = CSR_AES_GMAC_256_KEY_LEN;
qdf_mem_copy(set_key_cmd->Key, set_key->Key,
CSR_AES_GMAC_256_KEY_LEN);
*is_key_valid = true;
break;
#endif /* WLAN_FEATURE_11W */
default:
/* for open security also we want to enqueue command */
@ -14736,10 +14763,16 @@ bool csr_is_mfpc_capable(struct sDot11fIERSN *rsn)
static void csr_set_mgmt_enc_type(tCsrRoamProfile *profile,
tDot11fBeaconIEs *ies, tSirSmeJoinReq *csr_join_req)
{
sme_debug("mgmt encryption type %d MFPe %d MFPr %d",
profile->mgmt_encryption_type,
profile->MFPEnabled, profile->MFPRequired);
if (profile->MFPEnabled)
csr_join_req->MgmtEncryptionType = eSIR_ED_AES_128_CMAC;
csr_join_req->MgmtEncryptionType =
profile->mgmt_encryption_type;
else
csr_join_req->MgmtEncryptionType = eSIR_ED_NONE;
if (profile->MFPEnabled &&
!(profile->MFPRequired) &&
!csr_is_mfpc_capable(&ies->RSN))

View file

@ -5246,6 +5246,27 @@ static eCsrEncryptionType csr_covert_enc_type_old(enum wlan_enc_type enc)
}
}
#ifdef WLAN_FEATURE_11W
/**
* csr_update_pmf_cap: Updates PMF cap
* @src_filter: Source filter
* @dst_filter: Destination filter
*
* Return: None
*/
static void csr_update_pmf_cap(tCsrScanResultFilter *src_filter,
struct scan_filter *dst_filter) {
if (src_filter->MFPCapable || src_filter->MFPEnabled)
dst_filter->pmf_cap = WLAN_PMF_CAPABLE;
if (src_filter->MFPRequired)
dst_filter->pmf_cap = WLAN_PMF_REQUIRED;
}
#else
static inline void csr_update_pmf_cap(tCsrScanResultFilter *src_filter,
struct scan_filter *dst_filter)
{}
#endif
static QDF_STATUS csr_prepare_scan_filter(tpAniSirGlobal mac_ctx,
tCsrScanResultFilter *pFilter, struct scan_filter *filter)
@ -5324,10 +5345,7 @@ static QDF_STATUS csr_prepare_scan_filter(tpAniSirGlobal mac_ctx,
filter->p2p_results = pFilter->p2pResult;
if (pFilter->MFPCapable || pFilter->MFPEnabled)
filter->pmf_cap = WLAN_PMF_CAPABLE;
if (pFilter->MFPRequired)
filter->pmf_cap = WLAN_PMF_REQUIRED;
csr_update_pmf_cap(pFilter, filter);
if (pFilter->BSSType == eCSR_BSS_TYPE_INFRASTRUCTURE)
filter->bss_type = WLAN_TYPE_BSS;

View file

@ -139,6 +139,16 @@ uint8_t csr_wapi_oui[][CSR_WAPI_OUI_SIZE] = {
uint8_t csr_wme_info_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
uint8_t csr_wme_parm_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
uint8_t csr_group_mgmt_oui[][CSR_RSN_OUI_SIZE] = {
#define ENUM_CMAC 0
{0x00, 0x0F, 0xAC, 0x06},
#define ENUM_GMAC_128 1
{0x00, 0x0F, 0xAC, 0x0B},
#define ENUM_GMAC_256 2
{0x00, 0x0F, 0xAC, 0x0C},
};
/* ////////////////////////////////////////////////////////////////////// */
/**
@ -3240,7 +3250,7 @@ static bool csr_is_auth_dpp_rsn(tpAniSirGlobal mac,
* @suite_count: all supported akm suites count
* @oui: Oui needs to be matched
*
* Return: True if OUI is SAE, false otherwise
* Return: True if OUI is OWE, false otherwise
*/
static bool csr_is_auth_wpa_owe(tpAniSirGlobal mac,
uint8_t all_suites[][CSR_RSN_OUI_SIZE],
@ -3301,6 +3311,40 @@ static bool csr_is_auth_wpa_psk(tpAniSirGlobal pMac,
(pMac, AllSuites, cAllSuites, csr_wpa_oui[02], Oui);
}
/*
* csr_is_group_mgmt_gmac_128() - check whether oui is GMAC_128
* @mac: Global MAC context
* @all_suites: pointer to all supported akm suites
* @suite_count: all supported akm suites count
* @oui: Oui needs to be matched
*
* Return: True if OUI is GMAC_128, false otherwise
*/
static bool csr_is_group_mgmt_gmac_128(tpAniSirGlobal pMac,
uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
uint8_t cAllSuites, uint8_t Oui[])
{
return csr_is_oui_match(pMac, AllSuites, cAllSuites,
csr_group_mgmt_oui[ENUM_GMAC_128], Oui);
}
/*
* csr_is_group_mgmt_gmac_256() - check whether oui is GMAC_256
* @mac: Global MAC context
* @all_suites: pointer to all supported akm suites
* @suite_count: all supported akm suites count
* @oui: Oui needs to be matched
*
* Return: True if OUI is GMAC_256, false otherwise
*/
static bool csr_is_group_mgmt_gmac_256(tpAniSirGlobal pMac,
uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
uint8_t cAllSuites, uint8_t Oui[])
{
return csr_is_oui_match(pMac, AllSuites, cAllSuites,
csr_group_mgmt_oui[ENUM_GMAC_256], Oui);
}
static uint8_t csr_get_oui_index_from_cipher(eCsrEncryptionType enType)
{
uint8_t OUIIndex;
@ -3414,6 +3458,8 @@ static void csr_is_fils_auth(tpAniSirGlobal mac_ctx,
* @capabilities: RSN capabilities
* @negotiated_authtype: Negotiated auth type
* @negotiated_mccipher: negotiated multicast cipher
* @gp_mgmt_cipher: group management cipher
* @mgmt_encryption_type: group management encryption type
*
* This routine will get all RSN information
*
@ -3426,18 +3472,24 @@ static bool csr_get_rsn_information(tHalHandle hal, tCsrAuthList *auth_type,
uint8_t *mcast_cipher, uint8_t *auth_suite,
tCsrRSNCapabilities *capabilities,
eCsrAuthType *negotiated_authtype,
eCsrEncryptionType *negotiated_mccipher)
eCsrEncryptionType *negotiated_mccipher,
uint8_t *gp_mgmt_cipher,
tAniEdType *mgmt_encryption_type)
{
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
bool acceptable_cipher = false;
bool group_mgmt_acceptable_cipher = false;
uint8_t c_ucast_cipher = 0;
uint8_t c_mcast_cipher = 0;
uint8_t c_group_mgmt_cipher = 0;
uint8_t c_auth_suites = 0, i;
uint8_t unicast[CSR_RSN_OUI_SIZE];
uint8_t multicast[CSR_RSN_OUI_SIZE];
uint8_t group_mgmt[CSR_RSN_OUI_SIZE];
uint8_t authsuites[CSR_RSN_MAX_AUTH_SUITES][CSR_RSN_OUI_SIZE];
uint8_t authentication[CSR_RSN_OUI_SIZE];
uint8_t mccipher_arr[CSR_RSN_MAX_MULTICAST_CYPHERS][CSR_RSN_OUI_SIZE];
uint8_t group_mgmt_arr[CSR_RSN_MAX_MULTICAST_CYPHERS][CSR_RSN_OUI_SIZE];
eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
if (!rsn_ie->present)
@ -3479,6 +3531,28 @@ static bool csr_get_rsn_information(tHalHandle hal, tCsrAuthList *auth_type,
if (negotiated_mccipher)
*negotiated_mccipher = mc_encryption->encryptionType[i];
/* Group Management Cipher only for 11w */
if (mgmt_encryption_type) {
c_group_mgmt_cipher++;
qdf_mem_copy(group_mgmt_arr, rsn_ie->gp_mgmt_cipher_suite,
CSR_RSN_OUI_SIZE);
if (csr_is_group_mgmt_gmac_128(mac_ctx, group_mgmt_arr,
c_group_mgmt_cipher, group_mgmt)) {
group_mgmt_acceptable_cipher = true;
*mgmt_encryption_type = eSIR_ED_AES_GMAC_128;
} else if (csr_is_group_mgmt_gmac_256(mac_ctx, group_mgmt_arr,
c_group_mgmt_cipher, group_mgmt)) {
group_mgmt_acceptable_cipher = true;
*mgmt_encryption_type = eSIR_ED_AES_GMAC_256;
} else {
/* Default is CMAC */
group_mgmt_acceptable_cipher = true;
*mgmt_encryption_type = eSIR_ED_AES_128_CMAC;
qdf_mem_copy(group_mgmt, csr_group_mgmt_oui[ENUM_CMAC],
CSR_RSN_OUI_SIZE);
}
}
/* Initializing with false as it has true value already */
acceptable_cipher = false;
for (i = 0; i < auth_type->numEntries; i++) {
@ -3587,6 +3661,10 @@ end:
if (ucast_cipher)
qdf_mem_copy(ucast_cipher, unicast, CSR_RSN_OUI_SIZE);
if (gp_mgmt_cipher && group_mgmt_acceptable_cipher)
qdf_mem_copy(gp_mgmt_cipher, group_mgmt,
CSR_RSN_OUI_SIZE);
if (auth_suite)
qdf_mem_copy(auth_suite, authentication,
CSR_RSN_OUI_SIZE);
@ -3715,7 +3793,7 @@ static bool csr_is_rsn_match(tHalHandle hHal, tCsrAuthList *pAuthType,
pEnMcType, &pIes->RSN,
NULL, NULL, NULL, NULL,
pNegotiatedAuthType,
pNegotiatedMCCipher);
pNegotiatedMCCipher, NULL, NULL);
#ifdef WLAN_FEATURE_11W
/* If all the filter matches then finally checks for PMF capabilities */
if (fRSNMatch)
@ -3933,6 +4011,7 @@ uint8_t csr_construct_rsn_ie(tHalHandle hHal, uint32_t sessionId,
uint8_t cbRSNIe = 0;
uint8_t UnicastCypher[CSR_RSN_OUI_SIZE];
uint8_t MulticastCypher[CSR_RSN_OUI_SIZE];
uint8_t gp_mgmt_cipher_suite[CSR_RSN_OUI_SIZE];
uint8_t AuthSuite[CSR_RSN_OUI_SIZE];
tCsrRSNAuthIe *pAuthSuite;
tCsrRSNCapabilities RSNCapabilities;
@ -3975,10 +4054,12 @@ uint8_t csr_construct_rsn_ie(tHalHandle hHal, uint32_t sessionId,
*/
fRSNMatch = csr_get_rsn_information(hHal, &pProfile->AuthType,
pProfile->negotiatedUCEncryptionType,
&pProfile->mcEncryptionType,
&pIesLocal->RSN, UnicastCypher,
MulticastCypher, AuthSuite,
&RSNCapabilities, &negAuthType, NULL);
&pProfile->mcEncryptionType,
&pIesLocal->RSN, UnicastCypher,
MulticastCypher, AuthSuite,
&RSNCapabilities, &negAuthType, NULL,
gp_mgmt_cipher_suite,
&pProfile->mgmt_encryption_type);
if (!fRSNMatch)
break;
@ -4055,8 +4136,8 @@ uint8_t csr_construct_rsn_ie(tHalHandle hHal, uint32_t sessionId,
pGroupMgmtCipherSuite =
(uint8_t *) pPMK + sizeof(uint16_t) +
(pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE);
qdf_mem_copy(pGroupMgmtCipherSuite, csr_rsn_oui[07],
CSR_WPA_OUI_SIZE);
qdf_mem_copy(pGroupMgmtCipherSuite,
gp_mgmt_cipher_suite, CSR_RSN_OUI_SIZE);
}
#endif
@ -4860,7 +4941,12 @@ tAniEdType csr_translate_encrypt_type_to_ed_type(eCsrEncryptionType EncryptType)
case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
edType = eSIR_ED_GCMP_256;
break;
case eCSR_ENCRYPT_TYPE_AES_GMAC_128:
edType = eSIR_ED_AES_GMAC_128;
break;
case eCSR_ENCRYPT_TYPE_AES_GMAC_256:
edType = eSIR_ED_AES_GMAC_256;
break;
#endif
}

View file

@ -1625,9 +1625,8 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle,
{
struct set_key_params params;
QDF_STATUS status = QDF_STATUS_SUCCESS;
#ifdef WLAN_FEATURE_11W
struct wma_txrx_node *iface = NULL;
#endif /* WLAN_FEATURE_11W */
if ((key_params->key_type == eSIR_ED_NONE &&
key_params->key_len) || (key_params->key_type != eSIR_ED_NONE &&
!key_params->key_len)) {
@ -1734,6 +1733,10 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle,
case eSIR_ED_AES_128_CMAC:
params.key_cipher = WMI_CIPHER_AES_CMAC;
break;
case eSIR_ED_AES_GMAC_128:
case eSIR_ED_AES_GMAC_256:
params.key_cipher = WMI_CIPHER_AES_GMAC;
break;
#endif /* WLAN_FEATURE_11W */
/* Firmware uses length to detect GCMP 128/256*/
case eSIR_ED_GCMP:
@ -1776,7 +1779,9 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle,
params.key_len = key_params->key_len;
#ifdef WLAN_FEATURE_11W
if (key_params->key_type == eSIR_ED_AES_128_CMAC) {
if ((key_params->key_type == eSIR_ED_AES_128_CMAC) ||
(key_params->key_type == eSIR_ED_AES_GMAC_128) ||
(key_params->key_type == eSIR_ED_AES_GMAC_256)) {
iface = &wma_handle->interfaces[key_params->vdev_id];
if (iface) {
iface->key.key_length = key_params->key_len;