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