Deleted Added
full compact
ar9300_keycache.c (250008) ar9300_keycache.c (278741)
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH

--- 422 unchanged lines hidden (view full) ---

431#define AH_KEY_REG_SIZE 8
432 int i;
433
434 for (i = 0; i < AH_KEY_REG_SIZE; i++) {
435 entry[i] = OS_REG_READ(ah, AR_KEYTABLE_KEY0(n) + i * 4);
436 }
437#undef AH_KEY_REG_SIZE
438}
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH

--- 422 unchanged lines hidden (view full) ---

431#define AH_KEY_REG_SIZE 8
432 int i;
433
434 for (i = 0; i < AH_KEY_REG_SIZE; i++) {
435 entry[i] = OS_REG_READ(ah, AR_KEYTABLE_KEY0(n) + i * 4);
436 }
437#undef AH_KEY_REG_SIZE
438}
439
440#if ATH_SUPPORT_KEYPLUMB_WAR
441/*
442 * Check the contents of the specified key cache entry
443 * and any associated MIC entry.
444 */
445 HAL_BOOL
446ar9300_check_key_cache_entry(struct ath_hal *ah, u_int16_t entry,
447 const HAL_KEYVAL *k, int xorKey)
448{
449 const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
450 u_int32_t key0, key1, key2, key3, key4;
451 u_int32_t keyType;
452 u_int32_t xorMask = xorKey ?
453 (KEY_XOR << 24 | KEY_XOR << 16 | KEY_XOR << 8 | KEY_XOR) : 0;
454 struct ath_hal_9300 *ahp = AH9300(ah);
455
456
457 if (entry >= pCap->hal_key_cache_size) {
458 HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
459 "%s: entry %u out of range\n", __func__, entry);
460 return AH_FALSE;
461 }
462 switch (k->kv_type) {
463 case HAL_CIPHER_AES_OCB:
464 keyType = AR_KEYTABLE_TYPE_AES;
465 break;
466 case HAL_CIPHER_AES_CCM:
467 if (!pCap->hal_cipher_aes_ccm_support) {
468 HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: AES-CCM not supported by "
469 "mac rev 0x%x\n",
470 __func__, AH_PRIVATE(ah)->ah_macRev);
471 return AH_FALSE;
472 }
473 keyType = AR_KEYTABLE_TYPE_CCM;
474 break;
475 case HAL_CIPHER_TKIP:
476 keyType = AR_KEYTABLE_TYPE_TKIP;
477 if (IS_MIC_ENABLED(ah) && entry + 64 >= pCap->hal_key_cache_size) {
478 HALDEBUG(ah, HAL_DEBUG_KEYCACHE,
479 "%s: entry %u inappropriate for TKIP\n",
480 __func__, entry);
481 return AH_FALSE;
482 }
483 break;
484 case HAL_CIPHER_WEP:
485 if (k->kv_len < 40 / NBBY) {
486 HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: WEP key length %u too small\n",
487 __func__, k->kv_len);
488 return AH_FALSE;
489 }
490 if (k->kv_len <= 40 / NBBY) {
491 keyType = AR_KEYTABLE_TYPE_40;
492 } else if (k->kv_len <= 104 / NBBY) {
493 keyType = AR_KEYTABLE_TYPE_104;
494 } else {
495 keyType = AR_KEYTABLE_TYPE_128;
496 }
497 break;
498 case HAL_CIPHER_CLR:
499 keyType = AR_KEYTABLE_TYPE_CLR;
500 return AH_TRUE;
501 default:
502 HALDEBUG(ah, HAL_DEBUG_KEYCACHE, "%s: cipher %u not supported\n",
503 __func__, k->kv_type);
504 return AH_TRUE;
505 }
506
507 key0 = LE_READ_4(k->kv_val + 0) ^ xorMask;
508 key1 = (LE_READ_2(k->kv_val + 4) ^ xorMask) & 0xffff;
509 key2 = LE_READ_4(k->kv_val + 6) ^ xorMask;
510 key3 = (LE_READ_2(k->kv_val + 10) ^ xorMask) & 0xffff;
511 key4 = LE_READ_4(k->kv_val + 12) ^ xorMask;
512 if (k->kv_len <= 104 / NBBY) {
513 key4 &= 0xff;
514 }
515
516 /*
517 * Note: key cache hardware requires that each double-word
518 * pair be written in even/odd order (since the destination is
519 * a 64-bit register). Don't reorder these writes w/o
520 * considering this!
521 */
522 if (keyType == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) {
523 u_int16_t micentry = entry + 64; /* MIC goes at slot+64 */
524
525
526 /*
527 * Invalidate the encrypt/decrypt key until the MIC
528 * key is installed so pending rx frames will fail
529 * with decrypt errors rather than a MIC error.
530 */
531 if ((OS_REG_READ(ah, AR_KEYTABLE_KEY0(entry)) == key0) &&
532 (OS_REG_READ(ah, AR_KEYTABLE_KEY1(entry)) == key1) &&
533 (OS_REG_READ(ah, AR_KEYTABLE_KEY2(entry)) == key2) &&
534 (OS_REG_READ(ah, AR_KEYTABLE_KEY3(entry)) == key3) &&
535 (OS_REG_READ(ah, AR_KEYTABLE_KEY4(entry)) == key4) &&
536 ((OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)) & AR_KEY_TYPE) == (keyType & AR_KEY_TYPE)))
537 {
538
539 /*
540 * since the AR_MISC_MODE register was written with the contents of
541 * ah_miscMode (if any) in ar9300Attach, just check ah_miscMode and
542 * save a pci read per key set.
543 */
544 if (ahp->ah_misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
545 u_int32_t mic0,mic1,mic2,mic3,mic4;
546 /*
547 * both RX and TX mic values can be combined into
548 * one cache slot entry.
549 * 8*N + 800 31:0 RX Michael key 0
550 * 8*N + 804 15:0 TX Michael key 0 [31:16]
551 * 8*N + 808 31:0 RX Michael key 1
552 * 8*N + 80C 15:0 TX Michael key 0 [15:0]
553 * 8*N + 810 31:0 TX Michael key 1
554 * 8*N + 814 15:0 reserved
555 * 8*N + 818 31:0 reserved
556 * 8*N + 81C 14:0 reserved
557 * 15 key valid == 0
558 */
559 /* RX mic */
560 mic0 = LE_READ_4(k->kv_mic + 0);
561 mic2 = LE_READ_4(k->kv_mic + 4);
562 /* TX mic */
563 mic1 = LE_READ_2(k->kv_txmic + 2) & 0xffff;
564 mic3 = LE_READ_2(k->kv_txmic + 0) & 0xffff;
565 mic4 = LE_READ_4(k->kv_txmic + 4);
566 if ((OS_REG_READ(ah, AR_KEYTABLE_KEY0(micentry)) == mic0) &&
567 (OS_REG_READ(ah, AR_KEYTABLE_KEY1(micentry)) == mic1) &&
568 (OS_REG_READ(ah, AR_KEYTABLE_KEY2(micentry)) == mic2) &&
569 (OS_REG_READ(ah, AR_KEYTABLE_KEY3(micentry)) == mic3) &&
570 (OS_REG_READ(ah, AR_KEYTABLE_KEY4(micentry)) == mic4) &&
571 ((OS_REG_READ(ah, AR_KEYTABLE_TYPE(micentry)) & AR_KEY_TYPE) == (AR_KEYTABLE_TYPE_CLR & AR_KEY_TYPE))) {
572 return AH_TRUE;
573 }
574
575 } else {
576 return AH_TRUE;
577 }
578 }
579 } else {
580 if ((OS_REG_READ(ah, AR_KEYTABLE_KEY0(entry)) == key0) &&
581 (OS_REG_READ(ah, AR_KEYTABLE_KEY1(entry)) == key1) &&
582 (OS_REG_READ(ah, AR_KEYTABLE_KEY2(entry)) == key2) &&
583 (OS_REG_READ(ah, AR_KEYTABLE_KEY3(entry)) == key3) &&
584 (OS_REG_READ(ah, AR_KEYTABLE_KEY4(entry)) == key4) &&
585 ((OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)) & AR_KEY_TYPE) == (keyType & AR_KEY_TYPE))) {
586 return AH_TRUE;
587 }
588 }
589 return AH_FALSE;
590}
591#endif