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