Linux-libre 3.10.48-gnu
[librecmc/linux-libre.git] / drivers / staging / vt6655 / key.c
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
39 #include "tmacro.h"
40 #include "key.h"
41 #include "mac.h"
42
43 /*---------------------  Static Definitions -------------------------*/
44
45 /*---------------------  Static Classes  ----------------------------*/
46
47 /*---------------------  Static Variables  --------------------------*/
48 static int msglevel = MSG_LEVEL_INFO;
49 //static int          msglevel                =MSG_LEVEL_DEBUG;
50 /*---------------------  Static Functions  --------------------------*/
51
52 /*---------------------  Export Variables  --------------------------*/
53
54 /*---------------------  Static Definitions -------------------------*/
55
56 /*---------------------  Static Classes  ----------------------------*/
57
58 /*---------------------  Static Variables  --------------------------*/
59
60 /*---------------------  Static Functions  --------------------------*/
61 static void
62 s_vCheckKeyTableValid(PSKeyManagement pTable, unsigned long dwIoBase)
63 {
64         int i;
65
66         for (i = 0; i < MAX_KEY_TABLE; i++) {
67                 if ((pTable->KeyTable[i].bInUse == true) &&
68                     (pTable->KeyTable[i].PairwiseKey.bKeyValid == false) &&
69                     (pTable->KeyTable[i].GroupKey[0].bKeyValid == false) &&
70                     (pTable->KeyTable[i].GroupKey[1].bKeyValid == false) &&
71                     (pTable->KeyTable[i].GroupKey[2].bKeyValid == false) &&
72                     (pTable->KeyTable[i].GroupKey[3].bKeyValid == false)
73 ) {
74                         pTable->KeyTable[i].bInUse = false;
75                         pTable->KeyTable[i].wKeyCtl = 0;
76                         pTable->KeyTable[i].bSoftWEP = false;
77                         MACvDisableKeyEntry(dwIoBase, i);
78                 }
79         }
80 }
81
82 /*---------------------  Export Functions  --------------------------*/
83
84 /*
85  * Description: Init Key management table
86  *
87  * Parameters:
88  *  In:
89  *      pTable          - Pointer to Key table
90  *  Out:
91  *      none
92  *
93  * Return Value: none
94  *
95  */
96 void KeyvInitTable(PSKeyManagement pTable, unsigned long dwIoBase)
97 {
98         int i;
99         int jj;
100
101         for (i = 0; i < MAX_KEY_TABLE; i++) {
102                 pTable->KeyTable[i].bInUse = false;
103                 pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
104                 pTable->KeyTable[i].PairwiseKey.pvKeyTable = (void *)&pTable->KeyTable[i];
105                 for (jj = 0; jj < MAX_GROUP_KEY; jj++) {
106                         pTable->KeyTable[i].GroupKey[jj].bKeyValid = false;
107                         pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (void *)&pTable->KeyTable[i];
108                 }
109                 pTable->KeyTable[i].wKeyCtl = 0;
110                 pTable->KeyTable[i].dwGTKeyIndex = 0;
111                 pTable->KeyTable[i].bSoftWEP = false;
112                 MACvDisableKeyEntry(dwIoBase, i);
113         }
114 }
115
116 /*
117  * Description: Get Key from table
118  *
119  * Parameters:
120  *  In:
121  *      pTable          - Pointer to Key table
122  *      pbyBSSID        - BSSID of Key
123  *      dwKeyIndex      - Key Index (0xFFFFFFFF means pairwise key)
124  *  Out:
125  *      pKey            - Key return
126  *
127  * Return Value: true if found otherwise false
128  *
129  */
130 bool KeybGetKey(
131         PSKeyManagement pTable,
132         unsigned char *pbyBSSID,
133         unsigned long dwKeyIndex,
134         PSKeyItem       *pKey
135 )
136 {
137         int i;
138
139         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetKey() \n");
140
141         *pKey = NULL;
142         for (i = 0; i < MAX_KEY_TABLE; i++) {
143                 if ((pTable->KeyTable[i].bInUse == true) &&
144                     !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
145                         if (dwKeyIndex == 0xFFFFFFFF) {
146                                 if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
147                                         *pKey = &(pTable->KeyTable[i].PairwiseKey);
148                                         return true;
149                                 } else {
150                                         return false;
151                                 }
152                         } else if (dwKeyIndex < MAX_GROUP_KEY) {
153                                 if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid == true) {
154                                         *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]);
155                                         return true;
156                                 } else {
157                                         return false;
158                                 }
159                         } else {
160                                 return false;
161                         }
162                 }
163         }
164         return false;
165 }
166
167 /*
168  * Description: Set Key to table
169  *
170  * Parameters:
171  *  In:
172  *      pTable          - Pointer to Key table
173  *      pbyBSSID        - BSSID of Key
174  *      dwKeyIndex      - Key index (reference to NDIS DDK)
175  *      uKeyLength      - Key length
176  *      KeyRSC          - Key RSC
177  *      pbyKey          - Pointer to key
178  *  Out:
179  *      none
180  *
181  * Return Value: true if success otherwise false
182  *
183  */
184 bool KeybSetKey(
185         PSKeyManagement pTable,
186         unsigned char *pbyBSSID,
187         unsigned long dwKeyIndex,
188         unsigned long uKeyLength,
189         PQWORD          pKeyRSC,
190         unsigned char *pbyKey,
191         unsigned char byKeyDecMode,
192         unsigned long dwIoBase,
193         unsigned char byLocalID
194 )
195 {
196         int i, j;
197         unsigned int ii;
198         PSKeyItem   pKey;
199         unsigned int uKeyIdx;
200
201         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetKey: %lX\n", dwKeyIndex);
202
203         j = (MAX_KEY_TABLE-1);
204         for (i = 0; i < (MAX_KEY_TABLE - 1); i++) {
205                 if ((pTable->KeyTable[i].bInUse == false) &&
206                     (j == (MAX_KEY_TABLE-1))) {
207                         // found empty table
208                         j = i;
209                 }
210                 if ((pTable->KeyTable[i].bInUse == true) &&
211                     !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
212                         // found table already exist
213                         if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
214                                 // Pairwise key
215                                 pKey = &(pTable->KeyTable[i].PairwiseKey);
216                                 pTable->KeyTable[i].wKeyCtl &= 0xFFF0;          // clear pairwise key control filed
217                                 pTable->KeyTable[i].wKeyCtl |= byKeyDecMode;
218                                 uKeyIdx = 4;                                    // use HW key entry 4 for pairwise key
219                         } else {
220                                 // Group key
221                                 if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
222                                         return false;
223                                 pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
224                                 if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
225                                         // Group transmit key
226                                         pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
227                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
228                                 }
229                                 pTable->KeyTable[i].wKeyCtl &= 0xFF0F;          // clear group key control filed
230                                 pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
231                                 pTable->KeyTable[i].wKeyCtl |= 0x0040;          // use group key for group address
232                                 uKeyIdx = (dwKeyIndex & 0x000000FF);
233                         }
234                         pTable->KeyTable[i].wKeyCtl |= 0x8000;              // enable on-fly
235
236                         pKey->bKeyValid = true;
237                         pKey->uKeyLength = uKeyLength;
238                         pKey->dwKeyIndex = dwKeyIndex;
239                         pKey->byCipherSuite = byKeyDecMode;
240                         memcpy(pKey->abyKey, pbyKey, uKeyLength);
241                         if (byKeyDecMode == KEY_CTL_WEP) {
242                                 if (uKeyLength == WLAN_WEP40_KEYLEN)
243                                         pKey->abyKey[15] &= 0x7F;
244                                 if (uKeyLength == WLAN_WEP104_KEYLEN)
245                                         pKey->abyKey[15] |= 0x80;
246                         }
247                         MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (unsigned long *)pKey->abyKey, byLocalID);
248
249                         if ((dwKeyIndex & USE_KEYRSC) == 0) {
250                                 // RSC set by NIC
251                                 memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
252                         } else {
253                                 memcpy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
254                         }
255                         pKey->dwTSC47_16 = 0;
256                         pKey->wTSC15_0 = 0;
257
258                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R): \n");
259                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n ", pKey->bKeyValid);
260                         //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n ", pKey->uKeyLength);
261                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: ");
262                         for (ii = 0; ii < pKey->uKeyLength; ii++) {
263                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
264                         }
265                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n");
266
267                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
268                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
269                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
270
271                         return true;
272                 }
273         }
274         if (j < (MAX_KEY_TABLE-1)) {
275                 memcpy(pTable->KeyTable[j].abyBSSID, pbyBSSID, ETH_ALEN);
276                 pTable->KeyTable[j].bInUse = true;
277                 if ((dwKeyIndex & PAIRWISE_KEY) != 0)  {
278                         // Pairwise key
279                         pKey = &(pTable->KeyTable[j].PairwiseKey);
280                         pTable->KeyTable[j].wKeyCtl &= 0xFFF0;          // clear pairwise key control filed
281                         pTable->KeyTable[j].wKeyCtl |= byKeyDecMode;
282                         uKeyIdx = 4;                                    // use HW key entry 4 for pairwise key
283                 } else {
284                         // Group key
285                         if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
286                                 return false;
287                         pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]);
288                         if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
289                                 // Group transmit key
290                                 pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex;
291                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j);
292                         }
293                         pTable->KeyTable[j].wKeyCtl &= 0xFF0F;          // clear group key control filed
294                         pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4);
295                         pTable->KeyTable[j].wKeyCtl |= 0x0040;          // use group key for group address
296                         uKeyIdx = (dwKeyIndex & 0x000000FF);
297                 }
298                 pTable->KeyTable[j].wKeyCtl |= 0x8000;              // enable on-fly
299
300                 pKey->bKeyValid = true;
301                 pKey->uKeyLength = uKeyLength;
302                 pKey->dwKeyIndex = dwKeyIndex;
303                 pKey->byCipherSuite = byKeyDecMode;
304                 memcpy(pKey->abyKey, pbyKey, uKeyLength);
305                 if (byKeyDecMode == KEY_CTL_WEP) {
306                         if (uKeyLength == WLAN_WEP40_KEYLEN)
307                                 pKey->abyKey[15] &= 0x7F;
308                         if (uKeyLength == WLAN_WEP104_KEYLEN)
309                                 pKey->abyKey[15] |= 0x80;
310                 }
311                 MACvSetKeyEntry(dwIoBase, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (unsigned long *)pKey->abyKey, byLocalID);
312
313                 if ((dwKeyIndex & USE_KEYRSC) == 0) {
314                         // RSC set by NIC
315                         memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
316                 } else {
317                         memcpy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
318                 }
319                 pKey->dwTSC47_16 = 0;
320                 pKey->wTSC15_0 = 0;
321
322                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(N): \n");
323                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n ", pKey->bKeyValid);
324                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
325                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: ");
326                 for (ii = 0; ii < pKey->uKeyLength; ii++) {
327                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
328                 }
329                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n");
330
331                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
332                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
333                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
334
335                 return true;
336         }
337         return false;
338 }
339
340 /*
341  * Description: Remove Key from table
342  *
343  * Parameters:
344  *  In:
345  *      pTable          - Pointer to Key table
346  *      pbyBSSID        - BSSID of Key
347  *      dwKeyIndex      - Key Index (reference to NDIS DDK)
348  *  Out:
349  *      none
350  *
351  * Return Value: true if success otherwise false
352  *
353  */
354 bool KeybRemoveKey(
355         PSKeyManagement pTable,
356         unsigned char *pbyBSSID,
357         unsigned long dwKeyIndex,
358         unsigned long dwIoBase
359 )
360 {
361         int  i;
362
363         if (is_broadcast_ether_addr(pbyBSSID)) {
364                 // delete all keys
365                 if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
366                         for (i = 0; i < MAX_KEY_TABLE; i++) {
367                                 pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
368                         }
369                         s_vCheckKeyTableValid(pTable, dwIoBase);
370                         return true;
371                 } else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
372                         for (i = 0; i < MAX_KEY_TABLE; i++) {
373                                 pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
374                                 if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
375                                         // remove Group transmit key
376                                         pTable->KeyTable[i].dwGTKeyIndex = 0;
377                                 }
378                         }
379                         s_vCheckKeyTableValid(pTable, dwIoBase);
380                         return true;
381                 } else {
382                         return false;
383                 }
384         }
385
386         for (i = 0; i < MAX_KEY_TABLE; i++) {
387                 if ((pTable->KeyTable[i].bInUse == true) &&
388                     !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
389                         if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
390                                 pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
391                                 s_vCheckKeyTableValid(pTable, dwIoBase);
392                                 return true;
393                         } else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
394                                 pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
395                                 if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
396                                         // remove Group transmit key
397                                         pTable->KeyTable[i].dwGTKeyIndex = 0;
398                                 }
399                                 s_vCheckKeyTableValid(pTable, dwIoBase);
400                                 return true;
401                         } else {
402                                 return false;
403                         }
404                 }
405         }
406         return false;
407 }
408
409 /*
410  * Description: Remove Key from table
411  *
412  * Parameters:
413  *  In:
414  *      pTable          - Pointer to Key table
415  *      pbyBSSID        - BSSID of Key
416  *  Out:
417  *      none
418  *
419  * Return Value: true if success otherwise false
420  *
421  */
422 bool KeybRemoveAllKey(
423         PSKeyManagement pTable,
424         unsigned char *pbyBSSID,
425         unsigned long dwIoBase
426 )
427 {
428         int i, u;
429
430         for (i = 0; i < MAX_KEY_TABLE; i++) {
431                 if ((pTable->KeyTable[i].bInUse == true) &&
432                     !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
433                         pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
434                         for (u = 0; u < MAX_GROUP_KEY; u++) {
435                                 pTable->KeyTable[i].GroupKey[u].bKeyValid = false;
436                         }
437                         pTable->KeyTable[i].dwGTKeyIndex = 0;
438                         s_vCheckKeyTableValid(pTable, dwIoBase);
439                         return true;
440                 }
441         }
442         return false;
443 }
444
445 /*
446  * Description: Remove WEP Key from table
447  *
448  * Parameters:
449  *  In:
450  *      pTable          - Pointer to Key table
451  *  Out:
452  *      none
453  *
454  * Return Value: true if success otherwise false
455  *
456  */
457 void KeyvRemoveWEPKey(
458         PSKeyManagement pTable,
459         unsigned long dwKeyIndex,
460         unsigned long dwIoBase
461 )
462 {
463         if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
464                 if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse == true) {
465                         if (pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].byCipherSuite == KEY_CTL_WEP) {
466                                 pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
467                                 if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex & 0x7FFFFFFF)) {
468                                         // remove Group transmit key
469                                         pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = 0;
470                                 }
471                         }
472                 }
473                 s_vCheckKeyTableValid(pTable, dwIoBase);
474         }
475         return;
476 }
477
478 void KeyvRemoveAllWEPKey(
479         PSKeyManagement pTable,
480         unsigned long dwIoBase
481 )
482 {
483         int i;
484
485         for (i = 0; i < MAX_GROUP_KEY; i++) {
486                 KeyvRemoveWEPKey(pTable, i, dwIoBase);
487         }
488 }
489
490 /*
491  * Description: Get Transmit Key from table
492  *
493  * Parameters:
494  *  In:
495  *      pTable          - Pointer to Key table
496  *      pbyBSSID        - BSSID of Key
497  *  Out:
498  *      pKey            - Key return
499  *
500  * Return Value: true if found otherwise false
501  *
502  */
503 bool KeybGetTransmitKey(
504         PSKeyManagement pTable,
505         unsigned char *pbyBSSID,
506         unsigned long dwKeyType,
507         PSKeyItem       *pKey
508 )
509 {
510         int i, ii;
511
512         *pKey = NULL;
513         for (i = 0; i < MAX_KEY_TABLE; i++) {
514                 if ((pTable->KeyTable[i].bInUse == true) &&
515                     !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
516                         if (dwKeyType == PAIRWISE_KEY) {
517                                 if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
518                                         *pKey = &(pTable->KeyTable[i].PairwiseKey);
519
520                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetTransmitKey:");
521                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PAIRWISE_KEY: KeyTable.abyBSSID: ");
522                                         for (ii = 0; ii < 6; ii++) {
523                                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%x ", pTable->KeyTable[i].abyBSSID[ii]);
524                                         }
525                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n");
526
527                                         return true;
528                                 } else {
529                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PairwiseKey.bKeyValid == false\n");
530                                         return false;
531                                 }
532                         } // End of Type == PAIRWISE
533                         else {
534                                 if (pTable->KeyTable[i].dwGTKeyIndex == 0) {
535                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ERROR: dwGTKeyIndex == 0 !!!\n");
536                                         return false;
537                                 }
538                                 if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == true) {
539                                         *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]);
540
541                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetTransmitKey:");
542                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP_KEY: KeyTable.abyBSSID\n");
543                                         for (ii = 0; ii < 6; ii++) {
544                                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%x ", pTable->KeyTable[i].abyBSSID[ii]);
545                                         }
546                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n");
547                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex);
548
549                                         return true;
550                                 } else {
551                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GroupKey.bKeyValid == false\n");
552                                         return false;
553                                 }
554                         } // End of Type = GROUP
555                 } // BSSID match
556         }
557         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ERROR: NO Match BSSID !!! ");
558         for (ii = 0; ii < 6; ii++) {
559                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *(pbyBSSID+ii));
560         }
561         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n");
562         return false;
563 }
564
565 /*
566  * Description: Check Pairewise Key
567  *
568  * Parameters:
569  *  In:
570  *      pTable          - Pointer to Key table
571  *  Out:
572  *      none
573  *
574  * Return Value: true if found otherwise false
575  *
576  */
577 bool KeybCheckPairewiseKey(
578         PSKeyManagement pTable,
579         PSKeyItem       *pKey
580 )
581 {
582         int i;
583
584         *pKey = NULL;
585         for (i = 0; i < MAX_KEY_TABLE; i++) {
586                 if ((pTable->KeyTable[i].bInUse == true) &&
587                     (pTable->KeyTable[i].PairwiseKey.bKeyValid == true)) {
588                         *pKey = &(pTable->KeyTable[i].PairwiseKey);
589                         return true;
590                 }
591         }
592         return false;
593 }
594
595 /*
596  * Description: Set Key to table
597  *
598  * Parameters:
599  *  In:
600  *      pTable          - Pointer to Key table
601  *      dwKeyIndex      - Key index (reference to NDIS DDK)
602  *      uKeyLength      - Key length
603  *      KeyRSC          - Key RSC
604  *      pbyKey          - Pointer to key
605  *  Out:
606  *      none
607  *
608  * Return Value: true if success otherwise false
609  *
610  */
611 bool KeybSetDefaultKey(
612         PSKeyManagement pTable,
613         unsigned long dwKeyIndex,
614         unsigned long uKeyLength,
615         PQWORD          pKeyRSC,
616         unsigned char *pbyKey,
617         unsigned char byKeyDecMode,
618         unsigned long dwIoBase,
619         unsigned char byLocalID
620 )
621 {
622         unsigned int ii;
623         PSKeyItem   pKey;
624         unsigned int uKeyIdx;
625
626         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetDefaultKey: %1x, %d \n", (int)dwKeyIndex, (int)uKeyLength);
627
628         if ((dwKeyIndex & PAIRWISE_KEY) != 0) {                  // Pairwise key
629                 return false;
630         } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
631                 return false;
632         }
633
634         if (uKeyLength > MAX_KEY_LEN)
635                 return false;
636
637         pTable->KeyTable[MAX_KEY_TABLE - 1].bInUse = true;
638         for (ii = 0; ii < ETH_ALEN; ii++)
639                 pTable->KeyTable[MAX_KEY_TABLE - 1].abyBSSID[ii] = 0xFF;
640
641         // Group key
642         pKey = &(pTable->KeyTable[MAX_KEY_TABLE - 1].GroupKey[dwKeyIndex & 0x000000FF]);
643         if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
644                 // Group transmit key
645                 pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex;
646                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, MAX_KEY_TABLE-1);
647
648         }
649         pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00;          // clear all key control filed
650         pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode << 4);
651         pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode);
652         pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x0044;          // use group key for all address
653         uKeyIdx = (dwKeyIndex & 0x000000FF);
654
655         if ((uKeyLength == WLAN_WEP232_KEYLEN) &&
656             (byKeyDecMode == KEY_CTL_WEP)) {
657                 pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000;              // disable on-fly disable address match
658                 pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = true;
659         } else {
660                 if (pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP == false)
661                         pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000;          // enable on-fly disable address match
662         }
663
664         pKey->bKeyValid = true;
665         pKey->uKeyLength = uKeyLength;
666         pKey->dwKeyIndex = dwKeyIndex;
667         pKey->byCipherSuite = byKeyDecMode;
668         memcpy(pKey->abyKey, pbyKey, uKeyLength);
669         if (byKeyDecMode == KEY_CTL_WEP) {
670                 if (uKeyLength == WLAN_WEP40_KEYLEN)
671                         pKey->abyKey[15] &= 0x7F;
672                 if (uKeyLength == WLAN_WEP104_KEYLEN)
673                         pKey->abyKey[15] |= 0x80;
674         }
675         MACvSetKeyEntry(dwIoBase, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (unsigned long *)pKey->abyKey, byLocalID);
676
677         if ((dwKeyIndex & USE_KEYRSC) == 0) {
678                 // RSC set by NIC
679                 memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
680         } else {
681                 memcpy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
682         }
683         pKey->dwTSC47_16 = 0;
684         pKey->wTSC15_0 = 0;
685
686         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R): \n");
687         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n", pKey->bKeyValid);
688         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n", (int)pKey->uKeyLength);
689         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: \n");
690         for (ii = 0; ii < pKey->uKeyLength; ii++) {
691                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%x", pKey->abyKey[ii]);
692         }
693         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n");
694
695         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16);
696         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
697         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex);
698
699         return true;
700 }
701
702 /*
703  * Description: Set Key to table
704  *
705  * Parameters:
706  *  In:
707  *      pTable          - Pointer to Key table
708  *      dwKeyIndex      - Key index (reference to NDIS DDK)
709  *      uKeyLength      - Key length
710  *      KeyRSC          - Key RSC
711  *      pbyKey          - Pointer to key
712  *  Out:
713  *      none
714  *
715  * Return Value: true if success otherwise false
716  *
717  */
718 bool KeybSetAllGroupKey(
719         PSKeyManagement pTable,
720         unsigned long dwKeyIndex,
721         unsigned long uKeyLength,
722         PQWORD          pKeyRSC,
723         unsigned char *pbyKey,
724         unsigned char byKeyDecMode,
725         unsigned long dwIoBase,
726         unsigned char byLocalID
727 )
728 {
729         int         i;
730         unsigned int ii;
731         PSKeyItem   pKey;
732         unsigned int uKeyIdx;
733
734         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex);
735
736         if ((dwKeyIndex & PAIRWISE_KEY) != 0) {                  // Pairwise key
737                 return false;
738         } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
739                 return false;
740         }
741
742         for (i = 0; i < MAX_KEY_TABLE - 1; i++) {
743                 if (pTable->KeyTable[i].bInUse == true) {
744                         // found table already exist
745                         // Group key
746                         pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
747                         if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
748                                 // Group transmit key
749                                 pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
750                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
751
752                         }
753                         pTable->KeyTable[i].wKeyCtl &= 0xFF0F;          // clear group key control filed
754                         pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
755                         pTable->KeyTable[i].wKeyCtl |= 0x0040;          // use group key for group address
756                         uKeyIdx = (dwKeyIndex & 0x000000FF);
757
758                         pTable->KeyTable[i].wKeyCtl |= 0x8000;              // enable on-fly
759
760                         pKey->bKeyValid = true;
761                         pKey->uKeyLength = uKeyLength;
762                         pKey->dwKeyIndex = dwKeyIndex;
763                         pKey->byCipherSuite = byKeyDecMode;
764                         memcpy(pKey->abyKey, pbyKey, uKeyLength);
765                         if (byKeyDecMode == KEY_CTL_WEP) {
766                                 if (uKeyLength == WLAN_WEP40_KEYLEN)
767                                         pKey->abyKey[15] &= 0x7F;
768                                 if (uKeyLength == WLAN_WEP104_KEYLEN)
769                                         pKey->abyKey[15] |= 0x80;
770                         }
771                         MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (unsigned long *)pKey->abyKey, byLocalID);
772
773                         if ((dwKeyIndex & USE_KEYRSC) == 0) {
774                                 // RSC set by NIC
775                                 memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
776                         } else {
777                                 memcpy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
778                         }
779                         pKey->dwTSC47_16 = 0;
780                         pKey->wTSC15_0 = 0;
781
782                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R): \n");
783                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n ", pKey->bKeyValid);
784                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
785                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: ");
786                         for (ii = 0; ii < pKey->uKeyLength; ii++) {
787                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
788                         }
789                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n");
790
791                         //DBG_PRN_GRP12(("pKey->dwTSC47_16: %lX\n ", pKey->dwTSC47_16));
792                         //DBG_PRN_GRP12(("pKey->wTSC15_0: %X\n ", pKey->wTSC15_0));
793                         //DBG_PRN_GRP12(("pKey->dwKeyIndex: %lX\n ", pKey->dwKeyIndex));
794
795                 } // (pTable->KeyTable[i].bInUse == true)
796         }
797         return true;
798 }