Browse Source

qcacld-3.0: Add support for GMAC cipher suite

Add changes to support GMAC group management cipher suite

Change-Id: Ic4855b77268464a1ed61efcf213f76a2d99ff0c4
CRs-Fixed: 2164828
Padma, Santhosh Kumar 7 years ago
parent
commit
4117d7a59c

+ 12 - 0
core/hdd/src/wlan_hdd_cfg80211.c

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

+ 3 - 1
core/mac/inc/ani_system_defs.h

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

+ 2 - 0
core/mac/src/pe/lim/lim_process_mlm_req_messages.c

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

+ 4 - 1
core/mac/src/pe/lim/lim_process_sme_req_messages.c

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

+ 5 - 3
core/sme/inc/csr_api.h

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

+ 34 - 1
core/sme/src/csr/csr_api_roam.c

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

+ 22 - 4
core/sme/src/csr/csr_api_scan.c

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

+ 96 - 10
core/sme/src/csr/csr_util.c

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

+ 8 - 3
core/wma/src/wma_mgmt.c

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