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