import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / combo / drv_wlan / mt6630 / wlan / mgmt / rsn.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rsn.c#3 $
3 */
4
5 /*! \file "rsn.c"
6 \brief This file including the 802.11i, wpa and wpa2(rsn) related function.
7
8 This file provided the macros and functions library support the wpa/rsn ie parsing,
9 cipher and AKM check to help the AP seleced deciding, tkip mic error handler and rsn PMKID support.
10 */
11
12
13
14 /*
15 ** $Log: rsn.c $
16 **
17 ** 08 13 2013 terry.wu
18 ** [BORA00002207] [MT6630 Wi-Fi] TXM & MQM Implementation
19 ** Remove unused code
20 **
21 ** 07 30 2013 wh.su
22 ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
23 ** update some debug code
24 **
25 ** 07 23 2013 wh.su
26 ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
27 ** Modify some security code for 11w and p2p
28 **
29 ** 07 23 2013 wh.su
30 ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
31 ** Sync the latest jb2.mp 11w code as draft version
32 ** Not the CM bit for avoid wapi 1x drop at re-key
33 **
34 ** 07 01 2013 wh.su
35 ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
36 ** Add some debug code, fixed some compiling warning
37 **
38 ** 03 12 2013 tsaiyuan.hsu
39 ** [BORA00002222] MT6630 unified MAC RXM
40 ** add rx data and mangement processing.
41 **
42 ** 03 08 2013 wh.su
43 ** [BORA00002446] [MT6630] [Wi-Fi] [Driver] Update the security function code
44 ** Remove non-used compiling flag and code
45 **
46 ** 02 19 2013 cp.wu
47 ** [BORA00002227] [MT6630 Wi-Fi][Driver] Update for Makefile and HIFSYS modifications
48 ** take use of GET_BSS_INFO_BY_INDEX() and MAX_BSS_INDEX macros
49 ** for correctly indexing of BSS-INFO pointers
50 **
51 ** 01 22 2013 cp.wu
52 ** [BORA00002253] [MT6630 Wi-Fi][Driver][Firmware] Add NLO and timeout mechanism to SCN module
53 ** modification for ucBssIndex migration
54 **
55 ** 09 17 2012 cm.chang
56 ** [BORA00002149] [MT6630 Wi-Fi] Initial software development
57 ** Duplicate source from MT6620 v2.3 driver branch
58 ** (Davinci label: MT6620_WIFI_Driver_V2_3_120913_1942_As_MT6630_Base)
59 **
60 ** 08 24 2012 cp.wu
61 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
62 ** .
63 **
64 ** 08 24 2012 cp.wu
65 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
66 ** cfg80211 support merge back from ALPS.JB to DaVinci - MT6620 Driver v2.3 branch.
67 *
68 * 07 17 2012 yuche.tsai
69 * NULL
70 * Compile no error before trial run.
71 *
72 * 03 09 2012 chinglan.wang
73 * NULL
74 * Fix the condition error.
75 *
76 * 03 02 2012 terry.wu
77 * NULL
78 * Snc CFG80211 modification for ICS migration from branch 2.2.
79 *
80 * 03 02 2012 terry.wu
81 * NULL
82 * Sync CFG80211 modification from branch 2,2.
83 *
84 * 11 11 2011 wh.su
85 * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
86 * modify the xlog related code.
87 *
88 * 11 10 2011 wh.su
89 * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
90 * change the debug module level.
91 *
92 * 10 12 2011 wh.su
93 * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
94 * adding the 802.11w related function and define .
95 *
96 * 03 17 2011 chinglan.wang
97 * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
98 * .
99 *
100 * 02 09 2011 wh.su
101 * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode
102 * adding the code for check STA privacy bit at AP mode, .
103 *
104 * 12 24 2010 chinglan.wang
105 * NULL
106 * [MT6620][Wi-Fi] Modify the key management in the driver for WPS function.
107 *
108 * 12 13 2010 cp.wu
109 * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
110 * create branch for Wi-Fi driver v1.1
111 *
112 * 11 05 2010 wh.su
113 * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value
114 * fixed the.pmkid value mismatch issue
115 *
116 * 11 03 2010 wh.su
117 * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
118 * Refine the HT rate disallow TKIP pairwise cipher .
119 *
120 * 10 04 2010 cp.wu
121 * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by ENUM_NETWORK_TYPE_INDEX_T only
122 * remove ENUM_NETWORK_TYPE_T definitions
123 *
124 * 09 29 2010 yuche.tsai
125 * NULL
126 * Fix compile error, remove unused pointer in rsnGenerateRSNIE().
127 *
128 * 09 28 2010 wh.su
129 * NULL
130 * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
131 *
132 * 09 24 2010 wh.su
133 * NULL
134 * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning.
135 *
136 * 09 06 2010 wh.su
137 * NULL
138 * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state.
139 *
140 * 08 30 2010 wh.su
141 * NULL
142 * remove non-used code.
143 *
144 * 08 19 2010 wh.su
145 * NULL
146 * adding the tx pkt call back handle for countermeasure.
147 *
148 * 07 24 2010 wh.su
149 *
150 * .support the Wi-Fi RSN
151 *
152 * 07 08 2010 cp.wu
153 *
154 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
155 *
156 * 06 21 2010 wh.su
157 * [WPD00003840][MT6620 5931] Security migration
158 * modify some code for concurrent network.
159 *
160 * 06 21 2010 cp.wu
161 * [WPD00003833][MT6620 and MT5931] Driver migration
162 * [WPD00003833][MT6620 and MT5931] Driver migration
163 * enable RX management frame handling.
164 *
165 * 06 19 2010 wh.su
166 * [WPD00003840][MT6620 5931] Security migration
167 * consdier the concurrent network setting.
168 *
169 * 06 18 2010 wh.su
170 * [WPD00003840][MT6620 5931] Security migration
171 * [WPD00003840] [MT6620 5931] Security migration
172 * migration from firmware.
173 *
174 * 05 27 2010 wh.su
175 * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
176 * not indiate pmkid candidate while no new one scaned.
177 *
178 * 04 29 2010 wh.su
179 * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
180 * adjsut the pre-authentication code.
181 *
182 * 03 03 2010 wh.su
183 * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
184 * move the AIS specific variable for security to AIS specific structure.
185 *
186 * 03 03 2010 wh.su
187 * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
188 * Fixed the pre-authentication timer not correctly init issue, and modify the security related callback function prototype.
189 *
190 * 01 27 2010 wh.su
191 * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
192 * add and fixed some security function.
193 *
194 * 12 18 2009 cm.chang
195 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
196 * .
197 *
198 * Dec 8 2009 mtk01088
199 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
200 * change the name
201 *
202 * Dec 7 2009 mtk01088
203 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
204 * using the Rx0 port to indicate event
205 *
206 * Dec 4 2009 mtk01088
207 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
208 * refine the code for generate the WPA/RSN IE for assoc req
209 *
210 * Dec 3 2009 mtk01088
211 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
212 * adjust code for pmkid event
213 *
214 * Dec 1 2009 mtk01088
215 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
216 * adding the code for event (mic error and pmkid indicate) and do some function rename
217 *
218 * Nov 23 2009 mtk01088
219 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
220 * adding some security function
221 *
222 * Nov 19 2009 mtk01088
223 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
224 * adding some security feature, including pmkid
225 *
226 * Nov 18 2009 mtk01088
227 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
228 *
229 **
230 */
231
232 /*******************************************************************************
233 * C O M P I L E R F L A G S
234 ********************************************************************************
235 */
236
237 /*******************************************************************************
238 * E X T E R N A L R E F E R E N C E S
239 ********************************************************************************
240 */
241 #include "precomp.h"
242
243 /*******************************************************************************
244 * C O N S T A N T S
245 ********************************************************************************
246 */
247
248 /*******************************************************************************
249 * D A T A T Y P E S
250 ********************************************************************************
251 */
252
253 /*******************************************************************************
254 * P U B L I C D A T A
255 ********************************************************************************
256 */
257
258 /*******************************************************************************
259 * P R I V A T E D A T A
260 ********************************************************************************
261 */
262
263 /*******************************************************************************
264 * M A C R O S
265 ********************************************************************************
266 */
267
268 /*******************************************************************************
269 * F U N C T I O N D E C L A R A T I O N S
270 ********************************************************************************
271 */
272
273 /*******************************************************************************
274 * F U N C T I O N S
275 ********************************************************************************
276 */
277
278 /*----------------------------------------------------------------------------*/
279 /*!
280 * \brief This routine is called to parse RSN IE.
281 *
282 * \param[in] prInfoElem Pointer to the RSN IE
283 * \param[out] prRsnInfo Pointer to the BSSDescription structure to store the
284 ** RSN information from the given RSN IE
285 *
286 * \retval TRUE - Succeeded
287 * \retval FALSE - Failed
288 */
289 /*----------------------------------------------------------------------------*/
290 BOOLEAN
291 rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo)
292 {
293 UINT_32 i;
294 INT_32 u4RemainRsnIeLen;
295 UINT_16 u2Version;
296 UINT_16 u2Cap = 0;
297 UINT_32 u4GroupSuite = RSN_CIPHER_SUITE_CCMP;
298 UINT_16 u2PairSuiteCount = 0;
299 UINT_16 u2AuthSuiteCount = 0;
300 PUINT_8 pucPairSuite = NULL;
301 PUINT_8 pucAuthSuite = NULL;
302 PUINT_8 cp;
303
304 DEBUGFUNC("rsnParseRsnIE");
305
306 ASSERT(prInfoElem);
307 ASSERT(prRsnInfo);
308
309 /* Verify the length of the RSN IE. */
310 if (prInfoElem->ucLength < 2) {
311 DBGLOG(RSN, TRACE, ("RSN IE length too short (length=%d)\n", prInfoElem->ucLength));
312 return FALSE;
313 }
314
315 /* Check RSN version: currently, we only support version 1. */
316 WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version);
317 if (u2Version != 1) {
318 DBGLOG(RSN, TRACE, ("Unsupported RSN IE version: %d\n", u2Version));
319 return FALSE;
320 }
321
322 cp = (PUCHAR) & prInfoElem->u4GroupKeyCipherSuite;
323 u4RemainRsnIeLen = (INT_32) prInfoElem->ucLength - 2;
324
325 do {
326 if (u4RemainRsnIeLen == 0) {
327 break;
328 }
329
330 /* Parse the Group Key Cipher Suite field. */
331 if (u4RemainRsnIeLen < 4) {
332 DBGLOG(RSN, TRACE,
333 ("Fail to parse RSN IE in group cipher suite (IE len: %d)\n",
334 prInfoElem->ucLength));
335 return FALSE;
336 }
337
338 WLAN_GET_FIELD_32(cp, &u4GroupSuite);
339 cp += 4;
340 u4RemainRsnIeLen -= 4;
341
342 if (u4RemainRsnIeLen == 0) {
343 break;
344 }
345
346 /* Parse the Pairwise Key Cipher Suite Count field. */
347 if (u4RemainRsnIeLen < 2) {
348 DBGLOG(RSN, TRACE,
349 ("Fail to parse RSN IE in pairwise cipher suite count (IE len: %d)\n",
350 prInfoElem->ucLength));
351 return FALSE;
352 }
353
354 WLAN_GET_FIELD_16(cp, &u2PairSuiteCount);
355 cp += 2;
356 u4RemainRsnIeLen -= 2;
357
358 /* Parse the Pairwise Key Cipher Suite List field. */
359 i = (UINT_32) u2PairSuiteCount * 4;
360 if (u4RemainRsnIeLen < (INT_32) i) {
361 DBGLOG(RSN, TRACE,
362 ("Fail to parse RSN IE in pairwise cipher suite list (IE len: %d)\n",
363 prInfoElem->ucLength));
364 return FALSE;
365 }
366
367 pucPairSuite = cp;
368
369 cp += i;
370 u4RemainRsnIeLen -= (INT_32) i;
371
372 if (u4RemainRsnIeLen == 0) {
373 break;
374 }
375
376 /* Parse the Authentication and Key Management Cipher Suite Count field. */
377 if (u4RemainRsnIeLen < 2) {
378 DBGLOG(RSN, TRACE,
379 ("Fail to parse RSN IE in auth & key mgt suite count (IE len: %d)\n",
380 prInfoElem->ucLength));
381 return FALSE;
382 }
383
384 WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount);
385 cp += 2;
386 u4RemainRsnIeLen -= 2;
387
388 /* Parse the Authentication and Key Management Cipher Suite List
389 field. */
390 i = (UINT_32) u2AuthSuiteCount * 4;
391 if (u4RemainRsnIeLen < (INT_32) i) {
392 DBGLOG(RSN, TRACE,
393 ("Fail to parse RSN IE in auth & key mgt suite list (IE len: %d)\n",
394 prInfoElem->ucLength));
395 return FALSE;
396 }
397
398 pucAuthSuite = cp;
399
400 cp += i;
401 u4RemainRsnIeLen -= (INT_32) i;
402
403 if (u4RemainRsnIeLen == 0) {
404 break;
405 }
406
407 /* Parse the RSN u2Capabilities field. */
408 if (u4RemainRsnIeLen < 2) {
409 DBGLOG(RSN, TRACE,
410 ("Fail to parse RSN IE in RSN capabilities (IE len: %d)\n",
411 prInfoElem->ucLength));
412 return FALSE;
413 }
414
415 WLAN_GET_FIELD_16(cp, &u2Cap);
416 } while (FALSE);
417
418 /* Save the RSN information for the BSS. */
419 prRsnInfo->ucElemId = ELEM_ID_RSN;
420
421 prRsnInfo->u2Version = u2Version;
422
423 prRsnInfo->u4GroupKeyCipherSuite = u4GroupSuite;
424
425 DBGLOG(RSN, LOUD, ("RSN: version %d, group key cipher suite %02x-%02x-%02x-%02x\n",
426 u2Version, (UCHAR) (u4GroupSuite & 0x000000FF),
427 (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF),
428 (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF),
429 (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)));
430
431 if (pucPairSuite) {
432 /* The information about the pairwise key cipher suites is present. */
433 if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) {
434 u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES;
435 }
436
437 prRsnInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount;
438
439 for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) {
440 WLAN_GET_FIELD_32(pucPairSuite, &prRsnInfo->au4PairwiseKeyCipherSuite[i]);
441 pucPairSuite += 4;
442
443 DBGLOG(RSN, LOUD,
444 ("RSN: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n",
445 (UINT_8) i,
446 (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF),
447 (UCHAR) ((prRsnInfo->
448 au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF),
449 (UCHAR) ((prRsnInfo->
450 au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF),
451 (UCHAR) ((prRsnInfo->
452 au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)));
453 }
454 } else {
455 /* The information about the pairwise key cipher suites is not present.
456 Use the default chipher suite for RSN: CCMP. */
457 prRsnInfo->u4PairwiseKeyCipherSuiteCount = 1;
458 prRsnInfo->au4PairwiseKeyCipherSuite[0] = RSN_CIPHER_SUITE_CCMP;
459
460 DBGLOG(RSN, LOUD,
461 ("RSN: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n",
462 (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF),
463 (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF),
464 (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF),
465 (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)));
466 }
467
468 if (pucAuthSuite) {
469 /* The information about the authentication and key management suites
470 is present. */
471 if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) {
472 u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES;
473 }
474
475 prRsnInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount;
476
477 for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) {
478 WLAN_GET_FIELD_32(pucAuthSuite, &prRsnInfo->au4AuthKeyMgtSuite[i]);
479 pucAuthSuite += 4;
480
481 DBGLOG(RSN, LOUD, ("RSN: AKM suite [%d]: %02x-%02x-%02x-%02x\n",
482 (UINT_8) i,
483 (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[i] & 0x000000FF),
484 (UCHAR) ((prRsnInfo->
485 au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF),
486 (UCHAR) ((prRsnInfo->
487 au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF),
488 (UCHAR) ((prRsnInfo->
489 au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)));
490 }
491 } else {
492 /* The information about the authentication and key management suites
493 is not present. Use the default AKM suite for RSN. */
494 prRsnInfo->u4AuthKeyMgtSuiteCount = 1;
495 prRsnInfo->au4AuthKeyMgtSuite[0] = RSN_AKM_SUITE_802_1X;
496
497 DBGLOG(RSN, LOUD, ("RSN: AKM suite: %02x-%02x-%02x-%02x (default)\n",
498 (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[0] & 0x000000FF),
499 (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF),
500 (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF),
501 (UCHAR) ((prRsnInfo->
502 au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)));
503 }
504
505 prRsnInfo->u2RsnCap = u2Cap;
506 prRsnInfo->fgRsnCapPresent = TRUE;
507 DBGLOG(RSN, LOUD, ("RSN cap: 0x%04x\n", prRsnInfo->u2RsnCap));
508
509 return TRUE;
510 } /* rsnParseRsnIE */
511
512
513 /*----------------------------------------------------------------------------*/
514 /*!
515 * \brief This routine is called to parse WPA IE.
516 *
517 * \param[in] prInfoElem Pointer to the WPA IE.
518 * \param[out] prWpaInfo Pointer to the BSSDescription structure to store the
519 * WPA information from the given WPA IE.
520 *
521 * \retval TRUE Succeeded.
522 * \retval FALSE Failed.
523 */
524 /*----------------------------------------------------------------------------*/
525 BOOLEAN
526 rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo)
527 {
528 UINT_32 i;
529 INT_32 u4RemainWpaIeLen;
530 UINT_16 u2Version;
531 UINT_16 u2Cap = 0;
532 UINT_32 u4GroupSuite = WPA_CIPHER_SUITE_TKIP;
533 UINT_16 u2PairSuiteCount = 0;
534 UINT_16 u2AuthSuiteCount = 0;
535 PUCHAR pucPairSuite = NULL;
536 PUCHAR pucAuthSuite = NULL;
537 PUCHAR cp;
538 BOOLEAN fgCapPresent = FALSE;
539
540 DEBUGFUNC("rsnParseWpaIE");
541
542 ASSERT(prInfoElem);
543 ASSERT(prWpaInfo);
544
545 /* Verify the length of the WPA IE. */
546 if (prInfoElem->ucLength < 6) {
547 DBGLOG(RSN, TRACE, ("WPA IE length too short (length=%d)\n", prInfoElem->ucLength));
548 return FALSE;
549 }
550
551 /* Check WPA version: currently, we only support version 1. */
552 WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version);
553 if (u2Version != 1) {
554 DBGLOG(RSN, TRACE, ("Unsupported WPA IE version: %d\n", u2Version));
555 return FALSE;
556 }
557
558 cp = (PUCHAR) &prInfoElem->u4GroupKeyCipherSuite;
559 u4RemainWpaIeLen = (INT_32) prInfoElem->ucLength - 6;
560
561 do {
562 if (u4RemainWpaIeLen == 0) {
563 break;
564 }
565
566 /* WPA_OUI : 4
567 Version : 2
568 GroupSuite : 4
569 PairwiseCount: 2
570 PairwiseSuite: 4 * pairSuiteCount
571 AuthCount : 2
572 AuthSuite : 4 * authSuiteCount
573 Cap : 2 */
574
575 /* Parse the Group Key Cipher Suite field. */
576 if (u4RemainWpaIeLen < 4) {
577 DBGLOG(RSN, TRACE,
578 ("Fail to parse WPA IE in group cipher suite (IE len: %d)\n",
579 prInfoElem->ucLength));
580 return FALSE;
581 }
582
583 WLAN_GET_FIELD_32(cp, &u4GroupSuite);
584 cp += 4;
585 u4RemainWpaIeLen -= 4;
586
587 if (u4RemainWpaIeLen == 0) {
588 break;
589 }
590
591 /* Parse the Pairwise Key Cipher Suite Count field. */
592 if (u4RemainWpaIeLen < 2) {
593 DBGLOG(RSN, TRACE,
594 ("Fail to parse WPA IE in pairwise cipher suite count (IE len: %d)\n",
595 prInfoElem->ucLength));
596 return FALSE;
597 }
598
599 WLAN_GET_FIELD_16(cp, &u2PairSuiteCount);
600 cp += 2;
601 u4RemainWpaIeLen -= 2;
602
603 /* Parse the Pairwise Key Cipher Suite List field. */
604 i = (UINT_32) u2PairSuiteCount * 4;
605 if (u4RemainWpaIeLen < (INT_32) i) {
606 DBGLOG(RSN, TRACE,
607 ("Fail to parse WPA IE in pairwise cipher suite list (IE len: %d)\n",
608 prInfoElem->ucLength));
609 return FALSE;
610 }
611
612 pucPairSuite = cp;
613
614 cp += i;
615 u4RemainWpaIeLen -= (INT_32) i;
616
617 if (u4RemainWpaIeLen == 0) {
618 break;
619 }
620
621 /* Parse the Authentication and Key Management Cipher Suite Count
622 field. */
623 if (u4RemainWpaIeLen < 2) {
624 DBGLOG(RSN, TRACE,
625 ("Fail to parse WPA IE in auth & key mgt suite count (IE len: %d)\n",
626 prInfoElem->ucLength));
627 return FALSE;
628 }
629
630 WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount);
631 cp += 2;
632 u4RemainWpaIeLen -= 2;
633
634 /* Parse the Authentication and Key Management Cipher Suite List
635 field. */
636 i = (UINT_32) u2AuthSuiteCount * 4;
637 if (u4RemainWpaIeLen < (INT_32) i) {
638 DBGLOG(RSN, TRACE,
639 ("Fail to parse WPA IE in auth & key mgt suite list (IE len: %d)\n",
640 prInfoElem->ucLength));
641 return FALSE;
642 }
643
644 pucAuthSuite = cp;
645
646 cp += i;
647 u4RemainWpaIeLen -= (INT_32) i;
648
649 if (u4RemainWpaIeLen == 0) {
650 break;
651 }
652
653 /* Parse the WPA u2Capabilities field. */
654 if (u4RemainWpaIeLen < 2) {
655 DBGLOG(RSN, TRACE,
656 ("Fail to parse WPA IE in WPA capabilities (IE len: %d)\n",
657 prInfoElem->ucLength));
658 return FALSE;
659 }
660
661 fgCapPresent = TRUE;
662 WLAN_GET_FIELD_16(cp, &u2Cap);
663 u4RemainWpaIeLen -= 2;
664 } while (FALSE);
665
666 /* Save the WPA information for the BSS. */
667
668 prWpaInfo->ucElemId = ELEM_ID_WPA;
669
670 prWpaInfo->u2Version = u2Version;
671
672 prWpaInfo->u4GroupKeyCipherSuite = u4GroupSuite;
673
674 DBGLOG(RSN, LOUD, ("WPA: version %d, group key cipher suite %02x-%02x-%02x-%02x\n",
675 u2Version, (UCHAR) (u4GroupSuite & 0x000000FF),
676 (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF),
677 (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF),
678 (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)));
679
680 if (pucPairSuite) {
681 /* The information about the pairwise key cipher suites is present. */
682 if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) {
683 u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES;
684 }
685
686 prWpaInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount;
687
688 for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) {
689 WLAN_GET_FIELD_32(pucPairSuite, &prWpaInfo->au4PairwiseKeyCipherSuite[i]);
690 pucPairSuite += 4;
691
692 DBGLOG(RSN, LOUD,
693 ("WPA: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n",
694 (UINT_8) i,
695 (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF),
696 (UCHAR) ((prWpaInfo->
697 au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF),
698 (UCHAR) ((prWpaInfo->
699 au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF),
700 (UCHAR) ((prWpaInfo->
701 au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)));
702 }
703 } else {
704 /* The information about the pairwise key cipher suites is not present.
705 Use the default chipher suite for WPA: TKIP. */
706 prWpaInfo->u4PairwiseKeyCipherSuiteCount = 1;
707 prWpaInfo->au4PairwiseKeyCipherSuite[0] = WPA_CIPHER_SUITE_TKIP;
708
709 DBGLOG(RSN, LOUD,
710 ("WPA: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n",
711 (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF),
712 (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF),
713 (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF),
714 (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)));
715 }
716
717 if (pucAuthSuite) {
718 /* The information about the authentication and key management suites
719 is present. */
720 if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) {
721 u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES;
722 }
723
724 prWpaInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount;
725
726 for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) {
727 WLAN_GET_FIELD_32(pucAuthSuite, &prWpaInfo->au4AuthKeyMgtSuite[i]);
728 pucAuthSuite += 4;
729
730 DBGLOG(RSN, LOUD, ("WPA: AKM suite [%d]: %02x-%02x-%02x-%02x\n",
731 (UINT_8) i,
732 (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[i] & 0x000000FF),
733 (UCHAR) ((prWpaInfo->
734 au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF),
735 (UCHAR) ((prWpaInfo->
736 au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF),
737 (UCHAR) ((prWpaInfo->
738 au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)));
739 }
740 } else {
741 /* The information about the authentication and key management suites
742 is not present. Use the default AKM suite for WPA. */
743 prWpaInfo->u4AuthKeyMgtSuiteCount = 1;
744 prWpaInfo->au4AuthKeyMgtSuite[0] = WPA_AKM_SUITE_802_1X;
745
746 DBGLOG(RSN, LOUD, ("WPA: AKM suite: %02x-%02x-%02x-%02x (default)\n",
747 (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[0] & 0x000000FF),
748 (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF),
749 (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF),
750 (UCHAR) ((prWpaInfo->
751 au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)));
752 }
753
754 if (fgCapPresent) {
755 prWpaInfo->fgRsnCapPresent = TRUE;
756 prWpaInfo->u2RsnCap = u2Cap;
757 DBGLOG(RSN, LOUD, ("WPA: RSN cap: 0x%04x\n", prWpaInfo->u2RsnCap));
758 } else {
759 prWpaInfo->fgRsnCapPresent = FALSE;
760 prWpaInfo->u2RsnCap = 0;
761 }
762
763 return TRUE;
764 } /* rsnParseWpaIE */
765
766
767 /*----------------------------------------------------------------------------*/
768 /*!
769 * \brief This routine is called to search the desired pairwise
770 * cipher suite from the MIB Pairwise Cipher Suite
771 * configuration table.
772 *
773 * \param[in] u4Cipher The desired pairwise cipher suite to be searched
774 * \param[out] pu4Index Pointer to the index of the desired pairwise cipher in
775 * the table
776 *
777 * \retval TRUE - The desired pairwise cipher suite is found in the table.
778 * \retval FALSE - The desired pairwise cipher suite is not found in the
779 * table.
780 */
781 /*----------------------------------------------------------------------------*/
782 BOOLEAN
783 rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index)
784 {
785 UINT_8 i;
786 P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry;
787
788 DEBUGFUNC("rsnSearchSupportedCipher");
789
790 ASSERT(pu4Index);
791
792 for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) {
793 prEntry = &prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i];
794 if (prEntry->dot11RSNAConfigPairwiseCipher == u4Cipher &&
795 prEntry->dot11RSNAConfigPairwiseCipherEnabled) {
796 *pu4Index = i;
797 return TRUE;
798 }
799 }
800 return FALSE;
801 } /* rsnSearchSupportedCipher */
802
803
804 /*----------------------------------------------------------------------------*/
805 /*!
806 * \brief Whether BSS RSN is matched from upper layer set.
807 *
808 * \param[in] prAdapter Pointer to the Adapter structure, BSS RSN Information
809 *
810 * \retval BOOLEAN
811 */
812 /*----------------------------------------------------------------------------*/
813 BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo)
814 {
815 UINT_8 i = 0;
816
817 DEBUGFUNC("rsnIsSuitableBSS");
818
819 do {
820
821 if ((prAdapter->rWifiVar.rConnSettings.rRsnInfo.
822 u4GroupKeyCipherSuite & 0x000000FF) !=
823 GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite)) {
824 DBGLOG(RSN, TRACE, ("Break by GroupKeyCipherSuite\n"));
825 break;
826 }
827 for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
828 if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.
829 au4PairwiseKeyCipherSuite[0] & 0x000000FF) !=
830 GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]))
831 && (i == prBssRsnInfo->u4PairwiseKeyCipherSuiteCount - 1)) {
832 DBGLOG(RSN, TRACE, ("Break by PairwiseKeyCipherSuite\n"));
833 break;
834 }
835 }
836 for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) {
837 if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.
838 au4AuthKeyMgtSuite[0] & 0x000000FF) !=
839 GET_SELECTOR_TYPE(prBssRsnInfo->au4AuthKeyMgtSuite[0]))
840 && (i == prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1)) {
841 DBGLOG(RSN, TRACE, ("Break by AuthKeyMgtSuite\n"));
842 break;
843 }
844 }
845 return TRUE;
846 } while (FALSE);
847 return FALSE;
848 }
849
850
851 /*----------------------------------------------------------------------------*/
852 /*!
853 *
854 * \brief This routine is called to search the desired
855 * authentication and key management (AKM) suite from the
856 * MIB Authentication and Key Management Suites table.
857 *
858 * \param[in] u4AkmSuite The desired AKM suite to be searched
859 * \param[out] pu4Index Pointer to the index of the desired AKM suite in the
860 * table
861 *
862 * \retval TRUE The desired AKM suite is found in the table.
863 * \retval FALSE The desired AKM suite is not found in the table.
864 *
865 * \note
866 */
867 /*----------------------------------------------------------------------------*/
868 BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index)
869 {
870 UINT_8 i;
871 P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry;
872
873 DEBUGFUNC("rsnSearchAKMSuite");
874
875 ASSERT(pu4Index);
876
877 for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) {
878 prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i];
879 if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite &&
880 prEntry->dot11RSNAConfigAuthenticationSuiteEnabled) {
881 *pu4Index = i;
882 return TRUE;
883 }
884 }
885 return FALSE;
886 } /* rsnSearchAKMSuite */
887
888
889 /*----------------------------------------------------------------------------*/
890 /*!
891 * \brief This routine is called to perform RSNA or TSN policy
892 * selection for a given BSS.
893 *
894 * \param[in] prBss Pointer to the BSS description
895 *
896 * \retval TRUE - The RSNA/TSN policy selection for the given BSS is
897 * successful. The selected pairwise and group cipher suites
898 * are returned in the BSS description.
899 * \retval FALSE - The RSNA/TSN policy selection for the given BSS is failed.
900 * The driver shall not attempt to join the given BSS.
901 *
902 * \note The Encrypt status matched score will save to bss for final ap select.
903 */
904 /*----------------------------------------------------------------------------*/
905 BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss)
906 {
907 #if CFG_SUPPORT_802_11W
908 INT_32 i;
909 UINT_32 j;
910 #else
911 UINT_32 i, j;
912 #endif
913 BOOLEAN fgSuiteSupported;
914 UINT_32 u4PairwiseCipher = 0;
915 UINT_32 u4GroupCipher = 0;
916 UINT_32 u4AkmSuite = 0;
917 P_RSN_INFO_T prBssRsnInfo;
918 UINT_8 ucBssIndex;
919 BOOLEAN fgIsWpsActive = (BOOLEAN) FALSE;
920
921 DEBUGFUNC("rsnPerformPolicySelection");
922
923 ASSERT(prBss);
924
925 DBGLOG(RSN, TRACE, ("rsnPerformPolicySelection\n"));
926 /* Todo:: */
927 ucBssIndex = prAdapter->prAisBssInfo->ucBssIndex;
928
929 prBss->u4RsnSelectedPairwiseCipher = 0;
930 prBss->u4RsnSelectedGroupCipher = 0;
931 prBss->u4RsnSelectedAKMSuite = 0;
932 prBss->ucEncLevel = 0;
933
934 #if CFG_SUPPORT_WPS
935 fgIsWpsActive = kalWSCGetActiveState(prAdapter->prGlueInfo);
936
937 /* CR1640, disable the AP select privacy check */
938 if (fgIsWpsActive &&
939 (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) &&
940 (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)) {
941 DBGLOG(RSN, INFO, ("-- Skip the Protected BSS check\n"));
942 return TRUE;
943 }
944 #endif
945
946 /* Protection is not required in this BSS. */
947 if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) == 0) {
948
949 if (secEnabledInAis(prAdapter) == FALSE) {
950 DBGLOG(RSN, INFO, ("-- No Protected BSS\n"));
951 return TRUE;
952 } else {
953 DBGLOG(RSN, INFO, ("-- Protected BSS\n"));
954 return FALSE;
955 }
956 }
957
958 /* Protection is required in this BSS. */
959 if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) != 0) {
960 if (secEnabledInAis(prAdapter) == FALSE) {
961 DBGLOG(RSN, INFO, ("-- Protected BSS\n"));
962 return FALSE;
963 }
964 }
965
966 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA ||
967 prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK ||
968 prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) {
969
970 if (prBss->fgIEWPA) {
971 prBssRsnInfo = &prBss->rWPAInfo;
972 } else {
973 DBGLOG(RSN, INFO, ("WPA Information Element does not exist.\n"));
974 return FALSE;
975 }
976 } else if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2 ||
977 prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK) {
978
979 if (prBss->fgIERSN) {
980 prBssRsnInfo = &prBss->rRSNInfo;
981 } else {
982 DBGLOG(RSN, INFO, ("RSN Information Element does not exist.\n"));
983 return FALSE;
984 }
985 } else if (prAdapter->rWifiVar.rConnSettings.eEncStatus != ENUM_ENCRYPTION1_ENABLED) {
986 /* If the driver is configured to use WEP only, ignore this BSS. */
987 DBGLOG(RSN, INFO, ("-- Not WEP-only legacy BSS\n"));
988 return FALSE;
989 } else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) {
990 /* If the driver is configured to use WEP only, use this BSS. */
991 DBGLOG(RSN, INFO, ("-- WEP-only legacy BSS\n"));
992 return TRUE;
993 }
994
995 if (!rsnIsSuitableBSS(prAdapter, prBssRsnInfo)) {
996 DBGLOG(RSN, INFO, ("RSN info check no matched\n"));
997 return FALSE;
998 }
999
1000 if (prBssRsnInfo->u4PairwiseKeyCipherSuiteCount == 1 &&
1001 GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[0]) == CIPHER_SUITE_NONE) {
1002 /* Since the pairwise cipher use the same cipher suite as the group
1003 cipher in the BSS, we check the group cipher suite against the
1004 current encryption status. */
1005 fgSuiteSupported = FALSE;
1006
1007 switch (prBssRsnInfo->u4GroupKeyCipherSuite) {
1008 case WPA_CIPHER_SUITE_CCMP:
1009 case RSN_CIPHER_SUITE_CCMP:
1010 if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
1011 ENUM_ENCRYPTION3_ENABLED) {
1012 fgSuiteSupported = TRUE;
1013 }
1014 break;
1015
1016 case WPA_CIPHER_SUITE_TKIP:
1017 case RSN_CIPHER_SUITE_TKIP:
1018 if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
1019 ENUM_ENCRYPTION2_ENABLED) {
1020 fgSuiteSupported = TRUE;
1021 }
1022 break;
1023
1024 case WPA_CIPHER_SUITE_WEP40:
1025 case WPA_CIPHER_SUITE_WEP104:
1026 if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
1027 ENUM_ENCRYPTION1_ENABLED) {
1028 fgSuiteSupported = TRUE;
1029 }
1030 break;
1031 }
1032
1033 if (fgSuiteSupported) {
1034 u4PairwiseCipher = WPA_CIPHER_SUITE_NONE;
1035 u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
1036 }
1037 #if DBG
1038 else {
1039 DBGLOG(RSN, TRACE,
1040 ("Inproper encryption status %d for group-key-only BSS\n",
1041 prAdapter->rWifiVar.rConnSettings.eEncStatus));
1042 }
1043 #endif
1044 } else {
1045 fgSuiteSupported = FALSE;
1046
1047 DBGLOG(RSN, TRACE,
1048 ("eEncStatus %d %lu 0x%lx\n", prAdapter->rWifiVar.rConnSettings.eEncStatus,
1049 prBssRsnInfo->u4PairwiseKeyCipherSuiteCount,
1050 prBssRsnInfo->au4PairwiseKeyCipherSuite[0]));
1051 /* Select pairwise/group ciphers */
1052 switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) {
1053 case ENUM_ENCRYPTION3_ENABLED:
1054 for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
1055 if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
1056 == CIPHER_SUITE_CCMP) {
1057 u4PairwiseCipher =
1058 prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
1059 }
1060 }
1061 u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
1062 break;
1063
1064 case ENUM_ENCRYPTION2_ENABLED:
1065 for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
1066 if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
1067 == CIPHER_SUITE_TKIP) {
1068 u4PairwiseCipher =
1069 prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
1070 }
1071 }
1072 if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
1073 CIPHER_SUITE_CCMP) {
1074 DBGLOG(RSN, TRACE, ("Cannot join CCMP BSS\n"));
1075 } else {
1076 u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
1077 }
1078 break;
1079
1080 case ENUM_ENCRYPTION1_ENABLED:
1081 for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
1082 if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
1083 == CIPHER_SUITE_WEP40 ||
1084 GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
1085 == CIPHER_SUITE_WEP104) {
1086 u4PairwiseCipher =
1087 prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
1088 }
1089 }
1090 if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
1091 CIPHER_SUITE_CCMP ||
1092 GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
1093 CIPHER_SUITE_TKIP) {
1094 DBGLOG(RSN, TRACE, ("Cannot join CCMP/TKIP BSS\n"));
1095 } else {
1096 u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
1097 }
1098 break;
1099
1100 default:
1101 break;
1102 }
1103 }
1104
1105 /* Exception handler */
1106 /* If we cannot find proper pairwise and group cipher suites to join the
1107 BSS, do not check the supported AKM suites. */
1108 if (u4PairwiseCipher == 0 || u4GroupCipher == 0) {
1109 DBGLOG(RSN, TRACE, ("Failed to select pairwise/group cipher (0x%08lx/0x%08lx)\n",
1110 u4PairwiseCipher, u4GroupCipher));
1111 return FALSE;
1112 }
1113 #if CFG_ENABLE_WIFI_DIRECT
1114 if ((prAdapter->fgIsP2PRegistered) &&
1115 (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType == NETWORK_TYPE_P2P)) {
1116 if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP ||
1117 u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) {
1118 DBGLOG(RSN, TRACE,
1119 ("Failed to select pairwise/group cipher for P2P network (0x%08lx/0x%08lx)\n",
1120 u4PairwiseCipher, u4GroupCipher));
1121 return FALSE;
1122 }
1123 }
1124 #endif
1125
1126 #if CFG_ENABLE_BT_OVER_WIFI
1127 if (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType == NETWORK_TYPE_BOW) {
1128 if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP ||
1129 u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) {
1130 }
1131 DBGLOG(RSN, TRACE,
1132 ("Failed to select pairwise/group cipher for BT over Wi-Fi network (0x%08lx/0x%08lx)\n",
1133 u4PairwiseCipher, u4GroupCipher));
1134 return FALSE;
1135 }
1136 #endif
1137
1138
1139 /* Verify if selected pairwisse cipher is supported */
1140 fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4PairwiseCipher, &i);
1141
1142 /* Verify if selected group cipher is supported */
1143 if (fgSuiteSupported) {
1144 fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4GroupCipher, &i);
1145 }
1146
1147 if (!fgSuiteSupported) {
1148 DBGLOG(RSN, TRACE,
1149 ("Failed to support selected pairwise/group cipher (0x%08lx/0x%08lx)\n",
1150 u4PairwiseCipher, u4GroupCipher));
1151 return FALSE;
1152 }
1153
1154 /* Select AKM */
1155 /* If the driver cannot support any authentication suites advertised in
1156 the given BSS, we fail to perform RSNA policy selection. */
1157 /* Attempt to find any overlapping supported AKM suite. */
1158 #if CFG_SUPPORT_802_11W
1159 if (i != 0)
1160 for (i = (prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1); i >= 0; i--)
1161 #else
1162 for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++)
1163 #endif
1164 {
1165 if (rsnSearchAKMSuite(prAdapter, prBssRsnInfo->au4AuthKeyMgtSuite[i], &j)) {
1166 u4AkmSuite = prBssRsnInfo->au4AuthKeyMgtSuite[i];
1167 break;
1168 }
1169 }
1170
1171 if (u4AkmSuite == 0) {
1172 DBGLOG(RSN, TRACE, ("Cannot support any AKM suites\n"));
1173 return FALSE;
1174 }
1175
1176 DBGLOG(RSN, TRACE,
1177 ("Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n",
1178 (UINT_8) (u4PairwiseCipher & 0x000000FF),
1179 (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF),
1180 (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF),
1181 (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF),
1182 (UINT_8) (u4GroupCipher & 0x000000FF), (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF),
1183 (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF),
1184 (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)));
1185
1186 DBGLOG(RSN, TRACE, ("Selected AKM suite: %02x-%02x-%02x-%02x\n",
1187 (UINT_8) (u4AkmSuite & 0x000000FF),
1188 (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF),
1189 (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF),
1190 (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)));
1191
1192 #if CFG_SUPPORT_802_11W
1193 DBGLOG(RSN, TRACE, ("[MFP] MFP setting = %lu\n ", kalGetMfpSetting(prAdapter->prGlueInfo)));
1194
1195 if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) {
1196 if (!prBssRsnInfo->fgRsnCapPresent) {
1197 DBGLOG(RSN, TRACE, ("[MFP] Skip RSN IE, No MFP Required Capability.\n"));
1198 return FALSE;
1199 } else if (!(prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC)) {
1200 DBGLOG(RSN, TRACE, ("[MFP] Skip RSN IE, No MFP Required\n"));
1201 return FALSE;
1202 }
1203 prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
1204 } else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) {
1205 if (prBssRsnInfo->u2RsnCap && ((prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR) ||
1206 (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC))) {
1207 prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
1208 } else {
1209 prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE;
1210 }
1211 } else {
1212 if (prBssRsnInfo->fgRsnCapPresent && prBssRsnInfo->u2RsnCap) {
1213 if (/* (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR) || */
1214 (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC)) {
1215 prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
1216 prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_OPTIONAL;
1217 }
1218 /* else if ((prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC) && */
1219 /* !(prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR)) { */
1220 /* prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; */
1221 /* prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_OPTIONAL; */
1222 /* } */
1223 else {
1224 prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE;
1225 }
1226 }
1227 if (prBssRsnInfo->fgRsnCapPresent && (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR)) {
1228 if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection == FALSE) {
1229 DBGLOG(RSN, INFO,
1230 ("[MFP] Skip RSN IE, No MFP Required Capability\n"));
1231 return FALSE;
1232 }
1233 }
1234 }
1235 DBGLOG(RSN, TRACE,
1236 ("[MFP] fgMgmtProtection = %d\n ",
1237 prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection));
1238
1239 prAdapter->rWifiVar.rAisSpecificBssInfo.fgAPApplyPmfReq = FALSE;
1240 if (prBssRsnInfo->fgRsnCapPresent && (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR))
1241 prAdapter->rWifiVar.rAisSpecificBssInfo.fgAPApplyPmfReq = TRUE;
1242 #endif
1243
1244 if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_CCMP) {
1245 prBss->ucEncLevel = 3;
1246 } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_TKIP) {
1247 prBss->ucEncLevel = 2;
1248 } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP40 ||
1249 GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP104) {
1250 prBss->ucEncLevel = 1;
1251 } else {
1252 ASSERT(FALSE);
1253 }
1254 prBss->u4RsnSelectedPairwiseCipher = u4PairwiseCipher;
1255 prBss->u4RsnSelectedGroupCipher = u4GroupCipher;
1256 prBss->u4RsnSelectedAKMSuite = u4AkmSuite;
1257
1258 return TRUE;
1259
1260 } /* rsnPerformPolicySelection */
1261
1262
1263 /*----------------------------------------------------------------------------*/
1264 /*!
1265 * \brief This routine is called to generate WPA IE for beacon frame.
1266 *
1267 * \param[in] pucIeStartAddr Pointer to put the generated WPA IE.
1268 *
1269 * \return The append WPA-None IE length
1270 * \note
1271 * Called by: JOIN module, compose beacon IE
1272 */
1273 /*----------------------------------------------------------------------------*/
1274 VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
1275 {
1276 UINT_32 i;
1277 P_WPA_INFO_ELEM_T prWpaIE;
1278 UINT_32 u4Suite;
1279 UINT_16 u2SuiteCount;
1280 PUINT_8 cp, cp2;
1281 UINT_8 ucExpendedLen = 0;
1282 PUINT_8 pucBuffer;
1283 UINT_8 ucBssIndex;
1284
1285 DEBUGFUNC("rsnGenerateWpaNoneIE");
1286
1287 ASSERT(prMsduInfo);
1288
1289 if (prAdapter->rWifiVar.rConnSettings.eAuthMode != AUTH_MODE_WPA_NONE) {
1290 return;
1291 }
1292
1293 ucBssIndex = prMsduInfo->ucBssIndex;
1294
1295 if (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType != NETWORK_TYPE_AIS)
1296 return;
1297
1298 pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket +
1299 (ULONG) prMsduInfo->u2FrameLength);
1300
1301 ASSERT(pucBuffer);
1302
1303 prWpaIE = (P_WPA_INFO_ELEM_T) (pucBuffer);
1304
1305 /* Start to construct a WPA IE. */
1306 /* Fill the Element ID field. */
1307 prWpaIE->ucElemId = ELEM_ID_WPA;
1308
1309 /* Fill the OUI and OUI Type fields. */
1310 prWpaIE->aucOui[0] = 0x00;
1311 prWpaIE->aucOui[1] = 0x50;
1312 prWpaIE->aucOui[2] = 0xF2;
1313 prWpaIE->ucOuiType = VENDOR_OUI_TYPE_WPA;
1314
1315 /* Fill the Version field. */
1316 WLAN_SET_FIELD_16(&prWpaIE->u2Version, 1); /* version 1 */
1317 ucExpendedLen = 6;
1318
1319 /* Fill the Pairwise Key Cipher Suite List field. */
1320 u2SuiteCount = 0;
1321 cp = (PUINT_8) &prWpaIE->aucPairwiseKeyCipherSuite1[0];
1322
1323 if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) {
1324 u4Suite = WPA_CIPHER_SUITE_CCMP;
1325 } else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) {
1326 u4Suite = WPA_CIPHER_SUITE_TKIP;
1327 } else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) {
1328 u4Suite = WPA_CIPHER_SUITE_WEP104;
1329 } else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) {
1330 u4Suite = WPA_CIPHER_SUITE_WEP40;
1331 } else {
1332 u4Suite = WPA_CIPHER_SUITE_TKIP;
1333 }
1334
1335 WLAN_SET_FIELD_32(cp, u4Suite);
1336 u2SuiteCount++;
1337 ucExpendedLen += 4;
1338 cp += 4;
1339
1340 /* Fill the Group Key Cipher Suite field as the same in pair-wise key. */
1341 WLAN_SET_FIELD_32(&prWpaIE->u4GroupKeyCipherSuite, u4Suite);
1342 ucExpendedLen += 4;
1343
1344 /* Fill the Pairwise Key Cipher Suite Count field. */
1345 WLAN_SET_FIELD_16(&prWpaIE->u2PairwiseKeyCipherSuiteCount, u2SuiteCount);
1346 ucExpendedLen += 2;
1347
1348 cp2 = cp;
1349
1350 /* Fill the Authentication and Key Management Suite List field. */
1351 u2SuiteCount = 0;
1352 cp += 2;
1353
1354 if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_802_1X, &i)) {
1355 u4Suite = WPA_AKM_SUITE_802_1X;
1356 } else if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_PSK, &i)) {
1357 u4Suite = WPA_AKM_SUITE_PSK;
1358 } else {
1359 u4Suite = WPA_AKM_SUITE_NONE;
1360 }
1361
1362 /* This shall be the only avaiable value for current implementation */
1363 ASSERT(u4Suite == WPA_AKM_SUITE_NONE);
1364
1365 WLAN_SET_FIELD_32(cp, u4Suite);
1366 u2SuiteCount++;
1367 ucExpendedLen += 4;
1368 cp += 4;
1369
1370 /* Fill the Authentication and Key Management Suite Count field. */
1371 WLAN_SET_FIELD_16(cp2, u2SuiteCount);
1372 ucExpendedLen += 2;
1373
1374 /* Fill the Length field. */
1375 prWpaIE->ucLength = (UINT_8) ucExpendedLen;
1376
1377 /* Increment the total IE length for the Element ID and Length fields. */
1378 prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1379
1380 } /* rsnGenerateWpaNoneIE */
1381
1382
1383 /*----------------------------------------------------------------------------*/
1384 /*!
1385 *
1386 * \brief This routine is called to generate WPA IE for
1387 * associate request frame.
1388 *
1389 * \param[in] prCurrentBss The Selected BSS description
1390 *
1391 * \retval The append WPA IE length
1392 *
1393 * \note
1394 * Called by: AIS module, Associate request
1395 */
1396 /*----------------------------------------------------------------------------*/
1397 VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
1398 {
1399 PUCHAR cp;
1400 PUINT_8 pucBuffer;
1401 UINT_8 ucBssIndex;
1402 P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo;
1403
1404 DEBUGFUNC("rsnGenerateWPAIE");
1405
1406 ASSERT(prMsduInfo);
1407
1408 pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket +
1409 (ULONG) prMsduInfo->u2FrameLength);
1410
1411 ASSERT(pucBuffer);
1412
1413 ucBssIndex = prMsduInfo->ucBssIndex;
1414 prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
1415
1416 /* if (eNetworkId != NETWORK_TYPE_AIS_INDEX) */
1417 /* return; */
1418
1419 #if CFG_ENABLE_WIFI_DIRECT
1420 if ((1 /* prCurrentBss->fgIEWPA */ &&
1421 ((prAdapter->fgIsP2PRegistered) &&
1422 (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType == NETWORK_TYPE_P2P) &&
1423 (kalP2PGetTkipCipher(prAdapter->prGlueInfo)))) ||
1424 ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) ||
1425 (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK)))
1426 #else
1427 if ((1 /* prCurrentBss->fgIEWPA */ &&
1428 ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) ||
1429 (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK))))
1430 #endif
1431 {
1432 if (prP2pSpecificBssInfo->u2WpaIeLen != 0) {
1433 kalMemCopy(pucBuffer, prP2pSpecificBssInfo->aucWpaIeBuffer,
1434 prP2pSpecificBssInfo->u2WpaIeLen);
1435 prMsduInfo->u2FrameLength += prP2pSpecificBssInfo->u2WpaIeLen;
1436 return;
1437 }
1438 /* Construct a WPA IE for association request frame. */
1439 WPA_IE(pucBuffer)->ucElemId = ELEM_ID_WPA;
1440 WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED;
1441 WPA_IE(pucBuffer)->aucOui[0] = 0x00;
1442 WPA_IE(pucBuffer)->aucOui[1] = 0x50;
1443 WPA_IE(pucBuffer)->aucOui[2] = 0xF2;
1444 WPA_IE(pucBuffer)->ucOuiType = VENDOR_OUI_TYPE_WPA;
1445 WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2Version, 1);
1446
1447 #if CFG_ENABLE_WIFI_DIRECT
1448 if (prAdapter->fgIsP2PRegistered
1449 && GET_BSS_INFO_BY_INDEX(prAdapter,
1450 ucBssIndex)->eNetworkType == NETWORK_TYPE_P2P) {
1451 WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite,
1452 WPA_CIPHER_SUITE_TKIP);
1453 } else
1454 #endif
1455 WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite,
1456 prAdapter->prAisBssInfo->u4RsnSelectedGroupCipher);
1457
1458 cp = (PUCHAR) &WPA_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0];
1459
1460 WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1);
1461 #if CFG_ENABLE_WIFI_DIRECT
1462 if (prAdapter->fgIsP2PRegistered
1463 && GET_BSS_INFO_BY_INDEX(prAdapter,
1464 ucBssIndex)->eNetworkType == NETWORK_TYPE_P2P) {
1465 WLAN_SET_FIELD_32(cp, WPA_CIPHER_SUITE_TKIP);
1466 } else
1467 #endif
1468 WLAN_SET_FIELD_32(cp, prAdapter->prAisBssInfo->u4RsnSelectedPairwiseCipher);
1469 cp += 4;
1470
1471 WLAN_SET_FIELD_16(cp, 1);
1472 cp += 2;
1473 #if CFG_ENABLE_WIFI_DIRECT
1474 if (prAdapter->fgIsP2PRegistered
1475 && GET_BSS_INFO_BY_INDEX(prAdapter,
1476 ucBssIndex)->eNetworkType == NETWORK_TYPE_P2P) {
1477 WLAN_SET_FIELD_32(cp, WPA_AKM_SUITE_PSK);
1478 } else
1479 #endif
1480 WLAN_SET_FIELD_32(cp, prAdapter->prAisBssInfo->u4RsnSelectedAKMSuite);
1481 cp += 4;
1482
1483 WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED;
1484
1485 prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1486 }
1487
1488 } /* rsnGenerateWPAIE */
1489
1490
1491 /*----------------------------------------------------------------------------*/
1492 /*!
1493 *
1494 * \brief This routine is called to generate RSN IE for
1495 * associate request frame.
1496 *
1497 * \param[in] prMsduInfo The Selected BSS description
1498 *
1499 * \retval The append RSN IE length
1500 *
1501 * \note
1502 * Called by: AIS module, P2P module, BOW module Associate request
1503 */
1504 /*----------------------------------------------------------------------------*/
1505 VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
1506 {
1507 UINT_32 u4Entry;
1508 PUCHAR cp;
1509 /* UINT_8 ucExpendedLen = 0; */
1510 PUINT_8 pucBuffer;
1511 UINT_8 ucBssIndex;
1512 P_STA_RECORD_T prStaRec;
1513
1514 DEBUGFUNC("rsnGenerateRSNIE");
1515
1516 ASSERT(prMsduInfo);
1517
1518 pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket +
1519 (ULONG) prMsduInfo->u2FrameLength);
1520
1521 ASSERT(pucBuffer);
1522
1523 /* Todo:: network id */
1524 ucBssIndex = prMsduInfo->ucBssIndex;
1525
1526 if (
1527 #if CFG_ENABLE_WIFI_DIRECT
1528 ((prAdapter->fgIsP2PRegistered) &&
1529 (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType == NETWORK_TYPE_P2P)
1530 && (kalP2PGetCcmpCipher(prAdapter->prGlueInfo))) ||
1531 #endif
1532 #if CFG_ENABLE_BT_OVER_WIFI
1533 (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType == NETWORK_TYPE_BOW)
1534 ||
1535 #endif
1536 (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType ==
1537 NETWORK_TYPE_AIS /* prCurrentBss->fgIERSN */ &&
1538 ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2)
1539 || (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK)))) {
1540 /* Construct a RSN IE for association request frame. */
1541 RSN_IE(pucBuffer)->ucElemId = ELEM_ID_RSN;
1542 RSN_IE(pucBuffer)->ucLength = ELEM_ID_RSN_LEN_FIXED;
1543 WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2Version, 1); /* Version */
1544 WLAN_SET_FIELD_32(&RSN_IE(pucBuffer)->u4GroupKeyCipherSuite, GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->u4RsnSelectedGroupCipher); /* Group key suite */
1545 cp = (PUCHAR) &RSN_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0];
1546 WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1);
1547 WLAN_SET_FIELD_32(cp,
1548 GET_BSS_INFO_BY_INDEX(prAdapter,
1549 ucBssIndex)->u4RsnSelectedPairwiseCipher);
1550 cp += 4;
1551 WLAN_SET_FIELD_16(cp, 1); /* AKM suite count */
1552 cp += 2;
1553 WLAN_SET_FIELD_32(cp, GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->u4RsnSelectedAKMSuite); /* AKM suite */
1554 cp += 4;
1555 #if CFG_SUPPORT_802_11W
1556 WLAN_SET_FIELD_16(cp, GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->u2RsnSelectedCapInfo); /* Capabilities */
1557 DBGLOG(RSN, TRACE,
1558 ("Gen RSN IE = %x\n",
1559 GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->u2RsnSelectedCapInfo));
1560 if (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType == NETWORK_TYPE_AIS
1561 && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection) {
1562 if (kalGetMfpSetting(prAdapter->prGlueInfo) ==
1563 RSN_AUTH_MFP_REQUIRED
1564 /* prAdapter->rWifiVar.rAisSpecificBssInfo.fgAPApplyPmfReq */) {
1565 WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC | ELEM_WPA_CAP_MFPR); /* Capabilities */
1566 DBGLOG(RSN, TRACE, ("RSN_AUTH_MFP_NO - MFPC & MFPR\n"));
1567 } else {
1568 WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC); /* Capabilities */
1569 DBGLOG(RSN, TRACE, ("RSN_AUTH_MFP_NO - MFPC\n"));
1570 }
1571 }
1572 #else
1573 WLAN_SET_FIELD_16(cp, GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->u2RsnSelectedCapInfo); /* Capabilities */
1574 #endif
1575 cp += 2;
1576
1577 if (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType == NETWORK_TYPE_AIS)
1578 prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
1579
1580 if (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType == NETWORK_TYPE_AIS
1581 && rsnSearchPmkidEntry(prAdapter, prStaRec->aucMacAddr, &u4Entry)) {
1582 /* DBGLOG(RSN, TRACE, ("Add Pmk at assoc req\n")); */
1583 /* DBGLOG(RSN, TRACE, ("addr " MACSTR" PMKID "MACSTR"\n", */
1584 /* MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arBSSID), MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID))); */
1585 if (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].
1586 fgPmkidExist) {
1587 RSN_IE(pucBuffer)->ucLength = 38;
1588 WLAN_SET_FIELD_16(cp, 1); /* PMKID count */
1589 cp += 2;
1590 DBGLOG(RSN, TRACE,
1591 ("BSSID " MACSTR " ind=%lu\n", MAC2STR(prStaRec->aucMacAddr),
1592 u4Entry));
1593 DBGLOG(RSN, TRACE,
1594 ("use PMKID " MACSTR "\n",
1595 MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.
1596 arPmkidCache[u4Entry].rBssidInfo.arPMKID)));
1597 kalMemCopy(cp,
1598 (PVOID) prAdapter->rWifiVar.rAisSpecificBssInfo.
1599 arPmkidCache[u4Entry].rBssidInfo.arPMKID,
1600 sizeof(PARAM_PMKID_VALUE));
1601 /* ucExpendedLen = 40; */
1602 } else {
1603 WLAN_SET_FIELD_16(cp, 0); /* PMKID count */
1604 /* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */
1605 #if CFG_SUPPORT_802_11W
1606 cp += 2;
1607 RSN_IE(pucBuffer)->ucLength += 2;
1608 #endif
1609 }
1610 } else {
1611 WLAN_SET_FIELD_16(cp, 0); /* PMKID count */
1612 /* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */
1613 #if CFG_SUPPORT_802_11W
1614 if ((GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType ==
1615 NETWORK_TYPE_AIS)
1616 && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection
1617 && (kalGetMfpSetting(prAdapter->prGlueInfo) !=
1618 RSN_AUTH_MFP_DISABLED)
1619 /* (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) */) {
1620 cp += 2;
1621 RSN_IE(pucBuffer)->ucLength += 2;
1622 }
1623 #endif
1624 }
1625
1626 #if CFG_SUPPORT_802_11W
1627 if ((GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType == NETWORK_TYPE_AIS)
1628 && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection
1629 && (kalGetMfpSetting(prAdapter->prGlueInfo) !=
1630 RSN_AUTH_MFP_DISABLED) /* (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) */
1631 ) {
1632 WLAN_SET_FIELD_32(cp, RSN_CIPHER_SUITE_AES_128_CMAC);
1633 cp += 4;
1634 RSN_IE(pucBuffer)->ucLength += 4;
1635 }
1636 #endif
1637 prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1638 }
1639
1640 } /* rsnGenerateRSNIE */
1641
1642 /*----------------------------------------------------------------------------*/
1643 /*!
1644 * \brief Parse the given IE buffer and check if it is WFA IE and return Type and
1645 * SubType for further process.
1646 *
1647 * \param[in] pucBuf Pointer to the buffer of WFA Information Element.
1648 * \param[out] pucOuiType Pointer to the storage of OUI Type.
1649 * \param[out] pu2SubTypeVersion Pointer to the storage of OUI SubType and Version.
1650
1651 * \retval TRUE Parse IE ok
1652 * \retval FALSE Parse IE fail
1653 */
1654 /*----------------------------------------------------------------------------*/
1655 BOOLEAN
1656 rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter,
1657 IN PUINT_8 pucBuf,
1658 OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion)
1659 {
1660 UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
1661 P_IE_WFA_T prWfaIE;
1662
1663 ASSERT(pucBuf);
1664 ASSERT(pucOuiType);
1665 ASSERT(pu2SubTypeVersion);
1666 prWfaIE = (P_IE_WFA_T) pucBuf;
1667
1668 do {
1669 if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) {
1670 break;
1671 } else if (prWfaIE->aucOui[0] != aucWfaOui[0] ||
1672 prWfaIE->aucOui[1] != aucWfaOui[1] ||
1673 prWfaIE->aucOui[2] != aucWfaOui[2]) {
1674 break;
1675 }
1676
1677 *pucOuiType = prWfaIE->ucOuiType;
1678 WLAN_GET_FIELD_16(&prWfaIE->aucOuiSubTypeVersion[0], pu2SubTypeVersion);
1679
1680 return TRUE;
1681 } while (FALSE);
1682
1683 return FALSE;
1684
1685 } /* end of rsnParseCheckForWFAInfoElem() */
1686
1687 #if CFG_SUPPORT_AAA
1688 /*----------------------------------------------------------------------------*/
1689 /*!
1690 * \brief Parse the given IE buffer and check if it is RSN IE with CCMP PSK
1691 *
1692 * \param[in] prAdapter Pointer to Adapter
1693 * \param[in] prSwRfb Pointer to the rx buffer
1694 * \param[in] pIE Pointer rthe buffer of Information Element.
1695 * \param[out] prStatusCode Pointer to the return status code.
1696
1697 * \retval none
1698 */
1699 /*----------------------------------------------------------------------------*/
1700 void
1701 rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode)
1702 {
1703
1704 RSN_INFO_T rRsnIe;
1705
1706 ASSERT(prAdapter);
1707 ASSERT(prIe);
1708 ASSERT(pu2StatusCode);
1709
1710 *pu2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT;
1711
1712 if (rsnParseRsnIE(prAdapter, prIe, &rRsnIe)) {
1713 if ((rRsnIe.u4PairwiseKeyCipherSuiteCount != 1)
1714 || (rRsnIe.au4PairwiseKeyCipherSuite[0] != RSN_CIPHER_SUITE_CCMP)) {
1715 *pu2StatusCode = STATUS_CODE_INVALID_PAIRWISE_CIPHER;
1716 return;
1717 }
1718 if ((rRsnIe.u4GroupKeyCipherSuite != RSN_CIPHER_SUITE_CCMP)) {
1719 *pu2StatusCode = STATUS_CODE_INVALID_GROUP_CIPHER;
1720 return;
1721 }
1722 if ((rRsnIe.u4AuthKeyMgtSuiteCount != 1)
1723 || (rRsnIe.au4AuthKeyMgtSuite[0] != RSN_AKM_SUITE_PSK)) {
1724 *pu2StatusCode = STATUS_CODE_INVALID_AKMP;
1725 return;
1726 }
1727
1728 DBGLOG(RSN, TRACE, ("RSN with CCMP-PSK\n"));
1729 *pu2StatusCode = WLAN_STATUS_SUCCESS;
1730 }
1731
1732 }
1733 #endif
1734
1735 /*----------------------------------------------------------------------------*/
1736 /*!
1737 * \brief This routine is called to generate an authentication event to NDIS.
1738 *
1739 * \param[in] u4Flags Authentication event: \n
1740 * PARAM_AUTH_REQUEST_REAUTH 0x01 \n
1741 * PARAM_AUTH_REQUEST_KEYUPDATE 0x02 \n
1742 * PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 \n
1743 * PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E \n
1744 *
1745 * \return (none)
1746 */
1747 /*----------------------------------------------------------------------------*/
1748 VOID rsnGenMicErrorEvent(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgFlags)
1749 {
1750 P_PARAM_AUTH_EVENT_T prAuthEvent;
1751
1752 DEBUGFUNC("rsnGenMicErrorEvent");
1753
1754 prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer;
1755
1756 /* Status type: Authentication Event */
1757 prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION;
1758
1759 /* Authentication request */
1760 prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T);
1761 kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid,
1762 (PVOID) prAdapter->prAisBssInfo->aucBSSID, MAC_ADDR_LEN);
1763
1764 if (fgFlags == TRUE)
1765 prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR;
1766 else
1767 prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR;
1768
1769 kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
1770 WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
1771 (PVOID) prAuthEvent,
1772 sizeof(PARAM_STATUS_INDICATION_T) +
1773 sizeof(PARAM_AUTH_REQUEST_T));
1774
1775 } /* rsnGenMicErrorEvent */
1776
1777
1778 /*----------------------------------------------------------------------------*/
1779 /*!
1780 * \brief This routine is called to handle TKIP MIC failures.
1781 *
1782 * \param[in] adapter_p Pointer to the adapter object data area.
1783 * \param[in] prSta Pointer to the STA which occur MIC Error
1784 * \param[in] fgErrorKeyType type of error key
1785 *
1786 * \retval none
1787 */
1788 /*----------------------------------------------------------------------------*/
1789 VOID
1790 rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter,
1791 IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType)
1792 {
1793 /* UINT_32 u4RsnaCurrentMICFailTime; */
1794 /* P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; */
1795
1796 DEBUGFUNC("rsnTkipHandleMICFailure");
1797
1798 ASSERT(prAdapter);
1799 #if 1
1800 rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType);
1801
1802 /* Generate authentication request event. */
1803 DBGLOG(RSN, INFO, ("Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType));
1804 #else
1805 ASSERT(prSta);
1806
1807 prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1808
1809 /* Record the MIC error occur time. */
1810 GET_CURRENT_SYSTIME(&u4RsnaCurrentMICFailTime);
1811
1812 /* Generate authentication request event. */
1813 DBGLOG(RSN, INFO, ("Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType));
1814
1815 /* If less than 60 seconds have passed since a previous TKIP MIC failure,
1816 disassociate from the AP and wait for 60 seconds before (re)associating
1817 with the same AP. */
1818 if (prAisSpecBssInfo->u4RsnaLastMICFailTime != 0 &&
1819 !CHECK_FOR_TIMEOUT(u4RsnaCurrentMICFailTime,
1820 prAisSpecBssInfo->u4RsnaLastMICFailTime,
1821 SEC_TO_SYSTIME(TKIP_COUNTERMEASURE_SEC))) {
1822 /* If less than 60 seconds expired since last MIC error, we have to
1823 block traffic. */
1824
1825 DBGLOG(RSN, INFO, ("Start blocking traffic!\n"));
1826 rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType);
1827
1828 secFsmEventStartCounterMeasure(prAdapter, prSta);
1829 } else {
1830 rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType);
1831 DBGLOG(RSN, INFO, ("First TKIP MIC error!\n"));
1832 }
1833
1834 COPY_SYSTIME(prAisSpecBssInfo->u4RsnaLastMICFailTime, u4RsnaCurrentMICFailTime);
1835 #endif
1836 } /* rsnTkipHandleMICFailure */
1837
1838
1839 /*----------------------------------------------------------------------------*/
1840 /*!
1841 * \brief This function is called to select a list of BSSID from
1842 * the scan results for PMKID candidate list.
1843 *
1844 * \param[in] prBssDesc the BSS Desc at scan result list
1845 * \param[out] pu4CandidateCount Pointer to the number of selected candidates.
1846 * It is set to zero if no BSSID matches our requirement.
1847 *
1848 * \retval none
1849 */
1850 /*----------------------------------------------------------------------------*/
1851 VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc)
1852 {
1853 P_CONNECTION_SETTINGS_T prConnSettings;
1854 P_BSS_INFO_T prAisBssInfo;
1855
1856 DEBUGFUNC("rsnSelectPmkidCandidateList");
1857
1858 ASSERT(prBssDesc);
1859
1860 prConnSettings = &prAdapter->rWifiVar.rConnSettings;
1861 prAisBssInfo = prAdapter->prAisBssInfo;
1862
1863 /* Search a BSS with the same SSID from the given BSS description set. */
1864 /* DBGLOG(RSN, TRACE, ("Check scan result ["MACSTR"]\n", */
1865 /* MAC2STR(prBssDesc->aucBSSID))); */
1866
1867 if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen,
1868 prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
1869 DBGLOG(RSN, TRACE, ("-- SSID not matched\n"));
1870 return;
1871 }
1872 #if 0
1873 if ((prBssDesc->u2BSSBasicRateSet &
1874 ~(rPhyAttributes[prAisBssInfo->ePhyType].u2SupportedRateSet)) ||
1875 prBssDesc->fgIsUnknownBssBasicRate) {
1876 DBGLOG(RSN, TRACE, ("-- Rate set not matched\n"));
1877 return;
1878 }
1879
1880 if (/* prBssDesc->u4RsnSelectedPairwiseCipher != prAisBssInfo->u4RsnSelectedPairwiseCipher || */
1881 prBssDesc->u4RsnSelectedGroupCipher != prAisBssInfo->u4RsnSelectedGroupCipher /*||
1882 prBssDesc->u4RsnSelectedAKMSuite != prAisBssInfo->u4RsnSelectedAKMSuite */) {
1883 DBGLOG(RSN, TRACE, ("-- Encrypt status not matched for PMKID\n"));
1884 return;
1885 }
1886 #endif
1887
1888 rsnUpdatePmkidCandidateList(prAdapter, prBssDesc);
1889
1890 } /* rsnSelectPmkidCandidateList */
1891
1892
1893 /*----------------------------------------------------------------------------*/
1894 /*!
1895 * \brief This function is called to select a list of BSSID from
1896 * the scan results for PMKID candidate list.
1897 *
1898 * \param[in] prBssDesc the BSS DESC at scan result list
1899 *
1900 * \retval none
1901 */
1902 /*----------------------------------------------------------------------------*/
1903 VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc)
1904 {
1905 UINT_32 i;
1906 P_CONNECTION_SETTINGS_T prConnSettings;
1907 P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
1908
1909 DEBUGFUNC("rsnUpdatePmkidCandidateList");
1910
1911 ASSERT(prBssDesc);
1912
1913 prConnSettings = &prAdapter->rWifiVar.rConnSettings;
1914 prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1915
1916 if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen,
1917 prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
1918 DBGLOG(RSN, TRACE, ("-- SSID not matched\n"));
1919 return;
1920 }
1921
1922 for (i = 0; i < CFG_MAX_PMKID_CACHE; i++) {
1923 if (EQUAL_MAC_ADDR
1924 (prBssDesc->aucBSSID, prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))
1925 return;
1926 }
1927
1928 /* If the number of selected BSSID exceed MAX_NUM_PMKID_CACHE(16),
1929 then we only store MAX_NUM_PMKID_CACHE(16) in PMKID cache */
1930 if ((prAisSpecBssInfo->u4PmkidCandicateCount + 1) > CFG_MAX_PMKID_CACHE) {
1931 prAisSpecBssInfo->u4PmkidCandicateCount--;
1932 }
1933
1934 i = prAisSpecBssInfo->u4PmkidCandicateCount;
1935
1936 COPY_MAC_ADDR((PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid,
1937 (PVOID) prBssDesc->aucBSSID);
1938
1939 if (prBssDesc->u2RsnCap & MASK_RSNIE_CAP_PREAUTH) {
1940 prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 1;
1941 DBGLOG(RSN, TRACE, ("Add " MACSTR " with pre-auth to candidate list\n",
1942 MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
1943 } else {
1944 prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 0;
1945 DBGLOG(RSN, TRACE, ("Add " MACSTR " without pre-auth to candidate list\n",
1946 MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
1947 }
1948
1949 prAisSpecBssInfo->u4PmkidCandicateCount++;
1950
1951 } /* rsnUpdatePmkidCandidateList */
1952
1953
1954 /*----------------------------------------------------------------------------*/
1955 /*!
1956 * \brief This routine is called to search the desired entry in
1957 * PMKID cache according to the BSSID
1958 *
1959 * \param[in] pucBssid Pointer to the BSSID
1960 * \param[out] pu4EntryIndex Pointer to place the found entry index
1961 *
1962 * \retval TRUE, if found one entry for specified BSSID
1963 * \retval FALSE, if not found
1964 */
1965 /*----------------------------------------------------------------------------*/
1966 BOOLEAN
1967 rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex)
1968 {
1969 UINT_32 i;
1970 P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
1971
1972 DEBUGFUNC("rsnSearchPmkidEntry");
1973
1974 ASSERT(pucBssid);
1975 ASSERT(pu4EntryIndex);
1976
1977 prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1978
1979 if (prAisSpecBssInfo->u4PmkidCacheCount > CFG_MAX_PMKID_CACHE) {
1980 return FALSE;
1981 }
1982
1983 ASSERT(prAisSpecBssInfo->u4PmkidCacheCount <= CFG_MAX_PMKID_CACHE);
1984
1985 /* Search for desired BSSID */
1986 for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) {
1987 if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, pucBssid,
1988 MAC_ADDR_LEN)) {
1989 break;
1990 }
1991 }
1992
1993 /* If desired BSSID is found, then set the PMKID */
1994 if (i < prAisSpecBssInfo->u4PmkidCacheCount) {
1995 *pu4EntryIndex = i;
1996
1997 return TRUE;
1998 }
1999
2000 return FALSE;
2001 } /* rsnSearchPmkidEntry */
2002
2003
2004 /*----------------------------------------------------------------------------*/
2005 /*!
2006 * \brief This routine is called to check if there is difference
2007 * between PMKID candicate list and PMKID cache. If there
2008 * is new candicate that no cache entry is available, then
2009 * add a new entry for the new candicate in the PMKID cache
2010 * and set the PMKID indication flag to TRUE.
2011 *
2012 * \retval TRUE, if new member in the PMKID candicate list
2013 * \retval FALSe, if no new member in the PMKID candicate list
2014 */
2015 /*----------------------------------------------------------------------------*/
2016 BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter)
2017 {
2018 P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
2019 UINT_32 i; /* Index for PMKID candicate */
2020 UINT_32 j; /* Indix for PMKID cache */
2021 BOOLEAN status = FALSE;
2022
2023 DEBUGFUNC("rsnCheckPmkidCandicate");
2024
2025 prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2026
2027 /* Check for each candicate */
2028 for (i = 0; i < prAisSpecBssInfo->u4PmkidCandicateCount; i++) {
2029 for (j = 0; j < prAisSpecBssInfo->u4PmkidCacheCount; j++) {
2030 if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID,
2031 prAisSpecBssInfo->arPmkidCandicate[i].aucBssid,
2032 MAC_ADDR_LEN)) {
2033 /* DBGLOG(RSN, TRACE, (MACSTR" at PMKID cache!!\n", MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))); */
2034 break;
2035 }
2036 }
2037
2038 /* No entry found in PMKID cache for the candicate, add new one */
2039 if (j == prAisSpecBssInfo->u4PmkidCacheCount
2040 && prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE) {
2041 DBGLOG(RSN, TRACE,
2042 ("Add " MACSTR " to PMKID cache!!\n",
2043 MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
2044 kalMemCopy((PVOID) prAisSpecBssInfo->
2045 arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.
2046 arBSSID, (PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid,
2047 MAC_ADDR_LEN);
2048 prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].
2049 fgPmkidExist = FALSE;
2050 prAisSpecBssInfo->u4PmkidCacheCount++;
2051
2052 status = TRUE;
2053 }
2054 }
2055
2056 return status;
2057 } /* rsnCheckPmkidCandicate */
2058
2059
2060 /*----------------------------------------------------------------------------*/
2061 /*!
2062 * \brief This function is called to wait a duration to indicate the pre-auth AP candicate
2063 *
2064 * \return (none)
2065 */
2066 /*----------------------------------------------------------------------------*/
2067 VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParamPtr)
2068 {
2069 DBGLOG(RSN, EVENT, ("Security - Time to indicate the PMKID cand.\n"));
2070
2071 /* If the authentication mode is WPA2 and indication PMKID flag
2072 is available, then we indicate the PMKID candidate list to NDIS and
2073 clear the flag, indicatePMKID */
2074
2075 if (prAdapter->prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED &&
2076 prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2077 rsnGeneratePmkidIndication(prAdapter);
2078 }
2079
2080 return;
2081 } /* end of rsnIndicatePmkidCand() */
2082
2083
2084 /*----------------------------------------------------------------------------*/
2085 /*!
2086 * \brief This routine is called to check the BSS Desc at scan result
2087 * with pre-auth cap at wpa2 mode. If there
2088 * is candicate that no cache entry is available, then
2089 * add a new entry for the new candicate in the PMKID cache
2090 * and set the PMKID indication flag to TRUE.
2091 *
2092 * \param[in] prBss The BSS Desc at scan result
2093 *
2094 * \return none
2095 */
2096 /*----------------------------------------------------------------------------*/
2097 VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss)
2098 {
2099 P_BSS_INFO_T prAisBssInfo;
2100 P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
2101 P_CONNECTION_SETTINGS_T prConnSettings;
2102
2103 DEBUGFUNC("rsnCheckPmkidCandicate");
2104
2105 ASSERT(prBss);
2106
2107 prConnSettings = &prAdapter->rWifiVar.rConnSettings;
2108 prAisBssInfo = prAdapter->prAisBssInfo;
2109 prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2110
2111 if ((prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) &&
2112 (prConnSettings->eAuthMode == AUTH_MODE_WPA2)) {
2113 rsnSelectPmkidCandidateList(prAdapter, prBss);
2114
2115 /* Set indication flag of PMKID to TRUE, and then connHandleNetworkConnection()
2116 will indicate this later */
2117 if (rsnCheckPmkidCandicate(prAdapter)) {
2118 DBGLOG(RSN, TRACE,
2119 ("Prepare a timer to indicate candidate PMKID Candidate\n"));
2120 cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer);
2121 cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer,
2122 SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
2123 }
2124 }
2125 }
2126
2127
2128 /*----------------------------------------------------------------------------*/
2129 /*!
2130 * \brief This routine is called to generate an PMKID candidate list
2131 * indication to NDIS.
2132 *
2133 * \param[in] prAdapter Pointer to the adapter object data area.
2134 * \param[in] u4Flags PMKID candidate list event:
2135 * PARAM_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
2136 *
2137 * \retval none
2138 */
2139 /*----------------------------------------------------------------------------*/
2140 VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter)
2141 {
2142 P_PARAM_STATUS_INDICATION_T prStatusEvent;
2143 P_PARAM_PMKID_CANDIDATE_LIST_T prPmkidEvent;
2144 P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo;
2145 UINT_8 i, j = 0, count = 0;
2146 UINT_32 u4LenOfUsedBuffer;
2147
2148 DEBUGFUNC("rsnGeneratePmkidIndication");
2149
2150 ASSERT(prAdapter);
2151
2152 prStatusEvent = (P_PARAM_STATUS_INDICATION_T) prAdapter->aucIndicationEventBuffer;
2153
2154 /* Status type: PMKID Candidatelist Event */
2155 prStatusEvent->eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST;
2156 ASSERT(prStatusEvent);
2157
2158 prPmkidEvent = (P_PARAM_PMKID_CANDIDATE_LIST_T) (&prStatusEvent->eStatusType + 1);
2159 ASSERT(prPmkidEvent);
2160
2161 prAisSpecificBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2162 ASSERT(prAisSpecificBssInfo);
2163
2164 for (i = 0; i < prAisSpecificBssInfo->u4PmkidCandicateCount; i++) {
2165 for (j = 0; j < prAisSpecificBssInfo->u4PmkidCacheCount; j++) {
2166 if (EQUAL_MAC_ADDR(prAisSpecificBssInfo->arPmkidCache[j].rBssidInfo.arBSSID,
2167 prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid) &&
2168 (prAisSpecificBssInfo->arPmkidCache[j].fgPmkidExist == TRUE)) {
2169 break;
2170 }
2171 }
2172 if (count >= CFG_MAX_PMKID_CACHE) {
2173 break;
2174 }
2175
2176 if (j == prAisSpecificBssInfo->u4PmkidCacheCount) {
2177 kalMemCopy((PVOID) prPmkidEvent->arCandidateList[count].arBSSID,
2178 (PVOID) prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid,
2179 PARAM_MAC_ADDR_LEN);
2180 prPmkidEvent->arCandidateList[count].u4Flags =
2181 prAisSpecificBssInfo->arPmkidCandicate[i].u4PreAuthFlags;
2182 DBGLOG(RSN, TRACE,
2183 (MACSTR " %lu\n",
2184 MAC2STR(prPmkidEvent->arCandidateList[count].arBSSID),
2185 prPmkidEvent->arCandidateList[count].u4Flags));
2186 count++;
2187 }
2188 }
2189
2190 /* PMKID Candidate List */
2191 prPmkidEvent->u4Version = 1;
2192 prPmkidEvent->u4NumCandidates = count;
2193 DBGLOG(RSN, TRACE, ("rsnGeneratePmkidIndication #%lu\n", prPmkidEvent->u4NumCandidates));
2194 u4LenOfUsedBuffer = sizeof(ENUM_STATUS_TYPE_T) + (2 * sizeof(UINT_32)) +
2195 (count * sizeof(PARAM_PMKID_CANDIDATE_T));
2196 /* dumpMemory8((PUINT_8)prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer); */
2197
2198 kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2199 WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
2200 (PVOID) prAdapter->aucIndicationEventBuffer,
2201 u4LenOfUsedBuffer);
2202
2203 } /* rsnGeneratePmkidIndication */
2204
2205 #if CFG_SUPPORT_WPS2
2206 /*----------------------------------------------------------------------------*/
2207 /*!
2208 *
2209 * \brief This routine is called to generate WSC IE for
2210 * associate request frame.
2211 *
2212 * \param[in] prCurrentBss The Selected BSS description
2213 *
2214 * \retval The append WSC IE length
2215 *
2216 * \note
2217 * Called by: AIS module, Associate request
2218 */
2219 /*----------------------------------------------------------------------------*/
2220 VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
2221 {
2222 PUINT_8 pucBuffer;
2223
2224 ASSERT(prAdapter);
2225 ASSERT(prMsduInfo);
2226
2227 if (prMsduInfo->ucBssIndex != prAdapter->prAisBssInfo->ucBssIndex)
2228 return;
2229
2230 pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket +
2231 (ULONG) prMsduInfo->u2FrameLength);
2232
2233 /* ASSOC INFO IE ID: 221 :0xDD */
2234 if (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) {
2235 kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWSCAssocInfoIE,
2236 prAdapter->prGlueInfo->u2WSCAssocInfoIELen);
2237 prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WSCAssocInfoIELen;
2238 }
2239
2240 }
2241 #endif
2242
2243
2244 #if CFG_SUPPORT_802_11W
2245
2246 /*----------------------------------------------------------------------------*/
2247 /*!
2248 * \brief to check if the Bip Key installed or not
2249 *
2250 * \param[in]
2251 * prAdapter
2252 *
2253 * \return
2254 * TRUE
2255 * FALSE
2256 */
2257 /*----------------------------------------------------------------------------*/
2258 UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
2259 {
2260 if (prStaRec
2261 && GET_BSS_INFO_BY_INDEX(prAdapter,
2262 prStaRec->ucBssIndex)->eNetworkType ==
2263 (UINT_8) NETWORK_TYPE_AIS)
2264 return prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled;
2265 else
2266 return FALSE;
2267 }
2268
2269 /*----------------------------------------------------------------------------*/
2270 /*!
2271 *
2272 * \brief This routine is called to check the Sa query timeout.
2273 *
2274 *
2275 * \note
2276 * Called by: AIS module, Handle by Sa Quert timeout
2277 */
2278 /*----------------------------------------------------------------------------*/
2279 UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter)
2280 {
2281 P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo;
2282 UINT_32 now;
2283
2284 prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2285 ASSERT(prBssSpecInfo);
2286
2287 GET_CURRENT_SYSTIME(&now);
2288
2289 if (CHECK_FOR_TIMEOUT(now, prBssSpecInfo->u4SaQueryStart, TU_TO_MSEC(1000))) {
2290 DBGLOG(RSN, INFO, ("association SA Query timed out\n"));
2291
2292 prBssSpecInfo->ucSaQueryTimedOut = 1;
2293 kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE,
2294 prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2295 prBssSpecInfo->pucSaQueryTransId = NULL;
2296 prBssSpecInfo->u4SaQueryCount = 0;
2297 cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer);
2298 #if 1
2299 if (prAdapter->prAisBssInfo->eConnectionState ==
2300 PARAM_MEDIA_STATE_CONNECTED /* STA_STATE_3 == prStaRec->ucStaState */) {
2301 P_MSG_AIS_ABORT_T prAisAbortMsg;
2302
2303 prAisAbortMsg =
2304 (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG,
2305 sizeof(MSG_AIS_ABORT_T));
2306 if (!prAisAbortMsg) {
2307 return 0;
2308 }
2309 prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT;
2310 prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_DISASSOCIATED;
2311 prAisAbortMsg->fgDelayIndication = FALSE;
2312
2313 mboxSendMsg(prAdapter,
2314 MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF);
2315 }
2316 #else
2317 /* Re-connect */
2318 kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2319 WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0);
2320 #endif
2321 return 1;
2322 }
2323
2324 return 0;
2325 }
2326
2327 /*----------------------------------------------------------------------------*/
2328 /*!
2329 *
2330 * \brief This routine is called to start the 802.11w sa query timer.
2331 *
2332 *
2333 * \note
2334 * Called by: AIS module, Handle Rx mgmt request
2335 */
2336 /*----------------------------------------------------------------------------*/
2337 void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter, IN ULONG ulParamPtr)
2338 {
2339 P_BSS_INFO_T prBssInfo;
2340 P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo;
2341 P_MSDU_INFO_T prMsduInfo;
2342 P_ACTION_SA_QUERY_FRAME prTxFrame;
2343 UINT_16 u2PayloadLen;
2344 PUINT_8 pucTmp = NULL;
2345 UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN];
2346
2347 prBssInfo = prAdapter->prAisBssInfo;
2348 ASSERT(prBssInfo);
2349
2350 prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2351 ASSERT(prBssSpecInfo);
2352
2353 DBGLOG(RSN, INFO, ("MFP: Start Sa Query\n"));
2354
2355 if (prBssInfo->prStaRecOfAP == NULL) {
2356 DBGLOG(RSN, INFO, ("MFP: unassociated AP!\n"));
2357 return;
2358 }
2359
2360 if (prBssSpecInfo->u4SaQueryCount > 0 && rsnCheckSaQueryTimeout(prAdapter)) {
2361 DBGLOG(RSN, INFO,
2362 ("MFP: u4SaQueryCount count =%lu\n", prBssSpecInfo->u4SaQueryCount));
2363 return;
2364 }
2365
2366 prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
2367 MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
2368
2369 if (!prMsduInfo)
2370 return;
2371
2372 prTxFrame = (P_ACTION_SA_QUERY_FRAME)
2373 ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
2374
2375 prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
2376 if (rsnCheckBipKeyInstalled(prAdapter, prBssInfo->prStaRecOfAP)) {
2377 prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
2378 }
2379 COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
2380 COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
2381 COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
2382
2383 prTxFrame->ucCategory = CATEGORY_SA_QUERY_ACTION;
2384 prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST;
2385
2386 if (prBssSpecInfo->u4SaQueryCount == 0) {
2387 GET_CURRENT_SYSTIME(&prBssSpecInfo->u4SaQueryStart);
2388 }
2389
2390 if (prBssSpecInfo->u4SaQueryCount) {
2391 pucTmp =
2392 kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN,
2393 VIR_MEM_TYPE);
2394 if (!pucTmp) {
2395 DBGLOG(RSN, INFO,
2396 ("MFP: Fail to alloc tmp buffer for backup sa query id\n"));
2397 return;
2398 }
2399 kalMemCopy(pucTmp, prBssSpecInfo->pucSaQueryTransId,
2400 prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2401 }
2402
2403 kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE,
2404 prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2405
2406 ucTransId[0] = (UINT_8) (kalRandomNumber() & 0xFF);
2407 ucTransId[1] = (UINT_8) (kalRandomNumber() & 0xFF);
2408
2409 kalMemCopy(prTxFrame->ucTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2410
2411 prBssSpecInfo->u4SaQueryCount++;
2412
2413 prBssSpecInfo->pucSaQueryTransId =
2414 kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE);
2415 if (!prBssSpecInfo->pucSaQueryTransId) {
2416 kalMemFree(pucTmp, VIR_MEM_TYPE,
2417 (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN);
2418 DBGLOG(RSN, INFO, ("MFP: Fail to alloc buffer for sa query id list\n"));
2419 return;
2420 }
2421
2422 if (pucTmp) {
2423 kalMemCopy(prBssSpecInfo->pucSaQueryTransId, pucTmp,
2424 (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN);
2425 kalMemCopy(&prBssSpecInfo->
2426 pucSaQueryTransId[(prBssSpecInfo->u4SaQueryCount -
2427 1) * ACTION_SA_QUERY_TR_ID_LEN], ucTransId,
2428 ACTION_SA_QUERY_TR_ID_LEN);
2429 kalMemFree(pucTmp, VIR_MEM_TYPE,
2430 (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN);
2431 } else {
2432 kalMemCopy(prBssSpecInfo->pucSaQueryTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2433 }
2434
2435 u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN;
2436
2437 /* 4 <3> Update information of MSDU_INFO_T */
2438 TX_SET_MMPDU(prAdapter,
2439 prMsduInfo,
2440 prBssInfo->prStaRecOfAP->ucBssIndex,
2441 prBssInfo->prStaRecOfAP->ucIndex,
2442 WLAN_MAC_MGMT_HEADER_LEN,
2443 WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, NULL, MSDU_RATE_MODE_AUTO);
2444
2445 if (rsnCheckBipKeyInstalled(prAdapter, prBssInfo->prStaRecOfAP)) {
2446 DBGLOG(RSN, INFO, ("Set MSDU_OPT_PROTECTED_FRAME\n"));
2447 nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE);
2448 }
2449 /* 4 Enqueue the frame to send this action frame. */
2450 nicTxEnqueueMsdu(prAdapter, prMsduInfo);
2451
2452 DBGLOG(RSN, INFO, ("Set SA Query timer %lu (%d Tu)\n", prBssSpecInfo->u4SaQueryCount, 201));
2453
2454 cnmTimerStartTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer, TU_TO_MSEC(201));
2455
2456 }
2457
2458
2459 /*----------------------------------------------------------------------------*/
2460 /*!
2461 *
2462 * \brief This routine is called to start the 802.11w sa query.
2463 *
2464 *
2465 * \note
2466 * Called by: AIS module, Handle Rx mgmt request
2467 */
2468 /*----------------------------------------------------------------------------*/
2469 void rsnStartSaQuery(IN P_ADAPTER_T prAdapter)
2470 {
2471 P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo;
2472
2473 prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2474 ASSERT(prBssSpecInfo);
2475
2476 if (prBssSpecInfo->u4SaQueryCount == 0)
2477 rsnStartSaQueryTimer(prAdapter, (ULONG)NULL);
2478 }
2479
2480
2481 /*----------------------------------------------------------------------------*/
2482 /*!
2483 *
2484 * \brief This routine is called to stop the 802.11w sa query.
2485 *
2486 *
2487 * \note
2488 * Called by: AIS module, Handle Rx mgmt request
2489 */
2490 /*----------------------------------------------------------------------------*/
2491 void rsnStopSaQuery(IN P_ADAPTER_T prAdapter)
2492 {
2493 P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo;
2494
2495 prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2496 ASSERT(prBssSpecInfo);
2497
2498 cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer);
2499 kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE,
2500 prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2501 prBssSpecInfo->pucSaQueryTransId = NULL;
2502 prBssSpecInfo->u4SaQueryCount = 0;
2503 }
2504
2505 /*----------------------------------------------------------------------------*/
2506 /*!
2507 *
2508 * \brief This routine is called to process the 802.11w sa query action frame.
2509 *
2510 *
2511 * \note
2512 * Called by: AIS module, Handle Rx mgmt request
2513 */
2514 /*----------------------------------------------------------------------------*/
2515 void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
2516 {
2517 P_BSS_INFO_T prBssInfo;
2518 P_MSDU_INFO_T prMsduInfo;
2519 P_ACTION_SA_QUERY_FRAME prRxFrame = NULL;
2520 UINT_16 u2PayloadLen;
2521 P_STA_RECORD_T prStaRec;
2522 P_ACTION_SA_QUERY_FRAME prTxFrame;
2523
2524 prBssInfo = prAdapter->prAisBssInfo;
2525 ASSERT(prBssInfo);
2526
2527 if (!prSwRfb) {
2528 return;
2529 }
2530
2531 prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader;
2532 if (!prRxFrame)
2533 return;
2534
2535 prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
2536 if (!prStaRec) { /* Todo:: for not AIS check */
2537 return;
2538 }
2539
2540 DBGLOG(RSN, INFO, ("IEEE 802.11: Received SA Query Request from "
2541 MACSTR "\n", MAC2STR(prStaRec->aucMacAddr)));
2542
2543 DBGLOG_MEM8(RSN, INFO, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2544
2545 if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) {
2546 DBGLOG(RSN, INFO, ("IEEE 802.11: Ignore SA Query Request "
2547 "from unassociated STA " MACSTR "\n",
2548 MAC2STR(prStaRec->aucMacAddr)));
2549 return;
2550 }
2551
2552 DBGLOG(RSN, INFO, ("IEEE 802.11: Sending SA Query Response to "
2553 MACSTR "\n", MAC2STR(prStaRec->aucMacAddr)));
2554
2555 prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
2556 MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
2557
2558 if (!prMsduInfo)
2559 return;
2560
2561 prTxFrame = (P_ACTION_SA_QUERY_FRAME)
2562 ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
2563
2564 prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
2565 if (rsnCheckBipKeyInstalled(prAdapter, prBssInfo->prStaRecOfAP)) {
2566 prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
2567 }
2568 COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
2569 COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
2570 COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
2571
2572 prTxFrame->ucCategory = CATEGORY_SA_QUERY_ACTION;
2573 prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE;
2574
2575 kalMemCopy(prTxFrame->ucTransId, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2576
2577 u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN;
2578
2579 /* 4 <3> Update information of MSDU_INFO_T */
2580 TX_SET_MMPDU(prAdapter,
2581 prMsduInfo,
2582 prBssInfo->prStaRecOfAP->ucBssIndex,
2583 prBssInfo->prStaRecOfAP->ucIndex,
2584 WLAN_MAC_MGMT_HEADER_LEN,
2585 WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, NULL, MSDU_RATE_MODE_AUTO);
2586
2587 if (rsnCheckBipKeyInstalled(prAdapter, prBssInfo->prStaRecOfAP)) {
2588 DBGLOG(RSN, INFO, ("Set MSDU_OPT_PROTECTED_FRAME\n"));
2589 nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE);
2590 }
2591 #if 0
2592 /* 4 Update information of MSDU_INFO_T */
2593 prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */
2594 prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
2595 prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
2596 prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
2597 prMsduInfo->fgIs802_1x = FALSE;
2598 prMsduInfo->fgIs802_11 = TRUE;
2599 prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
2600 prMsduInfo->ucPID = nicAssignPID(prAdapter);
2601 prMsduInfo->pfTxDoneHandler = NULL;
2602 prMsduInfo->fgIsBasicRate = FALSE;
2603 #endif
2604 /* 4 Enqueue the frame to send this action frame. */
2605 nicTxEnqueueMsdu(prAdapter, prMsduInfo);
2606
2607 }
2608
2609
2610 /*----------------------------------------------------------------------------*/
2611 /*!
2612 *
2613 * \brief This routine is called to process the 802.11w sa query action frame.
2614 *
2615 *
2616 * \note
2617 * Called by: AIS module, Handle Rx mgmt request
2618 */
2619 /*----------------------------------------------------------------------------*/
2620 void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
2621 {
2622 P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo;
2623 P_ACTION_SA_QUERY_FRAME prRxFrame;
2624 P_STA_RECORD_T prStaRec;
2625 UINT_32 i;
2626
2627 prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2628 ASSERT(prBssSpecInfo);
2629
2630 prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader;
2631 prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
2632
2633 if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) {
2634 DBGLOG(RSN, INFO, ("IEEE 802.11: Too short SA Query Action "
2635 "frame (len=%lu)\n", (unsigned long)prSwRfb->u2PacketLen));
2636 return;
2637 }
2638
2639 if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) {
2640 rsnSaQueryRequest(prAdapter, prSwRfb);
2641 return;
2642 }
2643
2644 if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) {
2645 DBGLOG(RSN, INFO, ("IEEE 802.11: Unexpected SA Query "
2646 "Action %d\n", prRxFrame->ucAction));
2647 return;
2648 }
2649
2650 DBGLOG(RSN, INFO, ("IEEE 802.11: Received SA Query Response from "
2651 MACSTR "\n", MAC2STR(prStaRec->aucMacAddr)));
2652
2653 DBGLOG_MEM8(RSN, INFO, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2654
2655 /* MLME-SAQuery.confirm */
2656
2657 for (i = 0; i < prBssSpecInfo->u4SaQueryCount; i++) {
2658 if (kalMemCmp(prBssSpecInfo->pucSaQueryTransId +
2659 i * ACTION_SA_QUERY_TR_ID_LEN,
2660 prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN) == 0)
2661 break;
2662 }
2663
2664 if (i >= prBssSpecInfo->u4SaQueryCount) {
2665 DBGLOG(RSN, INFO, ("IEEE 802.11: No matching SA Query "
2666 "transaction identifier found\n"));
2667 return;
2668 }
2669
2670 DBGLOG(RSN, INFO, ("Reply to pending SA Query received\n"));
2671
2672 rsnStopSaQuery(prAdapter);
2673 }
2674 #endif
2675
2676 #if CFG_SUPPORT_AAA
2677 #define WPS_DEV_OUI_WFA 0x0050f204
2678 #define ATTR_RESPONSE_TYPE 0x103b
2679
2680 #define ATTR_VERSION 0x104a
2681 #define ATTR_VENDOR_EXT 0x1049
2682 #define WPS_VENDOR_ID_WFA 14122
2683
2684 VOID rsnGenerateWSCIEForAssocRsp(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
2685 {
2686 P_IE_HDR_T PucIE;
2687 PUINT_8 puc;
2688 P_WIFI_VAR_T prWifiVar = NULL;
2689
2690 ASSERT(prAdapter);
2691 ASSERT(prMsduInfo);
2692 ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucBssIndex));
2693
2694 prWifiVar = &(prAdapter->rWifiVar);
2695 ASSERT(prWifiVar);
2696
2697 if (!prWifiVar->ucApWpsMode) /* Todo::Only at WPS certification ? */
2698 return;
2699
2700 DBGLOG(RSN, TRACE, ("WPS: Building WPS IE for (Re)Association Response"));
2701
2702 PucIE = (P_IE_HDR_T) (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
2703
2704 PucIE->ucId = ELEM_ID_VENDOR;
2705
2706 puc = PucIE->aucInfo;
2707
2708 WLAN_SET_FIELD_BE32(puc, WPS_DEV_OUI_WFA);
2709 puc += 4;
2710
2711 WLAN_SET_FIELD_BE16(puc, ATTR_VERSION);
2712 puc += 2;
2713 WLAN_SET_FIELD_BE16(puc, 1);
2714 puc += 2;
2715 *puc = 0x10;
2716 puc++;
2717
2718 WLAN_SET_FIELD_BE16(puc, ATTR_RESPONSE_TYPE);
2719 puc += 2;
2720 WLAN_SET_FIELD_BE16(puc, 1);
2721 puc += 2;
2722 *puc = 0x3;
2723 puc++;
2724
2725 WLAN_SET_FIELD_BE16(puc, ATTR_VENDOR_EXT);
2726 puc += 2;
2727 WLAN_SET_FIELD_BE16(puc, 6);
2728 puc += 2;
2729 WLAN_SET_FIELD_BE24(puc, 14122);
2730 puc += 3;
2731 *puc = 0x00; /* Version 2 */
2732 puc++;
2733 *puc = 0x01;
2734 puc++;
2735 *puc = 0x20; /* WPS2.0 */
2736 puc++;
2737
2738 PucIE->ucLength = puc - PucIE->aucInfo;
2739
2740 prMsduInfo->u2FrameLength += IE_SIZE(PucIE);
2741
2742 }
2743
2744 #endif