Browse Source

qcacld-3.0: crypto convergence support for SET KEY

Make changes to the legacy code to support the
new SET KEY converged infrastructure.

Change-Id: Ic5359e3a9035ac5f2a937a9a1013fa92764cda9d
CRs-Fixed: 2358795
Kiran Kumar Lokere 6 years ago
parent
commit
7d6e4c9dc1

+ 4 - 2
components/mlme/dispatcher/inc/wlan_mlme_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-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
@@ -64,6 +64,7 @@ QDF_STATUS wlan_mlme_get_edca_params(struct wlan_mlme_edca_params *edca_params,
 
 /*
  * mlme_get_wep_key() - get the wep key to process during auth frame
+ * @vdev: VDEV object for which the wep key is being requested
  * @wep_params: cfg wep parameters structure
  * @wep_key_id: default key number
  * @default_key: default key to be copied
@@ -71,7 +72,8 @@ QDF_STATUS wlan_mlme_get_edca_params(struct wlan_mlme_edca_params *edca_params,
  *
  * Return QDF_STATUS
  */
-QDF_STATUS mlme_get_wep_key(struct wlan_mlme_wep_cfg *wep_params,
+QDF_STATUS mlme_get_wep_key(struct wlan_objmgr_vdev *vdev,
+			    struct wlan_mlme_wep_cfg *wep_params,
 			    enum wep_key_id wep_keyid, uint8_t *default_key,
 			    qdf_size_t *key_len);
 

+ 33 - 2
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-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
@@ -26,6 +26,7 @@
 #include "wmi_unified.h"
 #include "wma.h"
 #include "wma_internal.h"
+#include "wlan_crypto_global_api.h"
 
 QDF_STATUS wlan_mlme_get_cfg_str(uint8_t *dst, struct mlme_cfg_str *cfg_str,
 				 qdf_size_t *len)
@@ -2140,7 +2141,36 @@ QDF_STATUS wlan_mlme_get_edca_params(struct wlan_mlme_edca_params *edca_params,
 	return QDF_STATUS_SUCCESS;
 }
 
-QDF_STATUS mlme_get_wep_key(struct wlan_mlme_wep_cfg *wep_params,
+#ifdef CRYPTO_SET_KEY_CONVERGED
+QDF_STATUS mlme_get_wep_key(struct wlan_objmgr_vdev *vdev,
+			    struct wlan_mlme_wep_cfg *wep_params,
+			    enum wep_key_id wep_keyid, uint8_t *default_key,
+			    qdf_size_t *key_len)
+{
+	struct wlan_crypto_key *crypto_key = NULL;
+
+	if (wep_keyid >= WLAN_CRYPTO_MAXKEYIDX) {
+		mlme_err("Incorrect wep key index %d", wep_keyid);
+		return QDF_STATUS_E_INVAL;
+	}
+	crypto_key = wlan_crypto_get_key(vdev, wep_keyid);
+	if (crypto_key == NULL) {
+		mlme_err("Crypto KEY not present");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (crypto_key->keylen > WLAN_CRYPTO_KEY_WEP104_LEN) {
+		mlme_err("Key too large to hold");
+		return QDF_STATUS_E_INVAL;
+	}
+	*key_len = crypto_key->keylen;
+	qdf_mem_copy(default_key, &crypto_key->keyval, crypto_key->keylen);
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+QDF_STATUS mlme_get_wep_key(struct wlan_objmgr_vdev *vdev,
+			    struct wlan_mlme_wep_cfg *wep_params,
 			    enum wep_key_id wep_keyid, uint8_t *default_key,
 			    qdf_size_t *key_len)
 {
@@ -2176,6 +2206,7 @@ QDF_STATUS mlme_get_wep_key(struct wlan_mlme_wep_cfg *wep_params,
 	mlme_debug("key_id:%d key_len:%zd", wep_keyid, *key_len);
 	return QDF_STATUS_SUCCESS;
 }
+#endif /* CRYPTO_SET_KEY_CONVERGED */
 
 QDF_STATUS mlme_set_wep_key(struct wlan_mlme_wep_cfg *wep_params,
 			    enum wep_key_id wep_keyid, uint8_t *key_to_set,

+ 46 - 9
core/hdd/src/wlan_hdd_assoc.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -64,6 +64,8 @@
 #include "wlan_hdd_scan.h"
 
 #include "wlan_hdd_nud_tracking.h"
+#include <wlan_cfg80211_crypto.h>
+#include <wlan_crypto_global_api.h>
 /* These are needed to recognize WPA and RSN suite types */
 #define HDD_WPA_OUI_SIZE 4
 #define HDD_RSN_OUI_SIZE 4
@@ -3772,6 +3774,40 @@ hdd_roam_mic_error_indication_handler(struct hdd_adapter *adapter,
 				     GFP_KERNEL);
 }
 
+#ifdef CRYPTO_SET_KEY_CONVERGED
+static QDF_STATUS wlan_hdd_set_key_helper(struct hdd_adapter *adapter,
+					  uint32_t *roam_id)
+{
+	int ret;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = hdd_objmgr_get_vdev(adapter);
+	if (!vdev)
+		return QDF_STATUS_E_FAILURE;
+	ret = wlan_cfg80211_crypto_add_key(vdev, true, 0);
+	hdd_objmgr_put_vdev(adapter);
+	if (ret != 0) {
+		hdd_err("crypto add key fail, status: %d", ret);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static QDF_STATUS wlan_hdd_set_key_helper(struct hdd_adapter *adapter,
+					  uint32_t *roam_id)
+{
+	struct hdd_station_ctx *sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	return sme_roam_set_key(hdd_ctx->mac_handle,
+				adapter->session_id,
+				&sta_ctx->ibss_enc_key,
+				roam_id);
+}
+#endif
+
 /**
  * roam_roam_connect_status_update_handler() - IBSS connect status update
  * @adapter: pointer to adapter
@@ -3792,6 +3828,7 @@ roam_roam_connect_status_update_handler(struct hdd_adapter *adapter,
 					eCsrRoamResult roamResult)
 {
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	struct wlan_objmgr_vdev *vdev;
 	QDF_STATUS qdf_status;
 
 	switch (roamResult) {
@@ -3853,18 +3890,18 @@ roam_roam_connect_status_update_handler(struct hdd_adapter *adapter,
 				eSIR_TX_RX;
 			qdf_copy_macaddr(&sta_ctx->ibss_enc_key.peerMac,
 					 &roam_info->peerMac);
+			vdev = hdd_objmgr_get_vdev(adapter);
+			if (!vdev)
+				return QDF_STATUS_E_FAILURE;
+			wlan_crypto_update_set_key_peer(vdev, true, 0,
+							&roam_info->peerMac);
+			hdd_objmgr_put_vdev(adapter);
 
 			hdd_debug("New peer joined set PTK encType=%d",
 				 encr_type);
-
-			qdf_status =
-				sme_roam_set_key(hdd_ctx->mac_handle,
-						 adapter->session_id,
-						 &sta_ctx->ibss_enc_key,
-						 &roamId);
-
+			qdf_status = wlan_hdd_set_key_helper(adapter, &roamId);
 			if (QDF_STATUS_SUCCESS != qdf_status) {
-				hdd_err("sme_roam_set_key failed, status: %d",
+				hdd_err("sme set_key fail status: %d",
 					qdf_status);
 				return QDF_STATUS_E_FAILURE;
 			}

+ 297 - 21
core/hdd/src/wlan_hdd_cfg80211.c

@@ -133,6 +133,7 @@
 #include "wlan_hdd_object_manager.h"
 #include "nan_ucfg_api.h"
 #include "wlan_fwol_ucfg_api.h"
+#include "wlan_cfg80211_crypto.h"
 
 #define g_mode_rates_size (12)
 #define a_mode_rates_size (8)
@@ -13380,7 +13381,7 @@ void wlan_hdd_cfg80211_deregister_frames(struct hdd_adapter *adapter)
 				  WNM_NOTIFICATION_FRAME_SIZE);
 }
 
-#ifdef FEATURE_WLAN_WAPI
+#if defined(FEATURE_WLAN_WAPI) && !defined(CRYPTO_SET_KEY_CONVERGED)
 static void wlan_hdd_cfg80211_set_key_wapi(struct hdd_adapter *adapter,
 					   uint8_t key_index,
 					   const uint8_t *mac_addr,
@@ -14069,6 +14070,215 @@ static int wlan_hdd_change_station(struct wiphy *wiphy,
 	return ret;
 }
 
+#ifdef CRYPTO_SET_KEY_CONVERGED
+#ifdef FEATURE_WLAN_ESE
+static bool hdd_is_krk_enc_type(uint32_t cipher_type)
+{
+	if (cipher_type == WLAN_CIPHER_SUITE_KRK)
+		return true;
+
+	return false;
+}
+#else
+static bool hdd_is_krk_enc_type(uint32_t cipher_type)
+{
+	return false;
+}
+#endif
+
+#if defined(FEATURE_WLAN_ESE) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
+static bool hdd_is_btk_enc_type(uint32_t cipher_type)
+{
+	if (cipher_type == WLAN_CIPHER_SUITE_BTK)
+		return true;
+
+	return false;
+}
+#else
+static bool hdd_is_btk_enc_type(uint32_t cipher_type)
+{
+	return false;
+}
+#endif
+#endif
+
+#ifdef CRYPTO_SET_KEY_CONVERGED
+static int wlan_hdd_add_key_ibss(struct hdd_adapter *adapter,
+				 bool pairwise, u8 key_index,
+				 const u8 *mac_addr, struct key_params *params,
+				 bool *key_already_installed)
+{
+	struct wlan_objmgr_vdev *vdev;
+	int errno;
+
+	if (pairwise)
+		return 0;
+	/* if a key is already installed, block all subsequent ones */
+	if (adapter->session.station.ibss_enc_key_installed) {
+		hdd_debug("IBSS key installed already");
+		*key_already_installed = true;
+		return 0;
+	}
+	/*Set the group key */
+	vdev = hdd_objmgr_get_vdev(adapter);
+	if (!vdev)
+		return -EINVAL;
+	errno = wlan_cfg80211_crypto_add_key(vdev, pairwise, key_index);
+	if (errno) {
+		hdd_err("add_ibss_key failed, errno: %d", errno);
+		hdd_objmgr_put_vdev(adapter);
+		return errno;
+	}
+	/* Save the keys here and call set_key for setting
+	 * the PTK after peer joins the IBSS network
+	 */
+	wlan_cfg80211_store_key(vdev, key_index, true, mac_addr, params);
+	hdd_objmgr_put_vdev(adapter);
+	adapter->session.station.ibss_enc_key_installed = 1;
+
+	return 0;
+}
+
+static int wlan_hdd_add_key_sap(struct hdd_adapter *adapter,
+				bool pairwise, u8 key_index)
+{
+	struct wlan_objmgr_vdev *vdev;
+	int errno = 0;
+	struct hdd_hostapd_state *hostapd_state =
+		WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+
+	vdev = hdd_objmgr_get_vdev(adapter);
+	if (!vdev)
+		return -EINVAL;
+	if (hostapd_state->bss_state == BSS_START)
+		errno = wlan_cfg80211_crypto_add_key(vdev, pairwise, key_index);
+	hdd_objmgr_put_vdev(adapter);
+
+	return errno;
+}
+
+static int wlan_hdd_add_key_sta(struct hdd_adapter *adapter,
+				bool pairwise, u8 key_index,
+				mac_handle_t mac_handle, bool *ft_mode)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct hdd_station_ctx *sta_ctx =
+		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	int errno;
+	QDF_STATUS status;
+
+	if (!pairwise) {
+		/* set group key */
+		if (sta_ctx->roam_info.defer_key_complete) {
+			hdd_debug("Perform Set key Complete");
+			hdd_perform_roam_set_key_complete(adapter);
+		}
+	}
+	/* The supplicant may attempt to set the PTK once
+	 * pre-authentication is done. Save the key in the
+	 * UMAC and include it in the ADD BSS request
+	 */
+	status = sme_check_ft_status(mac_handle, adapter->session_id);
+	if (status == QDF_STATUS_SUCCESS) {
+		*ft_mode = true;
+		return 0;
+	}
+	vdev = hdd_objmgr_get_vdev(adapter);
+	if (!vdev)
+		return -EINVAL;
+	errno = wlan_cfg80211_crypto_add_key(vdev, pairwise, key_index);
+	hdd_objmgr_put_vdev(adapter);
+	if (!errno && adapter->send_mode_change) {
+		wlan_hdd_send_mode_change_event();
+		adapter->send_mode_change = false;
+	}
+
+	return errno;
+}
+
+static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
+				       struct net_device *ndev,
+				       u8 key_index, bool pairwise,
+				       const u8 *mac_addr,
+				       struct key_params *params)
+{
+	struct hdd_context *hdd_ctx;
+	mac_handle_t mac_handle;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	struct wlan_objmgr_vdev *vdev;
+	bool key_already_installed = false, ft_mode = false;
+	enum wlan_crypto_cipher_type cipher;
+	int errno;
+
+	hdd_enter();
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_ADD_KEY,
+		  adapter->session_id, params->key_len);
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	hdd_debug("converged Device_mode %s(%d)",
+		  qdf_opmode_str(adapter->device_mode),
+		  adapter->device_mode);
+	 mac_handle = hdd_ctx->mac_handle;
+
+	if (hdd_is_btk_enc_type(params->cipher))
+		return sme_add_key_btk(mac_handle, adapter->session_id,
+				       params->key, params->key_len);
+	if (hdd_is_krk_enc_type(params->cipher))
+		return sme_add_key_krk(mac_handle, adapter->session_id,
+				       params->key, params->key_len);
+
+	vdev = hdd_objmgr_get_vdev(adapter);
+	if (!vdev)
+		return -EINVAL;
+	errno = wlan_cfg80211_store_key(vdev, key_index, pairwise, mac_addr,
+					params);
+	hdd_objmgr_put_vdev(adapter);
+	if (errno)
+		return errno;
+	switch (adapter->device_mode) {
+	case QDF_IBSS_MODE:
+		errno = wlan_hdd_add_key_ibss(adapter, pairwise, key_index,
+					      mac_addr, params,
+					      &key_already_installed);
+		if (key_already_installed)
+			return 0;
+		break;
+	case QDF_SAP_MODE:
+	case QDF_P2P_GO_MODE:
+		errno = wlan_hdd_add_key_sap(adapter, pairwise, key_index);
+		break;
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+		wlan_hdd_add_key_sta(adapter, pairwise, key_index,
+				     mac_handle, &ft_mode);
+		if (ft_mode)
+			return 0;
+		break;
+	default:
+		break;
+	}
+	if (!errno) {
+		cipher = osif_nl_to_crypto_cipher_type(params->cipher);
+		wma_update_set_key(adapter->session_id, pairwise, key_index,
+				   cipher);
+	}
+	hdd_exit();
+
+	return errno;
+}
+#else /* !CRYPTO_SET_KEY_CONVERGED */
 /*
  * FUNCTION: __wlan_hdd_cfg80211_add_key
  * This function is used to initialize the key information
@@ -14081,9 +14291,9 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
 {
 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
 	tCsrRoamSetKey setKey;
-	int status;
+	int errno;
 	uint32_t roamId = INVALID_ROAM_ID;
-	QDF_STATUS qdf_ret_status;
+	QDF_STATUS status;
 	struct hdd_context *hdd_ctx;
 	mac_handle_t mac_handle;
 
@@ -14097,14 +14307,13 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
 	if (wlan_hdd_validate_session_id(adapter->session_id))
 		return -EINVAL;
 
-	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
-			 TRACE_CODE_HDD_CFG80211_ADD_KEY,
-			 adapter->session_id, params->key_len));
+	qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_ADD_KEY,
+		  adapter->session_id, params->key_len);
 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-	status = wlan_hdd_validate_context(hdd_ctx);
+	errno = wlan_hdd_validate_context(hdd_ctx);
 
-	if (0 != status)
-		return status;
+	if (errno)
+		return errno;
 
 	hdd_debug("Device_mode %s(%d)",
 		  qdf_opmode_str(adapter->device_mode), adapter->device_mode);
@@ -14268,7 +14477,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
 			     &setKey, sizeof(tCsrRoamSetKey));
 
 		adapter->session.station.ibss_enc_key_installed = 1;
-		return status;
+		return qdf_status_to_os_return(status);
 	}
 	if ((adapter->device_mode == QDF_SAP_MODE) ||
 	    (adapter->device_mode == QDF_P2P_GO_MODE)) {
@@ -14326,19 +14535,20 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
 		 * pre-authentication is done. Save the key in the
 		 * UMAC and include it in the ADD BSS request
 		 */
-		qdf_ret_status = sme_ft_update_key(mac_handle,
-						   adapter->session_id, &setKey);
-		if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) {
+		status = sme_ft_update_key(mac_handle,
+					   adapter->session_id, &setKey);
+		if (status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) {
 			hdd_debug("Update PreAuth Key success");
 			return 0;
-		} else if (qdf_ret_status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) {
+		} else if (status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) {
 			hdd_err("Update PreAuth Key failed");
 			return -EINVAL;
 		}
 
 		/* issue set key request to SME */
 		status = sme_roam_set_key(mac_handle,
-					  adapter->session_id, &setKey, &roamId);
+					  adapter->session_id, &setKey,
+					  &roamId);
 
 		if (0 != status) {
 			hdd_err("sme_roam_set_key failed, status: %d", status);
@@ -14385,6 +14595,7 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
 	hdd_exit();
 	return 0;
 }
+#endif /* CRYPTO_SET_KEY_CONVERGED */
 
 static int wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
 				     struct net_device *ndev,
@@ -14487,9 +14698,8 @@ static int __wlan_hdd_cfg80211_get_key(struct wiphy *wiphy,
 		break;
 	}
 
-	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
-			 TRACE_CODE_HDD_CFG80211_GET_KEY,
-			 adapter->session_id, params.cipher));
+	qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_GET_KEY,
+		  adapter->session_id, params.cipher);
 
 	params.key_len = roam_profile->Keys.KeyLength[key_index];
 	params.seq_len = 0;
@@ -14577,6 +14787,7 @@ static int wlan_hdd_cfg80211_del_key(struct wiphy *wiphy,
 	return ret;
 }
 
+#ifndef CRYPTO_SET_KEY_CONVERGED
 #ifdef FEATURE_WLAN_WAPI
 static bool hdd_is_wapi_enc_type(eCsrEncryptionType ucEncryptionType)
 {
@@ -14591,7 +14802,72 @@ static bool hdd_is_wapi_enc_type(eCsrEncryptionType ucEncryptionType)
 	return false;
 }
 #endif
+#endif
 
+#ifdef CRYPTO_SET_KEY_CONVERGED
+static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy,
+					       struct net_device *ndev,
+					       u8 key_index,
+					       bool unicast, bool multicast)
+{
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
+	struct hdd_context *hdd_ctx;
+	struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT;
+	struct hdd_station_ctx *sta_ctx;
+	struct wlan_crypto_key *crypto_key;
+	int ret;
+	QDF_STATUS status;
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EINVAL;
+	}
+
+	if (wlan_hdd_validate_session_id(adapter->session_id))
+		return -EINVAL;
+
+	qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
+		  adapter->session_id, key_index);
+
+	hdd_debug("Device_mode %s(%d) key_index = %d",
+		  qdf_opmode_str(adapter->device_mode),
+		  adapter->device_mode, key_index);
+
+	if (CSR_MAX_NUM_KEY <= key_index) {
+		hdd_err("Invalid key index: %d", key_index);
+		return -EINVAL;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	ret = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != ret)
+		return ret;
+	crypto_key = wlan_crypto_get_key(adapter->vdev, key_index);
+	hdd_debug("unicast %d, cipher %d", unicast, crypto_key->cipher_type);
+	if (crypto_key->cipher_type != WLAN_CRYPTO_CIPHER_WEP)
+		return 0;
+	sta_ctx =  WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (unicast)
+		status =
+		wlan_cfg80211_set_default_key(adapter->vdev, key_index,
+					      &sta_ctx->conn_info.bssId);
+	else
+		status = wlan_cfg80211_set_default_key(adapter->vdev, key_index,
+						       &bssid);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("ret fail status %d", ret);
+		return -EINVAL;
+	}
+	if ((adapter->device_mode == QDF_STA_MODE) ||
+	    (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
+		ret = wlan_cfg80211_crypto_add_key(adapter->vdev, unicast,
+						   key_index);
+	}
+
+	return ret;
+}
+#else
 /*
  * FUNCTION: __wlan_hdd_cfg80211_set_default_key
  * This function is used to set the default tx key index
@@ -14616,9 +14892,8 @@ static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy,
 	if (wlan_hdd_validate_session_id(adapter->session_id))
 		return -EINVAL;
 
-	MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
-			 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
-			 adapter->session_id, key_index));
+	qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
+		  adapter->session_id, key_index);
 
 	hdd_debug("Device_mode %s(%d) key_index = %d",
 		  qdf_opmode_str(adapter->device_mode),
@@ -14744,6 +15019,7 @@ static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy,
 	hdd_exit();
 	return status;
 }
+#endif
 
 static int wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy,
 					     struct net_device *ndev,

+ 5 - 3
core/mac/src/pe/lim/lim_process_auth_frame.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-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
@@ -757,7 +757,8 @@ static void lim_process_auth_frame_type2(struct mac_context *mac_ctx,
 			qdf_mem_copy(defaultkey, key_ptr->key,
 					key_ptr->keyLength);
 		} else {
-			qdf_status = mlme_get_wep_key(wep_params,
+			qdf_status = mlme_get_wep_key(pe_session->vdev,
+						      wep_params,
 						      (MLME_WEP_DEFAULT_KEY_1 +
 						       key_id), defaultkey,
 						      &val);
@@ -1363,7 +1364,8 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 					key_ptr->keyLength);
 			val = key_ptr->keyLength;
 		} else {
-			qdf_status = mlme_get_wep_key(wep_params,
+			qdf_status = mlme_get_wep_key(pe_session->vdev,
+						      wep_params,
 						      (MLME_WEP_DEFAULT_KEY_1 +
 						      key_id), defaultkey,
 						      &val);

+ 42 - 29
core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -2808,6 +2808,7 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx,
 	struct pe_session *session_entry;
 	uint16_t key_len;
 	uint16_t result_status;
+	tSetStaKeyParams *set_key_params;
 
 	SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
 	qdf_mem_set((void *)&mlm_set_key_cnf, sizeof(tLimMlmSetKeysCnf), 0);
@@ -2815,8 +2816,9 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx,
 		pe_err("msg bodyptr is NULL");
 		return;
 	}
-	session_id = ((tpSetStaKeyParams) msg->bodyptr)->sessionId;
-	sme_session_id = ((tpSetBssKeyParams) msg->bodyptr)->smesessionId;
+	set_key_params = msg->bodyptr;
+	session_id = set_key_params->sessionId;
+	sme_session_id = set_key_params->smesessionId;
 	session_entry = pe_find_session_by_session_id(mac_ctx, session_id);
 	if (session_entry == NULL) {
 		pe_err("session does not exist for given session_id");
@@ -2828,17 +2830,21 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx,
 					     sme_session_id, 0);
 		return;
 	}
-	if (eLIM_MLM_WT_SET_STA_KEY_STATE != session_entry->limMlmState) {
-		pe_err("Received unexpected [Mesg Id - %d] in state %X",
-			msg->type, session_entry->limMlmState);
-		resp_reqd = 0;
-	} else {
-		mlm_set_key_cnf.resultCode =
-			(uint16_t)(((tpSetStaKeyParams) msg->bodyptr)->status);
+	result_status = set_key_params->status;
+	if (!lim_is_set_key_req_converged()) {
+		if (eLIM_MLM_WT_SET_STA_KEY_STATE !=
+				session_entry->limMlmState) {
+			pe_err("Received unexpected [Mesg Id - %d] in state %X",
+			       msg->type, session_entry->limMlmState);
+			resp_reqd = 0;
+		} else {
+			mlm_set_key_cnf.resultCode = result_status;
+		}
+		/* Restore MLME state */
+		session_entry->limMlmState = session_entry->limPrevMlmState;
 	}
 
-	result_status = (uint16_t)(((tpSetStaKeyParams) msg->bodyptr)->status);
-	key_len = ((tpSetStaKeyParams)msg->bodyptr)->key[0].keyLength;
+	key_len = set_key_params->key[0].keyLength;
 
 	if (result_status == eSIR_SME_SUCCESS && key_len)
 		mlm_set_key_cnf.key_len_nonzero = true;
@@ -2846,10 +2852,6 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx,
 		mlm_set_key_cnf.key_len_nonzero = false;
 
 
-	qdf_mem_free(msg->bodyptr);
-	msg->bodyptr = NULL;
-	/* Restore MLME state */
-	session_entry->limMlmState = session_entry->limPrevMlmState;
 	MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
 		session_entry->peSessionId, session_entry->limMlmState));
 	if (resp_reqd) {
@@ -2865,11 +2867,17 @@ void lim_process_mlm_set_sta_key_rsp(struct mac_context *mac_ctx,
 			 */
 			qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
 			mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
+		} else {
+			lim_copy_set_key_req_mac_addr(
+					&mlm_set_key_cnf.peer_macaddr,
+					&set_key_params->macaddr);
 		}
 		mlm_set_key_cnf.sessionId = session_id;
 		lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF,
 			(uint32_t *) &mlm_set_key_cnf);
 	}
+	qdf_mem_free(msg->bodyptr);
+	msg->bodyptr = NULL;
 }
 
 /**
@@ -2932,21 +2940,19 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx,
 	else
 		set_key_cnf.key_len_nonzero = false;
 
-	/* Validate MLME state */
-	if (eLIM_MLM_WT_SET_BSS_KEY_STATE != session_entry->limMlmState &&
-		eLIM_MLM_WT_SET_STA_BCASTKEY_STATE !=
-			session_entry->limMlmState) {
-		pe_err("Received unexpected [Mesg Id - %d] in state %X",
-			msg->type, session_entry->limMlmState);
-	} else {
-		set_key_cnf.resultCode = result_status;
+	if (!lim_is_set_key_req_converged()) {
+		if (eLIM_MLM_WT_SET_BSS_KEY_STATE !=
+				session_entry->limMlmState &&
+				eLIM_MLM_WT_SET_STA_BCASTKEY_STATE !=
+				session_entry->limMlmState) {
+			pe_err("Received unexpected [Mesg Id - %d] in state %X",
+			       msg->type, session_entry->limMlmState);
+		} else {
+			set_key_cnf.resultCode = result_status;
+		}
+		session_entry->limMlmState = session_entry->limPrevMlmState;
 	}
 
-	qdf_mem_free(msg->bodyptr);
-	msg->bodyptr = NULL;
-	/* Restore MLME state */
-	session_entry->limMlmState = session_entry->limPrevMlmState;
-
 	MTRACE(mac_trace
 		(mac_ctx, TRACE_CODE_MLM_STATE, session_entry->peSessionId,
 		session_entry->limMlmState));
@@ -2964,7 +2970,14 @@ void lim_process_mlm_set_bss_key_rsp(struct mac_context *mac_ctx,
 		 */
 		qdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
 		mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
+	} else {
+		lim_copy_set_key_req_mac_addr(
+				&set_key_cnf.peer_macaddr,
+				&((tpSetStaKeyParams)msg->bodyptr)->macaddr);
 	}
+	qdf_mem_free(msg->bodyptr);
+	msg->bodyptr = NULL;
+
 	lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF,
 		(uint32_t *) &set_key_cnf);
 }

+ 22 - 0
core/mac/src/pe/lim/lim_utils.h

@@ -1660,4 +1660,26 @@ QDF_STATUS lim_ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme,
 
 #endif
 
+#ifdef CRYPTO_SET_KEY_CONVERGED
+static inline bool lim_is_set_key_req_converged(void)
+{
+	return true;
+}
+
+static inline void lim_copy_set_key_req_mac_addr(struct qdf_mac_addr *dst,
+						 struct qdf_mac_addr *src)
+{
+	qdf_copy_macaddr(dst, src);
+}
+#else
+static inline bool lim_is_set_key_req_converged(void)
+{
+	return false;
+}
+
+static inline void lim_copy_set_key_req_mac_addr(struct qdf_mac_addr *dst,
+						 struct qdf_mac_addr *src)
+{
+}
+#endif
 #endif /* __LIM_UTILS_H */

+ 40 - 42
core/sap/src/sap_module.c

@@ -50,45 +50,14 @@
 #include "wlan_reg_services_api.h"
 #include <wlan_dfs_utils_api.h>
 #include <wlan_reg_ucfg_api.h>
+#include <wlan_cfg80211_crypto.h>
+#include <wlan_crypto_global_api.h>
 
-/*----------------------------------------------------------------------------
- * Preprocessor Definitions and Constants
- * -------------------------------------------------------------------------*/
 #define SAP_DEBUG
-
-/*----------------------------------------------------------------------------
- * Type Declarations
- * -------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
- * Global Data Definitions
- * -------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
- *  External declarations for global context
- * -------------------------------------------------------------------------*/
-/*  No!  Get this from CDS. */
-/*  The main per-Physical Link (per WLAN association) context. */
 static struct sap_context *gp_sap_ctx[SAP_MAX_NUM_SESSION];
 static qdf_atomic_t sap_ctx_ref_count[SAP_MAX_NUM_SESSION];
-
-/*----------------------------------------------------------------------------
- * Static Variable Definitions
- * -------------------------------------------------------------------------*/
 static qdf_mutex_t sap_context_lock;
 
-/*----------------------------------------------------------------------------
- * Static Function Declarations and Definitions
- * -------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
- * Externalized Function Definitions
- * -------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
- * Function Declarations and Documentation
- * -------------------------------------------------------------------------*/
-
 /**
  * wlansap_global_init() - Initialize SAP globals
  *
@@ -1401,19 +1370,28 @@ QDF_STATUS wlansap_set_channel_change_with_csa(struct sap_context *sapContext,
 	return QDF_STATUS_SUCCESS;
 }
 
-QDF_STATUS wlansap_set_key_sta(struct sap_context *sap_ctx,
-			       tCsrRoamSetKey *key_info)
+#ifdef CRYPTO_SET_KEY_CONVERGED
+static QDF_STATUS wlan_sap_set_key_helper(struct sap_context *sap_ctx,
+					  tCsrRoamSetKey *set_key_info)
 {
-	uint32_t roam_id = INVALID_ROAM_ID;
-	struct mac_context *mac;
+	struct wlan_crypto_key *crypto_key;
 
-	if (!sap_ctx) {
+	crypto_key = wlan_crypto_get_key(sap_ctx->vdev, 0);
+	if (!crypto_key) {
 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
-			  "%s: Invalid SAP pointer",
-			  __func__);
-		return QDF_STATUS_E_FAULT;
+				"Crypto KEY is NULL");
+		return QDF_STATUS_E_FAILURE;
 	}
 
+	return ucfg_crypto_set_key_req(sap_ctx->vdev, crypto_key, true);
+}
+#else
+static QDF_STATUS wlan_sap_set_key_helper(struct sap_context *sap_ctx,
+					  tCsrRoamSetKey *set_key_info)
+{
+	uint32_t roam_id = INVALID_ROAM_ID;
+	struct mac_context *mac;
+
 	mac = sap_get_mac_context();
 	if (!mac) {
 		QDF_TRACE_ERROR(QDF_MODULE_ID_SAP, "Invalid MAC context");
@@ -1421,7 +1399,27 @@ QDF_STATUS wlansap_set_key_sta(struct sap_context *sap_ctx,
 	}
 
 	return sme_roam_set_key(MAC_HANDLE(mac), sap_ctx->sessionId,
-				key_info, &roam_id);
+				set_key_info, &roam_id);
+}
+#endif
+
+QDF_STATUS wlansap_set_key_sta(struct sap_context *sap_ctx,
+			       tCsrRoamSetKey *set_key_info)
+{
+	QDF_STATUS qdf_status;
+
+	if (!sap_ctx) {
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Invalid SAP pointer",
+			  __func__);
+		return QDF_STATUS_E_FAULT;
+	}
+
+	qdf_status = wlan_sap_set_key_helper(sap_ctx, set_key_info);
+	if (qdf_status != QDF_STATUS_SUCCESS)
+		qdf_status = QDF_STATUS_E_FAULT;
+
+	return qdf_status;
 }
 
 QDF_STATUS wlan_sap_getstation_ie_information(struct sap_context *sap_ctx,

+ 38 - 0
core/sme/inc/sme_api.h

@@ -2927,6 +2927,44 @@ sme_get_sta_cxn_info(mac_handle_t mac_handle, uint32_t session_id,
 }
 #endif
 
+#ifdef FEATURE_WLAN_ESE
+/**
+ * sme_add_key_btk() - Add BTK key
+ * @mac_handle: MAC handle
+ * @session_id: SME session identifier
+ * @key: key material
+ * @key_len: length of the key
+ *
+ * Return: 0 on success and negative value for failure
+ */
+int sme_add_key_btk(mac_handle_t mac_handle, uint8_t session_id,
+		    const uint8_t *key, const int key_len);
+/**
+ * sme_add_key_krk() - Add KRK key
+ * @mac_handle: MAC handle
+ * @session_id: SME session identifier
+ * @key: key material
+ * @key_len: length of the key
+ *
+ * Return: 0 on success and negative value for failure
+ */
+int sme_add_key_krk(mac_handle_t mac_handle, uint8_t session_id,
+		    const uint8_t *key, const int key_len);
+
+#else
+static inline int sme_add_key_btk(mac_handle_t mac_handle, uint8_t session_id,
+				  const uint8_t *key, const int key_len)
+{
+	return 0;
+}
+
+static inline int sme_add_key_krk(mac_handle_t mac_handle, uint8_t session_id,
+				  const uint8_t *key, const int key_len)
+{
+	return 0;
+}
+#endif
+
 /**
  * sme_find_session_by_bssid() - checks whether has session
  * with given bssid

+ 10 - 1
core/sme/inc/sme_ft_api.h

@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2013-2016, 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, 2018, 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
@@ -86,6 +87,14 @@ void sme_get_ft_pre_auth_response(mac_handle_t mac_handle, uint32_t sessionId,
 void sme_get_rici_es(mac_handle_t mac_handle, uint32_t sessionId,
 		     uint8_t *ric_ies,
 		     uint32_t ric_ies_ip_len, uint32_t *ric_ies_length);
+/**
+ * sme_check_ft_status() - Check for key wait status in FT mode
+ * @mac_handle: MAC handle
+ * @session_id: vdev identifier
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_check_ft_status(mac_handle_t mac_handle, uint32_t session_id);
 void sme_preauth_reassoc_intvl_timer_callback(void *context);
 void sme_set_ft_pre_auth_state(mac_handle_t mac_handle, uint32_t sessionId,
 			       bool state);

+ 57 - 0
core/sme/src/common/sme_api.c

@@ -6242,6 +6242,63 @@ QDF_STATUS sme_config_fast_roaming(mac_handle_t mac_handle, uint8_t session_id,
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef FEATURE_WLAN_ESE
+int sme_add_key_krk(mac_handle_t mac_handle, uint8_t session_id,
+		    const uint8_t *key, const int key_len)
+{
+	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
+	struct csr_roam_session *session;
+
+	if (key_len < SIR_KRK_KEY_LEN) {
+		sme_warn("Invalid KRK keylength [= %d]", key_len);
+		return -EINVAL;
+	}
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("incorrect session/vdev ID");
+		return -EINVAL;
+	}
+
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	qdf_mem_copy(session->eseCckmInfo.krk, key, SIR_KRK_KEY_LEN);
+	session->eseCckmInfo.reassoc_req_num = 1;
+	session->eseCckmInfo.krk_plumbed = true;
+
+	return 0;
+}
+
+int sme_add_key_btk(mac_handle_t mac_handle, uint8_t session_id,
+		    const uint8_t *key, const int key_len)
+{
+	struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
+	struct csr_roam_session *session;
+
+	if (key_len < SIR_BTK_KEY_LEN) {
+		sme_warn("Invalid BTK keylength [= %d]", key_len);
+		return -EINVAL;
+	}
+
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
+		sme_err("incorrect session/vdev ID");
+		return -EINVAL;
+	}
+
+	session = CSR_GET_SESSION(mac_ctx, session_id);
+
+	qdf_mem_copy(session->eseCckmInfo.btk, key, SIR_BTK_KEY_LEN);
+	/*
+	 * KRK and BTK are updated by upper layer back to back. Send
+	 * updated KRK and BTK together to FW here.
+	 */
+	csr_roam_offload_scan(mac_ctx, session_id,
+			      ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+			      REASON_ROAM_PSK_PMK_CHANGED);
+
+	return 0;
+}
+#endif
+
 /**
  * sme_stop_roaming() - Stop roaming for a given sessionId
  *  This is a synchronous call

+ 41 - 1
core/sme/src/common/sme_ft_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -307,6 +307,46 @@ void sme_set_ftptk_state(mac_handle_t mac_handle, uint32_t sessionId,
 	pSession->ftSmeContext.setFTPTKState = state;
 }
 
+QDF_STATUS sme_check_ft_status(mac_handle_t mac_handle, uint32_t session_id)
+{
+	struct mac_context *mac = MAC_CONTEXT(mac_handle);
+	struct csr_roam_session *session = CSR_GET_SESSION(mac, session_id);
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (!session) {
+		sme_err("pSession is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (!(QDF_IS_STATUS_SUCCESS(status)))
+		return QDF_STATUS_E_FAILURE;
+
+	sme_debug("FT update key is received in state %d",
+		  session->ftSmeContext.FTState);
+
+	/* Global Station FT State */
+	switch (session->ftSmeContext.FTState) {
+	case eFT_SET_KEY_WAIT:
+		if (sme_get_ft_pre_auth_state(mac_handle, session_id) == true) {
+			sme_set_ft_pre_auth_state(mac_handle, session_id,
+						  false);
+			session->ftSmeContext.FTState = eFT_START_READY;
+			sme_debug("state changed to %d status %d",
+				  session->ftSmeContext.FTState, status);
+			sme_release_global_lock(&mac->sme);
+			return QDF_STATUS_SUCCESS;
+		}
+	default:
+		sme_debug("Unhandled state:%d", session->ftSmeContext.FTState);
+		status = QDF_STATUS_E_FAILURE;
+		break;
+	}
+	sme_release_global_lock(&mac->sme);
+
+	return status;
+}
+
 QDF_STATUS sme_ft_update_key(mac_handle_t mac_handle, uint32_t sessionId,
 			     tCsrRoamSetKey *pFTKeyInfo)
 {

+ 98 - 21
core/sme/src/csr/csr_api_roam.c

@@ -60,6 +60,8 @@
 #include "cfg_mlme.h"
 #include "cfg_ucfg_api.h"
 #include "wlan_mlme_api.h"
+#include "wlan_mlme_public_struct.h"
+#include <wlan_crypto_global_api.h>
 
 #define MAX_PWR_FCC_CHAN_12 8
 #define MAX_PWR_FCC_CHAN_13 2
@@ -6550,7 +6552,7 @@ static void csr_roam_process_start_bss_success(struct mac_context *mac_ctx,
 			 */
 			if (!CSR_IS_IBSS(session->pCurRoamProfile)) {
 				/* NO keys. these key parameters don't matter */
-				csr_roam_issue_set_context_req(mac_ctx,
+				csr_roam_issue_set_context_req_helper(mac_ctx,
 					session_id,
 					profile->negotiatedMCEncryptionType,
 					bss_desc, &bcast_mac, false,
@@ -6735,7 +6737,7 @@ static void csr_process_fils_join_rsp(struct mac_context *mac_ctx,
 		goto process_fils_join_rsp_fail;
 	}
 
-	status = csr_roam_issue_set_context_req(mac_ctx, session_id,
+	status = csr_roam_issue_set_context_req_helper(mac_ctx, session_id,
 					profile->negotiatedMCEncryptionType,
 					bss_desc, &bcast_mac, true, false,
 					eSIR_RX_ONLY, 2,
@@ -6746,7 +6748,7 @@ static void csr_process_fils_join_rsp(struct mac_context *mac_ctx,
 		goto process_fils_join_rsp_fail;
 	}
 
-	status = csr_roam_issue_set_context_req(mac_ctx, session_id,
+	status = csr_roam_issue_set_context_req_helper(mac_ctx, session_id,
 					profile->negotiatedUCEncryptionType,
 					bss_desc, &(bss_desc->bssId), true,
 					true, eSIR_TX_RX, 0,
@@ -6925,7 +6927,7 @@ static void csr_roam_process_join_res(struct mac_context *mac_ctx,
 			 * the Unicast STA context
 			 */
 			if (!QDF_IS_STATUS_SUCCESS(
-				csr_roam_issue_set_context_req(mac_ctx,
+				csr_roam_issue_set_context_req_helper(mac_ctx,
 					session_id,
 					profile->negotiatedUCEncryptionType,
 					bss_desc, &(bss_desc->bssId),
@@ -6941,7 +6943,8 @@ static void csr_roam_process_join_res(struct mac_context *mac_ctx,
 			 * to establish the Broadcast STA context
 			 * NO keys. these key parameters don't matter
 			 */
-			csr_roam_issue_set_context_req(mac_ctx, session_id,
+			csr_roam_issue_set_context_req_helper(mac_ctx,
+				session_id,
 				profile->negotiatedMCEncryptionType,
 				bss_desc, &bcast_mac, false, false,
 				eSIR_TX_RX, 0, 0, NULL, 0);
@@ -9732,15 +9735,69 @@ void csr_roam_joined_state_msg_processor(struct mac_context *mac, void *pMsgBuf)
 	}
 }
 
-QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac,
-					  uint32_t sessionId,
-					  eCsrEncryptionType EncryptType,
-					  tSirBssDescription *pBssDescription,
-					  tSirMacAddr *bssId, bool addKey,
-					  bool fUnicast,
-					  tAniKeyDirection aniKeyDirection,
-					  uint8_t keyId, uint16_t keyLength,
-					  uint8_t *pKey, uint8_t paeRole)
+#ifdef CRYPTO_SET_KEY_CONVERGED
+static QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac_ctx,
+						 uint32_t session_id,
+						 bool add_key, bool unicast,
+						 uint8_t key_idx)
+{
+	enum wlan_crypto_cipher_type cipher;
+	struct wlan_crypto_key *crypto_key;
+	uint8_t wep_key_idx = 0;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, session_id,
+						    WLAN_LEGACY_MAC_ID);
+	if (!vdev) {
+		sme_err("VDEV object not found for session_id %d", session_id);
+		return QDF_STATUS_E_INVAL;
+	}
+	cipher = wlan_crypto_get_cipher(vdev, unicast, key_idx);
+	if (cipher == WLAN_CRYPTO_CIPHER_WEP_40 ||
+	    cipher == WLAN_CRYPTO_CIPHER_WEP_104) {
+		wep_key_idx = wlan_crypto_get_default_key_idx(vdev, !unicast);
+		crypto_key = wlan_crypto_get_key(vdev, wep_key_idx);
+	} else {
+		/* TODO: Add code for storing FILS keys in case of add_key */
+		crypto_key = wlan_crypto_get_key(vdev, key_idx);
+	}
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
+
+	sme_debug("session:%d, cipher:%d, ucast:%d, idx:%d, wep:%d, add:%d",
+		  session_id, cipher, unicast, key_idx, wep_key_idx, add_key);
+	if (cipher != WLAN_CRYPTO_CIPHER_NONE ||
+	    cipher != WLAN_CRYPTO_CIPHER_WEP_40 ||
+	    cipher != WLAN_CRYPTO_CIPHER_WEP_104 ||
+	    !add_key)
+		return QDF_STATUS_E_INVAL;
+
+	return ucfg_crypto_set_key_req(vdev, crypto_key, unicast);
+}
+
+QDF_STATUS csr_roam_issue_set_context_req_helper(
+					struct mac_context *mac_ctx,
+					uint32_t session_id,
+					eCsrEncryptionType encr_type,
+					tSirBssDescription *bss_descr,
+					tSirMacAddr *bssid, bool addkey,
+					bool unicast,
+					tAniKeyDirection key_direction,
+					uint8_t key_id, uint16_t key_length,
+					uint8_t *key, uint8_t pae_role)
+{
+	return csr_roam_issue_set_context_req(mac_ctx, session_id, addkey,
+					      unicast, key_id);
+}
+
+#else
+static QDF_STATUS
+csr_roam_issue_set_context_req(struct mac_context *mac, uint32_t sessionId,
+			       eCsrEncryptionType EncryptType,
+			       tSirBssDescription *pBssDescription,
+			       tSirMacAddr *bssId, bool addKey, bool fUnicast,
+			       tAniKeyDirection aniKeyDirection, uint8_t keyId,
+			       uint16_t keyLength, uint8_t *pKey,
+			       uint8_t paeRole)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	tAniEdType edType;
@@ -9778,6 +9835,24 @@ QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac,
 	return status;
 }
 
+QDF_STATUS csr_roam_issue_set_context_req_helper(
+					struct mac_context *mac_ctx,
+					uint32_t session_id,
+					eCsrEncryptionType encr_type,
+					tSirBssDescription *bss_descr,
+					tSirMacAddr *bssid, bool addkey,
+					bool unicast,
+					tAniKeyDirection key_direction,
+					uint8_t key_id, uint16_t key_length,
+					uint8_t *key, uint8_t pae_role)
+{
+	return csr_roam_issue_set_context_req(mac_ctx, session_id, encr_type,
+					      bss_descr, bssid, addkey,
+					      unicast, key_direction, key_id,
+					      key_length, key, pae_role);
+}
+#endif
+
 /**
  * csr_update_key_cmd() - update key info in set key command
  * @mac_ctx:         mac global context
@@ -10594,11 +10669,13 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 		    CSR_IS_ENC_TYPE_STATIC(
 			session->pCurRoamProfile->negotiatedUCEncryptionType)) {
 			/* NO keys... these key parameters don't matter. */
-			csr_roam_issue_set_context_req(mac_ctx, sessionId,
-			session->pCurRoamProfile->negotiatedUCEncryptionType,
-			session->pConnectBssDesc,
-			&(roam_info_ptr->peerMac.bytes),
-			false, true, eSIR_TX_RX, 0, 0, NULL, 0);
+			csr_roam_issue_set_context_req_helper(mac_ctx,
+				sessionId,
+				session->pCurRoamProfile->
+				negotiatedUCEncryptionType,
+				session->pConnectBssDesc,
+				&roam_info_ptr->peerMac.bytes,
+				false, true, eSIR_TX_RX, 0, 0, NULL, 0);
 			roam_info_ptr->fAuthRequired = false;
 		} else {
 			roam_info_ptr->fAuthRequired = true;
@@ -11236,7 +11313,7 @@ csr_roam_chk_lnk_wm_status_change_ntf(struct mac_context *mac_ctx,
 
 		if ((eCSR_ENCRYPT_TYPE_NONE ==
 		     session->connectedProfile.EncryptionType)) {
-			csr_roam_issue_set_context_req(mac_ctx,
+			csr_roam_issue_set_context_req_helper(mac_ctx,
 			    sessionId,
 			    session->connectedProfile.EncryptionType,
 			    session->pConnectBssDesc,
@@ -11385,7 +11462,7 @@ csr_roam_chk_lnk_ibss_new_peer_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_
 	if ((eCSR_ENCRYPT_TYPE_NONE ==
 		session->connectedProfile.EncryptionType)) {
 		/* NO keys. these key parameters don't matter */
-		csr_roam_issue_set_context_req(mac_ctx, sessionId,
+		csr_roam_issue_set_context_req_helper(mac_ctx, sessionId,
 			session->connectedProfile.EncryptionType,
 			session->pConnectBssDesc,
 			&pIbssPeerInd->peer_addr.bytes,

+ 11 - 9
core/sme/src/csr/csr_inside_api.h

@@ -246,15 +246,17 @@ QDF_STATUS csr_roam_issue_reassoc(struct mac_context *mac, uint32_t sessionId,
 				  bool fImediate);
 void csr_roam_complete(struct mac_context *mac, enum csr_roamcomplete_result Result,
 		       void *Context, uint8_t session_id);
-QDF_STATUS csr_roam_issue_set_context_req(struct mac_context *mac,
-					uint32_t sessionId,
-					  eCsrEncryptionType EncryptType,
-					  tSirBssDescription *pBssDescription,
-					  tSirMacAddr *bssId, bool addKey,
-					  bool fUnicast,
-					  tAniKeyDirection aniKeyDirection,
-					  uint8_t keyId, uint16_t keyLength,
-					  uint8_t *pKey, uint8_t paeRole);
+QDF_STATUS
+csr_roam_issue_set_context_req_helper(struct mac_context *mac,
+				      uint32_t session_id,
+				      eCsrEncryptionType encr_type,
+				      tSirBssDescription *bss_descr,
+				      tSirMacAddr *bssid, bool addkey,
+				      bool unicast,
+				      tAniKeyDirection key_direction,
+				      uint8_t key_id, uint16_t key_length,
+				      uint8_t *key, uint8_t pae_role);
+
 QDF_STATUS csr_roam_process_disassoc_deauth(struct mac_context *mac,
 						tSmeCmd *pCommand,
 					    bool fDisassoc, bool fMICFailure);

+ 24 - 0
core/wma/inc/wma.h

@@ -2579,4 +2579,28 @@ uint8_t wma_rx_invalid_peer_ind(uint8_t vdev_id, void *wh);
  */
 struct wlan_objmgr_psoc *wma_get_psoc_from_scn_handle(void *scn_handle);
 
+#ifdef CRYPTO_SET_KEY_CONVERGED
+/**
+ * wma_update_set_key() - Update WMA layer for set key
+ * @session_id: vdev session identifier
+ * @pairwise: denotes if it is pairwise or group key
+ * @key_index: Key Index
+ * @cipher_type: cipher type being used for the encryption/decryption
+ *
+ * Return: None
+ */
+void wma_update_set_key(uint8_t session_id, bool pairwise,
+			uint8_t key_index,
+			enum wlan_crypto_cipher_type cipher_type);
+#endif
+
+/**
+ * wma_get_igtk() - Get the IGTK that was stored in the session earlier
+ * @iface: Interface for which the key is being requested
+ * @key_len: key length
+ *
+ * Return: Pointer to the key
+ */
+uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len);
+
 #endif

+ 4 - 0
core/wma/inc/wma_if.h

@@ -349,6 +349,7 @@ typedef struct {
  * @status: status
  * @sessionId: session id
  * @sendRsp: send response
+ * @macaddr: MAC address of the peer
  *
  * This is used by PE to configure the key information on a given station.
  * When the secType is WEP40 or WEP104, the defWEPIdx is used to locate
@@ -366,6 +367,7 @@ typedef struct {
 	QDF_STATUS status;
 	uint8_t sessionId;
 	uint8_t sendRsp;
+	struct qdf_mac_addr macaddr;
 } tSetStaKeyParams, *tpSetStaKeyParams;
 
 /**
@@ -660,6 +662,7 @@ typedef struct sSendProbeRespParams {
  * @smesessionId: sme session id
  * @status: return status of command
  * @sessionId: PE session id
+ * @macaddr: MAC address of the peer
  */
 typedef struct {
 	uint8_t bssIdx;
@@ -670,6 +673,7 @@ typedef struct {
 	uint8_t smesessionId;
 	QDF_STATUS status;
 	uint8_t sessionId;
+	struct qdf_mac_addr macaddr;
 } tSetBssKeyParams, *tpSetBssKeyParams;
 
 /**

+ 31 - 2
core/wma/inc/wma_internal.h

@@ -735,14 +735,43 @@ void wma_update_rts_params(tp_wma_handle wma, uint32_t value);
 
 void wma_update_frag_params(tp_wma_handle wma, uint32_t value);
 
-void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info);
-
 void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma,
 				      uint8_t vdev_id,
 				      int8_t peer_num_delta);
 
+#ifdef CRYPTO_SET_KEY_CONVERGED
+static inline void wma_set_stakey(tp_wma_handle wma_handle,
+				  tpSetStaKeyParams key_info)
+{
+}
+
+static inline void wma_set_bsskey(tp_wma_handle wma_handle,
+				  tpSetBssKeyParams key_info)
+{
+}
+#else
+/**
+ * wma_set_stakey() - set encryption key
+ * @wma_handle: wma handle
+ * @key_info: station key info
+ *
+ * This function sets encryption key for WEP/WPA/WPA2
+ * encryption mode in firmware and send response to upper layer.
+ *
+ * Return: none
+ */
 void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info);
 
+/**
+ * wma_set_bsskey() - set encryption key to fw.
+ * @wma_handle: wma handle
+ * @key_info: key info
+ *
+ * Return: none
+ */
+void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info);
+#endif
+
 QDF_STATUS wma_process_update_edca_param_req(WMA_HANDLE handle,
 						    tEdcaParams *edca_params);
 

+ 34 - 3
core/wma/src/wma_data.c

@@ -78,6 +78,7 @@
 #include <wlan_pmo_ucfg_api.h>
 #include "wlan_lmac_if_api.h"
 #include <wlan_cp_stats_mc_ucfg_api.h>
+#include <wlan_crypto_global_api.h>
 
 struct wma_search_rate {
 	int32_t rate;
@@ -2367,6 +2368,29 @@ static void wma_update_tx_send_params(struct tx_send_params *tx_param,
 		     tx_param->preamble_type);
 }
 
+#ifdef CRYPTO_SET_KEY_CONVERGED
+uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len)
+{
+	struct wlan_crypto_key *crypto_key;
+
+	crypto_key = wlan_crypto_get_key(iface->vdev, WMA_IGTK_KEY_INDEX_4);
+	if (!crypto_key) {
+		wma_err("IGTK not found");
+		*key_len = 0;
+		return NULL;
+	}
+	*key_len = crypto_key->keylen;
+
+	return &crypto_key->keyval[0];
+}
+#else
+uint8_t *wma_get_igtk(struct wma_txrx_node *iface, uint16_t *key_len)
+{
+	*key_len = iface->key.key_length;
+	return iface->key.key;
+}
+#endif
+
 QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen,
 			 eFrameType frmType, eFrameTxDir txDir, uint8_t tid,
 			 wma_tx_dwnld_comp_callback tx_frm_download_comp_cb,
@@ -2403,6 +2427,8 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen,
 	void *mac_addr;
 	bool is_5g = false;
 	uint8_t pdev_id;
+	uint8_t *igtk;
+	uint16_t key_len;
 
 	if (NULL == wma_handle) {
 		WMA_LOGE("wma_handle is NULL");
@@ -2530,13 +2556,18 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen,
 			qdf_mem_copy(pFrame, wh, sizeof(*wh));
 			qdf_mem_copy(pFrame + sizeof(*wh),
 				     pData + sizeof(*wh), frmLen - sizeof(*wh));
-			if (!cds_attach_mmie(iface->key.key,
+			igtk = wma_get_igtk(iface, &key_len);
+			if (!igtk) {
+				wma_alert("IGTK not present");
+				cds_packet_free((void *)tx_frame);
+				goto error;
+			}
+			if (!cds_attach_mmie(igtk,
 					     iface->key.key_id[0].ipn,
 					     WMA_IGTK_KEY_INDEX_4,
 					     pFrame,
 					     pFrame + newFrmLen, newFrmLen)) {
-				WMA_LOGP("%s: Failed to attach MMIE at the end of frame",
-					 __func__);
+				wma_alert("Failed to attach MMIE");
 				/* Free the original packet memory */
 				cds_packet_free((void *)tx_frame);
 				goto error;

+ 95 - 1
core/wma/src/wma_features.c

@@ -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
  * any purpose with or without fee is hereby granted, provided that the
@@ -68,6 +68,7 @@
 #ifdef WLAN_FEATURE_NAN
 #include "target_if_nan.h"
 #endif
+#include <wlan_crypto_global_api.h>
 
 #ifndef ARRAY_LENGTH
 #define ARRAY_LENGTH(a)         (sizeof(a) / sizeof((a)[0]))
@@ -5631,6 +5632,99 @@ int wma_vdev_obss_detection_info_handler(void *handle, uint8_t *event,
 	return 0;
 }
 
+#ifdef CRYPTO_SET_KEY_CONVERGED
+static void wma_send_set_key_rsp(uint8_t session_id, bool pairwise,
+				 uint8_t key_index)
+{
+	tSetStaKeyParams *key_info_uc;
+	tSetBssKeyParams *key_info_mc;
+	struct wlan_crypto_key *crypto_key;
+	struct wlan_objmgr_vdev *vdev;
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+
+	if (!wma) {
+		wma_err("WMA context does not exist");
+		return;
+	}
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
+						    session_id,
+						    WLAN_LEGACY_WMA_ID);
+	if (!vdev) {
+		wma_err("VDEV object not found");
+		return;
+	}
+	crypto_key = wlan_crypto_get_key(vdev, key_index);
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+	if (!crypto_key) {
+		wma_err("crypto_key not found");
+		return;
+	}
+
+	if (pairwise) {
+		key_info_uc = qdf_mem_malloc(sizeof(*key_info_uc));
+		if (!key_info_uc)
+			return;
+		key_info_uc->sessionId = session_id;
+		key_info_uc->smesessionId = session_id;
+		key_info_uc->status = QDF_STATUS_SUCCESS;
+		key_info_uc->key[0].keyLength = crypto_key->keylen;
+		qdf_mem_copy(&key_info_uc->macaddr, &crypto_key->macaddr,
+			     QDF_MAC_ADDR_SIZE);
+		wma_send_msg_high_priority(wma, WMA_SET_STAKEY_RSP,
+					   key_info_uc, 0);
+	} else {
+		key_info_mc = qdf_mem_malloc(sizeof(*key_info_mc));
+		if (!key_info_mc)
+			return;
+		key_info_mc->sessionId = session_id;
+		key_info_mc->smesessionId = session_id;
+		key_info_mc->status = QDF_STATUS_SUCCESS;
+		key_info_mc->key[0].keyLength = crypto_key->keylen;
+		qdf_mem_copy(&key_info_mc->macaddr, &crypto_key->macaddr,
+			     QDF_MAC_ADDR_SIZE);
+		wma_send_msg_high_priority(wma, WMA_SET_BSSKEY_RSP,
+					   key_info_mc, 0);
+	}
+}
+
+static void wma_reset_ipn(struct wma_txrx_node *iface, uint8_t key_index)
+{
+	if (key_index == WMA_IGTK_KEY_INDEX_4 ||
+	    key_index == WMA_IGTK_KEY_INDEX_5)
+		qdf_mem_zero(iface->key.key_id[key_index -
+				WMA_IGTK_KEY_INDEX_4].ipn,
+				CMAC_IPN_LEN);
+}
+
+void wma_update_set_key(uint8_t session_id, bool pairwise,
+			uint8_t key_index,
+			enum wlan_crypto_cipher_type cipher_type)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_txrx_node *iface;
+
+	if (!wma) {
+		wma_err("Invalid WMA context");
+		return;
+	}
+	iface = &wma->interfaces[session_id];
+	wma_reset_ipn(iface, key_index);
+	if (iface && pairwise)
+		iface->ucast_key_cipher =
+			wlan_crypto_cipher_to_wmi_cipher(cipher_type);
+	if (!pairwise && iface) {
+		/* Its GTK release the wake lock */
+		wma_debug("Release set key wake lock");
+		wma_release_wakelock(&iface->vdev_set_key_wakelock);
+	}
+	if (iface)
+		iface->is_waiting_for_key = false;
+
+	wma_send_set_key_rsp(session_id, pairwise, key_index);
+}
+#endif /* CRYPTO_SET_KEY_CONVERGED */
+
 int wma_vdev_bss_color_collision_info_handler(void *handle,
 					      uint8_t *event,
 					      uint32_t len)

+ 142 - 133
core/wma/src/wma_mgmt.c

@@ -77,6 +77,8 @@
 #include "cfg_mlme_sta.h"
 #include "wlan_mlme_api.h"
 #include "wmi_unified_bcn_api.h"
+#include <wlan_crypto_global_api.h>
+
 /**
  * wma_send_bcn_buf_ll() - prepare and send beacon buffer to fw for LL
  * @wma: wma handle
@@ -1729,12 +1731,14 @@ void wma_update_frag_params(tp_wma_handle wma, uint32_t value)
 	}
 }
 
+#ifndef CRYPTO_SET_KEY_CONVERGED
 /**
  * wma_read_cfg_wepkey() - fill key_info for WEP key
  * @wma_handle: wma handle
  * @key_info: key_info ptr
  * @def_key_idx: default key index
  * @num_keys: number of keys
+ * @vdev: vdev pointer
  *
  * This function reads WEP keys from cfg and fills
  * up key_info.
@@ -1743,7 +1747,8 @@ void wma_update_frag_params(tp_wma_handle wma, uint32_t value)
  */
 static void wma_read_cfg_wepkey(tp_wma_handle wma_handle,
 				tSirKeys *key_info, uint32_t *def_key_idx,
-				uint8_t *num_keys)
+				uint8_t *num_keys,
+				struct wlan_objmgr_vdev *vdev)
 {
 	QDF_STATUS status;
 	qdf_size_t val = SIR_MAC_KEY_LENGTH;
@@ -1756,7 +1761,7 @@ static void wma_read_cfg_wepkey(tp_wma_handle wma_handle,
 	*def_key_idx = mac_ctx->mlme_cfg->wep_params.wep_default_key_id;
 
 	for (i = 0, j = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++) {
-		status = mlme_get_wep_key(&mac_ctx->mlme_cfg->wep_params,
+		status = mlme_get_wep_key(vdev, &mac_ctx->mlme_cfg->wep_params,
 					  (MLME_WEP_DEFAULT_KEY_1 +
 					  i), key_info[j].key, &val);
 		if (QDF_IS_STATUS_ERROR(status)) {
@@ -1769,6 +1774,7 @@ static void wma_read_cfg_wepkey(tp_wma_handle wma_handle,
 	}
 	*num_keys = j;
 }
+#endif
 
 #ifdef FEATURE_WLAN_WAPI
 #define WPI_IV_LEN 16
@@ -1851,6 +1857,7 @@ static inline void wma_fill_in_wapi_key_params(
 #endif
 #endif
 
+#ifndef CRYPTO_SET_KEY_CONVERGED
 /**
  * wma_skip_bip_key_set() - skip the BIP key step or not
  * @wma_handle: wma handle
@@ -1935,12 +1942,7 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle,
 #endif
 	params.key_txmic_len = 0;
 	params.key_rxmic_len = 0;
-	params.key_rsc_counter = qdf_mem_malloc(sizeof(uint64_t));
-	if (!params.key_rsc_counter) {
-		WMA_LOGE(FL("can't allocate memory for key_rsc_counter"));
-		return QDF_STATUS_E_NOMEM;
-	}
-	qdf_mem_copy(params.key_rsc_counter,
+	qdf_mem_copy(&params.key_rsc_ctr,
 		     &key_params->key_rsc[0], sizeof(uint64_t));
 	params.key_flags = 0;
 	if (key_params->unicast)
@@ -2063,7 +2065,7 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle,
 	WMA_LOGD("unicast %d peer_mac %pM def_key_idx %d",
 		 key_params->unicast, key_params->peer_mac,
 		 key_params->def_key_idx);
-	WMA_LOGD("keyrsc param %llu", *(params.key_rsc_counter));
+	WMA_LOGD("keyrsc param %llu", params.key_rsc_ctr);
 
 	/*
 	 * To prevent from any replay-attack, PN number provided by
@@ -2112,17 +2114,113 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle,
 		iface->is_waiting_for_key = false;
 
 end:
-	qdf_mem_free(params.key_rsc_counter);
 	return status;
 }
+#endif
 
+#ifdef QCA_IBSS_SUPPORT
 /**
- * wma_set_bsskey() - set encryption key to fw.
- * @wma_handle: wma handle
- * @key_info: key info
+ * wma_calc_ibss_heart_beat_timer() - calculate IBSS heart beat timer
+ * @peer_num: number of peers
+ *
+ * Return: heart beat timer value
+ */
+static uint16_t wma_calc_ibss_heart_beat_timer(int16_t peer_num)
+{
+	/* heart beat timer value look-up table */
+	/* entry index : (the number of currently connected peers) - 1
+	 * entry value : the heart time threshold value in seconds for
+	 * detecting ibss peer departure
+	 */
+	static const uint16_t heart_beat_timer[MAX_PEERS] = {
+		4, 4, 4, 4, 4, 4, 4, 4,
+		8, 8, 8, 8, 8, 8, 8, 8,
+		12, 12, 12, 12, 12, 12, 12, 12,
+		16, 16, 16, 16, 16, 16, 16, 16
+	};
+
+	if (peer_num < 1 || peer_num > MAX_PEERS)
+		return 0;
+
+	return heart_beat_timer[peer_num - 1];
+}
+
+/**
+ * wma_adjust_ibss_heart_beat_timer() - set ibss heart beat timer in fw.
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ * @peer_num_delta: peer number delta value
  *
  * Return: none
  */
+void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma,
+				      uint8_t vdev_id,
+				      int8_t peer_num_delta)
+{
+	struct cdp_vdev *vdev;
+	int16_t new_peer_num;
+	uint16_t new_timer_value_sec;
+	uint32_t new_timer_value_ms;
+	QDF_STATUS status;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	if (peer_num_delta != 1 && peer_num_delta != -1) {
+		WMA_LOGE("Invalid peer_num_delta value %d", peer_num_delta);
+		return;
+	}
+
+	vdev = wma_find_vdev_by_id(wma, vdev_id);
+	if (!vdev) {
+		WMA_LOGE("vdev not found : vdev_id %d", vdev_id);
+		return;
+	}
+
+	/* adjust peer numbers */
+	new_peer_num = cdp_peer_update_ibss_add_peer_num_of_vdev(soc, vdev,
+								 peer_num_delta
+								 );
+	if (OL_TXRX_INVALID_NUM_PEERS == new_peer_num) {
+		WMA_LOGE("new peer num %d out of valid boundary", new_peer_num);
+		return;
+	}
+
+	/* reset timer value if all peers departed */
+	if (new_peer_num == 0) {
+		cdp_set_ibss_vdev_heart_beat_timer(soc, vdev, 0);
+		return;
+	}
+
+	/* calculate new timer value */
+	new_timer_value_sec = wma_calc_ibss_heart_beat_timer(new_peer_num);
+	if (new_timer_value_sec == 0) {
+		WMA_LOGE("timer value %d is invalid for peer number %d",
+			 new_timer_value_sec, new_peer_num);
+		return;
+	}
+	if (new_timer_value_sec ==
+	    cdp_set_ibss_vdev_heart_beat_timer(soc, vdev,
+					       new_timer_value_sec)) {
+		WMA_LOGD("timer value %d stays same, no need to notify target",
+			 new_timer_value_sec);
+		return;
+	}
+
+	new_timer_value_ms = ((uint32_t)new_timer_value_sec) * 1000;
+
+	status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
+				    WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS,
+				    new_timer_value_ms);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("Failed to set IBSS link monitoring timer value");
+		return;
+	}
+
+	WMA_LOGD("Set IBSS link monitor timer: peer_num = %d timer_value = %d",
+		 new_peer_num, new_timer_value_ms);
+}
+#endif /* QCA_IBSS_SUPPORT */
+
+#ifndef CRYPTO_SET_KEY_CONVERGED
 void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info)
 {
 	struct wma_set_key_params key_params;
@@ -2133,6 +2231,7 @@ void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info)
 	struct cdp_vdev *txrx_vdev;
 	uint8_t *mac_addr;
 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct wlan_objmgr_vdev *vdev;
 
 	WMA_LOGD("BSS key setup");
 	txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId);
@@ -2184,8 +2283,13 @@ void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info)
 	if (key_info->numKeys == 0 &&
 	    (key_info->encType == eSIR_ED_WEP40 ||
 	     key_info->encType == eSIR_ED_WEP104)) {
+		vdev =
+		wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc,
+						     key_info->smesessionId,
+						     WLAN_LEGACY_WMA_ID);
 		wma_read_cfg_wepkey(wma_handle, key_info->key,
-				    &def_key_idx, &key_info->numKeys);
+				    &def_key_idx, &key_info->numKeys, vdev);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
 	} else if ((key_info->encType == eSIR_ED_WEP40) ||
 		   (key_info->encType == eSIR_ED_WEP104)) {
 		struct wma_txrx_node *intf =
@@ -2246,108 +2350,6 @@ out:
 				   (void *)key_info, 0);
 }
 
-#ifdef QCA_IBSS_SUPPORT
-/**
- * wma_calc_ibss_heart_beat_timer() - calculate IBSS heart beat timer
- * @peer_num: number of peers
- *
- * Return: heart beat timer value
- */
-static uint16_t wma_calc_ibss_heart_beat_timer(int16_t peer_num)
-{
-	/* heart beat timer value look-up table */
-	/* entry index : (the number of currently connected peers) - 1
-	 * entry value : the heart time threshold value in seconds for
-	 * detecting ibss peer departure
-	 */
-	static const uint16_t heart_beat_timer[MAX_PEERS] = {
-		4, 4, 4, 4, 4, 4, 4, 4,
-		8, 8, 8, 8, 8, 8, 8, 8,
-		12, 12, 12, 12, 12, 12, 12, 12,
-		16, 16, 16, 16, 16, 16, 16, 16
-	};
-
-	if (peer_num < 1 || peer_num > MAX_PEERS)
-		return 0;
-
-	return heart_beat_timer[peer_num - 1];
-
-}
-
-/**
- * wma_adjust_ibss_heart_beat_timer() - set ibss heart beat timer in fw.
- * @wma: wma handle
- * @vdev_id: vdev id
- * @peer_num_delta: peer number delta value
- *
- * Return: none
- */
-void wma_adjust_ibss_heart_beat_timer(tp_wma_handle wma,
-				      uint8_t vdev_id,
-				      int8_t peer_num_delta)
-{
-	struct cdp_vdev *vdev;
-	int16_t new_peer_num;
-	uint16_t new_timer_value_sec;
-	uint32_t new_timer_value_ms;
-	QDF_STATUS status;
-	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
-
-	if (peer_num_delta != 1 && peer_num_delta != -1) {
-		WMA_LOGE("Invalid peer_num_delta value %d", peer_num_delta);
-		return;
-	}
-
-	vdev = wma_find_vdev_by_id(wma, vdev_id);
-	if (!vdev) {
-		WMA_LOGE("vdev not found : vdev_id %d", vdev_id);
-		return;
-	}
-
-	/* adjust peer numbers */
-	new_peer_num = cdp_peer_update_ibss_add_peer_num_of_vdev(soc,
-					vdev, peer_num_delta);
-	if (OL_TXRX_INVALID_NUM_PEERS == new_peer_num) {
-		WMA_LOGE("new peer num %d out of valid boundary", new_peer_num);
-		return;
-	}
-
-	/* reset timer value if all peers departed */
-	if (new_peer_num == 0) {
-		cdp_set_ibss_vdev_heart_beat_timer(soc, vdev, 0);
-		return;
-	}
-
-	/* calculate new timer value */
-	new_timer_value_sec = wma_calc_ibss_heart_beat_timer(new_peer_num);
-	if (new_timer_value_sec == 0) {
-		WMA_LOGE("timer value %d is invalid for peer number %d",
-			 new_timer_value_sec, new_peer_num);
-		return;
-	}
-	if (new_timer_value_sec ==
-	    cdp_set_ibss_vdev_heart_beat_timer(soc,
-						vdev, new_timer_value_sec)) {
-		WMA_LOGD("timer value %d stays same, no need to notify target",
-			 new_timer_value_sec);
-		return;
-	}
-
-	new_timer_value_ms = ((uint32_t) new_timer_value_sec) * 1000;
-
-	status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
-					 WMI_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS,
-					 new_timer_value_ms);
-	if (QDF_IS_STATUS_ERROR(status)) {
-		WMA_LOGE("Failed to set IBSS link monitoring timer value");
-		return;
-	}
-
-	WMA_LOGD("Set IBSS link monitor timer: peer_num = %d timer_value = %d",
-		 new_peer_num, new_timer_value_ms);
-}
-
-#endif /* QCA_IBSS_SUPPORT */
 /**
  * wma_set_ibsskey_helper() - cached IBSS key in wma handle
  * @wma_handle: wma handle
@@ -2367,6 +2369,7 @@ static void wma_set_ibsskey_helper(tp_wma_handle wma_handle,
 	struct cdp_vdev *txrx_vdev;
 	int opmode;
 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct wlan_objmgr_vdev *vdev;
 
 	WMA_LOGD("BSS key setup for peer");
 	txrx_vdev = wma_find_vdev_by_id(wma_handle, key_info->smesessionId);
@@ -2391,8 +2394,13 @@ static void wma_set_ibsskey_helper(tp_wma_handle wma_handle,
 	if (key_info->numKeys == 0 &&
 	    (key_info->encType == eSIR_ED_WEP40 ||
 	     key_info->encType == eSIR_ED_WEP104)) {
+		vdev =
+		wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc,
+						     key_info->smesessionId,
+						     WLAN_LEGACY_WMA_ID);
 		wma_read_cfg_wepkey(wma_handle, key_info->key,
-				    &def_key_idx, &key_info->numKeys);
+				    &def_key_idx, &key_info->numKeys, vdev);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
 	} else if ((key_info->encType == eSIR_ED_WEP40) ||
 		(key_info->encType == eSIR_ED_WEP104)) {
 		struct wma_txrx_node *intf =
@@ -2434,16 +2442,6 @@ static void wma_set_ibsskey_helper(tp_wma_handle wma_handle,
 	}
 }
 
-/**
- * wma_set_stakey() - set encryption key
- * @wma_handle: wma handle
- * @key_info: station key info
- *
- * This function sets encryption key for WEP/WPA/WPA2
- * encryption mode in firmware and send response to upper layer.
- *
- * Return: none
- */
 void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info)
 {
 	int32_t i;
@@ -2456,6 +2454,7 @@ void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info)
 	uint32_t def_key_idx = 0;
 	int opmode;
 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	struct wlan_objmgr_vdev *vdev;
 
 	WMA_LOGD("STA key setup");
 
@@ -2488,8 +2487,13 @@ void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info)
 	    (key_info->encType == eSIR_ED_WEP40 ||
 	     key_info->encType == eSIR_ED_WEP104) &&
 	    opmode != wlan_op_mode_ap) {
+		vdev =
+		wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc,
+						     key_info->smesessionId,
+						     WLAN_LEGACY_WMA_ID);
 		wma_read_cfg_wepkey(wma_handle, key_info->key,
-				    &def_key_idx, &num_keys);
+				    &def_key_idx, &num_keys, vdev);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
 		key_info->defWEPIdx = def_key_idx;
 	} else {
 		num_keys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
@@ -2568,6 +2572,7 @@ out:
 		wma_send_msg_high_priority(wma_handle, WMA_SET_STAKEY_RSP,
 					   (void *)key_info, 0);
 }
+#endif
 
 /**
  * wma_process_update_edca_param_req() - update EDCA params
@@ -3729,6 +3734,8 @@ int wma_process_bip(tp_wma_handle wma_handle,
 	uint16_t mmie_size;
 	uint16_t key_id;
 	uint8_t *efrm;
+	uint8_t *igtk;
+	uint16_t key_len;
 
 	efrm = qdf_nbuf_data(wbuf) + qdf_nbuf_len(wbuf);
 
@@ -3756,6 +3763,7 @@ int wma_process_bip(tp_wma_handle wma_handle,
 
 	WMA_LOGD(FL("key_cipher %d key_id %d"), iface->key.key_cipher, key_id);
 
+	igtk = wma_get_igtk(iface, &key_len);
 	switch (iface->key.key_cipher) {
 	case WMI_CIPHER_AES_CMAC:
 		if (wmi_service_enabled(wma_handle->wmi_handle,
@@ -3767,9 +3775,10 @@ int wma_process_bip(tp_wma_handle wma_handle,
 			 */
 			qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size());
 		} else {
-			if (cds_is_mmie_valid(iface->key.key,
-			   iface->key.key_id[key_id - WMA_IGTK_KEY_INDEX_4].ipn,
-			   (uint8_t *) wh, efrm)) {
+			if (cds_is_mmie_valid(igtk, iface->key.key_id[
+					      key_id -
+					      WMA_IGTK_KEY_INDEX_4].ipn,
+					      (uint8_t *)wh, efrm)) {
 				WMA_LOGD(FL("Protected BC/MC frame MMIE validation successful"));
 				/* Remove MMIE */
 				qdf_nbuf_trim_tail(wbuf, cds_get_mmie_size());
@@ -3791,9 +3800,9 @@ int wma_process_bip(tp_wma_handle wma_handle,
 			WMA_LOGD(FL("Trim GMAC MMIE"));
 			qdf_nbuf_trim_tail(wbuf, cds_get_gmac_mmie_size());
 		} else {
-			if (cds_is_gmac_mmie_valid(iface->key.key,
+			if (cds_is_gmac_mmie_valid(igtk,
 			   iface->key.key_id[key_id - WMA_IGTK_KEY_INDEX_4].ipn,
-			   (uint8_t *) wh, efrm, iface->key.key_length)) {
+			   (uint8_t *) wh, efrm, key_len)) {
 				WMA_LOGD(FL("Protected BC/MC frame GMAC MMIE validation successful"));
 				/* Remove MMIE */
 				qdf_nbuf_trim_tail(wbuf,