Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.13 737 lines 25 kB view raw
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 45static int msglevel =MSG_LEVEL_INFO; 46//static int msglevel =MSG_LEVEL_DEBUG; 47 48static 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 */ 95void 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 */ 144int 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 */ 197int 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 367int 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 */ 441int 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 */ 474int 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 555int 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 662int 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}