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