Browse Source

qcacld-3.0: Fix incorrect length of encrypted auth frame

Memory for encrypted auth frame is allocated based on macro
SIR_MAC_AUTH_CHALLENGE_LENGTH. SIR_MAC_AUTH_CHALLENGE_LENGTH
was updated to 253 from 128. Auth failure is observed on
receiving challenge text of length 128.

Fix is to use length based on the challenge text received.

Change-Id: I5ba5748c9ae00b61743883862ca884ac1134da15
CRs-Fixed: 2084599
yeshwanth sriram guntuka 7 years ago
parent
commit
343a3f2833

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

@@ -563,11 +563,13 @@
 #define SIR_MAC_AUTH_CHALLENGE_LENGTH        253
 #define SIR_MAC_WEP_IV_LENGTH                4
 #define SIR_MAC_WEP_ICV_LENGTH               4
+#define SIR_MAC_CHALLENGE_ID_LEN             2
 
 /* 2 bytes each for auth algo number, transaction number and status code */
 #define SIR_MAC_AUTH_FRAME_INFO_LEN          6
 /* 2 bytes for ID and length + SIR_MAC_AUTH_CHALLENGE_LENGTH */
-#define SIR_MAC_AUTH_CHALLENGE_BODY_LEN    (2 + SIR_MAC_AUTH_CHALLENGE_LENGTH)
+#define SIR_MAC_AUTH_CHALLENGE_BODY_LEN    (SIR_MAC_CHALLENGE_ID_LEN + \
+					    SIR_MAC_AUTH_CHALLENGE_LENGTH)
 
 /* / MAX key length when ULA is used */
 #define SIR_MAC_MAX_KEY_LENGTH               32

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

@@ -516,7 +516,7 @@ static void lim_process_auth_frame_type2(tpAniSirGlobal mac_ctx,
 	uint32_t val, key_length = 8;
 	uint8_t defaultkey[SIR_MAC_KEY_LENGTH];
 	struct tLimPreAuthNode *auth_node;
-	uint8_t encr_auth_frame[LIM_ENCR_AUTH_BODY_LEN];
+	uint8_t *encr_auth_frame;
 
 	/* AuthFrame 2 */
 	if (pe_session->limMlmState != eLIM_MLM_WT_AUTH_FRAME2_STATE) {
@@ -721,11 +721,17 @@ static void lim_process_auth_frame_type2(tpAniSirGlobal mac_ctx,
 		((tpSirMacAuthFrameBody)plainbody)->type =
 			SIR_MAC_CHALLENGE_TEXT_EID;
 		((tpSirMacAuthFrameBody)plainbody)->length =
-			SIR_MAC_AUTH_CHALLENGE_LENGTH;
+			rx_auth_frm_body->length;
 		qdf_mem_copy((uint8_t *) (
 			(tpSirMacAuthFrameBody)plainbody)->challengeText,
 			rx_auth_frm_body->challengeText,
-			SIR_MAC_AUTH_CHALLENGE_LENGTH);
+			rx_auth_frm_body->length);
+		encr_auth_frame = qdf_mem_malloc(rx_auth_frm_body->length +
+						 LIM_ENCR_AUTH_INFO_LEN);
+		if (!encr_auth_frame) {
+			pe_err("failed to allocate memory");
+			return;
+		}
 		lim_encrypt_auth_frame(mac_ctx, key_id,
 				defaultkey, plainbody,
 				encr_auth_frame, key_length);
@@ -735,9 +741,9 @@ static void lim_process_auth_frame_type2(tpAniSirGlobal mac_ctx,
 					pe_session->limMlmState));
 		lim_send_auth_mgmt_frame(mac_ctx,
 				(tpSirMacAuthFrameBody)encr_auth_frame,
-				mac_hdr->sa, LIM_WEP_IN_FC,
+				mac_hdr->sa, rx_auth_frm_body->length,
 				pe_session, false);
-
+		qdf_mem_free(encr_auth_frame);
 		return;
 	}
 }

+ 6 - 3
core/mac/src/pe/lim/lim_security_utils.c

@@ -517,22 +517,25 @@ lim_encrypt_auth_frame(tpAniSirGlobal pMac, uint8_t keyId, uint8_t *pKey,
 		       uint32_t keyLength)
 {
 	uint8_t seed[LIM_SEED_LENGTH], icv[SIR_MAC_WEP_ICV_LENGTH];
+	uint16_t frame_len;
 
+	frame_len = ((tpSirMacAuthFrameBody)pPlainText)->length +
+		     SIR_MAC_AUTH_FRAME_INFO_LEN + SIR_MAC_CHALLENGE_ID_LEN;
 	keyLength += 3;
 
 	/* Bytes 3-7 of seed is key */
 	qdf_mem_copy((uint8_t *) &seed[3], pKey, keyLength - 3);
 
 	/* Compute CRC-32 and place them in last 4 bytes of plain text */
-	lim_compute_crc32(icv, pPlainText, sizeof(tSirMacAuthFrameBody));
+	lim_compute_crc32(icv, pPlainText, frame_len);
 
-	qdf_mem_copy(pPlainText + sizeof(tSirMacAuthFrameBody),
+	qdf_mem_copy(pPlainText + frame_len,
 		     icv, SIR_MAC_WEP_ICV_LENGTH);
 
 	/* Run RC4 on plain text with the seed */
 	lim_rc4(pEncrBody + SIR_MAC_WEP_IV_LENGTH,
 		(uint8_t *) pPlainText, seed, keyLength,
-		LIM_ENCR_AUTH_BODY_LEN - SIR_MAC_WEP_IV_LENGTH);
+		frame_len + SIR_MAC_WEP_ICV_LENGTH);
 
 	/* Prepare IV */
 	pEncrBody[0] = seed[0];

+ 6 - 0
core/mac/src/pe/lim/lim_security_utils.h

@@ -44,6 +44,12 @@
 				 SIR_MAC_WEP_IV_LENGTH + \
 				 SIR_MAC_WEP_ICV_LENGTH)
 
+#define LIM_ENCR_AUTH_INFO_LEN	(SIR_MAC_AUTH_FRAME_INFO_LEN +\
+				 SIR_MAC_WEP_IV_LENGTH + \
+				 SIR_MAC_WEP_ICV_LENGTH + \
+				 SIR_MAC_CHALLENGE_ID_LEN)
+
+
 struct tLimPreAuthNode;
 
 uint8_t lim_is_auth_algo_supported(tpAniSirGlobal, tAniAuthType, tpPESession);

+ 8 - 5
core/mac/src/pe/lim/lim_send_management_frames.c

@@ -2088,7 +2088,7 @@ void
 lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
 			 tpSirMacAuthFrameBody auth_frame,
 			 tSirMacAddr peer_addr,
-			 uint8_t wep_bit,
+			 uint8_t wep_challenge_len,
 			 tpPESession session, bool wait_for_ack)
 {
 	uint8_t *frame, *body;
@@ -2108,7 +2108,7 @@ lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
 
 	sme_sessionid = session->smeSessionId;
 
-	if (wep_bit == LIM_WEP_IN_FC) {
+	if (wep_challenge_len) {
 		/*
 		 * Auth frame3 to be sent with encrypted framebody
 		 *
@@ -2121,7 +2121,7 @@ lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
 		pe_debug("Sending encrypted auth frame to " MAC_ADDRESS_STR,
 				MAC_ADDR_ARRAY(peer_addr));
 
-		body_len = LIM_ENCR_AUTH_BODY_LEN;
+		body_len = wep_challenge_len + LIM_ENCR_AUTH_INFO_LEN;
 		frame_len = sizeof(tSirMacMgmtHdr) + body_len;
 
 		goto alloc_packet;
@@ -2242,7 +2242,10 @@ alloc_packet:
 	lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
 		SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
 	mac_hdr = (tpSirMacMgmtHdr) frame;
-	mac_hdr->fc.wep = wep_bit;
+	if (wep_challenge_len)
+		mac_hdr->fc.wep = LIM_WEP_IN_FC;
+	else
+		mac_hdr->fc.wep = LIM_NO_WEP_IN_FC;
 
 	/* Prepare BSSId */
 	if (LIM_IS_AP_ROLE(session))
@@ -2253,7 +2256,7 @@ alloc_packet:
 	/* Prepare Authentication frame body */
 	body = frame + sizeof(tSirMacMgmtHdr);
 
-	if (wep_bit == LIM_WEP_IN_FC) {
+	if (wep_challenge_len) {
 		qdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
 
 		pe_debug("Sending Auth seq# 3 to " MAC_ADDRESS_STR,