Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
key.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  *
20  * File: key.c
21  *
22  * Purpose: Implement functions for 802.11i Key management
23  *
24  * Author: Jerry Chen
25  *
26  * Date: May 29, 2003
27  *
28  * Functions:
29  * KeyvInitTable - Init Key management table
30  * KeybGetKey - Get Key from table
31  * KeybSetKey - Set Key to table
32  * KeybRemoveKey - Remove Key from table
33  * KeybGetTransmitKey - Get Transmit Key from table
34  *
35  * Revision History:
36  *
37  */
38 
39 #include "tmacro.h"
40 #include "key.h"
41 #include "mac.h"
42 
43 /*--------------------- Static Definitions -------------------------*/
44 
45 /*--------------------- Static Classes ----------------------------*/
46 
47 /*--------------------- Static Variables --------------------------*/
48 static int msglevel =MSG_LEVEL_INFO;
49 //static int msglevel =MSG_LEVEL_DEBUG;
50 /*--------------------- Static Functions --------------------------*/
51 
52 /*--------------------- Export Variables --------------------------*/
53 
54 /*--------------------- Static Definitions -------------------------*/
55 
56 /*--------------------- Static Classes ----------------------------*/
57 
58 /*--------------------- Static Variables --------------------------*/
59 
60 /*--------------------- Static Functions --------------------------*/
61 static void
62 s_vCheckKeyTableValid (PSKeyManagement pTable, unsigned long dwIoBase)
63 {
64  int i;
65 
66  for (i=0;i<MAX_KEY_TABLE;i++) {
67  if ((pTable->KeyTable[i].bInUse == true) &&
68  (pTable->KeyTable[i].PairwiseKey.bKeyValid == false) &&
69  (pTable->KeyTable[i].GroupKey[0].bKeyValid == false) &&
70  (pTable->KeyTable[i].GroupKey[1].bKeyValid == false) &&
71  (pTable->KeyTable[i].GroupKey[2].bKeyValid == false) &&
72  (pTable->KeyTable[i].GroupKey[3].bKeyValid == false)
73  ) {
74 
75  pTable->KeyTable[i].bInUse = false;
76  pTable->KeyTable[i].wKeyCtl = 0;
77  pTable->KeyTable[i].bSoftWEP = false;
78  MACvDisableKeyEntry(dwIoBase, i);
79  }
80  }
81 }
82 
83 
84 /*--------------------- Export Functions --------------------------*/
85 
86 
87 /*
88  * Description: Init Key management table
89  *
90  * Parameters:
91  * In:
92  * pTable - Pointer to Key table
93  * Out:
94  * none
95  *
96  * Return Value: none
97  *
98  */
99 void KeyvInitTable (PSKeyManagement pTable, unsigned long dwIoBase)
100 {
101  int i;
102  int jj;
103 
104  for (i=0;i<MAX_KEY_TABLE;i++) {
105  pTable->KeyTable[i].bInUse = false;
106  pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
107  pTable->KeyTable[i].PairwiseKey.pvKeyTable = (void *)&pTable->KeyTable[i];
108  for (jj=0; jj < MAX_GROUP_KEY; jj++) {
109  pTable->KeyTable[i].GroupKey[jj].bKeyValid = false;
110  pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (void *)&pTable->KeyTable[i];
111  }
112  pTable->KeyTable[i].wKeyCtl = 0;
113  pTable->KeyTable[i].dwGTKeyIndex = 0;
114  pTable->KeyTable[i].bSoftWEP = false;
115  MACvDisableKeyEntry(dwIoBase, i);
116  }
117 }
118 
119 
120 /*
121  * Description: Get Key from table
122  *
123  * Parameters:
124  * In:
125  * pTable - Pointer to Key table
126  * pbyBSSID - BSSID of Key
127  * dwKeyIndex - Key Index (0xFFFFFFFF means pairwise key)
128  * Out:
129  * pKey - Key return
130  *
131  * Return Value: true if found otherwise false
132  *
133  */
135  PSKeyManagement pTable,
136  unsigned char *pbyBSSID,
137  unsigned long dwKeyIndex,
138  PSKeyItem *pKey
139  )
140 {
141  int i;
142 
143  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetKey() \n");
144 
145  *pKey = NULL;
146  for (i=0;i<MAX_KEY_TABLE;i++) {
147  if ((pTable->KeyTable[i].bInUse == true) &&
148  !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
149  if (dwKeyIndex == 0xFFFFFFFF) {
150  if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
151  *pKey = &(pTable->KeyTable[i].PairwiseKey);
152  return (true);
153  }
154  else {
155  return (false);
156  }
157  } else if (dwKeyIndex < MAX_GROUP_KEY) {
158  if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid == true) {
159  *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]);
160  return (true);
161  }
162  else {
163  return (false);
164  }
165  }
166  else {
167  return (false);
168  }
169  }
170  }
171  return (false);
172 }
173 
174 
175 /*
176  * Description: Set Key to table
177  *
178  * Parameters:
179  * In:
180  * pTable - Pointer to Key table
181  * pbyBSSID - BSSID of Key
182  * dwKeyIndex - Key index (reference to NDIS DDK)
183  * uKeyLength - Key length
184  * KeyRSC - Key RSC
185  * pbyKey - Pointer to key
186  * Out:
187  * none
188  *
189  * Return Value: true if success otherwise false
190  *
191  */
193  PSKeyManagement pTable,
194  unsigned char *pbyBSSID,
195  unsigned long dwKeyIndex,
196  unsigned long uKeyLength,
197  PQWORD pKeyRSC,
198  unsigned char *pbyKey,
199  unsigned char byKeyDecMode,
200  unsigned long dwIoBase,
201  unsigned char byLocalID
202  )
203 {
204  int i,j;
205  unsigned int ii;
206  PSKeyItem pKey;
207  unsigned int uKeyIdx;
208 
209  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetKey: %lX\n", dwKeyIndex);
210 
211  j = (MAX_KEY_TABLE-1);
212  for (i=0;i<(MAX_KEY_TABLE-1);i++) {
213  if ((pTable->KeyTable[i].bInUse == false) &&
214  (j == (MAX_KEY_TABLE-1))) {
215  // found empty table
216  j = i;
217  }
218  if ((pTable->KeyTable[i].bInUse == true) &&
219  !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
220  // found table already exist
221  if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
222  // Pairwise key
223  pKey = &(pTable->KeyTable[i].PairwiseKey);
224  pTable->KeyTable[i].wKeyCtl &= 0xFFF0; // clear pairwise key control filed
225  pTable->KeyTable[i].wKeyCtl |= byKeyDecMode;
226  uKeyIdx = 4; // use HW key entry 4 for pairwise key
227  } else {
228  // Group key
229  if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
230  return (false);
231  pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
232  if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
233  // Group transmit key
234  pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
235  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
236  }
237  pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed
238  pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
239  pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address
240  uKeyIdx = (dwKeyIndex & 0x000000FF);
241  }
242  pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly
243 
244  pKey->bKeyValid = true;
245  pKey->uKeyLength = uKeyLength;
246  pKey->dwKeyIndex = dwKeyIndex;
247  pKey->byCipherSuite = byKeyDecMode;
248  memcpy(pKey->abyKey, pbyKey, uKeyLength);
249  if (byKeyDecMode == KEY_CTL_WEP) {
250  if (uKeyLength == WLAN_WEP40_KEYLEN)
251  pKey->abyKey[15] &= 0x7F;
252  if (uKeyLength == WLAN_WEP104_KEYLEN)
253  pKey->abyKey[15] |= 0x80;
254  }
255  MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (unsigned long *)pKey->abyKey, byLocalID);
256 
257  if ((dwKeyIndex & USE_KEYRSC) == 0) {
258  // RSC set by NIC
259  memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
260  }
261  else {
262  memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD));
263  }
264  pKey->dwTSC47_16 = 0;
265  pKey->wTSC15_0 = 0;
266 
267  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
268  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
269  //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", pKey->uKeyLength);
270  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
271  for (ii = 0; ii < pKey->uKeyLength; ii++) {
272  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
273  }
275 
276  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
277  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
278  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
279 
280  return (true);
281  }
282  }
283  if (j < (MAX_KEY_TABLE-1)) {
284  memcpy(pTable->KeyTable[j].abyBSSID,pbyBSSID,ETH_ALEN);
285  pTable->KeyTable[j].bInUse = true;
286  if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
287  // Pairwise key
288  pKey = &(pTable->KeyTable[j].PairwiseKey);
289  pTable->KeyTable[j].wKeyCtl &= 0xFFF0; // clear pairwise key control filed
290  pTable->KeyTable[j].wKeyCtl |= byKeyDecMode;
291  uKeyIdx = 4; // use HW key entry 4 for pairwise key
292  } else {
293  // Group key
294  if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
295  return (false);
296  pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]);
297  if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
298  // Group transmit key
299  pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex;
300  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j);
301  }
302  pTable->KeyTable[j].wKeyCtl &= 0xFF0F; // clear group key control filed
303  pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4);
304  pTable->KeyTable[j].wKeyCtl |= 0x0040; // use group key for group address
305  uKeyIdx = (dwKeyIndex & 0x000000FF);
306  }
307  pTable->KeyTable[j].wKeyCtl |= 0x8000; // enable on-fly
308 
309  pKey->bKeyValid = true;
310  pKey->uKeyLength = uKeyLength;
311  pKey->dwKeyIndex = dwKeyIndex;
312  pKey->byCipherSuite = byKeyDecMode;
313  memcpy(pKey->abyKey, pbyKey, uKeyLength);
314  if (byKeyDecMode == KEY_CTL_WEP) {
315  if (uKeyLength == WLAN_WEP40_KEYLEN)
316  pKey->abyKey[15] &= 0x7F;
317  if (uKeyLength == WLAN_WEP104_KEYLEN)
318  pKey->abyKey[15] |= 0x80;
319  }
320  MACvSetKeyEntry(dwIoBase, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (unsigned long *)pKey->abyKey, byLocalID);
321 
322  if ((dwKeyIndex & USE_KEYRSC) == 0) {
323  // RSC set by NIC
324  memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
325  }
326  else {
327  memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD));
328  }
329  pKey->dwTSC47_16 = 0;
330  pKey->wTSC15_0 = 0;
331 
332  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(N): \n");
333  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
334  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
335  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
336  for (ii = 0; ii < pKey->uKeyLength; ii++) {
337  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
338  }
340 
341  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
342  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
343  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
344 
345  return (true);
346  }
347  return (false);
348 }
349 
350 
351 /*
352  * Description: Remove Key from table
353  *
354  * Parameters:
355  * In:
356  * pTable - Pointer to Key table
357  * pbyBSSID - BSSID of Key
358  * dwKeyIndex - Key Index (reference to NDIS DDK)
359  * Out:
360  * none
361  *
362  * Return Value: true if success otherwise false
363  *
364  */
366  PSKeyManagement pTable,
367  unsigned char *pbyBSSID,
368  unsigned long dwKeyIndex,
369  unsigned long dwIoBase
370  )
371 {
372  int i;
373 
374  if (is_broadcast_ether_addr(pbyBSSID)) {
375  // delete all keys
376  if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
377  for (i=0;i<MAX_KEY_TABLE;i++) {
378  pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
379  }
380  s_vCheckKeyTableValid(pTable, dwIoBase);
381  return true;
382  }
383  else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
384  for (i=0;i<MAX_KEY_TABLE;i++) {
385  pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
386  if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
387  // remove Group transmit key
388  pTable->KeyTable[i].dwGTKeyIndex = 0;
389  }
390  }
391  s_vCheckKeyTableValid(pTable, dwIoBase);
392  return true;
393  }
394  else {
395  return false;
396  }
397  }
398 
399  for (i=0;i<MAX_KEY_TABLE;i++) {
400  if ((pTable->KeyTable[i].bInUse == true) &&
401  !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
402  if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
403  pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
404  s_vCheckKeyTableValid(pTable, dwIoBase);
405  return (true);
406  }
407  else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
408  pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
409  if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
410  // remove Group transmit key
411  pTable->KeyTable[i].dwGTKeyIndex = 0;
412  }
413  s_vCheckKeyTableValid(pTable, dwIoBase);
414  return (true);
415  }
416  else {
417  return (false);
418  }
419  }
420  }
421  return (false);
422 }
423 
424 
425 /*
426  * Description: Remove Key from table
427  *
428  * Parameters:
429  * In:
430  * pTable - Pointer to Key table
431  * pbyBSSID - BSSID of Key
432  * Out:
433  * none
434  *
435  * Return Value: true if success otherwise false
436  *
437  */
439  PSKeyManagement pTable,
440  unsigned char *pbyBSSID,
441  unsigned long dwIoBase
442  )
443 {
444  int i,u;
445 
446  for (i=0;i<MAX_KEY_TABLE;i++) {
447  if ((pTable->KeyTable[i].bInUse == true) &&
448  !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
449  pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
450  for(u=0;u<MAX_GROUP_KEY;u++) {
451  pTable->KeyTable[i].GroupKey[u].bKeyValid = false;
452  }
453  pTable->KeyTable[i].dwGTKeyIndex = 0;
454  s_vCheckKeyTableValid(pTable, dwIoBase);
455  return (true);
456  }
457  }
458  return (false);
459 }
460 
461 /*
462  * Description: Remove WEP Key from table
463  *
464  * Parameters:
465  * In:
466  * pTable - Pointer to Key table
467  * Out:
468  * none
469  *
470  * Return Value: true if success otherwise false
471  *
472  */
474  PSKeyManagement pTable,
475  unsigned long dwKeyIndex,
476  unsigned long dwIoBase
477  )
478 {
479 
480  if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
481  if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse == true) {
482  if (pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].byCipherSuite == KEY_CTL_WEP) {
483  pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
484  if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex & 0x7FFFFFFF)) {
485  // remove Group transmit key
486  pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = 0;
487  }
488  }
489  }
490  s_vCheckKeyTableValid(pTable, dwIoBase);
491  }
492  return;
493 }
494 
496  PSKeyManagement pTable,
497  unsigned long dwIoBase
498  )
499 {
500  int i;
501 
502  for(i=0;i<MAX_GROUP_KEY;i++) {
503  KeyvRemoveWEPKey(pTable, i, dwIoBase);
504  }
505 }
506 
507 /*
508  * Description: Get Transmit Key from table
509  *
510  * Parameters:
511  * In:
512  * pTable - Pointer to Key table
513  * pbyBSSID - BSSID of Key
514  * Out:
515  * pKey - Key return
516  *
517  * Return Value: true if found otherwise false
518  *
519  */
521  PSKeyManagement pTable,
522  unsigned char *pbyBSSID,
523  unsigned long dwKeyType,
524  PSKeyItem *pKey
525  )
526 {
527  int i, ii;
528 
529  *pKey = NULL;
530  for (i=0;i<MAX_KEY_TABLE;i++) {
531  if ((pTable->KeyTable[i].bInUse == true) &&
532  !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
533 
534  if (dwKeyType == PAIRWISE_KEY) {
535 
536  if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
537  *pKey = &(pTable->KeyTable[i].PairwiseKey);
538 
539  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
540  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PAIRWISE_KEY: KeyTable.abyBSSID: ");
541  for (ii = 0; ii < 6; ii++) {
542  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
543  }
545 
546 
547  return (true);
548  }
549  else {
550  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PairwiseKey.bKeyValid == false\n");
551  return (false);
552  }
553  } // End of Type == PAIRWISE
554  else {
555  if (pTable->KeyTable[i].dwGTKeyIndex == 0) {
556  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: dwGTKeyIndex == 0 !!!\n");
557  return false;
558  }
559  if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == true) {
560  *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]);
561 
562  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
563  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GROUP_KEY: KeyTable.abyBSSID\n");
564  for (ii = 0; ii < 6; ii++) {
565  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
566  }
568  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex);
569 
570  return (true);
571  }
572  else {
573  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GroupKey.bKeyValid == false\n");
574  return (false);
575  }
576  } // End of Type = GROUP
577  } // BSSID match
578  }
579  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: NO Match BSSID !!! ");
580  for (ii = 0; ii < 6; ii++) {
581  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(pbyBSSID+ii));
582  }
584  return (false);
585 }
586 
587 
588 /*
589  * Description: Check Pairewise Key
590  *
591  * Parameters:
592  * In:
593  * pTable - Pointer to Key table
594  * Out:
595  * none
596  *
597  * Return Value: true if found otherwise false
598  *
599  */
601  PSKeyManagement pTable,
602  PSKeyItem *pKey
603  )
604 {
605  int i;
606 
607  *pKey = NULL;
608  for (i=0;i<MAX_KEY_TABLE;i++) {
609  if ((pTable->KeyTable[i].bInUse == true) &&
610  (pTable->KeyTable[i].PairwiseKey.bKeyValid == true)) {
611  *pKey = &(pTable->KeyTable[i].PairwiseKey);
612  return (true);
613  }
614  }
615  return (false);
616 }
617 
618 /*
619  * Description: Set Key to table
620  *
621  * Parameters:
622  * In:
623  * pTable - Pointer to Key table
624  * dwKeyIndex - Key index (reference to NDIS DDK)
625  * uKeyLength - Key length
626  * KeyRSC - Key RSC
627  * pbyKey - Pointer to key
628  * Out:
629  * none
630  *
631  * Return Value: true if success otherwise false
632  *
633  */
635  PSKeyManagement pTable,
636  unsigned long dwKeyIndex,
637  unsigned long uKeyLength,
638  PQWORD pKeyRSC,
639  unsigned char *pbyKey,
640  unsigned char byKeyDecMode,
641  unsigned long dwIoBase,
642  unsigned char byLocalID
643  )
644 {
645  unsigned int ii;
646  PSKeyItem pKey;
647  unsigned int uKeyIdx;
648 
649  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetDefaultKey: %1x, %d \n", (int)dwKeyIndex, (int)uKeyLength);
650 
651 
652  if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key
653  return (false);
654  } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
655  return (false);
656  }
657 
658  if (uKeyLength > MAX_KEY_LEN)
659  return false;
660 
661  pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = true;
662  for(ii=0;ii<ETH_ALEN;ii++)
663  pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF;
664 
665  // Group key
666  pKey = &(pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF]);
667  if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
668  // Group transmit key
669  pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex;
670  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);
671 
672  }
673  pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00; // clear all key control filed
674  pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode << 4);
675  pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode);
676  pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x0044; // use group key for all address
677  uKeyIdx = (dwKeyIndex & 0x000000FF);
678 
679  if ((uKeyLength == WLAN_WEP232_KEYLEN) &&
680  (byKeyDecMode == KEY_CTL_WEP)) {
681  pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000; // disable on-fly disable address match
682  pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = true;
683  } else {
684  if (pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP == false)
685  pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000; // enable on-fly disable address match
686  }
687 
688  pKey->bKeyValid = true;
689  pKey->uKeyLength = uKeyLength;
690  pKey->dwKeyIndex = dwKeyIndex;
691  pKey->byCipherSuite = byKeyDecMode;
692  memcpy(pKey->abyKey, pbyKey, uKeyLength);
693  if (byKeyDecMode == KEY_CTL_WEP) {
694  if (uKeyLength == WLAN_WEP40_KEYLEN)
695  pKey->abyKey[15] &= 0x7F;
696  if (uKeyLength == WLAN_WEP104_KEYLEN)
697  pKey->abyKey[15] |= 0x80;
698  }
699  MACvSetKeyEntry(dwIoBase, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (unsigned long *)pKey->abyKey, byLocalID);
700 
701  if ((dwKeyIndex & USE_KEYRSC) == 0) {
702  // RSC set by NIC
703  memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
704  } else {
705  memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD));
706  }
707  pKey->dwTSC47_16 = 0;
708  pKey->wTSC15_0 = 0;
709 
710 
711  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
712  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n", pKey->bKeyValid);
713  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n", (int)pKey->uKeyLength);
714  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: \n");
715  for (ii = 0; ii < pKey->uKeyLength; ii++) {
716  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x", pKey->abyKey[ii]);
717  }
719 
720  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16);
721  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
722  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex);
723 
724  return (true);
725 }
726 
727 
728 /*
729  * Description: Set Key to table
730  *
731  * Parameters:
732  * In:
733  * pTable - Pointer to Key table
734  * dwKeyIndex - Key index (reference to NDIS DDK)
735  * uKeyLength - Key length
736  * KeyRSC - Key RSC
737  * pbyKey - Pointer to key
738  * Out:
739  * none
740  *
741  * Return Value: true if success otherwise false
742  *
743  */
745  PSKeyManagement pTable,
746  unsigned long dwKeyIndex,
747  unsigned long uKeyLength,
748  PQWORD pKeyRSC,
749  unsigned char *pbyKey,
750  unsigned char byKeyDecMode,
751  unsigned long dwIoBase,
752  unsigned char byLocalID
753  )
754 {
755  int i;
756  unsigned int ii;
757  PSKeyItem pKey;
758  unsigned int uKeyIdx;
759 
760  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex);
761 
762 
763  if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key
764  return (false);
765  } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
766  return (false);
767  }
768 
769  for (i=0; i < MAX_KEY_TABLE-1; i++) {
770  if (pTable->KeyTable[i].bInUse == true) {
771  // found table already exist
772  // Group key
773  pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
774  if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
775  // Group transmit key
776  pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
777  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
778 
779  }
780  pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed
781  pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
782  pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address
783  uKeyIdx = (dwKeyIndex & 0x000000FF);
784 
785  pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly
786 
787  pKey->bKeyValid = true;
788  pKey->uKeyLength = uKeyLength;
789  pKey->dwKeyIndex = dwKeyIndex;
790  pKey->byCipherSuite = byKeyDecMode;
791  memcpy(pKey->abyKey, pbyKey, uKeyLength);
792  if (byKeyDecMode == KEY_CTL_WEP) {
793  if (uKeyLength == WLAN_WEP40_KEYLEN)
794  pKey->abyKey[15] &= 0x7F;
795  if (uKeyLength == WLAN_WEP104_KEYLEN)
796  pKey->abyKey[15] |= 0x80;
797  }
798  MACvSetKeyEntry(dwIoBase, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (unsigned long *)pKey->abyKey, byLocalID);
799 
800  if ((dwKeyIndex & USE_KEYRSC) == 0) {
801  // RSC set by NIC
802  memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
803  }
804  else {
805  memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD));
806  }
807  pKey->dwTSC47_16 = 0;
808  pKey->wTSC15_0 = 0;
809 
810  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
811  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
812  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
813  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
814  for (ii = 0; ii < pKey->uKeyLength; ii++) {
815  DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", pKey->abyKey[ii]);
816  }
818 
819  //DBG_PRN_GRP12(("pKey->dwTSC47_16: %lX\n ", pKey->dwTSC47_16));
820  //DBG_PRN_GRP12(("pKey->wTSC15_0: %X\n ", pKey->wTSC15_0));
821  //DBG_PRN_GRP12(("pKey->dwKeyIndex: %lX\n ", pKey->dwKeyIndex));
822 
823  } // (pTable->KeyTable[i].bInUse == true)
824  }
825  return (true);
826 }