1 1.1 alc /* 2 1.1 alc * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3 1.1 alc * Copyright (c) 2002-2008 Atheros Communications, Inc. 4 1.1 alc * 5 1.1 alc * Permission to use, copy, modify, and/or distribute this software for any 6 1.1 alc * purpose with or without fee is hereby granted, provided that the above 7 1.1 alc * copyright notice and this permission notice appear in all copies. 8 1.1 alc * 9 1.1 alc * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 1.1 alc * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 1.1 alc * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 1.1 alc * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 1.1 alc * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 1.1 alc * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 1.1 alc * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 1.1 alc * 17 1.1 alc * $Id: ar5212_keycache.c,v 1.1.1.1 2008/12/11 04:46:40 alc Exp $ 18 1.1 alc */ 19 1.1 alc #include "opt_ah.h" 20 1.1 alc 21 1.1 alc #include "ah.h" 22 1.1 alc #include "ah_internal.h" 23 1.1 alc 24 1.1 alc #include "ar5212/ar5212.h" 25 1.1 alc #include "ar5212/ar5212reg.h" 26 1.1 alc #include "ar5212/ar5212desc.h" 27 1.1 alc 28 1.1 alc /* 29 1.1 alc * Note: The key cache hardware requires that each double-word 30 1.1 alc * pair be written in even/odd order (since the destination is 31 1.1 alc * a 64-bit register). Don't reorder the writes in this code 32 1.1 alc * w/o considering this! 33 1.1 alc */ 34 1.1 alc #define KEY_XOR 0xaa 35 1.1 alc 36 1.1 alc #define IS_MIC_ENABLED(ah) \ 37 1.1 alc (AH5212(ah)->ah_staId1Defaults & AR_STA_ID1_CRPT_MIC_ENABLE) 38 1.1 alc 39 1.1 alc /* 40 1.1 alc * Return the size of the hardware key cache. 41 1.1 alc */ 42 1.1 alc uint32_t 43 1.1 alc ar5212GetKeyCacheSize(struct ath_hal *ah) 44 1.1 alc { 45 1.1 alc return AH_PRIVATE(ah)->ah_caps.halKeyCacheSize; 46 1.1 alc } 47 1.1 alc 48 1.1 alc /* 49 1.1 alc * Return true if the specific key cache entry is valid. 50 1.1 alc */ 51 1.1 alc HAL_BOOL 52 1.1 alc ar5212IsKeyCacheEntryValid(struct ath_hal *ah, uint16_t entry) 53 1.1 alc { 54 1.1 alc if (entry < AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) { 55 1.1 alc uint32_t val = OS_REG_READ(ah, AR_KEYTABLE_MAC1(entry)); 56 1.1 alc if (val & AR_KEYTABLE_VALID) 57 1.1 alc return AH_TRUE; 58 1.1 alc } 59 1.1 alc return AH_FALSE; 60 1.1 alc } 61 1.1 alc 62 1.1 alc /* 63 1.1 alc * Clear the specified key cache entry and any associated MIC entry. 64 1.1 alc */ 65 1.1 alc HAL_BOOL 66 1.1 alc ar5212ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry) 67 1.1 alc { 68 1.1 alc uint32_t keyType; 69 1.1 alc 70 1.1 alc if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) { 71 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: entry %u out of range\n", 72 1.1 alc __func__, entry); 73 1.1 alc return AH_FALSE; 74 1.1 alc } 75 1.1 alc keyType = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)); 76 1.1 alc 77 1.1 alc /* XXX why not clear key type/valid bit first? */ 78 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); 79 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); 80 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); 81 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); 82 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); 83 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); 84 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); 85 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); 86 1.1 alc if (keyType == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) { 87 1.1 alc uint16_t micentry = entry+64; /* MIC goes at slot+64 */ 88 1.1 alc 89 1.1 alc HALASSERT(micentry < AH_PRIVATE(ah)->ah_caps.halKeyCacheSize); 90 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); 91 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); 92 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); 93 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); 94 1.1 alc /* NB: key type and MAC are known to be ok */ 95 1.1 alc } 96 1.1 alc return AH_TRUE; 97 1.1 alc } 98 1.1 alc 99 1.1 alc /* 100 1.1 alc * Sets the mac part of the specified key cache entry (and any 101 1.1 alc * associated MIC entry) and mark them valid. 102 1.1 alc */ 103 1.1 alc HAL_BOOL 104 1.1 alc ar5212SetKeyCacheEntryMac(struct ath_hal *ah, uint16_t entry, const uint8_t *mac) 105 1.1 alc { 106 1.1 alc uint32_t macHi, macLo; 107 1.1 alc 108 1.1 alc if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) { 109 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: entry %u out of range\n", 110 1.1 alc __func__, entry); 111 1.1 alc return AH_FALSE; 112 1.1 alc } 113 1.1 alc /* 114 1.1 alc * Set MAC address -- shifted right by 1. MacLo is 115 1.1 alc * the 4 MSBs, and MacHi is the 2 LSBs. 116 1.1 alc */ 117 1.1 alc if (mac != AH_NULL) { 118 1.1 alc macHi = (mac[5] << 8) | mac[4]; 119 1.1 alc macLo = (mac[3] << 24)| (mac[2] << 16) 120 1.1 alc | (mac[1] << 8) | mac[0]; 121 1.1 alc macLo >>= 1; 122 1.1 alc macLo |= (macHi & 1) << 31; /* carry */ 123 1.1 alc macHi >>= 1; 124 1.1 alc } else { 125 1.1 alc macLo = macHi = 0; 126 1.1 alc } 127 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); 128 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID); 129 1.1 alc return AH_TRUE; 130 1.1 alc } 131 1.1 alc 132 1.1 alc /* 133 1.1 alc * Sets the contents of the specified key cache entry 134 1.1 alc * and any associated MIC entry. 135 1.1 alc */ 136 1.1 alc HAL_BOOL 137 1.1 alc ar5212SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry, 138 1.1 alc const HAL_KEYVAL *k, const uint8_t *mac, 139 1.1 alc int xorKey) 140 1.1 alc { 141 1.1 alc struct ath_hal_5212 *ahp = AH5212(ah); 142 1.1 alc const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; 143 1.1 alc uint32_t key0, key1, key2, key3, key4; 144 1.1 alc uint32_t keyType; 145 1.1 alc uint32_t xorMask = xorKey ? 146 1.1 alc (KEY_XOR << 24 | KEY_XOR << 16 | KEY_XOR << 8 | KEY_XOR) : 0; 147 1.1 alc 148 1.1 alc if (entry >= pCap->halKeyCacheSize) { 149 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: entry %u out of range\n", 150 1.1 alc __func__, entry); 151 1.1 alc return AH_FALSE; 152 1.1 alc } 153 1.1 alc switch (k->kv_type) { 154 1.1 alc case HAL_CIPHER_AES_OCB: 155 1.1 alc keyType = AR_KEYTABLE_TYPE_AES; 156 1.1 alc break; 157 1.1 alc case HAL_CIPHER_AES_CCM: 158 1.1 alc if (!pCap->halCipherAesCcmSupport) { 159 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 160 1.1 alc "%s: AES-CCM not supported by mac rev 0x%x\n", 161 1.1 alc __func__, AH_PRIVATE(ah)->ah_macRev); 162 1.1 alc return AH_FALSE; 163 1.1 alc } 164 1.1 alc keyType = AR_KEYTABLE_TYPE_CCM; 165 1.1 alc break; 166 1.1 alc case HAL_CIPHER_TKIP: 167 1.1 alc keyType = AR_KEYTABLE_TYPE_TKIP; 168 1.1 alc if (IS_MIC_ENABLED(ah) && entry+64 >= pCap->halKeyCacheSize) { 169 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 170 1.1 alc "%s: entry %u inappropriate for TKIP\n", 171 1.1 alc __func__, entry); 172 1.1 alc return AH_FALSE; 173 1.1 alc } 174 1.1 alc break; 175 1.1 alc case HAL_CIPHER_WEP: 176 1.1 alc if (k->kv_len < 40 / NBBY) { 177 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 178 1.1 alc "%s: WEP key length %u too small\n", 179 1.1 alc __func__, k->kv_len); 180 1.1 alc return AH_FALSE; 181 1.1 alc } 182 1.1 alc if (k->kv_len <= 40 / NBBY) 183 1.1 alc keyType = AR_KEYTABLE_TYPE_40; 184 1.1 alc else if (k->kv_len <= 104 / NBBY) 185 1.1 alc keyType = AR_KEYTABLE_TYPE_104; 186 1.1 alc else 187 1.1 alc keyType = AR_KEYTABLE_TYPE_128; 188 1.1 alc break; 189 1.1 alc case HAL_CIPHER_CLR: 190 1.1 alc keyType = AR_KEYTABLE_TYPE_CLR; 191 1.1 alc break; 192 1.1 alc default: 193 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: cipher %u not supported\n", 194 1.1 alc __func__, k->kv_type); 195 1.1 alc return AH_FALSE; 196 1.1 alc } 197 1.1 alc 198 1.1 alc key0 = LE_READ_4(k->kv_val+0) ^ xorMask; 199 1.1 alc key1 = (LE_READ_2(k->kv_val+4) ^ xorMask) & 0xffff; 200 1.1 alc key2 = LE_READ_4(k->kv_val+6) ^ xorMask; 201 1.1 alc key3 = (LE_READ_2(k->kv_val+10) ^ xorMask) & 0xffff; 202 1.1 alc key4 = LE_READ_4(k->kv_val+12) ^ xorMask; 203 1.1 alc if (k->kv_len <= 104 / NBBY) 204 1.1 alc key4 &= 0xff; 205 1.1 alc 206 1.1 alc /* 207 1.1 alc * Note: key cache hardware requires that each double-word 208 1.1 alc * pair be written in even/odd order (since the destination is 209 1.1 alc * a 64-bit register). Don't reorder these writes w/o 210 1.1 alc * considering this! 211 1.1 alc */ 212 1.1 alc if (keyType == AR_KEYTABLE_TYPE_TKIP && IS_MIC_ENABLED(ah)) { 213 1.1 alc uint16_t micentry = entry+64; /* MIC goes at slot+64 */ 214 1.1 alc uint32_t mic0, mic1, mic2, mic3, mic4; 215 1.1 alc 216 1.1 alc /* 217 1.1 alc * Invalidate the encrypt/decrypt key until the MIC 218 1.1 alc * key is installed so pending rx frames will fail 219 1.1 alc * with decrypt errors rather than a MIC error. 220 1.1 alc */ 221 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0); 222 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1); 223 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); 224 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); 225 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); 226 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); 227 1.1 alc (void) ar5212SetKeyCacheEntryMac(ah, entry, mac); 228 1.1 alc 229 1.1 alc 230 1.1 alc /* 231 1.1 alc * Write MIC entry according to new or old key layout. 232 1.1 alc * The MISC_MODE register is assumed already set so 233 1.1 alc * these writes will be handled properly (happens on 234 1.1 alc * attach and at every reset). 235 1.1 alc */ 236 1.1 alc /* RX mic */ 237 1.1 alc mic0 = LE_READ_4(k->kv_mic+0); 238 1.1 alc mic2 = LE_READ_4(k->kv_mic+4); 239 1.1 alc if (ahp->ah_miscMode & AR_MISC_MODE_MIC_NEW_LOC_ENABLE) { 240 1.1 alc /* 241 1.1 alc * Both RX and TX mic values can be combined into 242 1.1 alc * one cache slot entry: 243 1.1 alc * 8*N + 800 31:0 RX Michael key 0 244 1.1 alc * 8*N + 804 15:0 TX Michael key 0 [31:16] 245 1.1 alc * 8*N + 808 31:0 RX Michael key 1 246 1.1 alc * 8*N + 80C 15:0 TX Michael key 0 [15:0] 247 1.1 alc * 8*N + 810 31:0 TX Michael key 1 248 1.1 alc * 8*N + 814 15:0 reserved 249 1.1 alc * 8*N + 818 31:0 reserved 250 1.1 alc * 8*N + 81C 14:0 reserved 251 1.1 alc * 15 key valid == 0 252 1.1 alc */ 253 1.1 alc /* TX mic */ 254 1.1 alc mic1 = LE_READ_2(k->kv_txmic+2) & 0xffff; 255 1.1 alc mic3 = LE_READ_2(k->kv_txmic+0) & 0xffff; 256 1.1 alc mic4 = LE_READ_4(k->kv_txmic+4); 257 1.1 alc } else { 258 1.1 alc mic1 = mic3 = mic4 = 0; 259 1.1 alc } 260 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); 261 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); 262 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); 263 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3); 264 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4); 265 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), 266 1.1 alc AR_KEYTABLE_TYPE_CLR); 267 1.1 alc /* NB: MIC key is not marked valid and has no MAC address */ 268 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); 269 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); 270 1.1 alc 271 1.1 alc /* correct intentionally corrupted key */ 272 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); 273 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); 274 1.1 alc } else { 275 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); 276 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); 277 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); 278 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); 279 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); 280 1.1 alc OS_REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); 281 1.1 alc 282 1.1 alc (void) ar5212SetKeyCacheEntryMac(ah, entry, mac); 283 1.1 alc } 284 1.1 alc return AH_TRUE; 285 1.1 alc } 286