xref: /wlan-driver/qcacld-3.0/core/mac/src/pe/lim/lim_process_auth_frame.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1 /*
2  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*
21  *
22  * This file lim_process_auth_frame.cc contains the code
23  * for processing received Authentication Frame.
24  * Author:        Chandra Modumudi
25  * Date:          03/11/02
26  * History:-
27  * Date           Modified by    Modification Information
28  * --------------------------------------------------------------------
29  * 05/12/2010     js             To support Shared key authentication at AP side
30  *
31  */
32 
33 #include "wni_api.h"
34 #include "wni_cfg.h"
35 #include "ani_global.h"
36 #include "cfg_ucfg_api.h"
37 #include "utils_api.h"
38 #include "lim_utils.h"
39 #include "lim_assoc_utils.h"
40 #include "lim_security_utils.h"
41 #include "lim_ser_des_utils.h"
42 #include "lim_ft.h"
43 #include "cds_utils.h"
44 #include "lim_send_messages.h"
45 #include "lim_process_fils.h"
46 #include "wlan_mlme_api.h"
47 #include "wlan_connectivity_logging.h"
48 #include "lim_types.h"
49 #include <wlan_mlo_mgr_main.h>
50 #include "wlan_nan_api_i.h"
51 #include <utils_mlo.h>
52 /**
53  * is_auth_valid
54  *
55  ***FUNCTION:
56  * This function is called by lim_process_auth_frame() upon Authentication
57  * frame reception.
58  *
59  ***LOGIC:
60  * This function is used to test validity of auth frame:
61  * - AUTH1 and AUTH3 must be received in AP mode
62  * - AUTH2 and AUTH4 must be received in STA mode
63  * - AUTH3 and AUTH4 must have challenge text IE, that is,'type' field has been set to
64  *                 WLAN_ELEMID_CHALLENGE by parser
65  * -
66  *
67  ***ASSUMPTIONS:
68  *
69  ***NOTE:
70  *
71  * @param  *auth - Pointer to extracted auth frame body
72  *
73  * @return 0 or 1 (Valid)
74  */
75 
is_auth_valid(struct mac_context * mac,tpSirMacAuthFrameBody auth,struct pe_session * pe_session)76 static inline unsigned int is_auth_valid(struct mac_context *mac,
77 					 tpSirMacAuthFrameBody auth,
78 					 struct pe_session *pe_session)
79 {
80 	unsigned int valid = 1;
81 
82 	if (((auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_1) ||
83 	    (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_3)) &&
84 	    (LIM_IS_STA_ROLE(pe_session)))
85 		valid = 0;
86 
87 	if (((auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_2) ||
88 	    (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_4)) &&
89 	    (LIM_IS_AP_ROLE(pe_session)))
90 		valid = 0;
91 
92 	if (((auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_3) ||
93 	    (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_4)) &&
94 	    (auth->type != WLAN_ELEMID_CHALLENGE) &&
95 	    (auth->authAlgoNumber != eSIR_SHARED_KEY))
96 		valid = 0;
97 
98 	return valid;
99 }
100 
101 /**
102  * lim_get_wep_key_sap() - get sap's wep key for shared wep auth
103  * @pe_session: pointer to pe session
104  * @wep_params: pointer to wlan_mlme_wep_cfg
105  * @key_id: key id
106  * @default_key: output of the key
107  * @key_len: output of key length
108  *
109  * Return: QDF_STATUS
110  */
lim_get_wep_key_sap(struct pe_session * pe_session,struct wlan_mlme_wep_cfg * wep_params,uint8_t key_id,uint8_t * default_key,qdf_size_t * key_len)111 static QDF_STATUS lim_get_wep_key_sap(struct pe_session *pe_session,
112 				      struct wlan_mlme_wep_cfg *wep_params,
113 				      uint8_t key_id,
114 				      uint8_t *default_key,
115 				      qdf_size_t *key_len)
116 {
117 	return mlme_get_wep_key(pe_session->vdev,
118 				wep_params,
119 				(MLME_WEP_DEFAULT_KEY_1 + key_id),
120 				default_key,
121 				key_len);
122 }
123 
lim_process_auth_shared_system_algo(struct mac_context * mac_ctx,tpSirMacMgmtHdr mac_hdr,tSirMacAuthFrameBody * rx_auth_frm_body,tSirMacAuthFrameBody * auth_frame,struct pe_session * pe_session)124 static void lim_process_auth_shared_system_algo(struct mac_context *mac_ctx,
125 		tpSirMacMgmtHdr mac_hdr,
126 		tSirMacAuthFrameBody *rx_auth_frm_body,
127 		tSirMacAuthFrameBody *auth_frame,
128 		struct pe_session *pe_session)
129 {
130 	uint32_t val;
131 	uint8_t cfg_privacy_opt_imp;
132 	struct tLimPreAuthNode *auth_node;
133 	uint8_t challenge_txt_arr[SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH] = {0};
134 
135 	pe_debug("=======> eSIR_SHARED_KEY");
136 	if (LIM_IS_AP_ROLE(pe_session))
137 		val = pe_session->privacy;
138 	else
139 		val = mac_ctx->mlme_cfg->wep_params.is_privacy_enabled;
140 
141 	cfg_privacy_opt_imp = (uint8_t) val;
142 	if (!cfg_privacy_opt_imp) {
143 		pe_err("rx Auth frame for unsupported auth algorithm %d "
144 			QDF_MAC_ADDR_FMT,
145 			rx_auth_frm_body->authAlgoNumber,
146 			QDF_MAC_ADDR_REF(mac_hdr->sa));
147 
148 		/*
149 		 * Authenticator does not have WEP
150 		 * implemented.
151 		 * Reject by sending Authentication frame
152 		 * with Auth algorithm not supported status
153 		 * code.
154 		 */
155 		auth_frame->authAlgoNumber = rx_auth_frm_body->authAlgoNumber;
156 		auth_frame->authTransactionSeqNumber =
157 			rx_auth_frm_body->authTransactionSeqNumber + 1;
158 		auth_frame->authStatusCode =
159 			STATUS_NOT_SUPPORTED_AUTH_ALG;
160 
161 		lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
162 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
163 				pe_session);
164 		return;
165 	} else {
166 		/* Create entry for this STA in pre-auth list */
167 		auth_node = lim_acquire_free_pre_auth_node(mac_ctx,
168 					&mac_ctx->lim.gLimPreAuthTimerTable);
169 		if (!auth_node) {
170 			pe_warn("Max preauth-nodes reached SA: "QDF_MAC_ADDR_FMT,
171 				QDF_MAC_ADDR_REF(mac_hdr->sa));
172 			return;
173 		}
174 
175 		qdf_mem_copy((uint8_t *) auth_node->peerMacAddr, mac_hdr->sa,
176 				sizeof(tSirMacAddr));
177 		auth_node->mlmState = eLIM_MLM_WT_AUTH_FRAME3_STATE;
178 		auth_node->authType =
179 			(tAniAuthType) rx_auth_frm_body->authAlgoNumber;
180 		auth_node->fSeen = 0;
181 		auth_node->fTimerStarted = 0;
182 		auth_node->seq_num = ((mac_hdr->seqControl.seqNumHi << 4) |
183 						(mac_hdr->seqControl.seqNumLo));
184 		auth_node->timestamp = qdf_mc_timer_get_system_ticks();
185 		lim_add_pre_auth_node(mac_ctx, auth_node);
186 
187 		pe_debug("Alloc new data: %pK id: %d peer "QDF_MAC_ADDR_FMT,
188 			 auth_node, auth_node->authNodeIdx,
189 			 QDF_MAC_ADDR_REF(mac_hdr->sa));
190 		/* / Create and activate Auth Response timer */
191 		if (tx_timer_change_context(&auth_node->timer,
192 				auth_node->authNodeIdx) != TX_SUCCESS) {
193 			/* Could not start Auth response timer. Log error */
194 			pe_warn("Unable to chg context auth response timer for peer "QDF_MAC_ADDR_FMT,
195 				QDF_MAC_ADDR_REF(mac_hdr->sa));
196 
197 			/*
198 			 * Send Auth frame with unspecified failure status code.
199 			 */
200 
201 			auth_frame->authAlgoNumber =
202 				rx_auth_frm_body->authAlgoNumber;
203 			auth_frame->authTransactionSeqNumber =
204 				rx_auth_frm_body->authTransactionSeqNumber + 1;
205 			auth_frame->authStatusCode =
206 				STATUS_UNSPECIFIED_FAILURE;
207 
208 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
209 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
210 				pe_session);
211 			lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
212 			return;
213 		}
214 
215 		/*
216 		 * get random bytes and use as challenge text.
217 		 */
218 		get_random_bytes(challenge_txt_arr,
219 				 SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
220 		qdf_mem_zero(auth_node->challengeText,
221 			     SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
222 		if (!qdf_mem_cmp(challenge_txt_arr,
223 				 auth_node->challengeText,
224 				 SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH)) {
225 			pe_err("Challenge text preparation failed SA: "QDF_MAC_ADDR_FMT,
226 			       QDF_MAC_ADDR_REF(mac_hdr->sa));
227 			auth_frame->authAlgoNumber =
228 				rx_auth_frm_body->authAlgoNumber;
229 			auth_frame->authTransactionSeqNumber =
230 				rx_auth_frm_body->authTransactionSeqNumber + 1;
231 			auth_frame->authStatusCode =
232 				STATUS_ASSOC_REJECTED_TEMPORARILY;
233 			lim_send_auth_mgmt_frame(mac_ctx,
234 						 auth_frame,
235 						 mac_hdr->sa,
236 						 LIM_NO_WEP_IN_FC,
237 						 pe_session);
238 			lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
239 			return;
240 		}
241 
242 		lim_activate_auth_rsp_timer(mac_ctx, auth_node);
243 		auth_node->fTimerStarted = 1;
244 
245 		qdf_mem_copy(auth_node->challengeText,
246 			     challenge_txt_arr,
247 			     sizeof(challenge_txt_arr));
248 		/*
249 		 * Sending Authenticaton frame with challenge.
250 		 */
251 		auth_frame->authAlgoNumber = rx_auth_frm_body->authAlgoNumber;
252 		auth_frame->authTransactionSeqNumber =
253 			rx_auth_frm_body->authTransactionSeqNumber + 1;
254 		auth_frame->authStatusCode = STATUS_SUCCESS;
255 		auth_frame->type = WLAN_ELEMID_CHALLENGE;
256 		auth_frame->length = SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH;
257 		qdf_mem_copy(auth_frame->challengeText,
258 				auth_node->challengeText,
259 				SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
260 		lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
261 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
262 				pe_session);
263 	}
264 }
265 
lim_process_auth_open_system_algo(struct mac_context * mac_ctx,tpSirMacMgmtHdr mac_hdr,tSirMacAuthFrameBody * rx_auth_frm_body,tSirMacAuthFrameBody * auth_frame,struct pe_session * pe_session)266 static void lim_process_auth_open_system_algo(struct mac_context *mac_ctx,
267 		tpSirMacMgmtHdr mac_hdr,
268 		tSirMacAuthFrameBody *rx_auth_frm_body,
269 		tSirMacAuthFrameBody *auth_frame,
270 		struct pe_session *pe_session)
271 {
272 	struct tLimPreAuthNode *auth_node;
273 
274 	pe_debug("=======> eSIR_OPEN_SYSTEM");
275 	/* Create entry for this STA in pre-auth list */
276 	auth_node = lim_acquire_free_pre_auth_node(mac_ctx,
277 				&mac_ctx->lim.gLimPreAuthTimerTable);
278 	if (!auth_node) {
279 		pe_warn("Max pre-auth nodes reached SA: "QDF_MAC_ADDR_FMT,
280 			QDF_MAC_ADDR_REF(mac_hdr->sa));
281 		return;
282 	}
283 	pe_debug("Alloc new data: %pK peer "QDF_MAC_ADDR_FMT, auth_node,
284 		 QDF_MAC_ADDR_REF(mac_hdr->sa));
285 	qdf_mem_copy((uint8_t *) auth_node->peerMacAddr,
286 			mac_hdr->sa, sizeof(tSirMacAddr));
287 	auth_node->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
288 	auth_node->authType = (tAniAuthType) rx_auth_frm_body->authAlgoNumber;
289 	auth_node->fSeen = 0;
290 	auth_node->fTimerStarted = 0;
291 	auth_node->seq_num = ((mac_hdr->seqControl.seqNumHi << 4) |
292 				(mac_hdr->seqControl.seqNumLo));
293 	auth_node->timestamp = qdf_mc_timer_get_system_ticks();
294 
295 	/* Check for MLO IE in Auth request in case of MLO connection */
296 	if (wlan_vdev_mlme_is_mlo_ap(pe_session->vdev) &&
297 	    rx_auth_frm_body->is_mlo_ie_present) {
298 		auth_node->is_mlo_ie_present = true;
299 		pe_debug("MLO IE is present in auth req");
300 	}
301 
302 	lim_add_pre_auth_node(mac_ctx, auth_node);
303 	/*
304 	 * Send Authenticaton frame with Success
305 	 * status code.
306 	 */
307 	auth_frame->authAlgoNumber = rx_auth_frm_body->authAlgoNumber;
308 	auth_frame->authTransactionSeqNumber =
309 			rx_auth_frm_body->authTransactionSeqNumber + 1;
310 	auth_frame->authStatusCode = STATUS_SUCCESS;
311 	lim_send_auth_mgmt_frame(mac_ctx, auth_frame, mac_hdr->sa,
312 					LIM_NO_WEP_IN_FC,
313 					pe_session);
314 }
315 
316 static QDF_STATUS
lim_validate_mac_address_in_auth_frame(struct mac_context * mac_ctx,tpSirMacMgmtHdr mac_hdr,struct qdf_mac_addr * mld_addr,uint8_t vdev_id)317 lim_validate_mac_address_in_auth_frame(struct mac_context *mac_ctx,
318 				       tpSirMacMgmtHdr mac_hdr,
319 				       struct qdf_mac_addr *mld_addr,
320 				       uint8_t vdev_id)
321 {
322 	struct wlan_objmgr_vdev *vdev;
323 
324 	/* SA is same as any of the device vdev, return failure */
325 	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(mac_ctx->pdev,
326 							 mac_hdr->sa,
327 							 WLAN_LEGACY_MAC_ID);
328 	if (vdev) {
329 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
330 		return QDF_STATUS_E_ALREADY;
331 	}
332 
333 	if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(mac_hdr->sa, &vdev_id))
334 		return QDF_STATUS_E_ALREADY;
335 
336 	if (qdf_is_macaddr_zero(mld_addr))
337 		return QDF_STATUS_SUCCESS;
338 
339 	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(mac_ctx->pdev,
340 							 mld_addr->bytes,
341 							 WLAN_LEGACY_MAC_ID);
342 	if (vdev) {
343 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
344 		return QDF_STATUS_E_ALREADY;
345 	}
346 
347 	if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(mld_addr->bytes, &vdev_id))
348 		return QDF_STATUS_E_ALREADY;
349 
350 	return QDF_STATUS_SUCCESS;
351 }
352 
353 #ifdef WLAN_FEATURE_SAE
354 #ifdef WLAN_FEATURE_11BE_MLO
355 /**
356  * lim_external_auth_update_pre_auth_node_mld() - Update preauth node mld addr
357  * for the peer performing external authentication
358  * @auth_node: Pointer to pre-auth node to be added to the list
359  * @peer_mld: Peer MLD address
360  *
361  * Return: None
362  */
363 static void
lim_external_auth_update_pre_auth_node_mld(struct tLimPreAuthNode * auth_node,struct qdf_mac_addr * peer_mld)364 lim_external_auth_update_pre_auth_node_mld(struct tLimPreAuthNode *auth_node,
365 					   struct qdf_mac_addr *peer_mld)
366 {
367 	qdf_mem_copy((uint8_t *)auth_node->peer_mld, peer_mld->bytes,
368 		     QDF_MAC_ADDR_SIZE);
369 }
370 #else
371 static void
lim_external_auth_update_pre_auth_node_mld(struct tLimPreAuthNode * auth_node,struct qdf_mac_addr * peer_mld)372 lim_external_auth_update_pre_auth_node_mld(struct tLimPreAuthNode *auth_node,
373 					   struct qdf_mac_addr *peer_mld)
374 {
375 }
376 #endif
377 
378 /**
379  * lim_external_auth_add_pre_auth_node()- Add preauth node for the peer
380  *					  performing external authentication
381  * @mac_ctx: MAC context
382  * @mac_hdr: Mac header of the packet
383  * @mlm_state: MLM state to be marked to track SAE authentication
384  * @peer_mld: Peer MLD address
385  *
386  * Return: None
387  */
lim_external_auth_add_pre_auth_node(struct mac_context * mac_ctx,tpSirMacMgmtHdr mac_hdr,tLimMlmStates mlm_state,struct qdf_mac_addr * peer_mld)388 static void lim_external_auth_add_pre_auth_node(struct mac_context *mac_ctx,
389 						tpSirMacMgmtHdr mac_hdr,
390 						tLimMlmStates mlm_state,
391 						struct qdf_mac_addr *peer_mld)
392 {
393 	struct tLimPreAuthNode *auth_node;
394 	tpLimPreAuthTable preauth_table = &mac_ctx->lim.gLimPreAuthTimerTable;
395 
396 	pe_debug("=======> eSIR_AUTH_TYPE_SAE");
397 	/* Create entry for this STA in pre-auth list */
398 	auth_node = lim_acquire_free_pre_auth_node(mac_ctx, preauth_table);
399 	if (!auth_node) {
400 		pe_debug("Max pre-auth nodes reached " QDF_MAC_ADDR_FMT,
401 			 QDF_MAC_ADDR_REF(mac_hdr->sa));
402 		return;
403 	}
404 	pe_debug("Creating preauth node for SAE peer " QDF_MAC_ADDR_FMT,
405 		 QDF_MAC_ADDR_REF(mac_hdr->sa));
406 	qdf_mem_copy((uint8_t *)auth_node->peerMacAddr,
407 		     mac_hdr->sa, sizeof(tSirMacAddr));
408 	lim_external_auth_update_pre_auth_node_mld(auth_node, peer_mld);
409 
410 	auth_node->mlmState = mlm_state;
411 	auth_node->authType = eSIR_AUTH_TYPE_SAE;
412 	auth_node->timestamp = qdf_mc_timer_get_system_ticks();
413 	auth_node->seq_num = ((mac_hdr->seqControl.seqNumHi << 4) |
414 			      (mac_hdr->seqControl.seqNumLo));
415 	auth_node->assoc_req.present = false;
416 	lim_add_pre_auth_node(mac_ctx, auth_node);
417 }
418 
lim_sae_auth_cleanup_retry(struct mac_context * mac_ctx,uint8_t vdev_id)419 void lim_sae_auth_cleanup_retry(struct mac_context *mac_ctx,
420 				uint8_t vdev_id)
421 {
422 	struct pe_session *pe_session;
423 
424 	pe_session = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
425 	if (!pe_session) {
426 		pe_err("session not found for given vdev_id %d", vdev_id);
427 		return;
428 	}
429 
430 	pe_debug("sae auth cleanup for vdev_id %d", vdev_id);
431 	lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
432 	mlme_free_sae_auth_retry(pe_session->vdev);
433 }
434 
435 #define SAE_AUTH_ALGO_BYTES 2
436 #define SAE_AUTH_SEQ_NUM_BYTES 2
437 #define SAE_AUTH_SEQ_OFFSET 1
438 
439 /**
440  * lim_is_sae_auth_algo_match()- Match SAE auth seq in queued SAE auth and
441  * SAE auth rx frame
442  * @queued_frame: Pointer to queued SAE auth retry frame
443  * @q_len: length of queued sae auth retry frame
444  * @rx_pkt_info: Rx packet
445  *
446  * Return: True if SAE auth seq is matched else false
447  */
lim_is_sae_auth_algo_match(uint8_t * queued_frame,uint16_t q_len,uint8_t * rx_pkt_info)448 static bool lim_is_sae_auth_algo_match(uint8_t *queued_frame, uint16_t q_len,
449 				       uint8_t *rx_pkt_info)
450 {
451 	tpSirMacMgmtHdr qmac_hdr = (tpSirMacMgmtHdr)queued_frame;
452 	uint16_t *rxbody_ptr, *qbody_ptr, rxframe_len, min_len;
453 
454 	min_len = sizeof(tSirMacMgmtHdr) + SAE_AUTH_ALGO_BYTES +
455 			SAE_AUTH_SEQ_NUM_BYTES;
456 
457 	rxframe_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
458 	if (rxframe_len < min_len || q_len < min_len) {
459 		pe_debug("rxframe_len %d, queued_frame_len %d, min_len %d",
460 			 rxframe_len, q_len, min_len);
461 		return false;
462 	}
463 
464 	rxbody_ptr = (uint16_t *)WMA_GET_RX_MPDU_DATA(rx_pkt_info);
465 	qbody_ptr = (uint16_t *)((uint8_t *)qmac_hdr + sizeof(tSirMacMgmtHdr));
466 
467 	pe_debug("sae_auth : rx pkt auth seq %d queued pkt auth seq %d",
468 		 rxbody_ptr[SAE_AUTH_SEQ_OFFSET],
469 		 qbody_ptr[SAE_AUTH_SEQ_OFFSET]);
470 	if (rxbody_ptr[SAE_AUTH_SEQ_OFFSET] ==
471 	    qbody_ptr[SAE_AUTH_SEQ_OFFSET])
472 		return true;
473 
474 	return false;
475 }
476 
477 #ifdef WLAN_FEATURE_11BE_MLO
478 /*
479  * lim_skip_sae_fixed_field: This API is called to parse the SAE auth frame and
480  * skip the SAE fixed fields
481  * @body_ptr: Pointer to a SAE auth frame
482  * @frame_len: Length of SAE auth frame
483  * @ie_ptr: Buffer to be searched for the Multi-Link element or the start of the
484  * Multi-Link element fragment sequence
485  * @ie_len: Length of the buffer
486  *
487  * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
488  * the reason for error in the case of failure
489  */
lim_skip_sae_fixed_field(uint8_t * body_ptr,uint32_t frame_len,uint8_t ** ie_ptr,qdf_size_t * ie_len)490 static QDF_STATUS lim_skip_sae_fixed_field(uint8_t *body_ptr,
491 					   uint32_t frame_len,
492 					   uint8_t **ie_ptr, qdf_size_t *ie_len)
493 {
494 	uint16_t sae_status_code = 0;
495 	uint16_t sae_group_id = 0;
496 
497 	if (!body_ptr || !frame_len || !ie_ptr || !ie_len)
498 		return QDF_STATUS_E_NULL_VALUE;
499 
500 	if (frame_len < (SAE_AUTH_GROUP_ID_OFFSET + 2))
501 		return QDF_STATUS_E_INVAL;
502 
503 	sae_status_code = *(uint16_t *)(body_ptr + SAE_AUTH_STATUS_CODE_OFFSET);
504 
505 	if (sae_status_code != WLAN_SAE_STATUS_HASH_TO_ELEMENT &&
506 	    sae_status_code != WLAN_SAE_STATUS_PK)
507 		return QDF_STATUS_E_NOSUPPORT;
508 
509 	sae_group_id = *(uint16_t *)(body_ptr + SAE_AUTH_GROUP_ID_OFFSET);
510 	*ie_ptr = body_ptr + SAE_AUTH_GROUP_ID_OFFSET + 2;
511 	*ie_len = frame_len - SAE_AUTH_GROUP_ID_OFFSET - 2;
512 
513 	switch (sae_group_id) {
514 	case SAE_GROUP_ID_19:
515 		if (*ie_len < SAE_GROUP_19_FIXED_FIELDS_LEN)
516 			return QDF_STATUS_E_NOSUPPORT;
517 
518 		*ie_ptr = *ie_ptr + SAE_GROUP_19_FIXED_FIELDS_LEN;
519 		*ie_len = *ie_len - SAE_GROUP_19_FIXED_FIELDS_LEN;
520 		break;
521 	case SAE_GROUP_ID_20:
522 		if (*ie_len < SAE_GROUP_20_FIXED_FIELDS_LEN)
523 			return QDF_STATUS_E_NOSUPPORT;
524 
525 		*ie_ptr = *ie_ptr + SAE_GROUP_20_FIXED_FIELDS_LEN;
526 		*ie_len = *ie_len - SAE_GROUP_20_FIXED_FIELDS_LEN;
527 		break;
528 	case SAE_GROUP_ID_21:
529 		if (*ie_len < SAE_GROUP_21_FIXED_FIELDS_LEN)
530 			return QDF_STATUS_E_NOSUPPORT;
531 
532 		*ie_ptr = *ie_ptr + SAE_GROUP_21_FIXED_FIELDS_LEN;
533 		*ie_len = *ie_len - SAE_GROUP_21_FIXED_FIELDS_LEN;
534 		break;
535 	default:
536 		return QDF_STATUS_E_NOSUPPORT;
537 	}
538 
539 	if (*ie_len == 0)
540 		return QDF_STATUS_E_NOSUPPORT;
541 
542 	return QDF_STATUS_SUCCESS;
543 }
544 
545 /**
546  * lim_get_sta_mld_address: This API is called to get the STA MLD address
547  * from SAE 1st auth frame.
548  * @vdev: vdev
549  * @body_ptr: Pointer to a SAE auth frame
550  * @frame_len: Length of SAE auth frame
551  * @peer_mld: fill peer MLD address
552  *
553  * Return: void
554  */
lim_get_sta_mld_address(struct wlan_objmgr_vdev * vdev,uint8_t * body_ptr,uint32_t frame_len,struct qdf_mac_addr * peer_mld)555 static void lim_get_sta_mld_address(struct wlan_objmgr_vdev *vdev,
556 				    uint8_t *body_ptr, uint32_t frame_len,
557 				    struct qdf_mac_addr *peer_mld)
558 {
559 	uint8_t *ie_ptr = NULL;
560 	uint8_t *ml_ie = NULL;
561 	qdf_size_t ml_ie_total_len = 0;
562 	qdf_size_t ie_len = 0;
563 	QDF_STATUS status;
564 
565 	if (!wlan_cm_is_sae_auth_addr_conversion_required(vdev))
566 		return;
567 
568 	status = lim_skip_sae_fixed_field(body_ptr, frame_len, &ie_ptr,
569 					  &ie_len);
570 	if (QDF_IS_STATUS_ERROR(status)) {
571 		pe_debug("Failed in skip SAE field");
572 		return;
573 	}
574 
575 	status = util_find_mlie(ie_ptr, ie_len, &ml_ie, &ml_ie_total_len);
576 	if (QDF_IS_STATUS_ERROR(status)) {
577 		pe_debug("ML IE not found");
578 		return;
579 	}
580 
581 	util_get_bvmlie_mldmacaddr(ml_ie, ml_ie_total_len, peer_mld);
582 }
583 
584 /**
585  * lim_update_link_to_mld_address:This API is called to update SA and DA address
586  * @mac_ctx: Pointer to mac context
587  * @vdev: vdev
588  * @mac_hdr: Pointer to MAC management header
589  *
590  * Return: void
591  */
lim_update_link_to_mld_address(struct mac_context * mac_ctx,struct wlan_objmgr_vdev * vdev,tpSirMacMgmtHdr mac_hdr)592 static QDF_STATUS lim_update_link_to_mld_address(struct mac_context *mac_ctx,
593 						 struct wlan_objmgr_vdev *vdev,
594 						 tpSirMacMgmtHdr mac_hdr)
595 {
596 	struct qdf_mac_addr *self_mld_addr;
597 	struct tLimPreAuthNode *pre_auth_node;
598 	struct qdf_mac_addr peer_mld_addr;
599 	struct qdf_mac_addr *peer_roaming_mld_addr;
600 	enum QDF_OPMODE opmode;
601 	QDF_STATUS status;
602 
603 	if (!wlan_cm_is_sae_auth_addr_conversion_required(vdev))
604 		return QDF_STATUS_SUCCESS;
605 
606 	opmode = wlan_vdev_mlme_get_opmode(vdev);
607 	self_mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev);
608 
609 	switch (opmode) {
610 	case QDF_SAP_MODE:
611 		pre_auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa);
612 		if (!pre_auth_node)
613 			return QDF_STATUS_E_INVAL;
614 
615 		if (qdf_is_macaddr_zero(
616 			(struct qdf_mac_addr *)pre_auth_node->peer_mld))
617 			return QDF_STATUS_SUCCESS;
618 
619 		qdf_mem_copy(mac_hdr->sa, pre_auth_node->peer_mld,
620 			     QDF_MAC_ADDR_SIZE);
621 		qdf_mem_copy(mac_hdr->bssId, self_mld_addr->bytes,
622 			     QDF_MAC_ADDR_SIZE);
623 		break;
624 	case QDF_STA_MODE:
625 		if (!wlan_cm_is_vdev_roaming(vdev)) {
626 			status = wlan_vdev_get_bss_peer_mld_mac(vdev,
627 								&peer_mld_addr);
628 			if (QDF_IS_STATUS_ERROR(status))
629 				return status;
630 		} else {
631 			peer_roaming_mld_addr =
632 				wlan_cm_roaming_get_peer_mld_addr(vdev);
633 			if (!peer_roaming_mld_addr)
634 				return QDF_STATUS_E_FAILURE;
635 
636 			peer_mld_addr = *peer_roaming_mld_addr;
637 		}
638 
639 		qdf_mem_copy(mac_hdr->sa, peer_mld_addr.bytes,
640 			     QDF_MAC_ADDR_SIZE);
641 		qdf_mem_copy(mac_hdr->bssId, peer_mld_addr.bytes,
642 			     QDF_MAC_ADDR_SIZE);
643 		break;
644 	default:
645 		return QDF_STATUS_SUCCESS;
646 	}
647 
648 	qdf_mem_copy(mac_hdr->da, self_mld_addr->bytes, QDF_MAC_ADDR_SIZE);
649 
650 	return QDF_STATUS_SUCCESS;
651 }
652 #else
lim_get_sta_mld_address(struct wlan_objmgr_vdev * vdev,uint8_t * body_ptr,uint32_t frame_len,struct qdf_mac_addr * peer_mld)653 static void lim_get_sta_mld_address(struct wlan_objmgr_vdev *vdev,
654 				    uint8_t *body_ptr, uint32_t frame_len,
655 				    struct qdf_mac_addr *peer_mld)
656 {
657 }
658 
lim_update_link_to_mld_address(struct mac_context * mac_ctx,struct wlan_objmgr_vdev * vdev,tpSirMacMgmtHdr mac_hdr)659 static QDF_STATUS lim_update_link_to_mld_address(struct mac_context *mac_ctx,
660 						 struct wlan_objmgr_vdev *vdev,
661 						 tpSirMacMgmtHdr mac_hdr)
662 {
663 	return QDF_STATUS_SUCCESS;
664 }
665 #endif
666 
667 static bool
lim_check_and_trigger_pmf_sta_deletion(struct mac_context * mac,struct pe_session * pe_session,tpSirMacMgmtHdr mac_hdr)668 lim_check_and_trigger_pmf_sta_deletion(struct mac_context *mac,
669 				       struct pe_session *pe_session,
670 				       tpSirMacMgmtHdr mac_hdr)
671 {
672 	tpDphHashNode sta_ds_ptr = NULL;
673 	tLimMlmDisassocReq *mlm_disassoc_req = NULL;
674 	tLimMlmDeauthReq *mlm_deauth_req = NULL;
675 	bool is_connected = true;
676 	uint16_t associd = 0;
677 
678 	sta_ds_ptr = dph_lookup_hash_entry(mac, mac_hdr->sa, &associd,
679 					   &pe_session->dph.dphHashTable);
680 	if (!sta_ds_ptr)
681 		return false;
682 
683 	mlm_disassoc_req = mac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
684 	if (mlm_disassoc_req &&
685 	    !qdf_mem_cmp(mac_hdr->sa, &mlm_disassoc_req->peer_macaddr.bytes,
686 			 QDF_MAC_ADDR_SIZE)) {
687 		pe_debug("TODO:Ack pending for disassoc frame Issue del sta for "
688 			 QDF_MAC_ADDR_FMT,
689 			 QDF_MAC_ADDR_REF(mlm_disassoc_req->peer_macaddr.bytes));
690 		lim_process_disassoc_ack_timeout(mac);
691 		is_connected = false;
692 	}
693 
694 	mlm_deauth_req = mac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
695 	if (mlm_deauth_req &&
696 	    !qdf_mem_cmp(mac_hdr->sa, &mlm_deauth_req->peer_macaddr.bytes,
697 			 QDF_MAC_ADDR_SIZE)) {
698 		pe_debug("TODO:Ack for deauth frame is pending Issue del sta for "
699 			 QDF_MAC_ADDR_FMT,
700 			 QDF_MAC_ADDR_REF(mlm_deauth_req->peer_macaddr.bytes));
701 		lim_process_deauth_ack_timeout(mac, pe_session->vdev_id);
702 		is_connected = false;
703 	}
704 
705 	/*
706 	 * pStaDS != NULL and is_connected = 1 means the STA is already
707 	 * connected, But SAP received the Auth from that station. For non-PMF
708 	 * connection send Deauth frame as STA will retry to connect back. The
709 	 * reason for above logic is captured in CR620403. If we silently drop
710 	 * the auth, the subsequent EAPOL exchange will fail & peer STA will
711 	 * keep trying until DUT SAP/GO gets a kickout event from FW & cleans
712 	 * up.
713 	 *
714 	 * For PMF connection the AP should not tear down or otherwise modify
715 	 * the state of the existing association until the SA-Query procedure
716 	 * determines that the original SA is invalid.
717 	 */
718 	if (is_connected && !sta_ds_ptr->rmfEnabled) {
719 		pe_err("STA is already connected but received auth frame"
720 		       "Send the Deauth and lim Delete Station Context"
721 		       "(associd: %d) sta mac" QDF_MAC_ADDR_FMT,
722 		       associd, QDF_MAC_ADDR_REF(mac_hdr->sa));
723 
724 		lim_send_deauth_mgmt_frame(mac, REASON_UNSPEC_FAILURE,
725 					   mac_hdr->sa, pe_session, false);
726 		lim_trigger_sta_deletion(mac, sta_ds_ptr, pe_session);
727 
728 		return true;
729 	}
730 
731 	return false;
732 }
733 
734 /**
735  * lim_process_sae_auth_frame()-Process SAE authentication frame
736  * @mac_ctx: MAC context
737  * @rx_pkt_info: Rx packet
738  * @pe_session: PE session
739  *
740  * Return: None
741  */
lim_process_sae_auth_frame(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * pe_session)742 static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
743 		uint8_t *rx_pkt_info, struct pe_session *pe_session)
744 {
745 	tpSirMacMgmtHdr mac_hdr;
746 	uint32_t frame_len;
747 	uint8_t *body_ptr;
748 	enum rxmgmt_flags rx_flags = RXMGMT_FLAG_NONE;
749 	struct sae_auth_retry *sae_retry;
750 	uint16_t sae_auth_seq = 0, sae_status_code = 0;
751 	uint16_t auth_algo;
752 	QDF_STATUS status;
753 
754 	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
755 	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
756 	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
757 
758 	auth_algo = *(uint16_t *)body_ptr;
759 	if (frame_len >= (SAE_AUTH_STATUS_CODE_OFFSET + 2)) {
760 		sae_auth_seq = *(uint16_t *)(body_ptr + SAE_AUTH_SEQ_NUM_OFFSET);
761 		sae_status_code = *(uint16_t *)(body_ptr +
762 						SAE_AUTH_STATUS_CODE_OFFSET);
763 	}
764 
765 	pe_nofl_rl_info("vdev:%d SAE Auth RX type %d subtype %d trans_seq_num:%d from " QDF_MAC_ADDR_FMT,
766 			pe_session->vdev_id,
767 			mac_hdr->fc.type, mac_hdr->fc.subType,
768 			sae_auth_seq,
769 			QDF_MAC_ADDR_REF(mac_hdr->sa));
770 
771 	if (LIM_IS_STA_ROLE(pe_session) &&
772 	    pe_session->limMlmState != eLIM_MLM_WT_SAE_AUTH_STATE)
773 		pe_err("SAE auth response for STA in unexpected state %x",
774 		       pe_session->limMlmState);
775 
776 	if (LIM_IS_AP_ROLE(pe_session)) {
777 		struct tLimPreAuthNode *pre_auth_node;
778 		struct qdf_mac_addr peer_mld = {0};
779 
780 		rx_flags = RXMGMT_FLAG_EXTERNAL_AUTH;
781 		/*
782 		 * Add preauth node when the first SAE authentication frame
783 		 * is received and mark state as authenticating.
784 		 * It's not good to track SAE authentication frames with
785 		 * authTransactionSeqNumber as it's subjected to
786 		 * SAE protocol optimizations.
787 		 */
788 		pre_auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa);
789 		if (!pre_auth_node ||
790 		    (pre_auth_node->mlmState != eLIM_MLM_WT_SAE_AUTH_STATE)) {
791 			if (pre_auth_node) {
792 				pe_debug("Delete existing preauth node for SAE peer in state: %u "
793 					 QDF_MAC_ADDR_FMT,
794 					 pre_auth_node->mlmState,
795 					 QDF_MAC_ADDR_REF(mac_hdr->sa));
796 				lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
797 			}
798 			/* case: when SAP receives auth SAE 1st frame with
799 			 * SA, DA and bssid as link address. Driver needs to
800 			 * get the STA MLD address and save it in preauth node
801 			 * struct for further use.
802 			 * For the 1st SAE RX frame,
803 			 * driver does not need to convert it in mld_address.
804 			 */
805 			lim_get_sta_mld_address(pe_session->vdev, body_ptr,
806 						frame_len, &peer_mld);
807 			status = lim_validate_mac_address_in_auth_frame(mac_ctx,
808 									mac_hdr,
809 									&peer_mld,
810 									pe_session->vdev_id);
811 			if (QDF_IS_STATUS_ERROR(status)) {
812 				pe_debug("Drop SAE auth, duplicate entity found");
813 				return;
814 			}
815 
816 			lim_external_auth_add_pre_auth_node(mac_ctx, mac_hdr,
817 						eLIM_MLM_WT_SAE_AUTH_STATE,
818 						&peer_mld);
819 		} else {
820 			/* case: when SAP receives Auth SAE 3rd frame with
821 			 * SA, DA and bssid as link address. Needs to convert
822 			 * it into MLD address and send it userspace.
823 			 */
824 			status = lim_update_link_to_mld_address(mac_ctx,
825 								pe_session->vdev,
826 								mac_hdr);
827 			if (QDF_IS_STATUS_ERROR(status)) {
828 				pe_debug("SAE address conversion failure with status:%d",
829 					 status);
830 				return;
831 			}
832 		}
833 	}
834 
835 	sae_retry = mlme_get_sae_auth_retry(pe_session->vdev);
836 	if (LIM_IS_STA_ROLE(pe_session) && sae_retry &&
837 	    sae_retry->sae_auth.ptr) {
838 		if (lim_is_sae_auth_algo_match(sae_retry->sae_auth.ptr,
839 					       sae_retry->sae_auth.len,
840 					       rx_pkt_info))
841 			lim_sae_auth_cleanup_retry(mac_ctx,
842 						   pe_session->vdev_id);
843 	}
844 
845 	if (LIM_IS_STA_ROLE(pe_session)) {
846 		/*
847 		 * Cache the connectivity event with link address.
848 		 * So call the Connectivity logging API before address
849 		 * translation while forwarding the frame to userspace.
850 		 */
851 		wlan_connectivity_mgmt_event(
852 				mac_ctx->psoc,
853 				(struct wlan_frame_hdr *)mac_hdr,
854 				pe_session->vdev_id, sae_status_code, 0,
855 				WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
856 				auth_algo, sae_auth_seq, sae_auth_seq, 0,
857 				WLAN_AUTH_RESP);
858 
859 		lim_cp_stats_cstats_log_auth_evt(pe_session, CSTATS_DIR_RX,
860 						 auth_algo, sae_auth_seq,
861 						 sae_status_code);
862 
863 		status = lim_update_link_to_mld_address(mac_ctx,
864 							pe_session->vdev,
865 							mac_hdr);
866 		if (QDF_IS_STATUS_ERROR(status)) {
867 			pe_debug("vdev:%d STA SAE address conversion failed status:%d",
868 				 pe_session->vdev_id, status);
869 			return;
870 		}
871 	}
872 
873 	lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
874 				    (uint8_t *)mac_hdr,
875 				    frame_len + sizeof(tSirMacMgmtHdr),
876 				    pe_session->vdev_id,
877 				    WMA_GET_RX_FREQ(rx_pkt_info),
878 				    WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
879 				    rx_flags);
880 }
881 #else
lim_process_sae_auth_frame(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * pe_session)882 static inline void  lim_process_sae_auth_frame(struct mac_context *mac_ctx,
883 		uint8_t *rx_pkt_info, struct pe_session *pe_session)
884 {}
885 #endif
886 
lim_process_ft_auth_frame(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * pe_session)887 static void lim_process_ft_auth_frame(struct mac_context *mac_ctx,
888 				      uint8_t *rx_pkt_info,
889 				      struct pe_session *pe_session)
890 {
891 	tpSirMacMgmtHdr mac_hdr;
892 	uint32_t frame_len;
893 	uint8_t *body_ptr;
894 	enum rxmgmt_flags rx_flags = RXMGMT_FLAG_NONE;
895 	uint16_t auth_algo;
896 
897 	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
898 	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
899 	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
900 
901 	pe_debug("FT Auth RX type %d subtype %d from " QDF_MAC_ADDR_FMT,
902 		 mac_hdr->fc.type, mac_hdr->fc.subType,
903 		 QDF_MAC_ADDR_REF(mac_hdr->sa));
904 
905 	if (LIM_IS_AP_ROLE(pe_session)) {
906 		struct tLimPreAuthNode *sta_pre_auth_ctx;
907 
908 		rx_flags = RXMGMT_FLAG_EXTERNAL_AUTH;
909 		/* Extract pre-auth context for the STA, if any. */
910 		sta_pre_auth_ctx = lim_search_pre_auth_list(mac_ctx,
911 							    mac_hdr->sa);
912 		if (sta_pre_auth_ctx) {
913 			pe_debug("STA Auth ctx have ininted");
914 			/* Pre-auth context exists for the STA */
915 			if (sta_pre_auth_ctx->mlmState == eLIM_MLM_WT_FT_AUTH_STATE) {
916 				pe_warn("previous Auth not completed, don't process this auth frame");
917 				return;
918 			}
919 			lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
920 		}
921 
922 		/* Create entry for this STA in pre-auth list */
923 		sta_pre_auth_ctx = lim_acquire_free_pre_auth_node(mac_ctx,
924 			&mac_ctx->lim.gLimPreAuthTimerTable);
925 		if (!sta_pre_auth_ctx) {
926 			pe_warn("Max pre-auth nodes reached "QDF_MAC_ADDR_FMT,
927 				QDF_MAC_ADDR_REF(mac_hdr->sa));
928 			return;
929 		}
930 		pe_debug("Alloc new data: %pK peer "QDF_MAC_ADDR_FMT,
931 			 sta_pre_auth_ctx, QDF_MAC_ADDR_REF(mac_hdr->sa));
932 		auth_algo = *(uint16_t *)body_ptr;
933 		qdf_mem_copy((uint8_t *)sta_pre_auth_ctx->peerMacAddr,
934 			     mac_hdr->sa, sizeof(tSirMacAddr));
935 		sta_pre_auth_ctx->mlmState = eLIM_MLM_WT_FT_AUTH_STATE;
936 		sta_pre_auth_ctx->authType = (tAniAuthType) auth_algo;
937 		sta_pre_auth_ctx->fSeen = 0;
938 		sta_pre_auth_ctx->fTimerStarted = 0;
939 		sta_pre_auth_ctx->seq_num =
940 				((mac_hdr->seqControl.seqNumHi << 4) |
941 				(mac_hdr->seqControl.seqNumLo));
942 		sta_pre_auth_ctx->timestamp = qdf_mc_timer_get_system_ticks();
943 		lim_add_pre_auth_node(mac_ctx, sta_pre_auth_ctx);
944 		lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
945 			(uint8_t *)mac_hdr,
946 			frame_len + sizeof(tSirMacMgmtHdr),
947 			pe_session->smeSessionId,
948 			WMA_GET_RX_FREQ(rx_pkt_info),
949 			WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
950 			rx_flags);
951 	}
952 }
953 
954 static uint8_t
lim_get_pasn_peer_vdev_id(struct mac_context * mac,uint8_t * bssid)955 lim_get_pasn_peer_vdev_id(struct mac_context *mac, uint8_t *bssid)
956 {
957 	struct wlan_objmgr_peer *peer;
958 	uint8_t vdev_id;
959 
960 	peer = wlan_objmgr_get_peer_by_mac(mac->psoc, bssid,
961 					   WLAN_MGMT_RX_ID);
962 	if (!peer) {
963 		pe_err("PASN peer doesn't exist for bssid: " QDF_MAC_ADDR_FMT,
964 		       QDF_MAC_ADDR_REF(bssid));
965 		return WLAN_UMAC_VDEV_ID_MAX;
966 	}
967 
968 	vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer));
969 	wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_RX_ID);
970 
971 	return vdev_id;
972 }
973 
974 /**
975  * lim_process_pasn_auth_frame()- Process PASN authentication frame
976  * @mac_ctx: MAC context
977  * @vdev_id: Vdev identifier
978  * @rx_pkt_info: Rx packet
979  *
980  * Return: QDF_STATUS
981  */
982 static QDF_STATUS
lim_process_pasn_auth_frame(struct mac_context * mac_ctx,uint8_t vdev_id,uint8_t * rx_pkt_info)983 lim_process_pasn_auth_frame(struct mac_context *mac_ctx,
984 			    uint8_t vdev_id,
985 			    uint8_t *rx_pkt_info)
986 {
987 	tpSirMacMgmtHdr mac_hdr;
988 	uint32_t frame_len;
989 	uint8_t *body_ptr;
990 	enum rxmgmt_flags rx_flags = RXMGMT_FLAG_NONE;
991 
992 	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
993 	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
994 	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
995 
996 	pe_debug("vdev_id:%d", vdev_id);
997 	lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
998 				    (uint8_t *)mac_hdr,
999 				    frame_len + sizeof(tSirMacMgmtHdr),
1000 				    vdev_id, WMA_GET_RX_FREQ(rx_pkt_info),
1001 				    WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
1002 				    rx_flags);
1003 
1004 	return QDF_STATUS_SUCCESS;
1005 }
1006 
lim_process_auth_frame_type1(struct mac_context * mac_ctx,tpSirMacMgmtHdr mac_hdr,tSirMacAuthFrameBody * rx_auth_frm_body,uint8_t * rx_pkt_info,uint16_t curr_seq_num,tSirMacAuthFrameBody * auth_frame,struct pe_session * pe_session)1007 static void lim_process_auth_frame_type1(struct mac_context *mac_ctx,
1008 		tpSirMacMgmtHdr mac_hdr,
1009 		tSirMacAuthFrameBody *rx_auth_frm_body,
1010 		uint8_t *rx_pkt_info, uint16_t curr_seq_num,
1011 		tSirMacAuthFrameBody *auth_frame, struct pe_session *pe_session)
1012 {
1013 	tpDphHashNode sta_ds_ptr = NULL;
1014 	struct tLimPreAuthNode *auth_node;
1015 	uint32_t maxnum_preauth;
1016 	uint16_t associd = 0;
1017 	QDF_STATUS status;
1018 
1019 	if (lim_check_and_trigger_pmf_sta_deletion(mac_ctx, pe_session,
1020 						   mac_hdr))
1021 		return;
1022 
1023 	/* Check if there exists pre-auth context for this STA */
1024 	auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa);
1025 	if (auth_node) {
1026 		/* Pre-auth context exists for the STA */
1027 		if (!(mac_hdr->fc.retry == 0 ||
1028 					auth_node->seq_num != curr_seq_num)) {
1029 			/*
1030 			 * This can happen when first authentication frame is
1031 			 * received but ACK lost at STA side, in this case 2nd
1032 			 * auth frame is already in transmission queue
1033 			 */
1034 			pe_warn("STA is initiating Auth after ACK lost");
1035 			return;
1036 		}
1037 		/*
1038 		 * STA is initiating brand-new Authentication
1039 		 * sequence after local Auth Response timeout Or STA
1040 		 * retrying to transmit First Auth frame due to packet
1041 		 * drop OTA Delete Pre-auth node and fall through.
1042 		 */
1043 		if (auth_node->fTimerStarted)
1044 			lim_deactivate_and_change_per_sta_id_timer(
1045 					mac_ctx, eLIM_AUTH_RSP_TIMER,
1046 					auth_node->authNodeIdx);
1047 		pe_debug("STA is initiating brand-new Auth");
1048 		lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
1049 		/*
1050 		 *  SAP Mode:Disassociate the station and
1051 		 *  delete its entry if we have its entry
1052 		 *  already and received "auth" from the
1053 		 *  same station.
1054 		 *  SAP dphHashTable.size = 8
1055 		 */
1056 		for (associd = 0; associd < pe_session->dph.dphHashTable.size;
1057 		     associd++) {
1058 			sta_ds_ptr = dph_get_hash_entry(mac_ctx, associd,
1059 							&pe_session->dph.dphHashTable);
1060 			if (!sta_ds_ptr)
1061 				continue;
1062 
1063 			if (sta_ds_ptr->valid && (!qdf_mem_cmp(
1064 					(uint8_t *)&sta_ds_ptr->staAddr,
1065 					(uint8_t *) &(mac_hdr->sa),
1066 					(uint8_t) sizeof(tSirMacAddr))))
1067 				break;
1068 
1069 			sta_ds_ptr = NULL;
1070 		}
1071 
1072 		if (sta_ds_ptr && !sta_ds_ptr->rmfEnabled) {
1073 			pe_debug("lim Del Sta Ctx associd: %d sta mac"
1074 				 QDF_MAC_ADDR_FMT, associd,
1075 				 QDF_MAC_ADDR_REF(sta_ds_ptr->staAddr));
1076 			lim_send_deauth_mgmt_frame(mac_ctx,
1077 				REASON_UNSPEC_FAILURE,
1078 				(uint8_t *)auth_node->peerMacAddr,
1079 				pe_session, false);
1080 			lim_trigger_sta_deletion(mac_ctx, sta_ds_ptr,
1081 				pe_session);
1082 			return;
1083 		}
1084 	}
1085 
1086 	maxnum_preauth = mac_ctx->mlme_cfg->lfr.max_num_pre_auth;
1087 	if (mac_ctx->lim.gLimNumPreAuthContexts == maxnum_preauth &&
1088 	    !lim_delete_open_auth_pre_auth_node(mac_ctx)) {
1089 		pe_err("Max no of preauth context reached");
1090 		/*
1091 		 * Maximum number of pre-auth contexts reached.
1092 		 * Send Authentication frame with unspecified failure
1093 		 */
1094 		auth_frame->authAlgoNumber = rx_auth_frm_body->authAlgoNumber;
1095 		auth_frame->authTransactionSeqNumber =
1096 			rx_auth_frm_body->authTransactionSeqNumber + 1;
1097 		auth_frame->authStatusCode =
1098 			STATUS_UNSPECIFIED_FAILURE;
1099 
1100 		lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1101 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
1102 				pe_session);
1103 		return;
1104 	}
1105 	/* No Pre-auth context exists for the STA. */
1106 	if (lim_is_auth_algo_supported(mac_ctx,
1107 			(tAniAuthType) rx_auth_frm_body->authAlgoNumber,
1108 			pe_session)) {
1109 		struct qdf_mac_addr *mld_addr = &rx_auth_frm_body->peer_mld;
1110 
1111 		status = lim_validate_mac_address_in_auth_frame(mac_ctx,
1112 								mac_hdr,
1113 								mld_addr,
1114 								pe_session->vdev_id);
1115 		if (QDF_IS_STATUS_ERROR(status)) {
1116 			pe_err("Duplicate MAC address found, reject auth");
1117 			auth_frame->authAlgoNumber =
1118 				rx_auth_frm_body->authAlgoNumber;
1119 			auth_frame->authTransactionSeqNumber =
1120 				rx_auth_frm_body->authTransactionSeqNumber + 1;
1121 			auth_frame->authStatusCode =
1122 				STATUS_UNSPECIFIED_FAILURE;
1123 
1124 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1125 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
1126 				pe_session);
1127 			return;
1128 		}
1129 
1130 		switch (rx_auth_frm_body->authAlgoNumber) {
1131 		case eSIR_OPEN_SYSTEM:
1132 			lim_process_auth_open_system_algo(mac_ctx, mac_hdr,
1133 				rx_auth_frm_body, auth_frame, pe_session);
1134 			break;
1135 
1136 		case eSIR_SHARED_KEY:
1137 			lim_process_auth_shared_system_algo(mac_ctx, mac_hdr,
1138 				rx_auth_frm_body, auth_frame, pe_session);
1139 			break;
1140 		default:
1141 			pe_err("rx Auth frm for unsupported auth algo %d "
1142 				QDF_MAC_ADDR_FMT,
1143 				rx_auth_frm_body->authAlgoNumber,
1144 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1145 
1146 			/*
1147 			 * Responding party does not support the
1148 			 * authentication algorithm requested by
1149 			 * sending party.
1150 			 * Reject by sending Authentication frame
1151 			 * with auth algorithm not supported status code
1152 			 */
1153 			auth_frame->authAlgoNumber =
1154 				rx_auth_frm_body->authAlgoNumber;
1155 			auth_frame->authTransactionSeqNumber =
1156 				rx_auth_frm_body->authTransactionSeqNumber + 1;
1157 			auth_frame->authStatusCode =
1158 				STATUS_NOT_SUPPORTED_AUTH_ALG;
1159 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1160 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
1161 				pe_session);
1162 			return;
1163 		}
1164 	} else {
1165 		pe_err("received Authentication frame for unsupported auth algorithm %d "
1166 			QDF_MAC_ADDR_FMT,
1167 			rx_auth_frm_body->authAlgoNumber,
1168 			QDF_MAC_ADDR_REF(mac_hdr->sa));
1169 
1170 		/*
1171 		 * Responding party does not support the
1172 		 * authentication algorithm requested by sending party.
1173 		 * Reject Authentication with StatusCode=13.
1174 		 */
1175 		auth_frame->authAlgoNumber = rx_auth_frm_body->authAlgoNumber;
1176 		auth_frame->authTransactionSeqNumber =
1177 			rx_auth_frm_body->authTransactionSeqNumber + 1;
1178 		auth_frame->authStatusCode =
1179 			STATUS_NOT_SUPPORTED_AUTH_ALG;
1180 
1181 		lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1182 				mac_hdr->sa,
1183 				LIM_NO_WEP_IN_FC,
1184 				pe_session);
1185 		return;
1186 	}
1187 }
1188 
lim_process_auth_frame_type2(struct mac_context * mac_ctx,tpSirMacMgmtHdr mac_hdr,tSirMacAuthFrameBody * rx_auth_frm_body,tSirMacAuthFrameBody * auth_frame,uint8_t * plainbody,uint8_t * body_ptr,uint16_t frame_len,struct pe_session * pe_session)1189 static void lim_process_auth_frame_type2(struct mac_context *mac_ctx,
1190 		tpSirMacMgmtHdr mac_hdr,
1191 		tSirMacAuthFrameBody *rx_auth_frm_body,
1192 		tSirMacAuthFrameBody *auth_frame,
1193 		uint8_t *plainbody,
1194 		uint8_t *body_ptr, uint16_t frame_len,
1195 		struct pe_session *pe_session)
1196 {
1197 	uint8_t key_id, cfg_privacy_opt_imp;
1198 	uint32_t key_length = 8;
1199 	qdf_size_t val;
1200 	uint8_t defaultkey[SIR_MAC_KEY_LENGTH];
1201 	struct tLimPreAuthNode *auth_node;
1202 	uint8_t *encr_auth_frame;
1203 	struct wlan_mlme_wep_cfg *wep_params = &mac_ctx->mlme_cfg->wep_params;
1204 	QDF_STATUS qdf_status;
1205 
1206 	/* AuthFrame 2 */
1207 	if (pe_session->limMlmState != eLIM_MLM_WT_AUTH_FRAME2_STATE) {
1208 		/**
1209 		 * Check if a Reassociation is in progress and this is a
1210 		 * Pre-Auth frame
1211 		 */
1212 		if (LIM_IS_STA_ROLE(pe_session) &&
1213 		    (pe_session->limSmeState == eLIM_SME_WT_REASSOC_STATE) &&
1214 		    (rx_auth_frm_body->authStatusCode == STATUS_SUCCESS) &&
1215 		    (pe_session->ftPEContext.pFTPreAuthReq) &&
1216 		    (!qdf_mem_cmp(
1217 			pe_session->ftPEContext.pFTPreAuthReq->preAuthbssId,
1218 			mac_hdr->sa, sizeof(tSirMacAddr)))) {
1219 
1220 			/* Update the FTIEs in the saved auth response */
1221 			pe_warn("rx PreAuth frm2 in smestate: %d from: "QDF_MAC_ADDR_FMT,
1222 				pe_session->limSmeState,
1223 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1224 			pe_session->ftPEContext.saved_auth_rsp_length = 0;
1225 
1226 			if ((body_ptr) && (frame_len < MAX_FTIE_SIZE)) {
1227 				qdf_mem_copy(
1228 					pe_session->ftPEContext.saved_auth_rsp,
1229 					body_ptr, frame_len);
1230 				pe_session->ftPEContext.saved_auth_rsp_length =
1231 					frame_len;
1232 			}
1233 		} else {
1234 			/*
1235 			 * Received Auth frame2 in an unexpected state.
1236 			 * Log error and ignore the frame.
1237 			 */
1238 			pe_debug("rx Auth frm2 from peer in state: %d addr "QDF_MAC_ADDR_FMT,
1239 				 pe_session->limMlmState,
1240 				 QDF_MAC_ADDR_REF(mac_hdr->sa));
1241 		}
1242 		return;
1243 	}
1244 
1245 	if (qdf_mem_cmp((uint8_t *) mac_hdr->sa,
1246 			(uint8_t *) &mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
1247 			sizeof(tSirMacAddr))) {
1248 		/*
1249 		 * Received Authentication frame from an entity
1250 		 * other than one request was initiated.
1251 		 * Wait until Authentication Failure Timeout.
1252 		 */
1253 
1254 		pe_warn("received Auth frame2 from unexpected peer"
1255 			QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_hdr->sa));
1256 		return;
1257 	}
1258 
1259 	if (LIM_IS_STA_ROLE(pe_session) &&
1260 	    wlan_vdev_mlme_is_mlo_vdev(pe_session->vdev)) {
1261 		if (!rx_auth_frm_body->is_mlo_ie_present) {
1262 			pe_err("MLO IE not present in auth frame from peer, abort connection");
1263 			lim_send_deauth_mgmt_frame(
1264 				mac_ctx, REASON_UNSPEC_FAILURE,
1265 				pe_session->bssId, pe_session, false);
1266 			lim_restore_from_auth_state(mac_ctx,
1267 						    eSIR_SME_INVALID_PARAMETERS,
1268 						    REASON_UNSPEC_FAILURE,
1269 						    pe_session);
1270 			return;
1271 		}
1272 	}
1273 
1274 	if (rx_auth_frm_body->authStatusCode ==
1275 			STATUS_NOT_SUPPORTED_AUTH_ALG) {
1276 		/*
1277 		 * Interoperability workaround: Linksys WAP4400N is returning
1278 		 * wrong authType in OpenAuth response in case of
1279 		 * SharedKey AP configuration. Pretend we don't see that,
1280 		 * so upper layer can fallback to SharedKey authType,
1281 		 * and successfully connect to the AP.
1282 		 */
1283 		if (rx_auth_frm_body->authAlgoNumber !=
1284 				mac_ctx->lim.gpLimMlmAuthReq->authType) {
1285 			rx_auth_frm_body->authAlgoNumber =
1286 				mac_ctx->lim.gpLimMlmAuthReq->authType;
1287 		}
1288 	}
1289 
1290 	if (rx_auth_frm_body->authAlgoNumber !=
1291 			mac_ctx->lim.gpLimMlmAuthReq->authType) {
1292 		/*
1293 		 * Auth algo is open in rx auth frame when auth type is SAE and
1294 		 * PMK is cached as driver sent auth algo as open in tx frame
1295 		 * as well.
1296 		 */
1297 		if ((mac_ctx->lim.gpLimMlmAuthReq->authType ==
1298 		    eSIR_AUTH_TYPE_SAE) && pe_session->sae_pmk_cached) {
1299 			pe_debug("rx Auth frame2 auth algo %d in SAE PMK case",
1300 				rx_auth_frm_body->authAlgoNumber);
1301 		} else {
1302 			/*
1303 			 * Received Authentication frame with an auth
1304 			 * algorithm other than one requested.
1305 			 * Wait until Authentication Failure Timeout.
1306 			 */
1307 
1308 			pe_warn("rx Auth frame2 for unexpected auth algo %d"
1309 				QDF_MAC_ADDR_FMT,
1310 				rx_auth_frm_body->authAlgoNumber,
1311 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1312 			return;
1313 		}
1314 	}
1315 
1316 	if (rx_auth_frm_body->authStatusCode != STATUS_SUCCESS) {
1317 		/*
1318 		 * Authentication failure.
1319 		 * Return Auth confirm with received failure code to SME
1320 		 */
1321 		pe_err("rx Auth frame from peer with failure code %d "
1322 			QDF_MAC_ADDR_FMT,
1323 			rx_auth_frm_body->authStatusCode,
1324 			QDF_MAC_ADDR_REF(mac_hdr->sa));
1325 		lim_restore_from_auth_state(mac_ctx, eSIR_SME_AUTH_REFUSED,
1326 			rx_auth_frm_body->authStatusCode,
1327 			pe_session);
1328 		return;
1329 	}
1330 
1331 	if (lim_process_fils_auth_frame2(mac_ctx, pe_session,
1332 					 rx_auth_frm_body)) {
1333 		lim_restore_from_auth_state(mac_ctx, eSIR_SME_SUCCESS,
1334 				rx_auth_frm_body->authStatusCode, pe_session);
1335 		return;
1336 	}
1337 
1338 	if (rx_auth_frm_body->authAlgoNumber == eSIR_OPEN_SYSTEM) {
1339 		pe_session->limCurrentAuthType = eSIR_OPEN_SYSTEM;
1340 		auth_node = lim_acquire_free_pre_auth_node(mac_ctx,
1341 				&mac_ctx->lim.gLimPreAuthTimerTable);
1342 		if (!auth_node) {
1343 			pe_warn("Max pre-auth nodes reached SA: "QDF_MAC_ADDR_FMT,
1344 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1345 			return;
1346 		}
1347 
1348 		pe_debug("add new auth node: for "QDF_MAC_ADDR_FMT,
1349 			 QDF_MAC_ADDR_REF(mac_hdr->sa));
1350 		qdf_mem_copy((uint8_t *) auth_node->peerMacAddr,
1351 				mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
1352 				sizeof(tSirMacAddr));
1353 		auth_node->fTimerStarted = 0;
1354 		auth_node->authType =
1355 			mac_ctx->lim.gpLimMlmAuthReq->authType;
1356 		auth_node->seq_num =
1357 			((mac_hdr->seqControl.seqNumHi << 4) |
1358 			 (mac_hdr->seqControl.seqNumLo));
1359 		auth_node->timestamp = qdf_mc_timer_get_system_ticks();
1360 		lim_add_pre_auth_node(mac_ctx, auth_node);
1361 		lim_restore_from_auth_state(mac_ctx, eSIR_SME_SUCCESS,
1362 				rx_auth_frm_body->authStatusCode, pe_session);
1363 	} else {
1364 		/* Shared key authentication */
1365 		if (LIM_IS_AP_ROLE(pe_session))
1366 			cfg_privacy_opt_imp = pe_session->privacy;
1367 		else
1368 			cfg_privacy_opt_imp = wep_params->is_privacy_enabled;
1369 
1370 		if (!cfg_privacy_opt_imp) {
1371 			/*
1372 			 * Requesting STA does not have WEP implemented.
1373 			 * Reject with unsupported authentication algo
1374 			 * Status code & wait until auth failure timeout
1375 			 */
1376 
1377 			pe_err("rx Auth frm from peer for unsupported auth algo %d "
1378 						QDF_MAC_ADDR_FMT,
1379 					rx_auth_frm_body->authAlgoNumber,
1380 					QDF_MAC_ADDR_REF(mac_hdr->sa));
1381 
1382 			auth_frame->authAlgoNumber =
1383 				rx_auth_frm_body->authAlgoNumber;
1384 			auth_frame->authTransactionSeqNumber =
1385 				rx_auth_frm_body->authTransactionSeqNumber + 1;
1386 			auth_frame->authStatusCode =
1387 				STATUS_NOT_SUPPORTED_AUTH_ALG;
1388 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1389 					mac_hdr->sa, LIM_NO_WEP_IN_FC,
1390 					pe_session);
1391 			return;
1392 		}
1393 		if (rx_auth_frm_body->type != WLAN_ELEMID_CHALLENGE) {
1394 			pe_err("rx auth frm with invalid challenge txtie");
1395 			return;
1396 		}
1397 
1398 		key_id = mac_ctx->mlme_cfg->wep_params.wep_default_key_id;
1399 		val = SIR_MAC_KEY_LENGTH;
1400 		if (LIM_IS_AP_ROLE(pe_session)) {
1401 			qdf_status = lim_get_wep_key_sap(pe_session,
1402 							 wep_params,
1403 							 key_id,
1404 							 defaultkey,
1405 							 &val);
1406 		} else {
1407 			qdf_status = mlme_get_wep_key(pe_session->vdev,
1408 						      wep_params,
1409 						      (MLME_WEP_DEFAULT_KEY_1 +
1410 						       key_id), defaultkey,
1411 						      &val);
1412 			if (QDF_IS_STATUS_ERROR(qdf_status)) {
1413 				pe_warn("cant retrieve Defaultkey");
1414 
1415 				auth_frame->authAlgoNumber =
1416 					rx_auth_frm_body->authAlgoNumber;
1417 				auth_frame->authTransactionSeqNumber =
1418 				rx_auth_frm_body->authTransactionSeqNumber + 1;
1419 
1420 				auth_frame->authStatusCode =
1421 					STATUS_CHALLENGE_FAIL;
1422 
1423 				lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1424 							 mac_hdr->sa,
1425 							 LIM_NO_WEP_IN_FC,
1426 							 pe_session);
1427 				lim_restore_from_auth_state(mac_ctx,
1428 					eSIR_SME_INVALID_WEP_DEFAULT_KEY,
1429 					REASON_UNSPEC_FAILURE,
1430 					pe_session);
1431 				return;
1432 			}
1433 		}
1434 		key_length = val;
1435 		((tpSirMacAuthFrameBody)plainbody)->authAlgoNumber =
1436 			sir_swap_u16if_needed(rx_auth_frm_body->authAlgoNumber);
1437 		((tpSirMacAuthFrameBody)plainbody)->authTransactionSeqNumber =
1438 			sir_swap_u16if_needed((uint16_t)(
1439 				rx_auth_frm_body->authTransactionSeqNumber
1440 				+ 1));
1441 		((tpSirMacAuthFrameBody)plainbody)->authStatusCode =
1442 			STATUS_SUCCESS;
1443 		((tpSirMacAuthFrameBody)plainbody)->type =
1444 			WLAN_ELEMID_CHALLENGE;
1445 		((tpSirMacAuthFrameBody)plainbody)->length =
1446 			rx_auth_frm_body->length;
1447 		qdf_mem_copy((uint8_t *) (
1448 			(tpSirMacAuthFrameBody)plainbody)->challengeText,
1449 			rx_auth_frm_body->challengeText,
1450 			rx_auth_frm_body->length);
1451 		encr_auth_frame = qdf_mem_malloc(rx_auth_frm_body->length +
1452 						 LIM_ENCR_AUTH_INFO_LEN);
1453 		if (!encr_auth_frame)
1454 			return;
1455 		lim_encrypt_auth_frame(mac_ctx, key_id,
1456 				defaultkey, plainbody,
1457 				encr_auth_frame, key_length);
1458 		pe_session->limMlmState = eLIM_MLM_WT_AUTH_FRAME4_STATE;
1459 		MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
1460 					pe_session->peSessionId,
1461 					pe_session->limMlmState));
1462 		lim_send_auth_mgmt_frame(mac_ctx,
1463 				(tpSirMacAuthFrameBody)encr_auth_frame,
1464 				mac_hdr->sa, rx_auth_frm_body->length,
1465 				pe_session);
1466 		qdf_mem_free(encr_auth_frame);
1467 		return;
1468 	}
1469 }
1470 
lim_process_auth_frame_type3(struct mac_context * mac_ctx,tpSirMacMgmtHdr mac_hdr,tSirMacAuthFrameBody * rx_auth_frm_body,tSirMacAuthFrameBody * auth_frame,struct pe_session * pe_session)1471 static void lim_process_auth_frame_type3(struct mac_context *mac_ctx,
1472 		tpSirMacMgmtHdr mac_hdr,
1473 		tSirMacAuthFrameBody *rx_auth_frm_body,
1474 		tSirMacAuthFrameBody *auth_frame,
1475 		struct pe_session *pe_session)
1476 {
1477 	struct tLimPreAuthNode *auth_node;
1478 
1479 	/* AuthFrame 3 */
1480 	if (rx_auth_frm_body->authAlgoNumber != eSIR_SHARED_KEY) {
1481 		pe_err("rx Auth frame3 from peer with auth algo number %d "
1482 			QDF_MAC_ADDR_FMT,
1483 			rx_auth_frm_body->authAlgoNumber,
1484 			QDF_MAC_ADDR_REF(mac_hdr->sa));
1485 		/*
1486 		 * Received Authentication frame3 with algorithm other than
1487 		 * Shared Key authentication type. Reject with Auth frame4
1488 		 * with 'out of sequence' status code.
1489 		 */
1490 		auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
1491 		auth_frame->authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_4;
1492 		auth_frame->authStatusCode =
1493 			STATUS_UNKNOWN_AUTH_TRANSACTION;
1494 		lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1495 			mac_hdr->sa, LIM_NO_WEP_IN_FC,
1496 			pe_session);
1497 		return;
1498 	}
1499 
1500 	if (LIM_IS_AP_ROLE(pe_session)) {
1501 		/*
1502 		 * Check if wep bit was set in FC. If not set,
1503 		 * reject with Authentication frame4 with
1504 		 * 'challenge failure' status code.
1505 		 */
1506 		if (!mac_hdr->fc.wep) {
1507 			pe_err("received Auth frame3 from peer with no WEP bit set "
1508 				QDF_MAC_ADDR_FMT,
1509 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1510 			/* WEP bit is not set in FC of Auth Frame3 */
1511 			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
1512 			auth_frame->authTransactionSeqNumber =
1513 				SIR_MAC_AUTH_FRAME_4;
1514 			auth_frame->authStatusCode =
1515 				STATUS_CHALLENGE_FAIL;
1516 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1517 					mac_hdr->sa,
1518 					LIM_NO_WEP_IN_FC,
1519 					pe_session);
1520 			return;
1521 		}
1522 
1523 		auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa);
1524 		if (!auth_node) {
1525 			pe_warn("received AuthFrame3 from peer that has no preauth context "
1526 				QDF_MAC_ADDR_FMT,
1527 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1528 			/*
1529 			 * No 'pre-auth' context exists for this STA that sent
1530 			 * an Authentication frame3. Send Auth frame4 with
1531 			 * 'out of sequence' status code.
1532 			 */
1533 			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
1534 			auth_frame->authTransactionSeqNumber =
1535 				SIR_MAC_AUTH_FRAME_4;
1536 			auth_frame->authStatusCode =
1537 				STATUS_UNKNOWN_AUTH_TRANSACTION;
1538 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1539 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
1540 				pe_session);
1541 			return;
1542 		}
1543 
1544 		if (auth_node->mlmState == eLIM_MLM_AUTH_RSP_TIMEOUT_STATE) {
1545 			pe_warn("auth response timer timedout for peer "
1546 				QDF_MAC_ADDR_FMT,
1547 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1548 			/*
1549 			 * Received Auth Frame3 after Auth Response timeout.
1550 			 * Reject by sending Auth Frame4 with
1551 			 * Auth respone timeout Status Code.
1552 			 */
1553 			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
1554 			auth_frame->authTransactionSeqNumber =
1555 				SIR_MAC_AUTH_FRAME_4;
1556 			auth_frame->authStatusCode =
1557 				STATUS_AUTH_TIMEOUT;
1558 
1559 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1560 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
1561 				pe_session);
1562 			/* Delete pre-auth context of STA */
1563 			lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
1564 			return;
1565 		}
1566 		if (rx_auth_frm_body->authStatusCode !=
1567 				STATUS_SUCCESS) {
1568 			/*
1569 			 * Received Authenetication Frame 3 with status code
1570 			 * other than success. Wait until Auth response timeout
1571 			 * to delete STA context.
1572 			 */
1573 			pe_err("rx Auth frm3 from peer with status code %d "
1574 				QDF_MAC_ADDR_FMT,
1575 				rx_auth_frm_body->authStatusCode,
1576 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1577 				return;
1578 		}
1579 		/*
1580 		 * Check if received challenge text is same as one sent in
1581 		 * Authentication frame3
1582 		 */
1583 		if (!qdf_mem_cmp(rx_auth_frm_body->challengeText,
1584 					auth_node->challengeText,
1585 					SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH)) {
1586 			/*
1587 			 * Challenge match. STA is authenticated
1588 			 * Delete Authentication response timer if running
1589 			 */
1590 			lim_deactivate_and_change_per_sta_id_timer(mac_ctx,
1591 				eLIM_AUTH_RSP_TIMER, auth_node->authNodeIdx);
1592 
1593 			auth_node->fTimerStarted = 0;
1594 			auth_node->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
1595 
1596 			/*
1597 			 * Send Auth Frame4 with 'success' Status Code.
1598 			 */
1599 			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
1600 			auth_frame->authTransactionSeqNumber =
1601 				SIR_MAC_AUTH_FRAME_4;
1602 			auth_frame->authStatusCode =
1603 				STATUS_SUCCESS;
1604 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1605 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
1606 				pe_session);
1607 			return;
1608 		} else {
1609 			pe_warn("Challenge failure for peer "QDF_MAC_ADDR_FMT,
1610 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1611 			/*
1612 			 * Challenge Failure.
1613 			 * Send Authentication frame4 with 'challenge failure'
1614 			 * status code and wait until Auth response timeout to
1615 			 * delete STA context.
1616 			 */
1617 			auth_frame->authAlgoNumber =
1618 				rx_auth_frm_body->authAlgoNumber;
1619 			auth_frame->authTransactionSeqNumber =
1620 				SIR_MAC_AUTH_FRAME_4;
1621 			auth_frame->authStatusCode =
1622 				STATUS_CHALLENGE_FAIL;
1623 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1624 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
1625 				pe_session);
1626 			return;
1627 		}
1628 	}
1629 }
1630 
lim_process_auth_frame_type4(struct mac_context * mac_ctx,tpSirMacMgmtHdr mac_hdr,tSirMacAuthFrameBody * rx_auth_frm_body,struct pe_session * pe_session)1631 static void lim_process_auth_frame_type4(struct mac_context *mac_ctx,
1632 		tpSirMacMgmtHdr mac_hdr,
1633 		tSirMacAuthFrameBody *rx_auth_frm_body,
1634 		struct pe_session *pe_session)
1635 {
1636 	struct tLimPreAuthNode *auth_node;
1637 
1638 	if (pe_session->limMlmState != eLIM_MLM_WT_AUTH_FRAME4_STATE) {
1639 		/*
1640 		 * Received Authentication frame4 in an unexpected state.
1641 		 * Log error and ignore the frame.
1642 		 */
1643 		pe_warn("received unexpected Auth frame4 from peer in state %d, addr "
1644 			QDF_MAC_ADDR_FMT,
1645 			pe_session->limMlmState,
1646 			QDF_MAC_ADDR_REF(mac_hdr->sa));
1647 		return;
1648 	}
1649 
1650 	if (rx_auth_frm_body->authAlgoNumber != eSIR_SHARED_KEY) {
1651 		/*
1652 		 * Received Authentication frame4 with algorithm other than
1653 		 * Shared Key authentication type.
1654 		 * Wait until Auth failure timeout to report authentication
1655 		 * failure to SME.
1656 		 */
1657 		pe_err("received Auth frame4 from peer with invalid auth algo %d"
1658 			QDF_MAC_ADDR_FMT,
1659 			rx_auth_frm_body->authAlgoNumber,
1660 			QDF_MAC_ADDR_REF(mac_hdr->sa));
1661 		return;
1662 	}
1663 
1664 	if (qdf_mem_cmp((uint8_t *) mac_hdr->sa,
1665 			(uint8_t *) &mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
1666 			sizeof(tSirMacAddr))) {
1667 		/*
1668 		 * Received Authentication frame from an entity
1669 		 * other than one to which request was initiated.
1670 		 * Wait until Authentication Failure Timeout.
1671 		 */
1672 
1673 		pe_warn("received Auth frame4 from unexpected peer "QDF_MAC_ADDR_FMT,
1674 			QDF_MAC_ADDR_REF(mac_hdr->sa));
1675 		return;
1676 	}
1677 
1678 	if (rx_auth_frm_body->authAlgoNumber !=
1679 			mac_ctx->lim.gpLimMlmAuthReq->authType) {
1680 		/*
1681 		 * Received Authentication frame with an auth algorithm
1682 		 * other than one requested.
1683 		 * Wait until Authentication Failure Timeout.
1684 		 */
1685 
1686 		pe_err("received Authentication frame from peer with invalid auth seq number %d "
1687 			QDF_MAC_ADDR_FMT,
1688 			rx_auth_frm_body->authTransactionSeqNumber,
1689 			QDF_MAC_ADDR_REF(mac_hdr->sa));
1690 		return;
1691 	}
1692 
1693 	if (rx_auth_frm_body->authStatusCode == STATUS_SUCCESS) {
1694 		/*
1695 		 * Authentication Success, Inform SME of same.
1696 		 */
1697 		pe_session->limCurrentAuthType = eSIR_SHARED_KEY;
1698 		auth_node = lim_acquire_free_pre_auth_node(mac_ctx,
1699 					&mac_ctx->lim.gLimPreAuthTimerTable);
1700 		if (!auth_node) {
1701 			pe_warn("Max pre-auth nodes reached SA: "QDF_MAC_ADDR_FMT,
1702 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1703 			return;
1704 		}
1705 		pe_debug("Alloc new data: %pK peer "QDF_MAC_ADDR_FMT, auth_node,
1706 			 QDF_MAC_ADDR_REF(mac_hdr->sa));
1707 		qdf_mem_copy((uint8_t *) auth_node->peerMacAddr,
1708 				mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
1709 				sizeof(tSirMacAddr));
1710 		auth_node->fTimerStarted = 0;
1711 		auth_node->authType = mac_ctx->lim.gpLimMlmAuthReq->authType;
1712 		auth_node->seq_num = ((mac_hdr->seqControl.seqNumHi << 4) |
1713 					(mac_hdr->seqControl.seqNumLo));
1714 		auth_node->timestamp = qdf_mc_timer_get_system_ticks();
1715 		lim_add_pre_auth_node(mac_ctx, auth_node);
1716 		lim_restore_from_auth_state(mac_ctx, eSIR_SME_SUCCESS,
1717 				rx_auth_frm_body->authStatusCode, pe_session);
1718 	} else {
1719 		/*
1720 		 * Authentication failure.
1721 		 * Return Auth confirm with received failure code to SME
1722 		 */
1723 		pe_err("Authentication failure from peer "QDF_MAC_ADDR_FMT,
1724 			QDF_MAC_ADDR_REF(mac_hdr->sa));
1725 		lim_restore_from_auth_state(mac_ctx, eSIR_SME_AUTH_REFUSED,
1726 				rx_auth_frm_body->authStatusCode,
1727 				pe_session);
1728 	}
1729 }
1730 
1731 /**
1732  * lim_process_auth_frame() - to process auth frame
1733  * @mac_ctx - Pointer to Global MAC structure
1734  * @rx_pkt_info - A pointer to Rx packet info structure
1735  * @session - A pointer to session
1736  *
1737  * This function is called by limProcessMessageQueue() upon Authentication
1738  * frame reception.
1739  *
1740  * LOGIC:
1741  * This function processes received Authentication frame and responds
1742  * with either next Authentication frame in sequence to peer MAC entity
1743  * or LIM_MLM_AUTH_IND on AP or LIM_MLM_AUTH_CNF on STA.
1744  *
1745  * NOTE:
1746  * 1. Authentication failures are reported to SME with same status code
1747  *    received from the peer MAC entity.
1748  * 2. Authentication frame2/4 received with algorithm number other than
1749  *    one requested in frame1/3 are logged with an error and auth confirm
1750  *    will be sent to SME only after auth failure timeout.
1751  * 3. Inconsistency in the spec:
1752  *    On receiving Auth frame2, specs says that if WEP key mapping key
1753  *    or default key is NULL, Auth frame3 with a status code 15 (challenge
1754  *    failure to be returned to peer entity. However, section 7.2.3.10,
1755  *    table 14 says that status code field is 'reserved' for frame3 !
1756  *    In the current implementation, Auth frame3 is returned with status
1757  *    code 15 overriding section 7.2.3.10.
1758  * 4. If number pre-authentications reach configrable max limit,
1759  *    Authentication frame with 'unspecified failure' status code is
1760  *    returned to requesting entity.
1761  *
1762  * Return: None
1763  */
1764 void
lim_process_auth_frame(struct mac_context * mac_ctx,uint8_t * rx_pkt_info,struct pe_session * pe_session)1765 lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
1766 		       struct pe_session *pe_session)
1767 {
1768 	uint8_t *body_ptr, key_id, cfg_privacy_opt_imp;
1769 	uint8_t defaultkey[SIR_MAC_KEY_LENGTH];
1770 	uint8_t *plainbody = NULL;
1771 	uint8_t decrypt_result;
1772 	uint16_t frame_len, curr_seq_num = 0, auth_alg;
1773 	uint32_t key_length = 8;
1774 	qdf_size_t val;
1775 	tSirMacAuthFrameBody *rx_auth_frm_body, *rx_auth_frame, *auth_frame;
1776 	tpSirMacMgmtHdr mac_hdr;
1777 	struct tLimPreAuthNode *auth_node;
1778 	struct wlan_mlme_wep_cfg *wep_params = &mac_ctx->mlme_cfg->wep_params;
1779 	QDF_STATUS qdf_status;
1780 
1781 	/* Get pointer to Authentication frame header and body */
1782 	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
1783 	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
1784 
1785 	if (!frame_len) {
1786 		/* Log error */
1787 		pe_err("received Auth frame with no body from: "QDF_MAC_ADDR_FMT,
1788 			QDF_MAC_ADDR_REF(mac_hdr->sa));
1789 		return;
1790 	}
1791 
1792 	if (IEEE80211_IS_MULTICAST(mac_hdr->sa)) {
1793 		/*
1794 		 * Received Auth frame from a BC/MC address
1795 		 * Log error and ignore it
1796 		 */
1797 		pe_err("received Auth frame from a BC/MC addr: "QDF_MAC_ADDR_FMT,
1798 			QDF_MAC_ADDR_REF(mac_hdr->sa));
1799 		return;
1800 	}
1801 	curr_seq_num = (mac_hdr->seqControl.seqNumHi << 4) |
1802 		(mac_hdr->seqControl.seqNumLo);
1803 
1804 	if (pe_session->prev_auth_seq_num == curr_seq_num &&
1805 	    !qdf_mem_cmp(pe_session->prev_auth_mac_addr, &mac_hdr->sa,
1806 			 ETH_ALEN) &&
1807 	    mac_hdr->fc.retry) {
1808 		pe_debug("auth frame, seq num: %d is already processed, drop it",
1809 			 curr_seq_num);
1810 		return;
1811 	}
1812 
1813 	/* Duplicate Auth frame from peer */
1814 	auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa);
1815 	if (auth_node && (auth_node->seq_num == curr_seq_num)) {
1816 		pe_err("Received an already processed auth frame with seq_num : %d",
1817 		       curr_seq_num);
1818 		return;
1819 	}
1820 
1821 	/* save seq number and mac_addr in pe_session */
1822 	pe_session->prev_auth_seq_num = curr_seq_num;
1823 	qdf_mem_copy(pe_session->prev_auth_mac_addr, mac_hdr->sa, ETH_ALEN);
1824 
1825 	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
1826 
1827 	if (frame_len < 2) {
1828 		pe_err("invalid frame len: %d", frame_len);
1829 		return;
1830 	}
1831 	auth_alg = *(uint16_t *) body_ptr;
1832 
1833 	pe_nofl_rl_info("Auth RX: vdev %d sys role %d lim_state %d from " QDF_MAC_ADDR_FMT " rssi %d auth_alg %d seq %d",
1834 			pe_session->vdev_id, GET_LIM_SYSTEM_ROLE(pe_session),
1835 			pe_session->limMlmState,
1836 			QDF_MAC_ADDR_REF(mac_hdr->sa),
1837 			WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
1838 			auth_alg, curr_seq_num);
1839 
1840 	/* Restore default failure timeout */
1841 	if (QDF_P2P_CLIENT_MODE == pe_session->opmode &&
1842 	    pe_session->defaultAuthFailureTimeout) {
1843 		pe_debug("Restore default failure timeout");
1844 		if (cfg_in_range(CFG_AUTH_FAILURE_TIMEOUT,
1845 				 pe_session->defaultAuthFailureTimeout)) {
1846 			mac_ctx->mlme_cfg->timeouts.auth_failure_timeout =
1847 				pe_session->defaultAuthFailureTimeout;
1848 		} else {
1849 			mac_ctx->mlme_cfg->timeouts.auth_failure_timeout =
1850 				cfg_default(CFG_AUTH_FAILURE_TIMEOUT);
1851 			pe_session->defaultAuthFailureTimeout =
1852 				cfg_default(CFG_AUTH_FAILURE_TIMEOUT);
1853 		}
1854 	}
1855 
1856 	rx_auth_frame = qdf_mem_malloc(sizeof(tSirMacAuthFrameBody));
1857 	if (!rx_auth_frame)
1858 		return;
1859 
1860 	auth_frame = qdf_mem_malloc(sizeof(tSirMacAuthFrameBody));
1861 	if (!auth_frame)
1862 		goto free;
1863 
1864 	plainbody = qdf_mem_malloc(LIM_ENCR_AUTH_BODY_LEN);
1865 	if (!plainbody)
1866 		goto free;
1867 
1868 	qdf_mem_zero(plainbody, LIM_ENCR_AUTH_BODY_LEN);
1869 
1870 	/*
1871 	 * Determine if WEP bit is set in the FC or received MAC header
1872 	 * Note: WEP bit is set in FC of MAC header.
1873 	 */
1874 	if (mac_hdr->fc.wep) {
1875 		if (frame_len < 4) {
1876 			pe_err("invalid frame len: %d", frame_len);
1877 			goto free;
1878 		}
1879 		/* Extract key ID from IV (most 2 bits of 4th byte of IV) */
1880 		key_id = (*(body_ptr + 3)) >> 6;
1881 
1882 		/*
1883 		 * On STA in infrastructure BSS, Authentication frames received
1884 		 * with WEP bit set in the FC must be rejected with challenge
1885 		 * failure status code (weird thing in the spec - this should've
1886 		 * been rejected with unspecified failure/unexpected assertion
1887 		 * of wep bit (this status code does not exist though) or
1888 		 * Out-of-sequence-Authentication-Frame status code.
1889 		 */
1890 		if (LIM_IS_STA_ROLE(pe_session)) {
1891 			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
1892 			auth_frame->authTransactionSeqNumber =
1893 				SIR_MAC_AUTH_FRAME_4;
1894 			auth_frame->authStatusCode =
1895 				STATUS_CHALLENGE_FAIL;
1896 			/* Log error */
1897 			pe_err("rx Auth frm with wep bit set role: %d "QDF_MAC_ADDR_FMT,
1898 				GET_LIM_SYSTEM_ROLE(pe_session),
1899 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1900 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1901 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
1902 				pe_session);
1903 			goto free;
1904 		}
1905 
1906 		if ((frame_len < LIM_ENCR_AUTH_BODY_LEN_SAP) ||
1907 		    (frame_len > LIM_ENCR_AUTH_BODY_LEN)) {
1908 			/* Log error */
1909 			pe_err("Not enough size: %d to decry rx Auth frm "QDF_MAC_ADDR_FMT,
1910 			       frame_len, QDF_MAC_ADDR_REF(mac_hdr->sa));
1911 			goto free;
1912 		}
1913 
1914 		/*
1915 		 * Accept Authentication frame only if Privacy is
1916 		 * implemented
1917 		 */
1918 		if (LIM_IS_AP_ROLE(pe_session))
1919 			cfg_privacy_opt_imp = pe_session->privacy;
1920 		else
1921 			cfg_privacy_opt_imp = wep_params->is_privacy_enabled;
1922 
1923 		if (!cfg_privacy_opt_imp) {
1924 			pe_err("received Authentication frame3 from peer that while privacy option is turned OFF "
1925 				QDF_MAC_ADDR_FMT,
1926 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1927 			/*
1928 			 * Privacy option is not implemented.
1929 			 * So reject Authentication frame received with
1930 			 * WEP bit set by sending Authentication frame
1931 			 * with 'challenge failure' status code. This is
1932 			 * another strange thing in the spec. Status code
1933 			 * should have been 'unsupported algorithm' status code.
1934 			 */
1935 			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
1936 			auth_frame->authTransactionSeqNumber =
1937 				SIR_MAC_AUTH_FRAME_4;
1938 			auth_frame->authStatusCode =
1939 				STATUS_CHALLENGE_FAIL;
1940 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1941 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
1942 				pe_session);
1943 			goto free;
1944 		}
1945 
1946 		/*
1947 		 * Privacy option is implemented. Check if the received frame is
1948 		 * Authentication frame3 and there is a context for requesting
1949 		 * STA. If not, reject with unspecified failure status code
1950 		 */
1951 		if (!auth_node) {
1952 			pe_err("rx Auth frame with no preauth ctx with WEP bit set "
1953 				QDF_MAC_ADDR_FMT,
1954 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1955 			/*
1956 			 * No 'pre-auth' context exists for this STA
1957 			 * that sent an Authentication frame with FC
1958 			 * bit set. Send Auth frame4 with
1959 			 * 'out of sequence' status code.
1960 			 */
1961 			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
1962 			auth_frame->authTransactionSeqNumber =
1963 				SIR_MAC_AUTH_FRAME_4;
1964 			auth_frame->authStatusCode =
1965 				STATUS_UNKNOWN_AUTH_TRANSACTION;
1966 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1967 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
1968 				pe_session);
1969 			goto free;
1970 		}
1971 		/* Change the auth-response timeout */
1972 		lim_deactivate_and_change_per_sta_id_timer(mac_ctx,
1973 				eLIM_AUTH_RSP_TIMER, auth_node->authNodeIdx);
1974 
1975 		/* 'Pre-auth' status exists for STA */
1976 		if ((auth_node->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE) &&
1977 			(auth_node->mlmState !=
1978 				eLIM_MLM_AUTH_RSP_TIMEOUT_STATE)) {
1979 			pe_err("received Authentication frame from peer that is in state %d "
1980 				QDF_MAC_ADDR_FMT,
1981 				auth_node->mlmState,
1982 				QDF_MAC_ADDR_REF(mac_hdr->sa));
1983 			/*
1984 			 * Should not have received Authentication frame
1985 			 * with WEP bit set in FC in other states.
1986 			 * Reject by sending Authenticaton frame with
1987 			 * out of sequence Auth frame status code.
1988 			 */
1989 			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
1990 			auth_frame->authTransactionSeqNumber =
1991 				SIR_MAC_AUTH_FRAME_4;
1992 			auth_frame->authStatusCode =
1993 				STATUS_UNKNOWN_AUTH_TRANSACTION;
1994 
1995 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
1996 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
1997 				pe_session);
1998 			goto free;
1999 		}
2000 
2001 		val = SIR_MAC_KEY_LENGTH;
2002 
2003 		if (LIM_IS_AP_ROLE(pe_session)) {
2004 			qdf_status = lim_get_wep_key_sap(pe_session,
2005 							 wep_params,
2006 							 key_id,
2007 							 defaultkey,
2008 							 &val);
2009 		} else {
2010 			qdf_status = mlme_get_wep_key(pe_session->vdev,
2011 						      wep_params,
2012 						      (MLME_WEP_DEFAULT_KEY_1 +
2013 						      key_id), defaultkey,
2014 						      &val);
2015 			if (QDF_IS_STATUS_ERROR(qdf_status)) {
2016 				pe_warn("could not retrieve Default key");
2017 
2018 				/*
2019 				 * Send Authentication frame
2020 				 * with challenge failure status code
2021 				 */
2022 				auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
2023 				auth_frame->authTransactionSeqNumber =
2024 							SIR_MAC_AUTH_FRAME_4;
2025 				auth_frame->authStatusCode =
2026 					STATUS_CHALLENGE_FAIL;
2027 				lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
2028 						mac_hdr->sa, LIM_NO_WEP_IN_FC,
2029 						pe_session);
2030 				goto free;
2031 			}
2032 		}
2033 
2034 		key_length = val;
2035 		decrypt_result = lim_decrypt_auth_frame(mac_ctx, defaultkey,
2036 					body_ptr, plainbody, key_length,
2037 					(uint16_t) (frame_len -
2038 							SIR_MAC_WEP_IV_LENGTH));
2039 		if (decrypt_result == LIM_DECRYPT_ICV_FAIL) {
2040 			pe_err("received Authentication frame from peer that failed decryption: "
2041 				QDF_MAC_ADDR_FMT,
2042 				QDF_MAC_ADDR_REF(mac_hdr->sa));
2043 			/* ICV failure */
2044 			lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
2045 			auth_frame->authAlgoNumber = eSIR_SHARED_KEY;
2046 			auth_frame->authTransactionSeqNumber =
2047 				SIR_MAC_AUTH_FRAME_4;
2048 			auth_frame->authStatusCode = STATUS_CHALLENGE_FAIL;
2049 
2050 			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
2051 				mac_hdr->sa, LIM_NO_WEP_IN_FC,
2052 				pe_session);
2053 			goto free;
2054 		}
2055 		if ((sir_convert_auth_frame2_struct(mac_ctx, plainbody,
2056 				frame_len - 8, rx_auth_frame) != QDF_STATUS_SUCCESS)
2057 				|| (!is_auth_valid(mac_ctx, rx_auth_frame,
2058 							pe_session))) {
2059 			pe_err("failed to convert Auth Frame to structure or Auth is not valid");
2060 			goto free;
2061 		}
2062 	} else if (auth_alg == eSIR_AUTH_TYPE_SAE) {
2063 		if (LIM_IS_STA_ROLE(pe_session) ||
2064 		    (LIM_IS_AP_ROLE(pe_session) &&
2065 		     mac_ctx->mlme_cfg->sap_cfg.sap_sae_enabled))
2066 			lim_process_sae_auth_frame(mac_ctx, rx_pkt_info,
2067 						   pe_session);
2068 		goto free;
2069 	} else if (auth_alg == eSIR_AUTH_TYPE_PASN) {
2070 		lim_process_pasn_auth_frame(mac_ctx, pe_session->vdev_id,
2071 					    rx_pkt_info);
2072 		goto free;
2073 	} else if (auth_alg == eSIR_FT_AUTH && LIM_IS_AP_ROLE(pe_session)) {
2074 		pe_debug("Auth Frame auth_alg  eSIR_FT_AUTH");
2075 			lim_process_ft_auth_frame(mac_ctx,
2076 						  rx_pkt_info, pe_session);
2077 		goto free;
2078 	} else if ((sir_convert_auth_frame2_struct(mac_ctx, body_ptr,
2079 				frame_len, rx_auth_frame) != QDF_STATUS_SUCCESS)
2080 				|| (!is_auth_valid(mac_ctx, rx_auth_frame,
2081 						pe_session))) {
2082 		pe_err("failed to convert Auth Frame to structure or Auth is not valid");
2083 		goto free;
2084 	}
2085 
2086 	rx_auth_frm_body = rx_auth_frame;
2087 
2088 	if (!lim_is_valid_fils_auth_frame(mac_ctx, pe_session,
2089 			rx_auth_frm_body)) {
2090 		pe_err("Received invalid FILS auth packet");
2091 		goto free;
2092 	}
2093 
2094 	/*
2095 	 * IOT Workaround: with invalid WEP key, some APs reply
2096 	 * AuthFrame 4 with invalid seqNumber. This AuthFrame
2097 	 * will be dropped by driver, thus driver sends the
2098 	 * generic status code instead of protocol status code.
2099 	 * As a workaround, override AuthFrame 4's seqNumber.
2100 	 */
2101 	if ((pe_session->limMlmState ==
2102 		eLIM_MLM_WT_AUTH_FRAME4_STATE) &&
2103 		(rx_auth_frm_body->authTransactionSeqNumber !=
2104 		SIR_MAC_AUTH_FRAME_1) &&
2105 		(rx_auth_frm_body->authTransactionSeqNumber !=
2106 		SIR_MAC_AUTH_FRAME_2) &&
2107 		(rx_auth_frm_body->authTransactionSeqNumber !=
2108 		SIR_MAC_AUTH_FRAME_3)) {
2109 		pe_warn("Override AuthFrame 4's seqNumber to 4");
2110 		rx_auth_frm_body->authTransactionSeqNumber =
2111 			SIR_MAC_AUTH_FRAME_4;
2112 	}
2113 
2114 	wlan_connectivity_mgmt_event(mac_ctx->psoc,
2115 				     (struct wlan_frame_hdr *)mac_hdr,
2116 				     pe_session->vdev_id,
2117 				     rx_auth_frm_body->authStatusCode,
2118 				     0, WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
2119 				     auth_alg, 0,
2120 				     rx_auth_frm_body->authTransactionSeqNumber,
2121 				     0, WLAN_AUTH_RESP);
2122 
2123 	lim_cp_stats_cstats_log_auth_evt
2124 			(pe_session, CSTATS_DIR_RX, auth_alg,
2125 			 rx_auth_frm_body->authTransactionSeqNumber,
2126 			 rx_auth_frm_body->authStatusCode);
2127 
2128 	switch (rx_auth_frm_body->authTransactionSeqNumber) {
2129 	case SIR_MAC_AUTH_FRAME_1:
2130 		lim_process_auth_frame_type1(mac_ctx,
2131 			mac_hdr, rx_auth_frm_body, rx_pkt_info,
2132 			curr_seq_num, auth_frame, pe_session);
2133 		break;
2134 	case SIR_MAC_AUTH_FRAME_2:
2135 		lim_process_auth_frame_type2(mac_ctx,
2136 			mac_hdr, rx_auth_frm_body, auth_frame, plainbody,
2137 			body_ptr, frame_len, pe_session);
2138 		break;
2139 	case SIR_MAC_AUTH_FRAME_3:
2140 		lim_process_auth_frame_type3(mac_ctx,
2141 			mac_hdr, rx_auth_frm_body, auth_frame, pe_session);
2142 		break;
2143 	case SIR_MAC_AUTH_FRAME_4:
2144 		lim_process_auth_frame_type4(mac_ctx,
2145 			mac_hdr, rx_auth_frm_body, pe_session);
2146 		break;
2147 	default:
2148 		/* Invalid Authentication Frame received. Ignore it. */
2149 		pe_warn("rx auth frm with invalid authseq no: %d from: "QDF_MAC_ADDR_FMT,
2150 			rx_auth_frm_body->authTransactionSeqNumber,
2151 			QDF_MAC_ADDR_REF(mac_hdr->sa));
2152 		break;
2153 	}
2154 free:
2155 	if (auth_frame)
2156 		qdf_mem_free(auth_frame);
2157 	if (rx_auth_frame)
2158 		qdf_mem_free(rx_auth_frame);
2159 	if (plainbody)
2160 		qdf_mem_free(plainbody);
2161 }
2162 
2163 /**
2164  * lim_process_sae_preauth_frame() - Send the WPA3 preauth SAE frame received
2165  * to the user space.
2166  * @mac: Global mac context
2167  * @rx_pkt: Received auth packet
2168  *
2169  * SAE auth frame will be received with no session if its SAE preauth during
2170  * roaming offloaded to the host. Forward this frame to the wpa supplicant.
2171  *
2172  * Return: True if auth algo is SAE else false
2173  */
2174 static
lim_process_sae_preauth_frame(struct mac_context * mac,uint8_t * rx_pkt)2175 bool lim_process_sae_preauth_frame(struct mac_context *mac, uint8_t *rx_pkt)
2176 {
2177 	tpSirMacMgmtHdr dot11_hdr;
2178 	tSirMacMgmtHdr original_hdr;
2179 	uint16_t auth_alg, frm_len;
2180 	uint16_t sae_auth_seq = 0, sae_status_code = 0;
2181 	uint8_t *frm_body, pdev_id, vdev_id;
2182 	struct wlan_objmgr_vdev *vdev;
2183 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2184 
2185 	dot11_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt);
2186 	original_hdr = *dot11_hdr;
2187 	frm_body = WMA_GET_RX_MPDU_DATA(rx_pkt);
2188 	frm_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt);
2189 
2190 	if (frm_len < 2) {
2191 		pe_debug("LFR3: Invalid auth frame len:%d", frm_len);
2192 		return false;
2193 	}
2194 
2195 	auth_alg = *(uint16_t *)frm_body;
2196 	if (auth_alg != eSIR_AUTH_TYPE_SAE)
2197 		return false;
2198 
2199 	if (frm_len >= (SAE_AUTH_STATUS_CODE_OFFSET + 2)) {
2200 		sae_auth_seq =
2201 			*(uint16_t *)(frm_body + SAE_AUTH_SEQ_NUM_OFFSET);
2202 		sae_status_code =
2203 			*(uint16_t *)(frm_body + SAE_AUTH_STATUS_CODE_OFFSET);
2204 	}
2205 
2206 	pe_debug("LFR3: SAE auth frame: seq_ctrl:0x%X auth_transaction_num:%d",
2207 		 ((dot11_hdr->seqControl.seqNumHi << 8) |
2208 		  (dot11_hdr->seqControl.seqNumLo << 4) |
2209 		  (dot11_hdr->seqControl.fragNum)), *(uint16_t *)(frm_body + 2));
2210 
2211 	pdev_id = wlan_objmgr_pdev_get_pdev_id(mac->pdev);
2212 	vdev = wlan_objmgr_get_vdev_by_macaddr_from_psoc(mac->psoc, pdev_id,
2213 							 dot11_hdr->da,
2214 							 WLAN_LEGACY_MAC_ID);
2215 	if (!vdev) {
2216 		vdev = wlan_objmgr_pdev_get_roam_vdev(mac->pdev,
2217 						      WLAN_LEGACY_MAC_ID);
2218 		if (!vdev) {
2219 			pe_err("not able to find roaming vdev");
2220 			return false;
2221 		}
2222 	}
2223 
2224 	vdev_id = wlan_vdev_get_id(vdev);
2225 	lim_sae_auth_cleanup_retry(mac, vdev_id);
2226 	status = lim_update_link_to_mld_address(mac, vdev, dot11_hdr);
2227 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
2228 	if (QDF_IS_STATUS_ERROR(status)) {
2229 		pe_err("vdev:%d dropping auth frame BSSID: " QDF_MAC_ADDR_FMT ", SAE address conversion failure",
2230 		       vdev_id, QDF_MAC_ADDR_REF(dot11_hdr->bssId));
2231 		return false;
2232 	}
2233 
2234 	wlan_connectivity_mgmt_event(mac->psoc,
2235 				     (struct wlan_frame_hdr *)&original_hdr,
2236 				     vdev_id, sae_status_code,
2237 				     0, WMA_GET_RX_RSSI_NORMALIZED(rx_pkt),
2238 				     auth_alg, sae_auth_seq,
2239 				     sae_auth_seq, 0, WLAN_AUTH_RESP);
2240 
2241 	lim_send_sme_mgmt_frame_ind(mac, dot11_hdr->fc.subType,
2242 				    (uint8_t *)dot11_hdr,
2243 				    frm_len + sizeof(tSirMacMgmtHdr),
2244 				    SME_SESSION_ID_ANY,
2245 				    WMA_GET_RX_FREQ(rx_pkt),
2246 				    WMA_GET_RX_RSSI_NORMALIZED(rx_pkt),
2247 				    RXMGMT_FLAG_NONE);
2248 	return true;
2249 }
2250 
2251 #define WLAN_MIN_AUTH_FRM_ALGO_FIELD_LEN 2
2252 
2253 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
lim_process_ft_sae_auth_frame(struct mac_context * mac,struct pe_session * pe_session,uint8_t * body,uint16_t frame_len)2254 static void lim_process_ft_sae_auth_frame(struct mac_context *mac,
2255 					  struct pe_session *pe_session,
2256 					  uint8_t *body, uint16_t frame_len)
2257 {
2258 }
2259 #else
2260 /**
2261  * lim_process_ft_sae_auth_frame() - process SAE pre auth frame for LFR2
2262  * @mac: pointer to mac_context
2263  * @pe_session: pointer to pe session
2264  * @body: auth frame body
2265  * @frame_len: auth frame length
2266  *
2267  * Return: void
2268  */
lim_process_ft_sae_auth_frame(struct mac_context * mac,struct pe_session * pe_session,uint8_t * body,uint16_t frame_len)2269 static void lim_process_ft_sae_auth_frame(struct mac_context *mac,
2270 					  struct pe_session *pe_session,
2271 					  uint8_t *body, uint16_t frame_len)
2272 {
2273 	tpSirMacAuthFrameBody auth = (tpSirMacAuthFrameBody)body;
2274 
2275 	if (!pe_session || !pe_session->ftPEContext.pFTPreAuthReq) {
2276 		pe_debug("cannot find session or FT in FT pre-auth phase");
2277 		return;
2278 	}
2279 
2280 	if (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_2)
2281 		lim_handle_ft_pre_auth_rsp(mac, QDF_STATUS_SUCCESS, body,
2282 					   frame_len, pe_session);
2283 }
2284 #endif
2285 
2286 /**
2287  *
2288  * Pass the received Auth frame. This is possibly the pre-auth from the
2289  * neighbor AP, in the same mobility domain.
2290  * This will be used in case of 11r FT.
2291  *
2292  ***----------------------------------------------------------------------
2293  */
lim_process_auth_frame_no_session(struct mac_context * mac,uint8_t * pBd,void * body)2294 QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac,
2295 					     uint8_t *pBd, void *body)
2296 {
2297 	tpSirMacMgmtHdr mac_hdr;
2298 	struct pe_session *pe_session = NULL;
2299 	uint8_t *pBody;
2300 	uint8_t vdev_id;
2301 	uint16_t frameLen, curr_seq_num, auth_alg = 0;
2302 	tSirMacAuthFrameBody *rx_auth_frame;
2303 	QDF_STATUS ret_status = QDF_STATUS_E_FAILURE;
2304 	int i;
2305 	bool sae_auth_frame;
2306 
2307 	mac_hdr = WMA_GET_RX_MAC_HEADER(pBd);
2308 	pBody = WMA_GET_RX_MPDU_DATA(pBd);
2309 	frameLen = WMA_GET_RX_PAYLOAD_LEN(pBd);
2310 	curr_seq_num = mac_hdr->seqControl.seqNumHi << 4 |
2311 		       mac_hdr->seqControl.seqNumLo;
2312 
2313 	if (frameLen == 0) {
2314 		pe_err("Frame len = 0");
2315 		return QDF_STATUS_E_FAILURE;
2316 	}
2317 
2318 	if (frameLen > WLAN_MIN_AUTH_FRM_ALGO_FIELD_LEN)
2319 		auth_alg = *(uint16_t *)pBody;
2320 
2321 	pe_debug("Auth RX: BSSID " QDF_MAC_ADDR_FMT " RSSI:%d auth_alg:%d seq:%d",
2322 		 QDF_MAC_ADDR_REF(mac_hdr->bssId),
2323 		 (uint)abs((int8_t)WMA_GET_RX_RSSI_NORMALIZED(pBd)),
2324 		 auth_alg, curr_seq_num);
2325 
2326 	/* Auth frame has come on a new BSS, however, we need to find the session
2327 	 * from where the auth-req was sent to the new AP
2328 	 */
2329 	for (i = 0; i < mac->lim.maxBssId; i++) {
2330 		/* Find first free room in session table */
2331 		if (mac->lim.gpSession[i].valid == true &&
2332 		    mac->lim.gpSession[i].ftPEContext.ftPreAuthSession ==
2333 		    true) {
2334 			/* Found the session */
2335 			pe_session = &mac->lim.gpSession[i];
2336 			mac->lim.gpSession[i].ftPEContext.ftPreAuthSession =
2337 				false;
2338 		}
2339 	}
2340 
2341 	sae_auth_frame = lim_process_sae_preauth_frame(mac, pBd);
2342 	if (sae_auth_frame) {
2343 		lim_process_ft_sae_auth_frame(mac, pe_session, pBody, frameLen);
2344 		return QDF_STATUS_SUCCESS;
2345 	}
2346 
2347 	if (auth_alg == eSIR_AUTH_TYPE_PASN) {
2348 		vdev_id = lim_get_pasn_peer_vdev_id(mac, mac_hdr->bssId);
2349 		if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) {
2350 			/*
2351 			 * This can be NAN auth mgmt frame and for NAN, PASN
2352 			 * peer is not available.
2353 			 */
2354 			vdev_id = wlan_nan_get_vdev_id_from_bssid(mac->pdev,
2355 							mac_hdr->bssId,
2356 							WLAN_MGMT_RX_ID);
2357 			if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) {
2358 				pe_err("NAN vdev_id not found");
2359 				return QDF_STATUS_E_FAILURE;
2360 			}
2361 		}
2362 
2363 		return lim_process_pasn_auth_frame(mac, vdev_id, pBd);
2364 	}
2365 
2366 	if (!pe_session) {
2367 		pe_debug("cannot find session id in FT pre-auth phase");
2368 		return QDF_STATUS_E_FAILURE;
2369 	}
2370 
2371 	if (!pe_session->ftPEContext.pFTPreAuthReq) {
2372 		pe_err("Error: No FT");
2373 		/* No FT in progress. */
2374 		return QDF_STATUS_E_FAILURE;
2375 	}
2376 
2377 	/* Check that its the same bssId we have for preAuth */
2378 	if (qdf_mem_cmp
2379 		    (pe_session->ftPEContext.pFTPreAuthReq->preAuthbssId,
2380 		     mac_hdr->bssId, sizeof(tSirMacAddr))) {
2381 		pe_err("Error: Same bssid as preauth BSSID");
2382 		/* In this case SME if indeed has triggered a */
2383 		/* pre auth it will time out. */
2384 		return QDF_STATUS_E_FAILURE;
2385 	}
2386 
2387 	if (true ==
2388 	    pe_session->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) {
2389 		/*
2390 		 * This is likely a duplicate for the same pre-auth request.
2391 		 * PE/LIM already posted a response to SME. Hence, drop it.
2392 		 * TBD:
2393 		 * 1) How did we even receive multiple auth responses?
2394 		 * 2) Do we need to delete pre-auth session? Suppose we
2395 		 * previously received an auth resp with failure which
2396 		 * would not have created the session and forwarded to SME.
2397 		 * And, we subsequently received an auth resp with success
2398 		 * which would have created the session. This will now be
2399 		 * dropped without being forwarded to SME! However, it is
2400 		 * very unlikely to receive auth responses from the same
2401 		 * AP with different reason codes.
2402 		 * NOTE: return QDF_STATUS_SUCCESS so that the packet is dropped
2403 		 * as this was indeed a response from the BSSID we tried to
2404 		 * pre-auth.
2405 		 */
2406 		pe_debug("Auth rsp already posted to SME"
2407 			       " (session %pK, FT session %pK)", pe_session,
2408 			       pe_session);
2409 		return QDF_STATUS_SUCCESS;
2410 	} else {
2411 		pe_warn("Auth rsp not yet posted to SME"
2412 			       " (session %pK, FT session %pK)", pe_session,
2413 			       pe_session);
2414 		pe_session->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed =
2415 			true;
2416 	}
2417 
2418 	/* Stopping timer now, that we have our unicast from the AP */
2419 	/* of our choice. */
2420 	lim_deactivate_and_change_timer(mac, eLIM_FT_PREAUTH_RSP_TIMER);
2421 
2422 	rx_auth_frame = qdf_mem_malloc(sizeof(*rx_auth_frame));
2423 	if (!rx_auth_frame) {
2424 		lim_handle_ft_pre_auth_rsp(mac, QDF_STATUS_E_FAILURE, NULL, 0,
2425 					   pe_session);
2426 		return QDF_STATUS_E_NOMEM;
2427 	}
2428 
2429 	/* Save off the auth resp. */
2430 	if ((sir_convert_auth_frame2_struct(mac, pBody, frameLen,
2431 					    rx_auth_frame) !=
2432 					    QDF_STATUS_SUCCESS)) {
2433 		pe_err("failed to convert Auth frame to struct");
2434 		lim_handle_ft_pre_auth_rsp(mac, QDF_STATUS_E_FAILURE, NULL, 0,
2435 					   pe_session);
2436 		qdf_mem_free(rx_auth_frame);
2437 		return QDF_STATUS_E_FAILURE;
2438 	}
2439 	pe_info("Pre-Auth RX: type: %d trans_seqnum: %d status: %d %d from " QDF_MAC_ADDR_FMT,
2440 		(uint32_t)rx_auth_frame->authAlgoNumber,
2441 		(uint32_t)rx_auth_frame->authTransactionSeqNumber,
2442 		(uint32_t)rx_auth_frame->authStatusCode,
2443 		(uint32_t)mac->lim.gLimNumPreAuthContexts,
2444 		QDF_MAC_ADDR_REF(mac_hdr->sa));
2445 
2446 	switch (rx_auth_frame->authTransactionSeqNumber) {
2447 	case SIR_MAC_AUTH_FRAME_2:
2448 		if (rx_auth_frame->authStatusCode != STATUS_SUCCESS) {
2449 			pe_err("Auth status code received is %d",
2450 				(uint32_t)rx_auth_frame->authStatusCode);
2451 			if (STATUS_AP_UNABLE_TO_HANDLE_NEW_STA ==
2452 			    rx_auth_frame->authStatusCode)
2453 				ret_status = QDF_STATUS_E_NOSPC;
2454 		} else {
2455 			ret_status = QDF_STATUS_SUCCESS;
2456 		}
2457 		break;
2458 
2459 	default:
2460 		pe_warn("Seq. no incorrect expected 2 received %d",
2461 			(uint32_t)rx_auth_frame->authTransactionSeqNumber);
2462 		break;
2463 	}
2464 
2465 	/* Send the Auth response to SME */
2466 	lim_handle_ft_pre_auth_rsp(mac, ret_status, pBody,
2467 				   frameLen, pe_session);
2468 	qdf_mem_free(rx_auth_frame);
2469 
2470 	return ret_status;
2471 }
2472