qcacmn: Fix WEP functionality in converged set key

Fix WEP security mode issues in converged set key.

Change-Id: Idd4071c8aef141cb45db9006c5773a94b352879a
CRs-Fixed: 2400864
diff --git a/os_if/linux/crypto/src/wlan_cfg80211_crypto.c b/os_if/linux/crypto/src/wlan_cfg80211_crypto.c
index 697258c..c059cf1 100644
--- a/os_if/linux/crypto/src/wlan_cfg80211_crypto.c
+++ b/os_if/linux/crypto/src/wlan_cfg80211_crypto.c
@@ -38,10 +38,23 @@
 	qdf_mem_zero(crypto_key, sizeof(*crypto_key));
 	crypto_key->keylen = params->key_len;
 	crypto_key->keyix = key_index;
+	cfg80211_debug("key_type %d, opmode %d, key_len %d, seq_len %d",
+		       key_type, vdev->vdev_mlme.vdev_opmode,
+		       params->key_len, params->seq_len);
 	qdf_mem_copy(&crypto_key->keyval[0], params->key, params->key_len);
 	qdf_mem_copy(&crypto_key->keyrsc[0], params->seq, params->seq_len);
 
 	crypto_key->cipher_type = osif_nl_to_crypto_cipher_type(params->cipher);
+	if (IS_WEP_CIPHER(crypto_key->cipher_type) && !mac_addr) {
+		/*
+		 * This is a valid scenario in case of WEP, where-in the
+		 * keys are passed by the user space during the connect request
+		 * but since we did not connect yet, so we do not know the peer
+		 * address yet.
+		 */
+		cfg80211_debug("No Mac Address to copy");
+		return;
+	}
 	if (key_type == WLAN_CRYPTO_KEY_TYPE_UNICAST) {
 		qdf_mem_copy(&crypto_key->macaddr, mac_addr, QDF_MAC_ADDR_SIZE);
 	} else {
@@ -54,8 +67,7 @@
 				     vdev->vdev_mlme.macaddr,
 				     QDF_MAC_ADDR_SIZE);
 	}
-	cfg80211_debug("key_type %d, opmode %d, mac %pM", key_type,
-		       vdev->vdev_mlme.vdev_opmode, crypto_key->macaddr);
+	cfg80211_debug("mac %pM", crypto_key->macaddr);
 }
 
 int wlan_cfg80211_store_key(struct wlan_objmgr_vdev *vdev,
@@ -76,10 +88,6 @@
 		cfg80211_err("Key params is NULL");
 		return -EINVAL;
 	}
-	if ((key_type == WLAN_CRYPTO_KEY_TYPE_UNICAST) && !mac_addr) {
-		cfg80211_err("mac_addr is NULL for pairwise Key");
-		return -EINVAL;
-	}
 	cipher_len = osif_nl_to_crypto_cipher_len(params->cipher);
 	if (cipher_len < 0 || params->key_len < cipher_len) {
 		cfg80211_err("cipher length %d less than reqd len %d",
@@ -87,6 +95,13 @@
 		return -EINVAL;
 	}
 	cipher = osif_nl_to_crypto_cipher_type(params->cipher);
+	if (!IS_WEP_CIPHER(cipher)) {
+		if ((key_type == WLAN_CRYPTO_KEY_TYPE_UNICAST) &&
+		    !mac_addr) {
+			cfg80211_err("mac_addr is NULL for pairwise Key");
+			return -EINVAL;
+		}
+	}
 	status = wlan_crypto_validate_key_params(cipher, key_index,
 						 params->key_len,
 						 params->seq_len);
diff --git a/target_if/crypto/src/target_if_crypto.c b/target_if/crypto/src/target_if_crypto.c
index 01c6951..074c33f 100644
--- a/target_if/crypto/src/target_if_crypto.c
+++ b/target_if/crypto/src/target_if_crypto.c
@@ -182,6 +182,8 @@
 
 	switch (req->cipher_type) {
 	case WLAN_CRYPTO_CIPHER_WEP:
+	case WLAN_CRYPTO_CIPHER_WEP_40:
+	case WLAN_CRYPTO_CIPHER_WEP_104:
 		def_tx_idx = wlan_crypto_get_default_key_idx(vdev, false);
 		if (pairwise && params.key_idx == def_tx_idx)
 			params.key_flags |= TX_USAGE;
@@ -203,6 +205,7 @@
 	params.key_len = req->keylen;
 	if (peer) {
 		/* Set PN check & security type in data path */
+		qdf_mem_copy(&pn[0], &params.key_rsc_ctr, sizeof(pn));
 		cdp_set_pn_check(soc, txrx_vdev, peer, sec_type, pn);
 		cdp_set_key(soc, peer, pairwise, (uint32_t *)(req->keyval +
 			    WLAN_CRYPTO_IV_SIZE + WLAN_CRYPTO_MIC_LEN));
diff --git a/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h b/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h
index 99c2021..87f563b 100644
--- a/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h
+++ b/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h
@@ -207,6 +207,9 @@
 	WLAN_CRYPTO_KEY_TYPE_GROUP,
 };
 
+#define IS_WEP_CIPHER(_c)      ((_c == WLAN_CRYPTO_CIPHER_WEP) || \
+				(_c == WLAN_CRYPTO_CIPHER_WEP_40) || \
+				(_c == WLAN_CRYPTO_CIPHER_WEP_104))
 /**
  * struct wlan_crypto_pmksa - structure of crypto to contain pmkid
  * @bssid: bssid for which pmkid is saved
diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c
index a974eaf..73875e3 100644
--- a/wmi/src/wmi_unified_api.c
+++ b/wmi/src/wmi_unified_api.c
@@ -4465,6 +4465,8 @@
 	case WLAN_CRYPTO_CIPHER_NONE:
 		return WMI_CIPHER_NONE;
 	case WLAN_CRYPTO_CIPHER_WEP:
+	case WLAN_CRYPTO_CIPHER_WEP_40:
+	case WLAN_CRYPTO_CIPHER_WEP_104:
 		return WMI_CIPHER_WEP;
 	case WLAN_CRYPTO_CIPHER_TKIP:
 		return WMI_CIPHER_TKIP;
@@ -4494,6 +4496,8 @@
 	case WLAN_CRYPTO_CIPHER_NONE:
 		return cdp_sec_type_none;
 	case WLAN_CRYPTO_CIPHER_WEP:
+	case WLAN_CRYPTO_CIPHER_WEP_40:
+	case WLAN_CRYPTO_CIPHER_WEP_104:
 		return cdp_sec_type_wep104;
 	case WLAN_CRYPTO_CIPHER_TKIP:
 		return cdp_sec_type_tkip;