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