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