wapi.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. /*
  2. ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/wapi.c#1
  3. */
  4. /*! \file "wapi.c"
  5. \brief This file including the WAPI related function.
  6. This file provided the macros and functions library support the wapi ie parsing,
  7. cipher and AKM check to help the AP seleced deciding.
  8. */
  9. /*
  10. ** Log: wapi.c
  11. **
  12. ** 10 24 2012 wh.su
  13. ** [ALPS00376392] [klocwork 9.1] in wapi.c, line 344
  14. ** Use MAX_NUM_SUPPORTED_WAPI_AKM_SUITESfor avoid Klocwork warning.
  15. **
  16. ** 10 24 2012 wh.su
  17. ** [ALPS00376391] [klocwork 9.1] in wapi.c, line 311
  18. ** Use the MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES for avoid Klccwork waring.
  19. *
  20. * 11 10 2011 wh.su
  21. * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
  22. * change the debug module level.
  23. *
  24. * 10 20 2010 wh.su
  25. * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function
  26. * fixed the network type
  27. *
  28. * 09 01 2010 wh.su
  29. * NULL
  30. * adding the wapi support for integration test.
  31. *
  32. * 07 20 2010 wh.su
  33. *
  34. * .
  35. *
  36. * 04 06 2010 wh.su
  37. * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query
  38. * fixed the firmware return the broadcast frame at wrong tc.
  39. *
  40. * 03 03 2010 wh.su
  41. * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
  42. * move the AIS specific variable for security to AIS specific structure.
  43. *
  44. * 12 18 2009 cm.chang
  45. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  46. * .
  47. *
  48. * Dec 8 2009 mtk01088
  49. * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
  50. * adding the function to check and update the default wapi tx
  51. *
  52. * Dec 7 2009 mtk01088
  53. * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
  54. * adding the generate wapi ie function, and replace the tabe by space
  55. *
  56. * Nov 23 2009 mtk01088
  57. * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
  58. *
  59. */
  60. /*******************************************************************************
  61. * C O M P I L E R F L A G S
  62. ********************************************************************************
  63. */
  64. /*******************************************************************************
  65. * E X T E R N A L R E F E R E N C E S
  66. ********************************************************************************
  67. */
  68. #include "precomp.h"
  69. #if CFG_SUPPORT_WAPI
  70. /*******************************************************************************
  71. * C O N S T A N T S
  72. ********************************************************************************
  73. */
  74. /*******************************************************************************
  75. * D A T A T Y P E S
  76. ********************************************************************************
  77. */
  78. /*******************************************************************************
  79. * P U B L I C D A T A
  80. ********************************************************************************
  81. */
  82. /*******************************************************************************
  83. * P R I V A T E D A T A
  84. ********************************************************************************
  85. */
  86. /*******************************************************************************
  87. * M A C R O S
  88. ********************************************************************************
  89. */
  90. /*******************************************************************************
  91. * F U N C T I O N D E C L A R A T I O N S
  92. ********************************************************************************
  93. */
  94. /*******************************************************************************
  95. * F U N C T I O N S
  96. ********************************************************************************
  97. */
  98. /*----------------------------------------------------------------------------*/
  99. /*!
  100. *
  101. * \brief This routine is called to generate WPA IE for
  102. * associate request frame.
  103. *
  104. * \param[in] prCurrentBss The Selected BSS description
  105. *
  106. * \retval The append WPA IE length
  107. *
  108. * \note
  109. * Called by: AIS module, Associate request
  110. */
  111. /*----------------------------------------------------------------------------*/
  112. VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo)
  113. {
  114. PUINT_8 pucBuffer;
  115. ASSERT(prAdapter);
  116. ASSERT(prMsduInfo);
  117. if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX)
  118. return;
  119. pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + prMsduInfo->u2FrameLength);
  120. /* ASSOC INFO IE ID: 68 :0x44 */
  121. if (/* prWlanInfo->fgWapiMode && */ prAdapter->prGlueInfo->u2WapiAssocInfoIESz) {
  122. kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWapiAssocInfoIEs,
  123. prAdapter->prGlueInfo->u2WapiAssocInfoIESz);
  124. prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WapiAssocInfoIESz;
  125. }
  126. }
  127. /*----------------------------------------------------------------------------*/
  128. /*!
  129. * \brief This routine is called to parse WAPI IE.
  130. *
  131. * \param[in] prInfoElem Pointer to the RSN IE
  132. * \param[out] prRsnInfo Pointer to the BSSDescription structure to store the
  133. ** WAPI information from the given WAPI IE
  134. *
  135. * \retval TRUE - Succeeded
  136. * \retval FALSE - Failed
  137. */
  138. /*----------------------------------------------------------------------------*/
  139. BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo)
  140. {
  141. UINT_32 i;
  142. INT_32 u4RemainWapiIeLen;
  143. UINT_16 u2Version;
  144. UINT_16 u2Cap = 0;
  145. UINT_32 u4GroupSuite = WAPI_CIPHER_SUITE_WPI;
  146. UINT_16 u2PairSuiteCount = 0;
  147. UINT_16 u2AuthSuiteCount = 0;
  148. PUCHAR pucPairSuite = NULL;
  149. PUCHAR pucAuthSuite = NULL;
  150. PUCHAR cp;
  151. DEBUGFUNC("wapiParseWapiIE");
  152. ASSERT(prInfoElem);
  153. ASSERT(prWapiInfo);
  154. /* Verify the length of the WAPI IE. */
  155. if (prInfoElem->ucLength < 6) {
  156. DBGLOG(SEC, TRACE, "WAPI IE length too short (length=%d)\n", prInfoElem->ucLength);
  157. return FALSE;
  158. }
  159. /* Check WAPI version: currently, we only support version 1. */
  160. WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version);
  161. if (u2Version != 1) {
  162. DBGLOG(SEC, TRACE, "Unsupported WAPI IE version: %d\n", u2Version);
  163. return FALSE;
  164. }
  165. cp = (PUCHAR) &prInfoElem->u2AuthKeyMgtSuiteCount;
  166. u4RemainWapiIeLen = (INT_32) prInfoElem->ucLength - 2;
  167. do {
  168. if (u4RemainWapiIeLen == 0)
  169. break;
  170. /*
  171. AuthCount : 2
  172. AuthSuite : 4 * authSuiteCount
  173. PairwiseCount: 2
  174. PairwiseSuite: 4 * pairSuiteCount
  175. GroupSuite : 4
  176. Cap : 2 */
  177. /* Parse the Authentication and Key Management Cipher Suite Count
  178. field. */
  179. if (u4RemainWapiIeLen < 2) {
  180. DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite count (IE len: %d)\n",
  181. prInfoElem->ucLength);
  182. return FALSE;
  183. }
  184. WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount);
  185. cp += 2;
  186. u4RemainWapiIeLen -= 2;
  187. /* Parse the Authentication and Key Management Cipher Suite List
  188. field. */
  189. i = (UINT_32) u2AuthSuiteCount * 4;
  190. if (u4RemainWapiIeLen < (INT_32) i) {
  191. DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite list (IE len: %d)\n",
  192. prInfoElem->ucLength);
  193. return FALSE;
  194. }
  195. pucAuthSuite = cp;
  196. cp += i;
  197. u4RemainWapiIeLen -= (INT_32) i;
  198. if (u4RemainWapiIeLen == 0)
  199. break;
  200. /* Parse the Pairwise Key Cipher Suite Count field. */
  201. if (u4RemainWapiIeLen < 2) {
  202. DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite count (IE len: %d)\n",
  203. prInfoElem->ucLength);
  204. return FALSE;
  205. }
  206. WLAN_GET_FIELD_16(cp, &u2PairSuiteCount);
  207. cp += 2;
  208. u4RemainWapiIeLen -= 2;
  209. /* Parse the Pairwise Key Cipher Suite List field. */
  210. i = (UINT_32) u2PairSuiteCount * 4;
  211. if (u4RemainWapiIeLen < (INT_32) i) {
  212. DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite list (IE len: %d)\n",
  213. prInfoElem->ucLength);
  214. return FALSE;
  215. }
  216. pucPairSuite = cp;
  217. cp += i;
  218. u4RemainWapiIeLen -= (INT_32) i;
  219. /* Parse the Group Key Cipher Suite field. */
  220. if (u4RemainWapiIeLen < 4) {
  221. DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in group cipher suite (IE len: %d)\n",
  222. prInfoElem->ucLength);
  223. return FALSE;
  224. }
  225. WLAN_GET_FIELD_32(cp, &u4GroupSuite);
  226. cp += 4;
  227. u4RemainWapiIeLen -= 4;
  228. /* Parse the WAPI u2Capabilities field. */
  229. if (u4RemainWapiIeLen < 2) {
  230. DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in WAPI capabilities (IE len: %d)\n",
  231. prInfoElem->ucLength);
  232. return FALSE;
  233. }
  234. WLAN_GET_FIELD_16(cp, &u2Cap);
  235. u4RemainWapiIeLen -= 2;
  236. /* Todo:: BKID support */
  237. } while (FALSE);
  238. /* Save the WAPI information for the BSS. */
  239. prWapiInfo->ucElemId = ELEM_ID_WAPI;
  240. prWapiInfo->u2Version = u2Version;
  241. prWapiInfo->u4GroupKeyCipherSuite = u4GroupSuite;
  242. DBGLOG(SEC, LOUD, "WAPI: version %d, group key cipher suite %02x-%02x-%02x-%02x\n",
  243. u2Version, (UCHAR) (u4GroupSuite & 0x000000FF),
  244. (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF),
  245. (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF));
  246. if (pucPairSuite) {
  247. /* The information about the pairwise key cipher suites is present. */
  248. if (u2PairSuiteCount > MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES)
  249. u2PairSuiteCount = MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES;
  250. prWapiInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount;
  251. for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) {
  252. WLAN_GET_FIELD_32(pucPairSuite, &prWapiInfo->au4PairwiseKeyCipherSuite[i]);
  253. pucPairSuite += 4;
  254. DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n",
  255. (UINT_8) i, (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF),
  256. (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF),
  257. (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF),
  258. (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF));
  259. }
  260. } else {
  261. /* The information about the pairwise key cipher suites is not present.
  262. Use the default chipher suite for WAPI: WPI. */
  263. prWapiInfo->u4PairwiseKeyCipherSuiteCount = 1;
  264. prWapiInfo->au4PairwiseKeyCipherSuite[0] = WAPI_CIPHER_SUITE_WPI;
  265. DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n",
  266. (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF),
  267. (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF),
  268. (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF),
  269. (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF));
  270. }
  271. if (pucAuthSuite) {
  272. /* The information about the authentication and key management suites
  273. is present. */
  274. if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_WAPI_AKM_SUITES)
  275. u2AuthSuiteCount = MAX_NUM_SUPPORTED_WAPI_AKM_SUITES;
  276. prWapiInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount;
  277. for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) {
  278. WLAN_GET_FIELD_32(pucAuthSuite, &prWapiInfo->au4AuthKeyMgtSuite[i]);
  279. pucAuthSuite += 4;
  280. DBGLOG(SEC, LOUD, "WAPI: AKM suite [%d]: %02x-%02x-%02x-%02x\n",
  281. (UINT_8) i, (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[i] & 0x000000FF),
  282. (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF),
  283. (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF),
  284. (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF));
  285. }
  286. } else {
  287. /* The information about the authentication and key management suites
  288. is not present. Use the default AKM suite for WAPI. */
  289. prWapiInfo->u4AuthKeyMgtSuiteCount = 1;
  290. prWapiInfo->au4AuthKeyMgtSuite[0] = WAPI_AKM_SUITE_802_1X;
  291. DBGLOG(SEC, LOUD, "WAPI: AKM suite: %02x-%02x-%02x-%02x (default)\n",
  292. (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[0] & 0x000000FF),
  293. (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF),
  294. (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF),
  295. (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF));
  296. }
  297. prWapiInfo->u2WapiCap = u2Cap;
  298. DBGLOG(SEC, LOUD, "WAPI: cap: 0x%04x\n", prWapiInfo->u2WapiCap);
  299. return TRUE;
  300. } /* wapiParseWapiIE */
  301. /*----------------------------------------------------------------------------*/
  302. /*!
  303. * \brief This routine is called to perform WAPI policy selection for a given BSS.
  304. *
  305. * \param[in] prAdapter Pointer to the adapter object data area.
  306. * \param[in] prBss Pointer to the BSS description
  307. *
  308. * \retval TRUE - The WAPI policy selection for the given BSS is
  309. * successful. The selected pairwise and group cipher suites
  310. * are returned in the BSS description.
  311. * \retval FALSE - The WAPI policy selection for the given BSS is failed.
  312. * The driver shall not attempt to join the given BSS.
  313. *
  314. * \note The Encrypt status matched score will save to bss for final ap select.
  315. */
  316. /*----------------------------------------------------------------------------*/
  317. BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss)
  318. {
  319. UINT_32 i;
  320. UINT_32 u4PairwiseCipher = 0;
  321. UINT_32 u4GroupCipher = 0;
  322. UINT_32 u4AkmSuite = 0;
  323. P_WAPI_INFO_T prBssWapiInfo;
  324. P_WLAN_INFO_T prWlanInfo;
  325. DEBUGFUNC("wapiPerformPolicySelection");
  326. ASSERT(prBss);
  327. /* Notice!!!! WAPI AP not set the privacy bit for WAI and WAI-PSK at WZC configuration mode */
  328. prWlanInfo = &prAdapter->rWlanInfo;
  329. if (prBss->fgIEWAPI) {
  330. prBssWapiInfo = &prBss->rIEWAPI;
  331. } else {
  332. if (prAdapter->rWifiVar.rConnSettings.fgWapiMode == FALSE) {
  333. DBGLOG(SEC, TRACE, "-- No Protected BSS\n");
  334. return TRUE;
  335. }
  336. DBGLOG(SEC, TRACE, "WAPI Information Element does not exist.\n");
  337. return FALSE;
  338. }
  339. /* Select pairwise/group ciphers */
  340. for (i = 0; i < prBssWapiInfo->u4PairwiseKeyCipherSuiteCount; i++) {
  341. if (prBssWapiInfo->au4PairwiseKeyCipherSuite[i] ==
  342. prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher) {
  343. u4PairwiseCipher = prBssWapiInfo->au4PairwiseKeyCipherSuite[i];
  344. }
  345. }
  346. if (prBssWapiInfo->u4GroupKeyCipherSuite == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher)
  347. u4GroupCipher = prBssWapiInfo->u4GroupKeyCipherSuite;
  348. /* Exception handler */
  349. /* If we cannot find proper pairwise and group cipher suites to join the
  350. BSS, do not check the supported AKM suites. */
  351. if (u4PairwiseCipher == 0 || u4GroupCipher == 0) {
  352. DBGLOG(SEC, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n",
  353. u4PairwiseCipher, u4GroupCipher);
  354. return FALSE;
  355. }
  356. /* Select AKM */
  357. /* If the driver cannot support any authentication suites advertised in
  358. the given BSS, we fail to perform RSNA policy selection. */
  359. /* Attempt to find any overlapping supported AKM suite. */
  360. for (i = 0; i < prBssWapiInfo->u4AuthKeyMgtSuiteCount; i++) {
  361. if (prBssWapiInfo->au4AuthKeyMgtSuite[i] == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite) {
  362. u4AkmSuite = prBssWapiInfo->au4AuthKeyMgtSuite[i];
  363. break;
  364. }
  365. }
  366. if (u4AkmSuite == 0) {
  367. DBGLOG(SEC, TRACE, "Cannot support any AKM suites\n");
  368. return FALSE;
  369. }
  370. DBGLOG(SEC, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n",
  371. (UINT_8) (u4PairwiseCipher & 0x000000FF),
  372. (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF),
  373. (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF),
  374. (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF),
  375. (UINT_8) (u4GroupCipher & 0x000000FF),
  376. (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF),
  377. (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF),
  378. (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF));
  379. DBGLOG(SEC, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n",
  380. (UINT_8) (u4AkmSuite & 0x000000FF),
  381. (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF),
  382. (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF));
  383. return TRUE;
  384. } /* wapiPerformPolicySelection */
  385. #if 0
  386. /*----------------------------------------------------------------------------*/
  387. /*!
  388. * \brief This routine is use for wapi mode, to update the current wpi tx idx ? 0 :1 .
  389. *
  390. * \param[in] prStaRec Pointer to the Sta record
  391. * \param[out] ucWlanIdx The Rx status->wlanidx field
  392. *
  393. * \retval TRUE - Succeeded
  394. * \retval FALSE - Failed
  395. */
  396. /*----------------------------------------------------------------------------*/
  397. BOOLEAN wapiUpdateTxKeyIdx(IN P_STA_RECORD_T prStaRec, IN UINT_8 ucWlanIdx)
  398. {
  399. UINT_8 ucKeyId;
  400. if ((ucWlanIdx & BITS(0, 3)) == CIPHER_SUITE_WPI) {
  401. ucKeyId = ((ucWlanIdx & BITS(4, 5)) >> 4);
  402. if (ucKeyId != g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey) {
  403. DBGLOG(RSN, STATE,
  404. "Change wapi key index from %d->%d\n",
  405. g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey, ucKeyId);
  406. g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey = ucKeyId;
  407. prStaRec->ucWTEntry =
  408. (ucKeyId ==
  409. WTBL_AIS_BSSID_WAPI_IDX_0) ? WTBL_AIS_BSSID_WAPI_IDX_0 : WTBL_AIS_BSSID_WAPI_IDX_1;
  410. }
  411. }
  412. }
  413. #endif
  414. #endif