Browse Source

qcacld-3.0: Fix AEAD decryption failure with FILS PMF connection

AEAD decryption failure happens when AP sends association
rejection frame as part of the PMF SA query procedure. AP
doesn't include FILS Session IE, but STA tries to AEAD decrypt
the frame starting from the FILS session IE and drops the
association rejection frame due to AEAD decryption frame.
So association failure timeout kicks in and proper reason
code is not indicated to userspace due to which automatic
connection retry to the AP doesn't happen.

Skip AEAD decryption if status code is not success in the
association response frame and proceed to parse the frame.

Change-Id: I9dcc85afb896717cfd20102c219b58e0e982f340
CRs-Fixed: 2797416
Pragaspathi Thilagaraj 4 years ago
parent
commit
7503f44942

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

@@ -254,6 +254,7 @@
 
 /* Association/Reassociation offsets */
 #define SIR_MAC_REASSOC_REQ_SSID_OFFSET      10
+#define SIR_MAC_ASSOC_RSP_STATUS_CODE_OFFSET 2
 
 /* Association Request offsets */
 #define SIR_MAC_ASSOC_REQ_SSID_OFFSET        4

+ 13 - 2
core/mac/src/sys/legacy/src/utils/src/parser_api.c

@@ -3102,13 +3102,24 @@ sir_convert_assoc_resp_frame2_struct(struct mac_context *mac,
 	uint8_t cnt = 0;
 	bool sha384_akm;
 	uint8_t *ie_ptr;
+	uint16_t status_code;
 
 	ar = qdf_mem_malloc(sizeof(*ar));
 	if (!ar)
 		return QDF_STATUS_E_FAILURE;
 
-	/* decrypt the cipher text using AEAD decryption */
-	if (lim_is_fils_connection(session_entry)) {
+	status_code = sir_read_u16(frame +
+				   SIR_MAC_ASSOC_RSP_STATUS_CODE_OFFSET);
+	if (lim_is_fils_connection(session_entry) && status_code)
+		pe_debug("FILS: assoc reject Status code:%d", status_code);
+
+	/*
+	 * decrypt the cipher text using AEAD decryption, if association
+	 * response status code is successful, else the don't do AEAD decryption
+	 * since AP doesn't inlude FILS session IE when association reject is
+	 * sent
+	 */
+	if (lim_is_fils_connection(session_entry) && !status_code) {
 		status = aead_decrypt_assoc_rsp(mac, session_entry,
 						ar, frame, &frame_len);
 		if (!QDF_IS_STATUS_SUCCESS(status)) {