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