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