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