cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

key.c (17731B)


      1/*
      2 * Copyright (c) 2009 Atheros Communications Inc.
      3 * Copyright (c) 2010 Bruno Randolf <br1@einfach.org>
      4 *
      5 * Permission to use, copy, modify, and/or distribute this software for any
      6 * purpose with or without fee is hereby granted, provided that the above
      7 * copyright notice and this permission notice appear in all copies.
      8 *
      9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     16 */
     17
     18#include <linux/export.h>
     19#include <asm/unaligned.h>
     20#include <net/mac80211.h>
     21
     22#include "ath.h"
     23#include "reg.h"
     24
     25#define REG_READ			(common->ops->read)
     26#define REG_WRITE(_ah, _reg, _val)	(common->ops->write)(_ah, _val, _reg)
     27#define ENABLE_REGWRITE_BUFFER(_ah)			\
     28	if (common->ops->enable_write_buffer)		\
     29		common->ops->enable_write_buffer((_ah));
     30
     31#define REGWRITE_BUFFER_FLUSH(_ah)			\
     32	if (common->ops->write_flush)			\
     33		common->ops->write_flush((_ah));
     34
     35
     36#define IEEE80211_WEP_NKID      4       /* number of key ids */
     37
     38/************************/
     39/* Key Cache Management */
     40/************************/
     41
     42bool ath_hw_keyreset(struct ath_common *common, u16 entry)
     43{
     44	u32 keyType;
     45	void *ah = common->ah;
     46
     47	if (entry >= common->keymax) {
     48		ath_err(common, "keyreset: keycache entry %u out of range\n",
     49			entry);
     50		return false;
     51	}
     52
     53	keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
     54
     55	ENABLE_REGWRITE_BUFFER(ah);
     56
     57	REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
     58	REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
     59	REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
     60	REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
     61	REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
     62	REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
     63	REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
     64	REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
     65
     66	if (keyType == AR_KEYTABLE_TYPE_TKIP) {
     67		u16 micentry = entry + 64;
     68
     69		REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
     70		REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
     71		REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
     72		REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
     73		if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
     74			REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
     75			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
     76				  AR_KEYTABLE_TYPE_CLR);
     77		}
     78
     79	}
     80
     81	REGWRITE_BUFFER_FLUSH(ah);
     82
     83	return true;
     84}
     85EXPORT_SYMBOL(ath_hw_keyreset);
     86
     87bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac)
     88{
     89	u32 macHi, macLo;
     90	u32 unicast_flag = AR_KEYTABLE_VALID;
     91	void *ah = common->ah;
     92
     93	if (entry >= common->keymax) {
     94		ath_err(common, "keysetmac: keycache entry %u out of range\n",
     95			entry);
     96		return false;
     97	}
     98
     99	if (mac != NULL) {
    100		/*
    101		 * AR_KEYTABLE_VALID indicates that the address is a unicast
    102		 * address, which must match the transmitter address for
    103		 * decrypting frames.
    104		 * Not setting this bit allows the hardware to use the key
    105		 * for multicast frame decryption.
    106		 */
    107		if (mac[0] & 0x01)
    108			unicast_flag = 0;
    109
    110		macLo = get_unaligned_le32(mac);
    111		macHi = get_unaligned_le16(mac + 4);
    112		macLo >>= 1;
    113		macLo |= (macHi & 1) << 31;
    114		macHi >>= 1;
    115	} else {
    116		macLo = macHi = 0;
    117	}
    118	ENABLE_REGWRITE_BUFFER(ah);
    119
    120	REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
    121	REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
    122
    123	REGWRITE_BUFFER_FLUSH(ah);
    124
    125	return true;
    126}
    127EXPORT_SYMBOL(ath_hw_keysetmac);
    128
    129static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry,
    130				      const struct ath_keyval *k,
    131				      const u8 *mac)
    132{
    133	void *ah = common->ah;
    134	u32 key0, key1, key2, key3, key4;
    135	u32 keyType;
    136
    137	if (entry >= common->keymax) {
    138		ath_err(common, "set-entry: keycache entry %u out of range\n",
    139			entry);
    140		return false;
    141	}
    142
    143	switch (k->kv_type) {
    144	case ATH_CIPHER_AES_OCB:
    145		keyType = AR_KEYTABLE_TYPE_AES;
    146		break;
    147	case ATH_CIPHER_AES_CCM:
    148		if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) {
    149			ath_dbg(common, ANY,
    150				"AES-CCM not supported by this mac rev\n");
    151			return false;
    152		}
    153		keyType = AR_KEYTABLE_TYPE_CCM;
    154		break;
    155	case ATH_CIPHER_TKIP:
    156		keyType = AR_KEYTABLE_TYPE_TKIP;
    157		if (entry + 64 >= common->keymax) {
    158			ath_dbg(common, ANY,
    159				"entry %u inappropriate for TKIP\n", entry);
    160			return false;
    161		}
    162		break;
    163	case ATH_CIPHER_WEP:
    164		if (k->kv_len < WLAN_KEY_LEN_WEP40) {
    165			ath_dbg(common, ANY, "WEP key length %u too small\n",
    166				k->kv_len);
    167			return false;
    168		}
    169		if (k->kv_len <= WLAN_KEY_LEN_WEP40)
    170			keyType = AR_KEYTABLE_TYPE_40;
    171		else if (k->kv_len <= WLAN_KEY_LEN_WEP104)
    172			keyType = AR_KEYTABLE_TYPE_104;
    173		else
    174			keyType = AR_KEYTABLE_TYPE_128;
    175		break;
    176	case ATH_CIPHER_CLR:
    177		keyType = AR_KEYTABLE_TYPE_CLR;
    178		break;
    179	default:
    180		ath_err(common, "cipher %u not supported\n", k->kv_type);
    181		return false;
    182	}
    183
    184	key0 = get_unaligned_le32(k->kv_val + 0);
    185	key1 = get_unaligned_le16(k->kv_val + 4);
    186	key2 = get_unaligned_le32(k->kv_val + 6);
    187	key3 = get_unaligned_le16(k->kv_val + 10);
    188	key4 = get_unaligned_le32(k->kv_val + 12);
    189	if (k->kv_len <= WLAN_KEY_LEN_WEP104)
    190		key4 &= 0xff;
    191
    192	/*
    193	 * Note: Key cache registers access special memory area that requires
    194	 * two 32-bit writes to actually update the values in the internal
    195	 * memory. Consequently, the exact order and pairs used here must be
    196	 * maintained.
    197	 */
    198
    199	if (keyType == AR_KEYTABLE_TYPE_TKIP) {
    200		u16 micentry = entry + 64;
    201
    202		/*
    203		 * Write inverted key[47:0] first to avoid Michael MIC errors
    204		 * on frames that could be sent or received at the same time.
    205		 * The correct key will be written in the end once everything
    206		 * else is ready.
    207		 */
    208		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
    209		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
    210
    211		/* Write key[95:48] */
    212		REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
    213		REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
    214
    215		/* Write key[127:96] and key type */
    216		REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
    217		REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
    218
    219		/* Write MAC address for the entry */
    220		(void) ath_hw_keysetmac(common, entry, mac);
    221
    222		if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
    223			/*
    224			 * TKIP uses two key cache entries:
    225			 * Michael MIC TX/RX keys in the same key cache entry
    226			 * (idx = main index + 64):
    227			 * key0 [31:0] = RX key [31:0]
    228			 * key1 [15:0] = TX key [31:16]
    229			 * key1 [31:16] = reserved
    230			 * key2 [31:0] = RX key [63:32]
    231			 * key3 [15:0] = TX key [15:0]
    232			 * key3 [31:16] = reserved
    233			 * key4 [31:0] = TX key [63:32]
    234			 */
    235			u32 mic0, mic1, mic2, mic3, mic4;
    236
    237			mic0 = get_unaligned_le32(k->kv_mic + 0);
    238			mic2 = get_unaligned_le32(k->kv_mic + 4);
    239			mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
    240			mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
    241			mic4 = get_unaligned_le32(k->kv_txmic + 4);
    242
    243			ENABLE_REGWRITE_BUFFER(ah);
    244
    245			/* Write RX[31:0] and TX[31:16] */
    246			REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
    247			REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
    248
    249			/* Write RX[63:32] and TX[15:0] */
    250			REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
    251			REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
    252
    253			/* Write TX[63:32] and keyType(reserved) */
    254			REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
    255			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
    256				  AR_KEYTABLE_TYPE_CLR);
    257
    258			REGWRITE_BUFFER_FLUSH(ah);
    259
    260		} else {
    261			/*
    262			 * TKIP uses four key cache entries (two for group
    263			 * keys):
    264			 * Michael MIC TX/RX keys are in different key cache
    265			 * entries (idx = main index + 64 for TX and
    266			 * main index + 32 + 96 for RX):
    267			 * key0 [31:0] = TX/RX MIC key [31:0]
    268			 * key1 [31:0] = reserved
    269			 * key2 [31:0] = TX/RX MIC key [63:32]
    270			 * key3 [31:0] = reserved
    271			 * key4 [31:0] = reserved
    272			 *
    273			 * Upper layer code will call this function separately
    274			 * for TX and RX keys when these registers offsets are
    275			 * used.
    276			 */
    277			u32 mic0, mic2;
    278
    279			mic0 = get_unaligned_le32(k->kv_mic + 0);
    280			mic2 = get_unaligned_le32(k->kv_mic + 4);
    281
    282			ENABLE_REGWRITE_BUFFER(ah);
    283
    284			/* Write MIC key[31:0] */
    285			REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
    286			REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
    287
    288			/* Write MIC key[63:32] */
    289			REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
    290			REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
    291
    292			/* Write TX[63:32] and keyType(reserved) */
    293			REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
    294			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
    295				  AR_KEYTABLE_TYPE_CLR);
    296
    297			REGWRITE_BUFFER_FLUSH(ah);
    298		}
    299
    300		ENABLE_REGWRITE_BUFFER(ah);
    301
    302		/* MAC address registers are reserved for the MIC entry */
    303		REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
    304		REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
    305
    306		/*
    307		 * Write the correct (un-inverted) key[47:0] last to enable
    308		 * TKIP now that all other registers are set with correct
    309		 * values.
    310		 */
    311		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
    312		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
    313
    314		REGWRITE_BUFFER_FLUSH(ah);
    315	} else {
    316		ENABLE_REGWRITE_BUFFER(ah);
    317
    318		/* Write key[47:0] */
    319		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
    320		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
    321
    322		/* Write key[95:48] */
    323		REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
    324		REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
    325
    326		/* Write key[127:96] and key type */
    327		REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
    328		REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
    329
    330		REGWRITE_BUFFER_FLUSH(ah);
    331
    332		/* Write MAC address for the entry */
    333		(void) ath_hw_keysetmac(common, entry, mac);
    334	}
    335
    336	return true;
    337}
    338
    339static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
    340			   struct ath_keyval *hk, const u8 *addr,
    341			   bool authenticator)
    342{
    343	const u8 *key_rxmic;
    344	const u8 *key_txmic;
    345
    346	key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
    347	key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
    348
    349	if (addr == NULL) {
    350		/*
    351		 * Group key installation - only two key cache entries are used
    352		 * regardless of splitmic capability since group key is only
    353		 * used either for TX or RX.
    354		 */
    355		if (authenticator) {
    356			memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
    357			memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
    358		} else {
    359			memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
    360			memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
    361		}
    362		return ath_hw_set_keycache_entry(common, keyix, hk, addr);
    363	}
    364	if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
    365		/* TX and RX keys share the same key cache entry. */
    366		memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
    367		memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
    368		return ath_hw_set_keycache_entry(common, keyix, hk, addr);
    369	}
    370
    371	/* Separate key cache entries for TX and RX */
    372
    373	/* TX key goes at first index, RX key at +32. */
    374	memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
    375	if (!ath_hw_set_keycache_entry(common, keyix, hk, NULL)) {
    376		/* TX MIC entry failed. No need to proceed further */
    377		ath_err(common, "Setting TX MIC Key Failed\n");
    378		return 0;
    379	}
    380
    381	memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
    382	/* XXX delete tx key on failure? */
    383	return ath_hw_set_keycache_entry(common, keyix + 32, hk, addr);
    384}
    385
    386static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
    387{
    388	int i;
    389
    390	for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
    391		if (test_bit(i, common->keymap) ||
    392		    test_bit(i + 64, common->keymap))
    393			continue; /* At least one part of TKIP key allocated */
    394		if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) &&
    395		    (test_bit(i + 32, common->keymap) ||
    396		     test_bit(i + 64 + 32, common->keymap)))
    397			continue; /* At least one part of TKIP key allocated */
    398
    399		/* Found a free slot for a TKIP key */
    400		return i;
    401	}
    402	return -1;
    403}
    404
    405static int ath_reserve_key_cache_slot(struct ath_common *common,
    406				      u32 cipher)
    407{
    408	int i;
    409
    410	if (cipher == WLAN_CIPHER_SUITE_TKIP)
    411		return ath_reserve_key_cache_slot_tkip(common);
    412
    413	/* First, try to find slots that would not be available for TKIP. */
    414	if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
    415		for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
    416			if (!test_bit(i, common->keymap) &&
    417			    (test_bit(i + 32, common->keymap) ||
    418			     test_bit(i + 64, common->keymap) ||
    419			     test_bit(i + 64 + 32, common->keymap)))
    420				return i;
    421			if (!test_bit(i + 32, common->keymap) &&
    422			    (test_bit(i, common->keymap) ||
    423			     test_bit(i + 64, common->keymap) ||
    424			     test_bit(i + 64 + 32, common->keymap)))
    425				return i + 32;
    426			if (!test_bit(i + 64, common->keymap) &&
    427			    (test_bit(i , common->keymap) ||
    428			     test_bit(i + 32, common->keymap) ||
    429			     test_bit(i + 64 + 32, common->keymap)))
    430				return i + 64;
    431			if (!test_bit(i + 64 + 32, common->keymap) &&
    432			    (test_bit(i, common->keymap) ||
    433			     test_bit(i + 32, common->keymap) ||
    434			     test_bit(i + 64, common->keymap)))
    435				return i + 64 + 32;
    436		}
    437	} else {
    438		for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
    439			if (!test_bit(i, common->keymap) &&
    440			    test_bit(i + 64, common->keymap))
    441				return i;
    442			if (test_bit(i, common->keymap) &&
    443			    !test_bit(i + 64, common->keymap))
    444				return i + 64;
    445		}
    446	}
    447
    448	/* No partially used TKIP slots, pick any available slot */
    449	for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
    450		/* Do not allow slots that could be needed for TKIP group keys
    451		 * to be used. This limitation could be removed if we know that
    452		 * TKIP will not be used. */
    453		if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
    454			continue;
    455		if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
    456			if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
    457				continue;
    458			if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
    459				continue;
    460		}
    461
    462		if (!test_bit(i, common->keymap))
    463			return i; /* Found a free slot for a key */
    464	}
    465
    466	/* No free slot found */
    467	return -1;
    468}
    469
    470/*
    471 * Configure encryption in the HW.
    472 */
    473int ath_key_config(struct ath_common *common,
    474			  struct ieee80211_vif *vif,
    475			  struct ieee80211_sta *sta,
    476			  struct ieee80211_key_conf *key)
    477{
    478	struct ath_keyval hk;
    479	const u8 *mac = NULL;
    480	u8 gmac[ETH_ALEN];
    481	int ret = 0;
    482	int idx;
    483
    484	memset(&hk, 0, sizeof(hk));
    485
    486	switch (key->cipher) {
    487	case 0:
    488		hk.kv_type = ATH_CIPHER_CLR;
    489		break;
    490	case WLAN_CIPHER_SUITE_WEP40:
    491	case WLAN_CIPHER_SUITE_WEP104:
    492		hk.kv_type = ATH_CIPHER_WEP;
    493		break;
    494	case WLAN_CIPHER_SUITE_TKIP:
    495		hk.kv_type = ATH_CIPHER_TKIP;
    496		break;
    497	case WLAN_CIPHER_SUITE_CCMP:
    498		hk.kv_type = ATH_CIPHER_AES_CCM;
    499		break;
    500	default:
    501		return -EOPNOTSUPP;
    502	}
    503
    504	hk.kv_len = key->keylen;
    505	if (key->keylen)
    506		memcpy(hk.kv_val, key->key, key->keylen);
    507
    508	if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
    509		switch (vif->type) {
    510		case NL80211_IFTYPE_AP:
    511			memcpy(gmac, vif->addr, ETH_ALEN);
    512			gmac[0] |= 0x01;
    513			mac = gmac;
    514			idx = ath_reserve_key_cache_slot(common, key->cipher);
    515			break;
    516		case NL80211_IFTYPE_ADHOC:
    517			if (!sta) {
    518				idx = key->keyidx;
    519				break;
    520			}
    521			memcpy(gmac, sta->addr, ETH_ALEN);
    522			gmac[0] |= 0x01;
    523			mac = gmac;
    524			idx = ath_reserve_key_cache_slot(common, key->cipher);
    525			break;
    526		default:
    527			idx = key->keyidx;
    528			break;
    529		}
    530	} else if (key->keyidx) {
    531		if (WARN_ON(!sta))
    532			return -EOPNOTSUPP;
    533		mac = sta->addr;
    534
    535		if (vif->type != NL80211_IFTYPE_AP) {
    536			/* Only keyidx 0 should be used with unicast key, but
    537			 * allow this for client mode for now. */
    538			idx = key->keyidx;
    539		} else
    540			return -EIO;
    541	} else {
    542		if (WARN_ON(!sta))
    543			return -EOPNOTSUPP;
    544		mac = sta->addr;
    545
    546		idx = ath_reserve_key_cache_slot(common, key->cipher);
    547	}
    548
    549	if (idx < 0)
    550		return -ENOSPC; /* no free key cache entries */
    551
    552	if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
    553		ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
    554				      vif->type == NL80211_IFTYPE_AP);
    555	else
    556		ret = ath_hw_set_keycache_entry(common, idx, &hk, mac);
    557
    558	if (!ret)
    559		return -EIO;
    560
    561	set_bit(idx, common->keymap);
    562	if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
    563		set_bit(idx, common->ccmp_keymap);
    564
    565	if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
    566		set_bit(idx + 64, common->keymap);
    567		set_bit(idx, common->tkip_keymap);
    568		set_bit(idx + 64, common->tkip_keymap);
    569		if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
    570			set_bit(idx + 32, common->keymap);
    571			set_bit(idx + 64 + 32, common->keymap);
    572			set_bit(idx + 32, common->tkip_keymap);
    573			set_bit(idx + 64 + 32, common->tkip_keymap);
    574		}
    575	}
    576
    577	return idx;
    578}
    579EXPORT_SYMBOL(ath_key_config);
    580
    581/*
    582 * Delete Key.
    583 */
    584void ath_key_delete(struct ath_common *common, u8 hw_key_idx)
    585{
    586	/* Leave CCMP and TKIP (main key) configured to avoid disabling
    587	 * encryption for potentially pending frames already in a TXQ with the
    588	 * keyix pointing to this key entry. Instead, only clear the MAC address
    589	 * to prevent RX processing from using this key cache entry.
    590	 */
    591	if (test_bit(hw_key_idx, common->ccmp_keymap) ||
    592	    test_bit(hw_key_idx, common->tkip_keymap))
    593		ath_hw_keysetmac(common, hw_key_idx, NULL);
    594	else
    595		ath_hw_keyreset(common, hw_key_idx);
    596	if (hw_key_idx < IEEE80211_WEP_NKID)
    597		return;
    598
    599	clear_bit(hw_key_idx, common->keymap);
    600	clear_bit(hw_key_idx, common->ccmp_keymap);
    601	if (!test_bit(hw_key_idx, common->tkip_keymap))
    602		return;
    603
    604	clear_bit(hw_key_idx + 64, common->keymap);
    605
    606	clear_bit(hw_key_idx, common->tkip_keymap);
    607	clear_bit(hw_key_idx + 64, common->tkip_keymap);
    608
    609	if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
    610		ath_hw_keyreset(common, hw_key_idx + 32);
    611		clear_bit(hw_key_idx + 32, common->keymap);
    612		clear_bit(hw_key_idx + 64 + 32, common->keymap);
    613
    614		clear_bit(hw_key_idx + 32, common->tkip_keymap);
    615		clear_bit(hw_key_idx + 64 + 32, common->tkip_keymap);
    616	}
    617}
    618EXPORT_SYMBOL(ath_key_delete);