Browse Source

qcacmn: Fix PMF in crypto convergence

changed the parameters in qdf_mem_zero
fixed issues in MMIE calculation.

CRs-fixed: 2073813
Change-Id: I01baa30fa1f51bb50116458d7c563c894ed44ec5
Ashok Ponnaiah 7 years ago
parent
commit
2a3df50dea

+ 36 - 0
umac/cmn_services/crypto/inc/wlan_crypto_global_api.h

@@ -200,6 +200,17 @@ QDF_STATUS wlan_crypto_demic(struct wlan_objmgr_vdev *vdev,
 					uint8_t *macaddr,
 					uint8_t tid);
 
+/**
+ * wlan_crypto_vdev_is_pmf_enabled - called to check is pmf enabled in vdev
+ *
+ * @vdev: vdev
+ *
+ * This function gets called to check is pmf enabled or not in vdev.
+ *
+ * Return: true or false
+ */
+bool wlan_crypto_vdev_is_pmf_enabled(struct wlan_objmgr_vdev *vdev);
+
 /**
  * wlan_crypto_is_pmf_enabled - called by mgmt txrx to check is pmf enabled
  *
@@ -378,4 +389,29 @@ QDF_STATUS wlan_crypto_register_crypto_rx_ops(
  */
 struct wlan_lmac_if_crypto_rx_ops *wlan_crypto_get_crypto_rx_ops(
 			struct wlan_objmgr_psoc *psoc);
+/**
+ * wlan_crypto_vdev_has_auth_mode - check authmode for vdev
+ *
+ * @vdev: vdev
+ * @authvalue: authvalue to be checked
+ *
+ * This function check is authvalue passed is set in vdev or not
+ *
+ * Return: true or false
+ */
+bool wlan_crypto_vdev_has_auth_mode(struct wlan_objmgr_vdev *vdev,
+					wlan_crypto_auth_mode authmode);
+
+/**
+ * wlan_crypto_peer_has_auth_mode - check authmode for peer
+ *
+ * @peer: peer
+ * @authvalue: authvalue to be checked
+ *
+ * This function check is authvalue passed is set in peer or not
+ *
+ * Return: true or false
+ */
+bool wlan_crypto_peer_has_auth_mode(struct wlan_objmgr_peer *peer,
+					wlan_crypto_auth_mode authvalue);
 #endif /* end of _WLAN_CRYPTO_GLOBAL_API_H_ */

+ 1 - 1
umac/cmn_services/crypto/src/wlan_crypto_aes_ccm.c

@@ -52,7 +52,7 @@ static void aes_ccm_auth_start(void *aes, size_t M, size_t L,
 
 	wlan_crypto_put_be16(aad_buf, aad_len);
 	qdf_mem_copy(aad_buf + 2, aad, aad_len);
-	qdf_mem_set(aad_buf + 2 + aad_len, 0, sizeof(aad_buf) - 2 - aad_len);
+	qdf_mem_set(aad_buf + 2 + aad_len, sizeof(aad_buf) - 2 - aad_len, 0);
 
 	xor_aes_block(aad_buf, x);
 	wlan_crypto_aes_encrypt(aes, aad_buf, x); /* X_2 = E(K, X_1 XOR B_1) */

+ 3 - 3
umac/cmn_services/crypto/src/wlan_crypto_aes_gcm.c

@@ -70,7 +70,7 @@ static void gf_mult(const uint8_t *x, const uint8_t *y, uint8_t *z)
 	uint8_t v[16];
 	int i, j;
 
-	qdf_mem_set(z, 0, 16); /* Z_0 = 0^128 */
+	qdf_mem_set(z, 16, 0); /* Z_0 = 0^128 */
 	qdf_mem_copy(v, y, 16); /* V_0 = Y */
 
 	for (i = 0; i < 16; i++) {
@@ -99,7 +99,7 @@ static void gf_mult(const uint8_t *x, const uint8_t *y, uint8_t *z)
 static void ghash_start(uint8_t *y)
 {
 	/* Y_0 = 0^128 */
-	qdf_mem_set(y, 0, 16);
+	qdf_mem_set(y, 16, 0);
 }
 
 
@@ -127,7 +127,7 @@ static void ghash(const uint8_t *h, const uint8_t *x, size_t xlen, uint8_t *y)
 		/* Add zero padded last block */
 		size_t last = x + xlen - xpos;
 		qdf_mem_copy(tmp, xpos, last);
-		qdf_mem_set(tmp + last, 0, sizeof(tmp) - last);
+		qdf_mem_set(tmp + last, sizeof(tmp) - last, 0);
 
 		/* Y_i = (Y^(i-1) XOR X_i) dot H */
 		xor_block(y, tmp);

+ 12 - 8
umac/cmn_services/crypto/src/wlan_crypto_aes_i.h

@@ -50,6 +50,10 @@ extern const uint8_t rcons[10];
 #ifndef AES_SMALL_TABLES
 
 #define RCON(i) rcon[(i)]
+static inline uint32_t rotr(uint32_t val, int bits)
+{
+	return (val >> bits) | (val << (32 - bits));
+}
 
 #define TE0(i) Te0[((i) >> 24) & 0xff]
 #define TE1(i) Te1[((i) >> 16) & 0xff]
@@ -129,16 +133,16 @@ static inline uint32_t rotr(uint32_t val, int bits)
 #define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
 #define GETU32(p) SWAP(*((uint32_t *)(p)))
 #define PUTU32(ct, st) { *((uint32_t *)(ct)) = SWAP((st)); }
-
 #else
+#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
 
-#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
-((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
-
-#define PUTU32(ct, st) { \
-(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \
-(ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
-
+#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^\
+		    ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
+#define PUTU32(ct, st) {\
+			(ct)[0] = (u8)((st) >> 24);\
+			(ct)[1] = (u8)((st) >> 16);\
+			(ct)[2] = (u8)((st) >>  8);\
+			(ct)[3] = (u8)(st); }
 #endif
 
 #define AES_PRIV_SIZE (4 * 4 * 15 + 4)

+ 1 - 1
umac/cmn_services/crypto/src/wlan_crypto_aes_internal_dec.c

@@ -157,6 +157,6 @@ void wlan_crypto_aes_decrypt(void *ctx, const uint8_t *crypt, uint8_t *plain)
 
 void wlan_crypto_aes_decrypt_deinit(void *ctx)
 {
-	qdf_mem_set(ctx, 0, AES_PRIV_SIZE);
+	qdf_mem_set(ctx, AES_PRIV_SIZE, 0);
 	qdf_mem_free(ctx);
 }

+ 1 - 1
umac/cmn_services/crypto/src/wlan_crypto_aes_internal_enc.c

@@ -124,6 +124,6 @@ void wlan_crypto_aes_encrypt(void *ctx, const uint8_t *plain, uint8_t *crypt)
 
 void wlan_crypto_aes_encrypt_deinit(void *ctx)
 {
-	qdf_mem_set(ctx, 0, AES_PRIV_SIZE);
+	qdf_mem_set(ctx, AES_PRIV_SIZE, 0);
 	qdf_mem_free(ctx);
 }

+ 5 - 3
umac/cmn_services/crypto/src/wlan_crypto_aes_omac1.c

@@ -47,21 +47,23 @@ int omac1_aes_vector(const uint8_t *key, size_t key_len, size_t num_elem,
 		     const uint8_t *addr[], const size_t *len, uint8_t *mac)
 {
 	void *ctx;
-	uint8_t cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
 	const uint8_t *pos, *end;
 	int32_t status = -1;
 	size_t i, e, left, total_len;
+	uint8_t cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
+
 
 	ctx = wlan_crypto_aes_encrypt_init(key, key_len);
 	if (ctx == NULL)
 		return status;
-	qdf_mem_set(cbc, 0, AES_BLOCK_SIZE);
 
 	total_len = 0;
 	for (e = 0; e < num_elem; e++)
 		total_len += len[e];
 	left = total_len;
 
+	qdf_mem_set(cbc, AES_BLOCK_SIZE, 0);
+
 	e = 0;
 	pos = addr[0];
 	end = pos + len[0];
@@ -87,7 +89,7 @@ int omac1_aes_vector(const uint8_t *key, size_t key_len, size_t num_elem,
 		left -= AES_BLOCK_SIZE;
 	}
 
-	qdf_mem_set(pad, 0, AES_BLOCK_SIZE);
+	qdf_mem_set(pad, AES_BLOCK_SIZE, 0);
 	wlan_crypto_aes_encrypt(ctx, pad, pad);
 	gf_mulx(pad);
 

+ 1 - 4
umac/cmn_services/crypto/src/wlan_crypto_ccmp.c

@@ -55,22 +55,19 @@ static QDF_STATUS ccmp_encap(struct wlan_crypto_key *key,
 	/*
 	 * Copy down 802.11 header and add the IV, KeyID, and ExtIV.
 	 */
-
 	if (encapdone) {
 		ivp = (uint8_t *)qdf_nbuf_data(wbuf);
 	} else {
 		ivp = (uint8_t *)qdf_nbuf_push_head(wbuf,
 							cipher_table->header);
 		qdf_mem_move(ivp, ivp + cipher_table->header, hdrlen);
-		/* recompute hdr */
-		hdr = (struct ieee80211_hdr *) qdf_nbuf_data(wbuf);
+		ivp = (uint8_t *) qdf_nbuf_data(wbuf);
 	}
 
 	ivp += hdrlen;
 	/* XXX wrap at 48 bits */
 	key->keytsc++;
 
-
 	ivp[0] = key->keytsc >> 0;         /* PN0 */
 	ivp[1] = key->keytsc >> 8;         /* PN1 */
 	ivp[2] = 0;                         /* Reserved */

+ 35 - 3
umac/cmn_services/crypto/src/wlan_crypto_def_i.h

@@ -419,9 +419,33 @@ struct wlan_crypto_cipher {
 				qdf_nbuf_t, uint8_t,  uint8_t);
 };
 
-/*
-* Return the size of the 802.11 header for a management or data frame.
-*/
+
+/**
+ * wlan_crypto_is_data_protected - check is frame is protected or not
+ *
+ * @data: frame
+ * This function check is frame is protected or not
+ *
+ * Return: TRUE/FALSE
+ */
+static inline bool wlan_crypto_is_data_protected(const void *data)
+{
+	const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)data;
+
+	if (hdr->frame_control & WLAN_FC_ISWEP)
+		return true;
+	else
+		return false;
+}
+
+/**
+ * ieee80211_hdrsize - calculate frame header size
+ *
+ * @data: frame
+ * This function calculate frame header size
+ *
+ * Return: header size of the frame
+ */
 static inline int ieee80211_hdrsize(const void *data)
 {
 	const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)data;
@@ -442,6 +466,14 @@ static inline int ieee80211_hdrsize(const void *data)
 	return size;
 }
 
+/**
+ * wlan_get_tid - get tid of the frame
+ *
+ * @data: frame
+ * This function get tid of the frame
+ *
+ * Return: tid of the frame
+ */
 static inline int wlan_get_tid(const void *data)
 {
 	const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)data;

+ 143 - 47
umac/cmn_services/crypto/src/wlan_crypto_global_api.c

@@ -253,15 +253,6 @@ uint8_t wlan_crypto_is_htallowed(struct wlan_objmgr_vdev *vdev,
 }
 qdf_export_symbol(wlan_crypto_is_htallowed);
 
-static void  initialize_send_iv(uint8_t *iv, uint8_t *init_iv)
-{
-	int8_t i = 0;
-
-	for (i = 0; i < WLAN_CRYPTO_WAPI_IV_SIZE/4; i++) {
-		*(((uint32_t *)iv)+i) =
-				qdf_be32_to_cpu(*(((uint32_t *)(init_iv))+i));
-	}
-}
 /**
  * wlan_crypto_setkey - called by ucfg to setkey
  *
@@ -316,8 +307,8 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
 		return QDF_STATUS_E_INVAL;
 	}
 
-	if ((IS_MGMT_CIPHER(req_key->type))
-		|| ((req_key->keylen != (cipher->keylen/NBBY))
+	if (cipher && (!IS_MGMT_CIPHER(req_key->type))
+		&& ((req_key->keylen != (cipher->keylen/NBBY))
 		&& (req_key->type != WLAN_CRYPTO_CIPHER_WEP))) {
 		qdf_print("%s[%d] cipher invalid\n", __func__, __LINE__);
 		return QDF_STATUS_E_INVAL;
@@ -368,7 +359,13 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
 		}
 
 		if (IS_MGMT_CIPHER(req_key->type)) {
-			key = crypto_priv->igtk_key;
+			key = qdf_mem_malloc(sizeof(struct wlan_crypto_key));
+			if (key == NULL) {
+				qdf_print("%s[%d] igtk key alloc failed\n",
+						__func__, __LINE__);
+				return QDF_STATUS_E_NOMEM;
+			}
+			crypto_priv->igtk_key = key;
 			crypto_priv->igtk_key_type = req_key->type;
 		} else {
 			if (!HAS_MCAST_CIPHER(crypto_params, req_key->type)
@@ -421,7 +418,13 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
 			return QDF_STATUS_E_INVAL;
 		}
 		if (IS_MGMT_CIPHER(req_key->type)) {
-			key = crypto_priv->igtk_key;
+			key = qdf_mem_malloc(sizeof(struct wlan_crypto_key));
+			if (key == NULL) {
+				qdf_print("%s[%d] igtk key alloc failed\n",
+						__func__, __LINE__);
+				return QDF_STATUS_E_NOMEM;
+			}
+			crypto_priv->igtk_key = key;
 		} else {
 			uint16_t kid = req_key->keyix;
 			if (kid == WLAN_CRYPTO_KEYIX_NONE)
@@ -447,7 +450,8 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
 	else
 		key->keyix = req_key->keyix;
 
-	if (req_key->flags & WLAN_CRYPTO_KEY_DEFAULT) {
+	if (req_key->flags & WLAN_CRYPTO_KEY_DEFAULT
+		&& (!IS_MGMT_CIPHER(req_key->type)))  {
 		crypto_priv->def_tx_keyid = key->keyix;
 		key->flags |= WLAN_CRYPTO_KEY_DEFAULT;
 	}
@@ -471,18 +475,14 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
 			iv_AP[15] += 2;
 			qdf_mem_copy(key->recviv, iv_STA,
 						WLAN_CRYPTO_WAPI_IV_SIZE);
-			/*initialize send iv */
-			qdf_mem_zero((uint8_t *)(key->txiv),
+			qdf_mem_copy(key->txiv, iv_AP,
 						WLAN_CRYPTO_WAPI_IV_SIZE);
-			initialize_send_iv(key->txiv, iv_AP);
 		} else {
 			iv_STA[15] += 2;
 			qdf_mem_copy(key->recviv, iv_AP,
 						WLAN_CRYPTO_WAPI_IV_SIZE);
-			/*initialize send iv */
-			qdf_mem_zero((uint8_t *)(key->txiv),
+			qdf_mem_copy(key->txiv, iv_STA,
 						WLAN_CRYPTO_WAPI_IV_SIZE);
-			initialize_send_iv(key->txiv, iv_STA);
 		}
 	} else {
 		uint8_t i = 0;
@@ -497,9 +497,7 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
 
 	qdf_mem_copy(key->keyval, req_key->keydata, sizeof(key->keyval));
 	key->valid = 1;
-
-	if ((IS_MGMT_CIPHER(req_key->type))
-		&& HAS_MGMT_CIPHER(crypto_params, req_key->type)) {
+	if ((IS_MGMT_CIPHER(req_key->type))) {
 		if (HAS_CIPHER_CAP(crypto_params,
 					WLAN_CRYPTO_CAP_PMF_OFFLOAD)) {
 			if (WLAN_CRYPTO_TX_OPS_SETKEY(psoc)) {
@@ -596,9 +594,9 @@ QDF_STATUS wlan_crypto_getkey(struct wlan_objmgr_vdev *vdev,
 		}
 
 		if (req_key->keyix == WLAN_CRYPTO_KEYIX_NONE)
-		       key = crypto_priv->key[crypto_priv->def_tx_keyid];
+			key = crypto_priv->key[crypto_priv->def_tx_keyid];
 		else
-		       key = crypto_priv->key[req_key->keyix];
+			key = crypto_priv->key[req_key->keyix];
 		if (!key)
 			return QDF_STATUS_E_INVAL;
 	}
@@ -615,6 +613,10 @@ QDF_STATUS wlan_crypto_getkey(struct wlan_objmgr_vdev *vdev,
 		req_key->keylen = key->keylen;
 		req_key->flags = key->flags;
 		cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
+
+		if (!cipher_table)
+			return QDF_STATUS_SUCCESS;
+
 		req_key->type = cipher_table->cipher;
 	}
 
@@ -643,9 +645,9 @@ QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev,
 	uint8_t bssid_mac[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
 	if (!vdev || !macaddr || (key_idx >= WLAN_CRYPTO_MAXKEYIDX)) {
-		qdf_print("%s[%d] Invalid params vdev %p, macaddr %p keyidx %d\n",
-			  __func__, __LINE__, vdev,
-			  macaddr, key_idx);
+		qdf_print("%s[%d] Invalid params vdev %p, macaddr %p"
+					"keyidx %d\n", __func__, __LINE__, vdev,
+					macaddr, key_idx);
 		return QDF_STATUS_E_INVAL;
 	}
 
@@ -742,8 +744,9 @@ QDF_STATUS wlan_crypto_default_key(struct wlan_objmgr_vdev *vdev,
 	wlan_vdev_obj_unlock(vdev);
 
 	if (!vdev || !macaddr || (key_idx >= WLAN_CRYPTO_MAXKEYIDX)) {
-		qdf_print("%s[%d] Invalid params vdev %p, macaddr %p keyidx %d\n",
-			  __func__, __LINE__, vdev, macaddr, key_idx);
+		qdf_print("%s[%d] Invalid params vdev %p, macaddr %p"
+				"keyidx %d\n", __func__, __LINE__,
+				vdev, macaddr, key_idx);
 		return QDF_STATUS_E_INVAL;
 	}
 	if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)macaddr)) {
@@ -817,6 +820,9 @@ QDF_STATUS wlan_crypto_encap(struct wlan_objmgr_vdev *vdev,
 	struct wlan_objmgr_psoc *psoc;
 	uint8_t bssid_mac[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
+	if (!wlan_crypto_is_data_protected((uint8_t *)qdf_nbuf_data(wbuf)))
+		return QDF_STATUS_E_INVAL;
+
 	wlan_vdev_obj_lock(vdev);
 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
 	psoc = wlan_vdev_get_psoc(vdev);
@@ -868,7 +874,7 @@ QDF_STATUS wlan_crypto_encap(struct wlan_objmgr_vdev *vdev,
 	/* if tkip, is counter measures enabled, then drop the frame */
 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
 	status = cipher_table->encap(key, wbuf, encapdone,
-						ieee80211_hdrsize(wbuf));
+			ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf)));
 
 	return status;
 }
@@ -897,6 +903,9 @@ QDF_STATUS wlan_crypto_decap(struct wlan_objmgr_vdev *vdev,
 	struct wlan_objmgr_psoc *psoc;
 	uint8_t bssid_mac[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
+	if (!wlan_crypto_is_data_protected((uint8_t *)qdf_nbuf_data(wbuf)))
+		return QDF_STATUS_E_INVAL;
+
 	wlan_vdev_obj_lock(vdev);
 	qdf_mem_copy(bssid_mac, wlan_vdev_mlme_get_macaddr(vdev), WLAN_ALEN);
 	psoc = wlan_vdev_get_psoc(vdev);
@@ -947,7 +956,8 @@ QDF_STATUS wlan_crypto_decap(struct wlan_objmgr_vdev *vdev,
 	}
 	/* if tkip, is counter measures enabled, then drop the frame */
 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
-	status = cipher_table->decap(key, wbuf, tid, ieee80211_hdrsize(wbuf));
+	status = cipher_table->decap(key, wbuf, tid,
+			ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf)));
 
 	return status;
 }
@@ -1027,7 +1037,7 @@ QDF_STATUS wlan_crypto_enmic(struct wlan_objmgr_vdev *vdev,
 	/* if tkip, is counter measures enabled, then drop the frame */
 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
 	status = cipher_table->enmic(key, wbuf, encapdone,
-						ieee80211_hdrsize(wbuf));
+			ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf)));
 
 	return status;
 }
@@ -1106,11 +1116,45 @@ QDF_STATUS wlan_crypto_demic(struct wlan_objmgr_vdev *vdev,
 	}
 	/* if tkip, is counter measures enabled, then drop the frame */
 	cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
-	status = cipher_table->demic(key, wbuf, tid, ieee80211_hdrsize(wbuf));
+	status = cipher_table->demic(key, wbuf, tid,
+			ieee80211_hdrsize((uint8_t *)qdf_nbuf_data(wbuf)));
 
 	return status;
 }
 
+/**
+ * wlan_crypto_vdev_is_pmf_enabled - called to check is pmf enabled in vdev
+ *
+ * @vdev: vdev
+ *
+ * This function gets called to check is pmf enabled or not in vdev.
+ *
+ * Return: true or false
+ */
+bool wlan_crypto_vdev_is_pmf_enabled(struct wlan_objmgr_vdev *vdev)
+{
+
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *vdev_crypto_params;
+
+	if (!vdev)
+		return false;
+	vdev_crypto_params = wlan_crypto_vdev_get_comp_params(vdev,
+							&crypto_priv);
+	if (crypto_priv == NULL) {
+		qdf_print("%s[%d] crypto_priv NULL\n", __func__, __LINE__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if ((vdev_crypto_params->rsn_caps &
+					WLAN_CRYPTO_RSN_CAP_MFP_ENABLED)
+		|| (vdev_crypto_params->rsn_caps &
+					WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)) {
+		return true;
+	}
+
+	return false;
+}
 /**
  * wlan_crypto_is_pmf_enabled - called by mgmt txrx to check is pmf enabled
  *
@@ -1145,7 +1189,7 @@ bool wlan_crypto_is_pmf_enabled(struct wlan_objmgr_vdev *vdev,
 	}
 	if (((vdev_crypto_params->rsn_caps &
 					WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) &&
-		(vdev_crypto_params->rsn_caps &
+		(peer_crypto_params->rsn_caps &
 					WLAN_CRYPTO_RSN_CAP_MFP_ENABLED))
 		|| (vdev_crypto_params->rsn_caps &
 					WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED)) {
@@ -1154,7 +1198,6 @@ bool wlan_crypto_is_pmf_enabled(struct wlan_objmgr_vdev *vdev,
 
 	return false;
 }
-
 /**
  * wlan_crypto_add_mmie - called by mgmt txrx to add mmie in frame
  *
@@ -1174,6 +1217,7 @@ uint8_t *wlan_crypto_add_mmie(struct wlan_objmgr_vdev *vdev,
 	uint8_t *pn, *aad, *buf, *efrm, nounce[12];
 	struct ieee80211_hdr *hdr;
 	uint32_t i, hdrlen, mic_len, aad_len;
+	uint8_t mic[16];
 	struct wlan_crypto_comp_priv *crypto_priv;
 	struct wlan_crypto_params *crypto_params;
 	int32_t ret;
@@ -1201,12 +1245,20 @@ uint8_t *wlan_crypto_add_mmie(struct wlan_objmgr_vdev *vdev,
 	efrm = bfrm + len;
 	aad_len = 20;
 	hdrlen = sizeof(struct ieee80211_hdr);
+	len += sizeof(struct wlan_crypto_mmie);
 
 	mmie = (struct wlan_crypto_mmie *) efrm;
+	qdf_mem_zero((unsigned char *)mmie, sizeof(*mmie));
 	mmie->element_id = WLAN_ELEMID_MMIE;
 	mmie->length = sizeof(*mmie) - 2;
 	mmie->key_id = qdf_cpu_to_le16(key->keyix);
 
+	mic_len = (crypto_priv->igtk_key_type
+			== WLAN_CRYPTO_CIPHER_AES_CMAC) ? 8 : 16;
+	if (mic_len == 8) {
+		mmie->length -= 8;
+		len -= 8;
+	}
 	/* PN = PN + 1 */
 	pn = (uint8_t *)&key->keytsc;
 
@@ -1221,11 +1273,12 @@ uint8_t *wlan_crypto_add_mmie(struct wlan_objmgr_vdev *vdev,
 
 	hdr = (struct ieee80211_hdr *) bfrm;
 
-	buf = qdf_mem_malloc(len - hdrlen);
+	buf = qdf_mem_malloc(len - hdrlen + 20);
 	if (!buf) {
 		qdf_print("%s[%d] malloc failed\n", __func__, __LINE__);
 		return NULL;
 	}
+	qdf_mem_zero(buf, len - hdrlen + 20);
 	aad = buf;
 	/* generate BIP AAD: FC(masked) || A1 || A2 || A3 */
 
@@ -1238,27 +1291,35 @@ uint8_t *wlan_crypto_add_mmie(struct wlan_objmgr_vdev *vdev,
 	qdf_mem_copy(aad + 2, hdr->addr1, WLAN_ALEN);
 	qdf_mem_copy(aad + 8, hdr->addr2, WLAN_ALEN);
 	qdf_mem_copy(aad + 14, hdr->addr3, WLAN_ALEN);
-	qdf_mem_zero(mmie->mic, 16);
+	qdf_mem_zero(mic, 16);
+
 	/*
 	 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
 	 */
-	qdf_mem_copy(buf + 20, bfrm + hdrlen, len - hdrlen);
+
+	qdf_mem_copy(buf + aad_len, bfrm + hdrlen, len - hdrlen);
 	if (crypto_priv->igtk_key_type == WLAN_CRYPTO_CIPHER_AES_CMAC) {
-		mmie->length -= 8;
+
 		ret = omac1_aes_128(key->keyval, buf,
-					len + aad_len - hdrlen, mmie->mic);
+					len + aad_len - hdrlen, mic);
+		qdf_mem_copy(mmie->mic, mic, 8);
+
 	} else if (crypto_priv->igtk_key_type
 				== WLAN_CRYPTO_CIPHER_AES_CMAC_256) {
+
 		ret = omac1_aes_256(key->keyval, buf,
 					len + aad_len - hdrlen, mmie->mic);
+
 	} else if ((crypto_priv->igtk_key_type == WLAN_CRYPTO_CIPHER_AES_GMAC)
 			|| (crypto_priv->igtk_key_type
 					== WLAN_CRYPTO_CIPHER_AES_GMAC_256)) {
+
 		qdf_mem_copy(nounce, hdr->addr2, WLAN_ALEN);
 		qdf_mem_copy(nounce + 6, pn, 6);
 		ret = wlan_crypto_aes_gmac(key->keyval, key->keylen, nounce,
 					sizeof(nounce), buf,
 					len + aad_len - hdrlen, mmie->mic);
+
 	}
 	qdf_mem_free(buf);
 	if (ret < 0) {
@@ -1266,10 +1327,8 @@ uint8_t *wlan_crypto_add_mmie(struct wlan_objmgr_vdev *vdev,
 		return NULL;
 	}
 
-	len += sizeof(struct wlan_crypto_mmie);
-	if (mic_len == 8)
-		len -= 8;
 	key->keytsc++;
+
 	return bfrm + len;
 }
 
@@ -1342,7 +1401,7 @@ bool wlan_crypto_is_mmie_valid(struct wlan_objmgr_vdev *vdev,
 		return false;
 	}
 
-	buf = qdf_mem_malloc(len - hdrlen);
+	buf = qdf_mem_malloc(len - hdrlen + 20);
 	if (!buf) {
 		qdf_print("%s[%d] malloc failed\n", __func__, __LINE__);
 		return false;
@@ -1365,10 +1424,11 @@ bool wlan_crypto_is_mmie_valid(struct wlan_objmgr_vdev *vdev,
 	 * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
 	 */
 	qdf_mem_copy(buf + 20, frm + hdrlen, len - hdrlen);
+	qdf_mem_zero(buf + (len - hdrlen + 20 - mic_len), mic_len);
+	qdf_mem_zero(mic, 16);
 	if (crypto_priv->igtk_key_type == WLAN_CRYPTO_CIPHER_AES_CMAC) {
-		mmie->length -= 8;
 		ret = omac1_aes_128(key->keyval, buf,
-					len + aad_len - hdrlen, mic);
+					len - hdrlen + aad_len, mic);
 	} else if (crypto_priv->igtk_key_type
 				== WLAN_CRYPTO_CIPHER_AES_CMAC_256) {
 		ret = omac1_aes_256(key->keyval, buf,
@@ -1398,6 +1458,7 @@ bool wlan_crypto_is_mmie_valid(struct wlan_objmgr_vdev *vdev,
 
 	/* Update the receive sequence number */
 	qdf_mem_copy(key->keyrsc, ipn, 6);
+	qdf_print("%s[%d] mmie matched\n", __func__, __LINE__);
 
 	return true;
 }
@@ -2056,6 +2117,7 @@ uint8_t *wlan_crypto_build_rsnie(struct wlan_crypto_params *crypto_params,
 
 	return frm;
 }
+
 bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev,
 				struct wlan_crypto_params *crypto_params){
 	struct wlan_crypto_params *my_crypto_params;
@@ -2253,3 +2315,37 @@ struct wlan_lmac_if_crypto_rx_ops *wlan_crypto_get_crypto_rx_ops(
 	return &(psoc->soc_cb.rx_ops.crypto_rx_ops);
 }
 EXPORT_SYMBOL(wlan_crypto_get_crypto_rx_ops);
+
+/**
+ * wlan_crypto_vdev_has_auth_mode - check authmode for vdev
+ *
+ * @vdev: vdev
+ * @authvalue: authvalue to be checked
+ *
+ * This function check is authvalue passed is set in vdev or not
+ *
+ * Return: true or false
+ */
+bool wlan_crypto_vdev_has_auth_mode(struct wlan_objmgr_vdev *vdev,
+					wlan_crypto_auth_mode authvalue)
+{
+	return wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_AUTH_MODE)
+			& authvalue;
+}
+
+/**
+ * wlan_crypto_peer_has_auth_mode - check authmode for peer
+ *
+ * @peer: peer
+ * @authvalue: authvalue to be checked
+ *
+ * This function check is authvalue passed is set in peer or not
+ *
+ * Return: true or false
+ */
+bool wlan_crypto_peer_has_auth_mode(struct wlan_objmgr_peer *peer,
+					wlan_crypto_auth_mode authvalue)
+{
+	return wlan_crypto_get_peer_param(peer, WLAN_CRYPTO_PARAM_AUTH_MODE)
+			& authvalue;
+}