key.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794
  1. /*
  2. * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. *
  19. *
  20. * File: key.c
  21. *
  22. * Purpose: Implement functions for 802.11i Key management
  23. *
  24. * Author: Jerry Chen
  25. *
  26. * Date: May 29, 2003
  27. *
  28. * Functions:
  29. * KeyvInitTable - Init Key management table
  30. * KeybGetKey - Get Key from table
  31. * KeybSetKey - Set Key to table
  32. * KeybRemoveKey - Remove Key from table
  33. * KeybGetTransmitKey - Get Transmit Key from table
  34. *
  35. * Revision History:
  36. *
  37. */
  38. #include "tmacro.h"
  39. #include "key.h"
  40. #include "mac.h"
  41. /*--------------------- Static Definitions -------------------------*/
  42. /*--------------------- Static Classes ----------------------------*/
  43. /*--------------------- Static Functions --------------------------*/
  44. /*--------------------- Export Variables --------------------------*/
  45. /*--------------------- Static Definitions -------------------------*/
  46. /*--------------------- Static Classes ----------------------------*/
  47. /*--------------------- Static Variables --------------------------*/
  48. /*--------------------- Static Functions --------------------------*/
  49. static void
  50. s_vCheckKeyTableValid(PSKeyManagement pTable, void __iomem *dwIoBase)
  51. {
  52. int i;
  53. for (i = 0; i < MAX_KEY_TABLE; i++) {
  54. if (pTable->KeyTable[i].bInUse &&
  55. !pTable->KeyTable[i].PairwiseKey.bKeyValid &&
  56. !pTable->KeyTable[i].GroupKey[0].bKeyValid &&
  57. !pTable->KeyTable[i].GroupKey[1].bKeyValid &&
  58. !pTable->KeyTable[i].GroupKey[2].bKeyValid &&
  59. !pTable->KeyTable[i].GroupKey[3].bKeyValid) {
  60. pTable->KeyTable[i].bInUse = false;
  61. pTable->KeyTable[i].wKeyCtl = 0;
  62. pTable->KeyTable[i].bSoftWEP = false;
  63. MACvDisableKeyEntry(dwIoBase, i);
  64. }
  65. }
  66. }
  67. /*--------------------- Export Functions --------------------------*/
  68. /*
  69. * Description: Init Key management table
  70. *
  71. * Parameters:
  72. * In:
  73. * pTable - Pointer to Key table
  74. * Out:
  75. * none
  76. *
  77. * Return Value: none
  78. *
  79. */
  80. void KeyvInitTable(PSKeyManagement pTable, void __iomem *dwIoBase)
  81. {
  82. int i;
  83. int jj;
  84. for (i = 0; i < MAX_KEY_TABLE; i++) {
  85. pTable->KeyTable[i].bInUse = false;
  86. pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
  87. pTable->KeyTable[i].PairwiseKey.pvKeyTable = (void *)&pTable->KeyTable[i];
  88. for (jj = 0; jj < MAX_GROUP_KEY; jj++) {
  89. pTable->KeyTable[i].GroupKey[jj].bKeyValid = false;
  90. pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (void *)&pTable->KeyTable[i];
  91. }
  92. pTable->KeyTable[i].wKeyCtl = 0;
  93. pTable->KeyTable[i].dwGTKeyIndex = 0;
  94. pTable->KeyTable[i].bSoftWEP = false;
  95. MACvDisableKeyEntry(dwIoBase, i);
  96. }
  97. }
  98. /*
  99. * Description: Get Key from table
  100. *
  101. * Parameters:
  102. * In:
  103. * pTable - Pointer to Key table
  104. * pbyBSSID - BSSID of Key
  105. * dwKeyIndex - Key Index (0xFFFFFFFF means pairwise key)
  106. * Out:
  107. * pKey - Key return
  108. *
  109. * Return Value: true if found otherwise false
  110. *
  111. */
  112. bool KeybGetKey(
  113. PSKeyManagement pTable,
  114. unsigned char *pbyBSSID,
  115. unsigned long dwKeyIndex,
  116. PSKeyItem *pKey
  117. )
  118. {
  119. int i;
  120. pr_debug("KeybGetKey()\n");
  121. *pKey = NULL;
  122. for (i = 0; i < MAX_KEY_TABLE; i++) {
  123. if (pTable->KeyTable[i].bInUse &&
  124. ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
  125. if (dwKeyIndex == 0xFFFFFFFF) {
  126. if (pTable->KeyTable[i].PairwiseKey.bKeyValid) {
  127. *pKey = &(pTable->KeyTable[i].PairwiseKey);
  128. return true;
  129. } else {
  130. return false;
  131. }
  132. } else if (dwKeyIndex < MAX_GROUP_KEY) {
  133. if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid) {
  134. *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]);
  135. return true;
  136. } else {
  137. return false;
  138. }
  139. } else {
  140. return false;
  141. }
  142. }
  143. }
  144. return false;
  145. }
  146. /*
  147. * Description: Set Key to table
  148. *
  149. * Parameters:
  150. * In:
  151. * pTable - Pointer to Key table
  152. * pbyBSSID - BSSID of Key
  153. * dwKeyIndex - Key index (reference to NDIS DDK)
  154. * uKeyLength - Key length
  155. * KeyRSC - Key RSC
  156. * pbyKey - Pointer to key
  157. * Out:
  158. * none
  159. *
  160. * Return Value: true if success otherwise false
  161. *
  162. */
  163. bool KeybSetKey(
  164. PSKeyManagement pTable,
  165. unsigned char *pbyBSSID,
  166. unsigned long dwKeyIndex,
  167. unsigned long uKeyLength,
  168. u64 *pKeyRSC,
  169. unsigned char *pbyKey,
  170. unsigned char byKeyDecMode,
  171. void __iomem *dwIoBase,
  172. unsigned char byLocalID
  173. )
  174. {
  175. int i, j;
  176. unsigned int ii;
  177. PSKeyItem pKey;
  178. unsigned int uKeyIdx;
  179. pr_debug("Enter KeybSetKey: %lX\n", dwKeyIndex);
  180. j = (MAX_KEY_TABLE-1);
  181. for (i = 0; i < (MAX_KEY_TABLE - 1); i++) {
  182. if (!pTable->KeyTable[i].bInUse && (j == (MAX_KEY_TABLE-1))) {
  183. // found empty table
  184. j = i;
  185. }
  186. if (pTable->KeyTable[i].bInUse &&
  187. ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
  188. // found table already exist
  189. if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
  190. // Pairwise key
  191. pKey = &(pTable->KeyTable[i].PairwiseKey);
  192. pTable->KeyTable[i].wKeyCtl &= 0xFFF0; // clear pairwise key control filed
  193. pTable->KeyTable[i].wKeyCtl |= byKeyDecMode;
  194. uKeyIdx = 4; // use HW key entry 4 for pairwise key
  195. } else {
  196. // Group key
  197. if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
  198. return false;
  199. pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
  200. if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
  201. // Group transmit key
  202. pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
  203. pr_debug("Group transmit key(R)[%lX]: %d\n",
  204. pTable->KeyTable[i].dwGTKeyIndex, i);
  205. }
  206. pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed
  207. pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
  208. pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address
  209. uKeyIdx = (dwKeyIndex & 0x000000FF);
  210. }
  211. pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly
  212. pKey->bKeyValid = true;
  213. pKey->uKeyLength = uKeyLength;
  214. pKey->dwKeyIndex = dwKeyIndex;
  215. pKey->byCipherSuite = byKeyDecMode;
  216. memcpy(pKey->abyKey, pbyKey, uKeyLength);
  217. if (byKeyDecMode == KEY_CTL_WEP) {
  218. if (uKeyLength == WLAN_WEP40_KEYLEN)
  219. pKey->abyKey[15] &= 0x7F;
  220. if (uKeyLength == WLAN_WEP104_KEYLEN)
  221. pKey->abyKey[15] |= 0x80;
  222. }
  223. MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (u32 *)pKey->abyKey, byLocalID);
  224. if ((dwKeyIndex & USE_KEYRSC) == 0) {
  225. // RSC set by NIC
  226. pKey->KeyRSC = 0;
  227. } else {
  228. pKey->KeyRSC = *pKeyRSC;
  229. }
  230. pKey->dwTSC47_16 = 0;
  231. pKey->wTSC15_0 = 0;
  232. pr_debug("KeybSetKey(R):\n");
  233. pr_debug("pKey->bKeyValid: %d\n ", pKey->bKeyValid);
  234. pr_debug("pKey->abyKey: ");
  235. for (ii = 0; ii < pKey->uKeyLength; ii++)
  236. pr_debug("%02x ", pKey->abyKey[ii]);
  237. pr_debug("\n");
  238. pr_debug("pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
  239. pr_debug("pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
  240. pr_debug("pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
  241. return true;
  242. }
  243. }
  244. if (j < (MAX_KEY_TABLE-1)) {
  245. memcpy(pTable->KeyTable[j].abyBSSID, pbyBSSID, ETH_ALEN);
  246. pTable->KeyTable[j].bInUse = true;
  247. if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
  248. // Pairwise key
  249. pKey = &(pTable->KeyTable[j].PairwiseKey);
  250. pTable->KeyTable[j].wKeyCtl &= 0xFFF0; // clear pairwise key control filed
  251. pTable->KeyTable[j].wKeyCtl |= byKeyDecMode;
  252. uKeyIdx = 4; // use HW key entry 4 for pairwise key
  253. } else {
  254. // Group key
  255. if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
  256. return false;
  257. pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]);
  258. if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
  259. // Group transmit key
  260. pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex;
  261. pr_debug("Group transmit key(N)[%lX]: %d\n",
  262. pTable->KeyTable[j].dwGTKeyIndex, j);
  263. }
  264. pTable->KeyTable[j].wKeyCtl &= 0xFF0F; // clear group key control filed
  265. pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4);
  266. pTable->KeyTable[j].wKeyCtl |= 0x0040; // use group key for group address
  267. uKeyIdx = (dwKeyIndex & 0x000000FF);
  268. }
  269. pTable->KeyTable[j].wKeyCtl |= 0x8000; // enable on-fly
  270. pKey->bKeyValid = true;
  271. pKey->uKeyLength = uKeyLength;
  272. pKey->dwKeyIndex = dwKeyIndex;
  273. pKey->byCipherSuite = byKeyDecMode;
  274. memcpy(pKey->abyKey, pbyKey, uKeyLength);
  275. if (byKeyDecMode == KEY_CTL_WEP) {
  276. if (uKeyLength == WLAN_WEP40_KEYLEN)
  277. pKey->abyKey[15] &= 0x7F;
  278. if (uKeyLength == WLAN_WEP104_KEYLEN)
  279. pKey->abyKey[15] |= 0x80;
  280. }
  281. MACvSetKeyEntry(dwIoBase, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (u32 *)pKey->abyKey, byLocalID);
  282. if ((dwKeyIndex & USE_KEYRSC) == 0) {
  283. // RSC set by NIC
  284. pKey->KeyRSC = 0;
  285. } else {
  286. pKey->KeyRSC = *pKeyRSC;
  287. }
  288. pKey->dwTSC47_16 = 0;
  289. pKey->wTSC15_0 = 0;
  290. pr_debug("KeybSetKey(N):\n");
  291. pr_debug("pKey->bKeyValid: %d\n ", pKey->bKeyValid);
  292. pr_debug("pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
  293. pr_debug("pKey->abyKey: ");
  294. for (ii = 0; ii < pKey->uKeyLength; ii++)
  295. pr_debug("%02x ", pKey->abyKey[ii]);
  296. pr_debug("\n");
  297. pr_debug("pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
  298. pr_debug("pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
  299. pr_debug("pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
  300. return true;
  301. }
  302. return false;
  303. }
  304. /*
  305. * Description: Remove Key from table
  306. *
  307. * Parameters:
  308. * In:
  309. * pTable - Pointer to Key table
  310. * pbyBSSID - BSSID of Key
  311. * dwKeyIndex - Key Index (reference to NDIS DDK)
  312. * Out:
  313. * none
  314. *
  315. * Return Value: true if success otherwise false
  316. *
  317. */
  318. bool KeybRemoveKey(
  319. PSKeyManagement pTable,
  320. unsigned char *pbyBSSID,
  321. unsigned long dwKeyIndex,
  322. void __iomem *dwIoBase
  323. )
  324. {
  325. int i;
  326. if (is_broadcast_ether_addr(pbyBSSID)) {
  327. // delete all keys
  328. if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
  329. for (i = 0; i < MAX_KEY_TABLE; i++)
  330. pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
  331. s_vCheckKeyTableValid(pTable, dwIoBase);
  332. return true;
  333. } else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
  334. for (i = 0; i < MAX_KEY_TABLE; i++) {
  335. pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
  336. if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
  337. // remove Group transmit key
  338. pTable->KeyTable[i].dwGTKeyIndex = 0;
  339. }
  340. }
  341. s_vCheckKeyTableValid(pTable, dwIoBase);
  342. return true;
  343. } else {
  344. return false;
  345. }
  346. }
  347. for (i = 0; i < MAX_KEY_TABLE; i++) {
  348. if (pTable->KeyTable[i].bInUse &&
  349. ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
  350. if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
  351. pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
  352. s_vCheckKeyTableValid(pTable, dwIoBase);
  353. return true;
  354. } else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
  355. pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
  356. if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
  357. // remove Group transmit key
  358. pTable->KeyTable[i].dwGTKeyIndex = 0;
  359. }
  360. s_vCheckKeyTableValid(pTable, dwIoBase);
  361. return true;
  362. } else {
  363. return false;
  364. }
  365. }
  366. }
  367. return false;
  368. }
  369. /*
  370. * Description: Remove Key from table
  371. *
  372. * Parameters:
  373. * In:
  374. * pTable - Pointer to Key table
  375. * pbyBSSID - BSSID of Key
  376. * Out:
  377. * none
  378. *
  379. * Return Value: true if success otherwise false
  380. *
  381. */
  382. bool KeybRemoveAllKey(
  383. PSKeyManagement pTable,
  384. unsigned char *pbyBSSID,
  385. void __iomem *dwIoBase
  386. )
  387. {
  388. int i, u;
  389. for (i = 0; i < MAX_KEY_TABLE; i++) {
  390. if (pTable->KeyTable[i].bInUse &&
  391. ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
  392. pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
  393. for (u = 0; u < MAX_GROUP_KEY; u++)
  394. pTable->KeyTable[i].GroupKey[u].bKeyValid = false;
  395. pTable->KeyTable[i].dwGTKeyIndex = 0;
  396. s_vCheckKeyTableValid(pTable, dwIoBase);
  397. return true;
  398. }
  399. }
  400. return false;
  401. }
  402. /*
  403. * Description: Remove WEP Key from table
  404. *
  405. * Parameters:
  406. * In:
  407. * pTable - Pointer to Key table
  408. * Out:
  409. * none
  410. *
  411. * Return Value: true if success otherwise false
  412. *
  413. */
  414. void KeyvRemoveWEPKey(
  415. PSKeyManagement pTable,
  416. unsigned long dwKeyIndex,
  417. void __iomem *dwIoBase
  418. )
  419. {
  420. if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
  421. if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse) {
  422. if (pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].byCipherSuite == KEY_CTL_WEP) {
  423. pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
  424. if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex & 0x7FFFFFFF)) {
  425. // remove Group transmit key
  426. pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = 0;
  427. }
  428. }
  429. }
  430. s_vCheckKeyTableValid(pTable, dwIoBase);
  431. }
  432. }
  433. void KeyvRemoveAllWEPKey(
  434. PSKeyManagement pTable,
  435. void __iomem *dwIoBase
  436. )
  437. {
  438. int i;
  439. for (i = 0; i < MAX_GROUP_KEY; i++)
  440. KeyvRemoveWEPKey(pTable, i, dwIoBase);
  441. }
  442. /*
  443. * Description: Get Transmit Key from table
  444. *
  445. * Parameters:
  446. * In:
  447. * pTable - Pointer to Key table
  448. * pbyBSSID - BSSID of Key
  449. * Out:
  450. * pKey - Key return
  451. *
  452. * Return Value: true if found otherwise false
  453. *
  454. */
  455. bool KeybGetTransmitKey(
  456. PSKeyManagement pTable,
  457. unsigned char *pbyBSSID,
  458. unsigned long dwKeyType,
  459. PSKeyItem *pKey
  460. )
  461. {
  462. int i, ii;
  463. *pKey = NULL;
  464. for (i = 0; i < MAX_KEY_TABLE; i++) {
  465. if (pTable->KeyTable[i].bInUse &&
  466. ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
  467. if (dwKeyType == PAIRWISE_KEY) {
  468. if (pTable->KeyTable[i].PairwiseKey.bKeyValid) {
  469. *pKey = &(pTable->KeyTable[i].PairwiseKey);
  470. pr_debug("KeybGetTransmitKey:");
  471. pr_debug("PAIRWISE_KEY: KeyTable.abyBSSID: ");
  472. for (ii = 0; ii < 6; ii++)
  473. pr_debug("%x ",
  474. pTable->KeyTable[i].abyBSSID[ii]);
  475. pr_debug("\n");
  476. return true;
  477. } else {
  478. pr_debug("PairwiseKey.bKeyValid == false\n");
  479. return false;
  480. }
  481. } // End of Type == PAIRWISE
  482. else {
  483. if (pTable->KeyTable[i].dwGTKeyIndex == 0) {
  484. pr_debug("ERROR: dwGTKeyIndex == 0 !!!\n");
  485. return false;
  486. }
  487. if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid) {
  488. *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]);
  489. pr_debug("KeybGetTransmitKey:");
  490. pr_debug("GROUP_KEY: KeyTable.abyBSSID\n");
  491. for (ii = 0; ii < 6; ii++)
  492. pr_debug("%x ",
  493. pTable->KeyTable[i].abyBSSID[ii]);
  494. pr_debug("\n");
  495. pr_debug("dwGTKeyIndex: %lX\n",
  496. pTable->KeyTable[i].dwGTKeyIndex);
  497. return true;
  498. } else {
  499. pr_debug("GroupKey.bKeyValid == false\n");
  500. return false;
  501. }
  502. } // End of Type = GROUP
  503. } // BSSID match
  504. }
  505. pr_debug("ERROR: NO Match BSSID !!! ");
  506. for (ii = 0; ii < 6; ii++)
  507. pr_debug("%02x ", *(pbyBSSID+ii));
  508. pr_debug("\n");
  509. return false;
  510. }
  511. /*
  512. * Description: Check Pairewise Key
  513. *
  514. * Parameters:
  515. * In:
  516. * pTable - Pointer to Key table
  517. * Out:
  518. * none
  519. *
  520. * Return Value: true if found otherwise false
  521. *
  522. */
  523. bool KeybCheckPairewiseKey(
  524. PSKeyManagement pTable,
  525. PSKeyItem *pKey
  526. )
  527. {
  528. int i;
  529. *pKey = NULL;
  530. for (i = 0; i < MAX_KEY_TABLE; i++) {
  531. if (pTable->KeyTable[i].bInUse &&
  532. pTable->KeyTable[i].PairwiseKey.bKeyValid) {
  533. *pKey = &(pTable->KeyTable[i].PairwiseKey);
  534. return true;
  535. }
  536. }
  537. return false;
  538. }
  539. /*
  540. * Description: Set Key to table
  541. *
  542. * Parameters:
  543. * In:
  544. * pTable - Pointer to Key table
  545. * dwKeyIndex - Key index (reference to NDIS DDK)
  546. * uKeyLength - Key length
  547. * KeyRSC - Key RSC
  548. * pbyKey - Pointer to key
  549. * Out:
  550. * none
  551. *
  552. * Return Value: true if success otherwise false
  553. *
  554. */
  555. bool KeybSetDefaultKey(
  556. PSKeyManagement pTable,
  557. unsigned long dwKeyIndex,
  558. unsigned long uKeyLength,
  559. u64 *pKeyRSC,
  560. unsigned char *pbyKey,
  561. unsigned char byKeyDecMode,
  562. void __iomem *dwIoBase,
  563. unsigned char byLocalID
  564. )
  565. {
  566. unsigned int ii;
  567. PSKeyItem pKey;
  568. unsigned int uKeyIdx;
  569. pr_debug("Enter KeybSetDefaultKey: %1x, %d\n",
  570. (int)dwKeyIndex, (int)uKeyLength);
  571. if ((dwKeyIndex & PAIRWISE_KEY) != 0) // Pairwise key
  572. return false;
  573. else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
  574. return false;
  575. if (uKeyLength > MAX_KEY_LEN)
  576. return false;
  577. pTable->KeyTable[MAX_KEY_TABLE - 1].bInUse = true;
  578. for (ii = 0; ii < ETH_ALEN; ii++)
  579. pTable->KeyTable[MAX_KEY_TABLE - 1].abyBSSID[ii] = 0xFF;
  580. // Group key
  581. pKey = &(pTable->KeyTable[MAX_KEY_TABLE - 1].GroupKey[dwKeyIndex & 0x000000FF]);
  582. if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
  583. // Group transmit key
  584. pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex;
  585. pr_debug("Group transmit key(R)[%lX]: %d\n",
  586. pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex,
  587. MAX_KEY_TABLE-1);
  588. }
  589. pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00; // clear all key control filed
  590. pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode << 4);
  591. pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode);
  592. pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x0044; // use group key for all address
  593. uKeyIdx = (dwKeyIndex & 0x000000FF);
  594. if ((uKeyLength == WLAN_WEP232_KEYLEN) &&
  595. (byKeyDecMode == KEY_CTL_WEP)) {
  596. pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000; // disable on-fly disable address match
  597. pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = true;
  598. } else {
  599. if (!pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP)
  600. pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000; // enable on-fly disable address match
  601. }
  602. pKey->bKeyValid = true;
  603. pKey->uKeyLength = uKeyLength;
  604. pKey->dwKeyIndex = dwKeyIndex;
  605. pKey->byCipherSuite = byKeyDecMode;
  606. memcpy(pKey->abyKey, pbyKey, uKeyLength);
  607. if (byKeyDecMode == KEY_CTL_WEP) {
  608. if (uKeyLength == WLAN_WEP40_KEYLEN)
  609. pKey->abyKey[15] &= 0x7F;
  610. if (uKeyLength == WLAN_WEP104_KEYLEN)
  611. pKey->abyKey[15] |= 0x80;
  612. }
  613. MACvSetKeyEntry(dwIoBase, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (u32 *)pKey->abyKey, byLocalID);
  614. if ((dwKeyIndex & USE_KEYRSC) == 0) {
  615. // RSC set by NIC
  616. pKey->KeyRSC = 0;
  617. } else {
  618. pKey->KeyRSC = *pKeyRSC;
  619. }
  620. pKey->dwTSC47_16 = 0;
  621. pKey->wTSC15_0 = 0;
  622. pr_debug("KeybSetKey(R):\n");
  623. pr_debug("pKey->bKeyValid: %d\n", pKey->bKeyValid);
  624. pr_debug("pKey->uKeyLength: %d\n", (int)pKey->uKeyLength);
  625. pr_debug("pKey->abyKey:\n");
  626. for (ii = 0; ii < pKey->uKeyLength; ii++)
  627. pr_debug("%x", pKey->abyKey[ii]);
  628. pr_debug("\n");
  629. pr_debug("pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16);
  630. pr_debug("pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
  631. pr_debug("pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex);
  632. return true;
  633. }
  634. /*
  635. * Description: Set Key to table
  636. *
  637. * Parameters:
  638. * In:
  639. * pTable - Pointer to Key table
  640. * dwKeyIndex - Key index (reference to NDIS DDK)
  641. * uKeyLength - Key length
  642. * KeyRSC - Key RSC
  643. * pbyKey - Pointer to key
  644. * Out:
  645. * none
  646. *
  647. * Return Value: true if success otherwise false
  648. *
  649. */
  650. bool KeybSetAllGroupKey(
  651. PSKeyManagement pTable,
  652. unsigned long dwKeyIndex,
  653. unsigned long uKeyLength,
  654. u64 *pKeyRSC,
  655. unsigned char *pbyKey,
  656. unsigned char byKeyDecMode,
  657. void __iomem *dwIoBase,
  658. unsigned char byLocalID
  659. )
  660. {
  661. int i;
  662. unsigned int ii;
  663. PSKeyItem pKey;
  664. unsigned int uKeyIdx;
  665. pr_debug("Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex);
  666. if ((dwKeyIndex & PAIRWISE_KEY) != 0) // Pairwise key
  667. return false;
  668. else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
  669. return false;
  670. for (i = 0; i < MAX_KEY_TABLE - 1; i++) {
  671. if (pTable->KeyTable[i].bInUse) {
  672. // found table already exist
  673. // Group key
  674. pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
  675. if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
  676. // Group transmit key
  677. pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
  678. pr_debug("Group transmit key(R)[%lX]: %d\n",
  679. pTable->KeyTable[i].dwGTKeyIndex, i);
  680. }
  681. pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed
  682. pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
  683. pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address
  684. uKeyIdx = (dwKeyIndex & 0x000000FF);
  685. pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly
  686. pKey->bKeyValid = true;
  687. pKey->uKeyLength = uKeyLength;
  688. pKey->dwKeyIndex = dwKeyIndex;
  689. pKey->byCipherSuite = byKeyDecMode;
  690. memcpy(pKey->abyKey, pbyKey, uKeyLength);
  691. if (byKeyDecMode == KEY_CTL_WEP) {
  692. if (uKeyLength == WLAN_WEP40_KEYLEN)
  693. pKey->abyKey[15] &= 0x7F;
  694. if (uKeyLength == WLAN_WEP104_KEYLEN)
  695. pKey->abyKey[15] |= 0x80;
  696. }
  697. MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (u32 *)pKey->abyKey, byLocalID);
  698. if ((dwKeyIndex & USE_KEYRSC) == 0) {
  699. // RSC set by NIC
  700. pKey->KeyRSC = 0;
  701. } else {
  702. pKey->KeyRSC = *pKeyRSC;
  703. }
  704. pKey->dwTSC47_16 = 0;
  705. pKey->wTSC15_0 = 0;
  706. pr_debug("KeybSetKey(R):\n");
  707. pr_debug("pKey->bKeyValid: %d\n ", pKey->bKeyValid);
  708. pr_debug("pKey->uKeyLength: %d\n ",
  709. (int)pKey->uKeyLength);
  710. pr_debug("pKey->abyKey: ");
  711. for (ii = 0; ii < pKey->uKeyLength; ii++)
  712. pr_debug("%02x ", pKey->abyKey[ii]);
  713. pr_debug("\n");
  714. } // (pTable->KeyTable[i].bInUse == true)
  715. }
  716. return true;
  717. }