2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/wapi.c#1 $
6 \brief This file including the WAPI related function.
8 This file provided the macros and functions library support the wapi ie parsing,
9 cipher and AKM check to help the AP seleced deciding.
18 * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
19 * change the debug module level.
22 * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function
23 * fixed the network type
27 * adding the wapi support for integration test.
34 * [BORA00000680][MT6620] Support the statistic for Microsoft os query
35 * fixed the firmware return the broadcast frame at wrong tc.
38 * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
39 * move the AIS specific variable for security to AIS specific structure.
42 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
46 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
47 * adding the function to check and update the default wapi tx
50 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
51 * adding the generate wapi ie function, and replace the tabe by space
53 * Nov 23 2009 mtk01088
54 * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
58 /*******************************************************************************
59 * C O M P I L E R F L A G S
60 ********************************************************************************
63 /*******************************************************************************
64 * E X T E R N A L R E F E R E N C E S
65 ********************************************************************************
71 /*******************************************************************************
73 ********************************************************************************
76 /*******************************************************************************
78 ********************************************************************************
81 /*******************************************************************************
83 ********************************************************************************
86 /*******************************************************************************
87 * P R I V A T E D A T A
88 ********************************************************************************
91 /*******************************************************************************
93 ********************************************************************************
96 /*******************************************************************************
97 * F U N C T I O N D E C L A R A T I O N S
98 ********************************************************************************
101 /*******************************************************************************
103 ********************************************************************************
106 /*----------------------------------------------------------------------------*/
109 * \brief This routine is called to generate WPA IE for
110 * associate request frame.
112 * \param[in] prCurrentBss The Selected BSS description
114 * \retval The append WPA IE length
117 * Called by: AIS module, Associate request
119 /*----------------------------------------------------------------------------*/
122 IN P_ADAPTER_T prAdapter,
123 IN P_MSDU_INFO_T prMsduInfo
131 if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX)
134 pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
135 (UINT_32)prMsduInfo->u2FrameLength);
137 /* ASSOC INFO IE ID: 68 :0x44 */
138 if (/* prWlanInfo->fgWapiMode && */ prAdapter->prGlueInfo->u2WapiAssocInfoIESz) {
139 kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWapiAssocInfoIEs, prAdapter->prGlueInfo->u2WapiAssocInfoIESz);
140 prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WapiAssocInfoIESz;
146 /*----------------------------------------------------------------------------*/
148 * \brief This routine is called to parse WAPI IE.
150 * \param[in] prInfoElem Pointer to the RSN IE
151 * \param[out] prRsnInfo Pointer to the BSSDescription structure to store the
152 ** WAPI information from the given WAPI IE
154 * \retval TRUE - Succeeded
155 * \retval FALSE - Failed
157 /*----------------------------------------------------------------------------*/
160 IN P_WAPI_INFO_ELEM_T prInfoElem,
161 OUT P_WAPI_INFO_T prWapiInfo
165 INT_32 u4RemainWapiIeLen;
168 UINT_32 u4GroupSuite = WAPI_CIPHER_SUITE_WPI;
169 UINT_16 u2PairSuiteCount = 0;
170 UINT_16 u2AuthSuiteCount = 0;
171 PUCHAR pucPairSuite = NULL;
172 PUCHAR pucAuthSuite = NULL;
175 DEBUGFUNC("wapiParseWapiIE");
180 /* Verify the length of the WAPI IE. */
181 if (prInfoElem->ucLength < 6) {
182 DBGLOG(SEC, TRACE, ("WAPI IE length too short (length=%d)\n", prInfoElem->ucLength));
186 /* Check WAPI version: currently, we only support version 1. */
187 WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version);
188 if (u2Version != 1) {
189 DBGLOG(SEC, TRACE, ("Unsupported WAPI IE version: %d\n", u2Version));
193 cp = (PUCHAR) &prInfoElem->u2AuthKeyMgtSuiteCount;
194 u4RemainWapiIeLen = (INT_32) prInfoElem->ucLength - 2;
197 if (u4RemainWapiIeLen == 0) {
203 AuthSuite : 4 * authSuiteCount
205 PairwiseSuite: 4 * pairSuiteCount
209 /* Parse the Authentication and Key Management Cipher Suite Count
211 if (u4RemainWapiIeLen < 2) {
212 DBGLOG(SEC, TRACE, ("Fail to parse WAPI IE in auth & key mgt suite count (IE len: %d)\n",
213 prInfoElem->ucLength));
217 WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount);
219 u4RemainWapiIeLen -= 2;
221 /* Parse the Authentication and Key Management Cipher Suite List
223 i = (UINT_32) u2AuthSuiteCount * 4;
224 if (u4RemainWapiIeLen < (INT_32) i) {
225 DBGLOG(SEC, TRACE, ("Fail to parse WAPI IE in auth & key mgt suite list (IE len: %d)\n",
226 prInfoElem->ucLength));
233 u4RemainWapiIeLen -= (INT_32) i;
235 if (u4RemainWapiIeLen == 0) {
239 /* Parse the Pairwise Key Cipher Suite Count field. */
240 if (u4RemainWapiIeLen < 2) {
241 DBGLOG(SEC, TRACE, ("Fail to parse WAPI IE in pairwise cipher suite count (IE len: %d)\n",
242 prInfoElem->ucLength));
246 WLAN_GET_FIELD_16(cp, &u2PairSuiteCount);
248 u4RemainWapiIeLen -= 2;
250 /* Parse the Pairwise Key Cipher Suite List field. */
251 i = (UINT_32) u2PairSuiteCount * 4;
252 if (u4RemainWapiIeLen < (INT_32) i) {
253 DBGLOG(SEC, TRACE, ("Fail to parse WAPI IE in pairwise cipher suite list (IE len: %d)\n",
254 prInfoElem->ucLength));
261 u4RemainWapiIeLen -= (INT_32) i;
263 /* Parse the Group Key Cipher Suite field. */
264 if (u4RemainWapiIeLen < 4) {
265 DBGLOG(SEC, TRACE, ("Fail to parse WAPI IE in group cipher suite (IE len: %d)\n",
266 prInfoElem->ucLength));
270 WLAN_GET_FIELD_32(cp, &u4GroupSuite);
272 u4RemainWapiIeLen -= 4;
274 /* Parse the WAPI u2Capabilities field. */
275 if (u4RemainWapiIeLen < 2) {
276 DBGLOG(SEC, TRACE, ("Fail to parse WAPI IE in WAPI capabilities (IE len: %d)\n",
277 prInfoElem->ucLength));
281 WLAN_GET_FIELD_16(cp, &u2Cap);
282 u4RemainWapiIeLen -= 2;
284 /* Todo:: BKID support */
287 /* Save the WAPI information for the BSS. */
289 prWapiInfo->ucElemId = ELEM_ID_WAPI;
291 prWapiInfo->u2Version = u2Version;
293 prWapiInfo->u4GroupKeyCipherSuite = u4GroupSuite;
295 DBGLOG(SEC, LOUD, ("WAPI: version %d, group key cipher suite %02x-%02x-%02x-%02x\n",
296 u2Version, (UCHAR) (u4GroupSuite & 0x000000FF),
297 (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF),
298 (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF),
299 (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)));
302 /* The information about the pairwise key cipher suites is present. */
303 if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) {
304 u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES;
307 prWapiInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount;
309 for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) {
310 WLAN_GET_FIELD_32(pucPairSuite,
311 &prWapiInfo->au4PairwiseKeyCipherSuite[i]);
314 DBGLOG(SEC, LOUD,("WAPI: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n",
315 (UINT_8)i, (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF),
316 (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF),
317 (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF),
318 (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)));
322 /* The information about the pairwise key cipher suites is not present.
323 Use the default chipher suite for WAPI: WPI. */
324 prWapiInfo->u4PairwiseKeyCipherSuiteCount = 1;
325 prWapiInfo->au4PairwiseKeyCipherSuite[0] = WAPI_CIPHER_SUITE_WPI;
327 DBGLOG(SEC, LOUD, ("WAPI: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n",
328 (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF),
329 (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF),
330 (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF),
331 (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)));
335 /* The information about the authentication and key management suites
337 if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) {
338 u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES;
341 prWapiInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount;
343 for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) {
344 WLAN_GET_FIELD_32(pucAuthSuite, &prWapiInfo->au4AuthKeyMgtSuite[i]);
347 DBGLOG(SEC, LOUD, ("WAPI: AKM suite [%d]: %02x-%02x-%02x-%02x\n",
348 (UINT_8)i, (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[i] & 0x000000FF),
349 (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF),
350 (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF),
351 (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)));
355 /* The information about the authentication and key management suites
356 is not present. Use the default AKM suite for WAPI. */
357 prWapiInfo->u4AuthKeyMgtSuiteCount = 1;
358 prWapiInfo->au4AuthKeyMgtSuite[0] = WAPI_AKM_SUITE_802_1X;
360 DBGLOG(SEC, LOUD, ("WAPI: AKM suite: %02x-%02x-%02x-%02x (default)\n",
361 (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[0] & 0x000000FF),
362 (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF),
363 (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF),
364 (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)));
367 prWapiInfo->u2WapiCap = u2Cap;
368 DBGLOG(SEC, LOUD, ("WAPI: cap: 0x%04x\n", prWapiInfo->u2WapiCap));
371 } /* wapiParseWapiIE */
374 /*----------------------------------------------------------------------------*/
376 * \brief This routine is called to perform WAPI policy selection for a given BSS.
378 * \param[in] prAdapter Pointer to the adapter object data area.
379 * \param[in] prBss Pointer to the BSS description
381 * \retval TRUE - The WAPI policy selection for the given BSS is
382 * successful. The selected pairwise and group cipher suites
383 * are returned in the BSS description.
384 * \retval FALSE - The WAPI policy selection for the given BSS is failed.
385 * The driver shall not attempt to join the given BSS.
387 * \note The Encrypt status matched score will save to bss for final ap select.
389 /*----------------------------------------------------------------------------*/
391 wapiPerformPolicySelection (
392 IN P_ADAPTER_T prAdapter,
393 IN P_BSS_DESC_T prBss
397 UINT_32 u4PairwiseCipher = 0;
398 UINT_32 u4GroupCipher = 0;
399 UINT_32 u4AkmSuite = 0;
400 P_WAPI_INFO_T prBssWapiInfo;
401 P_WLAN_INFO_T prWlanInfo;
403 DEBUGFUNC("wapiPerformPolicySelection");
407 /* Notice!!!! WAPI AP not set the privacy bit for WAI and WAI-PSK at WZC configuration mode */
408 prWlanInfo = &prAdapter->rWlanInfo;
410 if (prBss->fgIEWAPI) {
411 prBssWapiInfo = &prBss->rIEWAPI;
414 if (prAdapter->rWifiVar.rConnSettings.fgWapiMode == FALSE) {
415 DBGLOG(SEC, TRACE,("-- No Protected BSS\n"));
419 DBGLOG(SEC, TRACE, ("WAPI Information Element does not exist.\n"));
424 /* Select pairwise/group ciphers */
425 for (i = 0; i < prBssWapiInfo->u4PairwiseKeyCipherSuiteCount; i++) {
426 if (prBssWapiInfo->au4PairwiseKeyCipherSuite[i] ==
427 prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher) {
428 u4PairwiseCipher = prBssWapiInfo->au4PairwiseKeyCipherSuite[i];
431 if (prBssWapiInfo->u4GroupKeyCipherSuite ==
432 prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher)
433 u4GroupCipher = prBssWapiInfo->u4GroupKeyCipherSuite;
435 /* Exception handler */
436 /* If we cannot find proper pairwise and group cipher suites to join the
437 BSS, do not check the supported AKM suites. */
438 if (u4PairwiseCipher == 0 || u4GroupCipher == 0) {
439 DBGLOG(SEC, TRACE, ("Failed to select pairwise/group cipher (0x%08lx/0x%08lx)\n",
440 u4PairwiseCipher, u4GroupCipher));
445 /* If the driver cannot support any authentication suites advertised in
446 the given BSS, we fail to perform RSNA policy selection. */
447 /* Attempt to find any overlapping supported AKM suite. */
448 for (i = 0; i < prBssWapiInfo->u4AuthKeyMgtSuiteCount; i++) {
449 if (prBssWapiInfo->au4AuthKeyMgtSuite[i] == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite) {
450 u4AkmSuite = prBssWapiInfo->au4AuthKeyMgtSuite[i];
455 if (u4AkmSuite == 0) {
456 DBGLOG(SEC, TRACE, ("Cannot support any AKM suites\n"));
460 DBGLOG(SEC, TRACE, ("Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n",
461 (UINT_8) (u4PairwiseCipher & 0x000000FF),
462 (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF),
463 (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF),
464 (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF),
465 (UINT_8) (u4GroupCipher & 0x000000FF),
466 (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF),
467 (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF),
468 (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)));
470 DBGLOG(SEC, TRACE, ("Selected AKM suite: %02x-%02x-%02x-%02x\n",
471 (UINT_8) (u4AkmSuite & 0x000000FF),
472 (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF),
473 (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF),
474 (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)));
477 } /* wapiPerformPolicySelection */
480 /*----------------------------------------------------------------------------*/
482 * \brief This routine is use for wapi mode, to update the current wpi tx idx ? 0 :1 .
484 * \param[in] prStaRec Pointer to the Sta record
485 * \param[out] ucWlanIdx The Rx status->wlanidx field
487 * \retval TRUE - Succeeded
488 * \retval FALSE - Failed
490 /*----------------------------------------------------------------------------*/
493 IN P_STA_RECORD_T prStaRec,
499 if ((ucWlanIdx & BITS(0, 3)) == CIPHER_SUITE_WPI) {
501 ucKeyId = ((ucWlanIdx & BITS(4, 5)) >> 4);
503 if (ucKeyId != g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey) {
504 DBGLOG(RSN, STATE, ("Change wapi key index from %d->%d\n", g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey, ucKeyId));
505 g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey = ucKeyId;
507 prStaRec->ucWTEntry =
508 (ucKeyId == WTBL_AIS_BSSID_WAPI_IDX_0) ? WTBL_AIS_BSSID_WAPI_IDX_0 : WTBL_AIS_BSSID_WAPI_IDX_1;