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