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