1219185Sadrian/*- 2219185Sadrian * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3219185Sadrian * All rights reserved. 4219185Sadrian * 5219185Sadrian * Redistribution and use in source and binary forms, with or without 6219185Sadrian * modification, are permitted provided that the following conditions 7219185Sadrian * are met: 8219185Sadrian * 1. Redistributions of source code must retain the above copyright 9219185Sadrian * notice, this list of conditions and the following disclaimer, 10219185Sadrian * without modification. 11219185Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12219185Sadrian * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13219185Sadrian * redistribution must be conditioned upon including a substantially 14219185Sadrian * similar Disclaimer requirement for further binary redistribution. 15219185Sadrian * 16219185Sadrian * NO WARRANTY 17219185Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18219185Sadrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19219185Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20219185Sadrian * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21219185Sadrian * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22219185Sadrian * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23219185Sadrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24219185Sadrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25219185Sadrian * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26219185Sadrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27219185Sadrian * THE POSSIBILITY OF SUCH DAMAGES. 28219185Sadrian */ 29219185Sadrian 30219185Sadrian#include <sys/cdefs.h> 31219185Sadrian__FBSDID("$FreeBSD: releng/10.3/sys/dev/ath/if_ath_keycache.c 243318 2012-11-19 23:54:05Z adrian $"); 32219185Sadrian 33219185Sadrian/* 34219185Sadrian * Driver for the Atheros Wireless LAN controller. 35219185Sadrian * 36219185Sadrian * This software is derived from work of Atsushi Onoe; his contribution 37219185Sadrian * is greatly appreciated. 38219185Sadrian */ 39219185Sadrian 40219185Sadrian#include "opt_inet.h" 41219185Sadrian#include "opt_ath.h" 42219185Sadrian#include "opt_wlan.h" 43219185Sadrian 44219185Sadrian#include <sys/param.h> 45219185Sadrian#include <sys/systm.h> 46219185Sadrian#include <sys/sysctl.h> 47219185Sadrian#include <sys/mbuf.h> 48219185Sadrian#include <sys/malloc.h> 49219185Sadrian#include <sys/lock.h> 50219185Sadrian#include <sys/mutex.h> 51219185Sadrian#include <sys/kernel.h> 52219185Sadrian#include <sys/socket.h> 53219185Sadrian#include <sys/sockio.h> 54219185Sadrian#include <sys/errno.h> 55219185Sadrian#include <sys/callout.h> 56219185Sadrian#include <sys/bus.h> 57219185Sadrian#include <sys/endian.h> 58219185Sadrian#include <sys/kthread.h> 59219185Sadrian#include <sys/taskqueue.h> 60219185Sadrian#include <sys/priv.h> 61219185Sadrian 62219185Sadrian#include <machine/bus.h> 63219185Sadrian 64219185Sadrian#include <net/if.h> 65219185Sadrian#include <net/if_dl.h> 66219185Sadrian#include <net/if_media.h> 67219185Sadrian#include <net/if_types.h> 68219185Sadrian#include <net/if_arp.h> 69219185Sadrian#include <net/ethernet.h> 70219185Sadrian#include <net/if_llc.h> 71219185Sadrian 72219185Sadrian#include <net80211/ieee80211_var.h> 73219185Sadrian 74219185Sadrian#include <net/bpf.h> 75219185Sadrian 76219185Sadrian#include <dev/ath/if_athvar.h> 77219185Sadrian 78219185Sadrian#include <dev/ath/if_ath_debug.h> 79219185Sadrian#include <dev/ath/if_ath_keycache.h> 80219185Sadrian 81219185Sadrian#ifdef ATH_DEBUG 82219185Sadrianstatic void 83219185Sadrianath_keyprint(struct ath_softc *sc, const char *tag, u_int ix, 84219185Sadrian const HAL_KEYVAL *hk, const u_int8_t mac[IEEE80211_ADDR_LEN]) 85219185Sadrian{ 86219185Sadrian static const char *ciphers[] = { 87219185Sadrian "WEP", 88219185Sadrian "AES-OCB", 89219185Sadrian "AES-CCM", 90219185Sadrian "CKIP", 91219185Sadrian "TKIP", 92219185Sadrian "CLR", 93219185Sadrian }; 94219185Sadrian int i, n; 95219185Sadrian 96219185Sadrian printf("%s: [%02u] %-7s ", tag, ix, ciphers[hk->kv_type]); 97219185Sadrian for (i = 0, n = hk->kv_len; i < n; i++) 98219185Sadrian printf("%02x", hk->kv_val[i]); 99219185Sadrian printf(" mac %s", ether_sprintf(mac)); 100219185Sadrian if (hk->kv_type == HAL_CIPHER_TKIP) { 101219185Sadrian printf(" %s ", sc->sc_splitmic ? "mic" : "rxmic"); 102219185Sadrian for (i = 0; i < sizeof(hk->kv_mic); i++) 103219185Sadrian printf("%02x", hk->kv_mic[i]); 104219185Sadrian if (!sc->sc_splitmic) { 105219185Sadrian printf(" txmic "); 106219185Sadrian for (i = 0; i < sizeof(hk->kv_txmic); i++) 107219185Sadrian printf("%02x", hk->kv_txmic[i]); 108219185Sadrian } 109219185Sadrian } 110219185Sadrian printf("\n"); 111219185Sadrian} 112219185Sadrian#endif 113219185Sadrian 114219185Sadrian/* 115219185Sadrian * Set a TKIP key into the hardware. This handles the 116219185Sadrian * potential distribution of key state to multiple key 117219185Sadrian * cache slots for TKIP. 118219185Sadrian */ 119219185Sadrianstatic int 120219185Sadrianath_keyset_tkip(struct ath_softc *sc, const struct ieee80211_key *k, 121219185Sadrian HAL_KEYVAL *hk, const u_int8_t mac[IEEE80211_ADDR_LEN]) 122219185Sadrian{ 123219185Sadrian#define IEEE80211_KEY_XR (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV) 124219185Sadrian static const u_int8_t zerobssid[IEEE80211_ADDR_LEN]; 125219185Sadrian struct ath_hal *ah = sc->sc_ah; 126219185Sadrian 127219185Sadrian KASSERT(k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP, 128219185Sadrian ("got a non-TKIP key, cipher %u", k->wk_cipher->ic_cipher)); 129219185Sadrian if ((k->wk_flags & IEEE80211_KEY_XR) == IEEE80211_KEY_XR) { 130219185Sadrian if (sc->sc_splitmic) { 131219185Sadrian /* 132219185Sadrian * TX key goes at first index, RX key at the rx index. 133219185Sadrian * The hal handles the MIC keys at index+64. 134219185Sadrian */ 135219185Sadrian memcpy(hk->kv_mic, k->wk_txmic, sizeof(hk->kv_mic)); 136219185Sadrian KEYPRINTF(sc, k->wk_keyix, hk, zerobssid); 137219185Sadrian if (!ath_hal_keyset(ah, k->wk_keyix, hk, zerobssid)) 138219185Sadrian return 0; 139219185Sadrian 140219185Sadrian memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic)); 141219185Sadrian KEYPRINTF(sc, k->wk_keyix+32, hk, mac); 142219185Sadrian /* XXX delete tx key on failure? */ 143219185Sadrian return ath_hal_keyset(ah, k->wk_keyix+32, hk, mac); 144219185Sadrian } else { 145219185Sadrian /* 146219185Sadrian * Room for both TX+RX MIC keys in one key cache 147219185Sadrian * slot, just set key at the first index; the hal 148219185Sadrian * will handle the rest. 149219185Sadrian */ 150219185Sadrian memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic)); 151219185Sadrian memcpy(hk->kv_txmic, k->wk_txmic, sizeof(hk->kv_txmic)); 152219185Sadrian KEYPRINTF(sc, k->wk_keyix, hk, mac); 153219185Sadrian return ath_hal_keyset(ah, k->wk_keyix, hk, mac); 154219185Sadrian } 155219185Sadrian } else if (k->wk_flags & IEEE80211_KEY_XMIT) { 156219185Sadrian if (sc->sc_splitmic) { 157219185Sadrian /* 158219185Sadrian * NB: must pass MIC key in expected location when 159219185Sadrian * the keycache only holds one MIC key per entry. 160219185Sadrian */ 161219185Sadrian memcpy(hk->kv_mic, k->wk_txmic, sizeof(hk->kv_txmic)); 162219185Sadrian } else 163219185Sadrian memcpy(hk->kv_txmic, k->wk_txmic, sizeof(hk->kv_txmic)); 164219185Sadrian KEYPRINTF(sc, k->wk_keyix, hk, mac); 165219185Sadrian return ath_hal_keyset(ah, k->wk_keyix, hk, mac); 166219185Sadrian } else if (k->wk_flags & IEEE80211_KEY_RECV) { 167219185Sadrian memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic)); 168219185Sadrian KEYPRINTF(sc, k->wk_keyix, hk, mac); 169219185Sadrian return ath_hal_keyset(ah, k->wk_keyix, hk, mac); 170219185Sadrian } 171219185Sadrian return 0; 172219185Sadrian#undef IEEE80211_KEY_XR 173219185Sadrian} 174219185Sadrian 175219185Sadrian/* 176219185Sadrian * Set a net80211 key into the hardware. This handles the 177219185Sadrian * potential distribution of key state to multiple key 178219185Sadrian * cache slots for TKIP with hardware MIC support. 179219185Sadrian */ 180219185Sadrianint 181227357Sadrianath_keyset(struct ath_softc *sc, struct ieee80211vap *vap, 182227357Sadrian const struct ieee80211_key *k, 183219185Sadrian struct ieee80211_node *bss) 184219185Sadrian{ 185219185Sadrian#define N(a) (sizeof(a)/sizeof(a[0])) 186219185Sadrian static const u_int8_t ciphermap[] = { 187219185Sadrian HAL_CIPHER_WEP, /* IEEE80211_CIPHER_WEP */ 188219185Sadrian HAL_CIPHER_TKIP, /* IEEE80211_CIPHER_TKIP */ 189219185Sadrian HAL_CIPHER_AES_OCB, /* IEEE80211_CIPHER_AES_OCB */ 190219185Sadrian HAL_CIPHER_AES_CCM, /* IEEE80211_CIPHER_AES_CCM */ 191219185Sadrian (u_int8_t) -1, /* 4 is not allocated */ 192219185Sadrian HAL_CIPHER_CKIP, /* IEEE80211_CIPHER_CKIP */ 193219185Sadrian HAL_CIPHER_CLR, /* IEEE80211_CIPHER_NONE */ 194219185Sadrian }; 195219185Sadrian struct ath_hal *ah = sc->sc_ah; 196219185Sadrian const struct ieee80211_cipher *cip = k->wk_cipher; 197219185Sadrian u_int8_t gmac[IEEE80211_ADDR_LEN]; 198219185Sadrian const u_int8_t *mac; 199219185Sadrian HAL_KEYVAL hk; 200219185Sadrian 201219185Sadrian memset(&hk, 0, sizeof(hk)); 202219185Sadrian /* 203219185Sadrian * Software crypto uses a "clear key" so non-crypto 204219185Sadrian * state kept in the key cache are maintained and 205219185Sadrian * so that rx frames have an entry to match. 206219185Sadrian */ 207219185Sadrian if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) { 208219185Sadrian KASSERT(cip->ic_cipher < N(ciphermap), 209219185Sadrian ("invalid cipher type %u", cip->ic_cipher)); 210219185Sadrian hk.kv_type = ciphermap[cip->ic_cipher]; 211219185Sadrian hk.kv_len = k->wk_keylen; 212219185Sadrian memcpy(hk.kv_val, k->wk_key, k->wk_keylen); 213219185Sadrian } else 214219185Sadrian hk.kv_type = HAL_CIPHER_CLR; 215219185Sadrian 216227357Sadrian /* 217243318Sadrian * If we're installing a clear cipher key and 218243318Sadrian * the hardware doesn't support that, just succeed. 219243318Sadrian * Leave it up to the net80211 layer to figure it out. 220243318Sadrian */ 221243318Sadrian if (hk.kv_type == HAL_CIPHER_CLR && sc->sc_hasclrkey == 0) { 222243318Sadrian return (1); 223243318Sadrian } 224243318Sadrian 225243318Sadrian /* 226227357Sadrian * XXX TODO: check this: 227227357Sadrian * 228227357Sadrian * Group keys on hardware that supports multicast frame 229227357Sadrian * key search should only be done in adhoc/hostap mode, 230227357Sadrian * not STA mode. 231227357Sadrian * 232227357Sadrian * XXX TODO: what about mesh, tdma? 233227357Sadrian */ 234227357Sadrian#if 0 235227357Sadrian if ((vap->iv_opmode == IEEE80211_M_HOSTAP || 236227357Sadrian vap->iv_opmode == IEEE80211_M_IBSS) && 237227357Sadrian#else 238227357Sadrian if ( 239227357Sadrian#endif 240227357Sadrian (k->wk_flags & IEEE80211_KEY_GROUP) && 241227357Sadrian sc->sc_mcastkey) { 242219185Sadrian /* 243219185Sadrian * Group keys on hardware that supports multicast frame 244219185Sadrian * key search use a MAC that is the sender's address with 245219185Sadrian * the multicast bit set instead of the app-specified address. 246219185Sadrian */ 247219185Sadrian IEEE80211_ADDR_COPY(gmac, bss->ni_macaddr); 248219185Sadrian gmac[0] |= 0x01; 249219185Sadrian mac = gmac; 250219185Sadrian } else 251219185Sadrian mac = k->wk_macaddr; 252219185Sadrian 253219185Sadrian if (hk.kv_type == HAL_CIPHER_TKIP && 254219185Sadrian (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) { 255219185Sadrian return ath_keyset_tkip(sc, k, &hk, mac); 256219185Sadrian } else { 257219185Sadrian KEYPRINTF(sc, k->wk_keyix, &hk, mac); 258219185Sadrian return ath_hal_keyset(ah, k->wk_keyix, &hk, mac); 259219185Sadrian } 260219185Sadrian#undef N 261219185Sadrian} 262219185Sadrian 263219185Sadrian/* 264219185Sadrian * Allocate tx/rx key slots for TKIP. We allocate two slots for 265219185Sadrian * each key, one for decrypt/encrypt and the other for the MIC. 266219185Sadrian */ 267219185Sadrianstatic u_int16_t 268219185Sadriankey_alloc_2pair(struct ath_softc *sc, 269219185Sadrian ieee80211_keyix *txkeyix, ieee80211_keyix *rxkeyix) 270219185Sadrian{ 271219185Sadrian#define N(a) (sizeof(a)/sizeof(a[0])) 272219185Sadrian u_int i, keyix; 273219185Sadrian 274219185Sadrian KASSERT(sc->sc_splitmic, ("key cache !split")); 275219185Sadrian /* XXX could optimize */ 276219185Sadrian for (i = 0; i < N(sc->sc_keymap)/4; i++) { 277219185Sadrian u_int8_t b = sc->sc_keymap[i]; 278219185Sadrian if (b != 0xff) { 279219185Sadrian /* 280219185Sadrian * One or more slots in this byte are free. 281219185Sadrian */ 282219185Sadrian keyix = i*NBBY; 283219185Sadrian while (b & 1) { 284219185Sadrian again: 285219185Sadrian keyix++; 286219185Sadrian b >>= 1; 287219185Sadrian } 288219185Sadrian /* XXX IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV */ 289219185Sadrian if (isset(sc->sc_keymap, keyix+32) || 290219185Sadrian isset(sc->sc_keymap, keyix+64) || 291219185Sadrian isset(sc->sc_keymap, keyix+32+64)) { 292219185Sadrian /* full pair unavailable */ 293219185Sadrian /* XXX statistic */ 294219185Sadrian if (keyix == (i+1)*NBBY) { 295219185Sadrian /* no slots were appropriate, advance */ 296219185Sadrian continue; 297219185Sadrian } 298219185Sadrian goto again; 299219185Sadrian } 300219185Sadrian setbit(sc->sc_keymap, keyix); 301219185Sadrian setbit(sc->sc_keymap, keyix+64); 302219185Sadrian setbit(sc->sc_keymap, keyix+32); 303219185Sadrian setbit(sc->sc_keymap, keyix+32+64); 304219185Sadrian DPRINTF(sc, ATH_DEBUG_KEYCACHE, 305219185Sadrian "%s: key pair %u,%u %u,%u\n", 306219185Sadrian __func__, keyix, keyix+64, 307219185Sadrian keyix+32, keyix+32+64); 308219185Sadrian *txkeyix = keyix; 309219185Sadrian *rxkeyix = keyix+32; 310219185Sadrian return 1; 311219185Sadrian } 312219185Sadrian } 313219185Sadrian DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: out of pair space\n", __func__); 314219185Sadrian return 0; 315219185Sadrian#undef N 316219185Sadrian} 317219185Sadrian 318219185Sadrian/* 319219185Sadrian * Allocate tx/rx key slots for TKIP. We allocate two slots for 320219185Sadrian * each key, one for decrypt/encrypt and the other for the MIC. 321219185Sadrian */ 322219185Sadrianstatic u_int16_t 323219185Sadriankey_alloc_pair(struct ath_softc *sc, 324219185Sadrian ieee80211_keyix *txkeyix, ieee80211_keyix *rxkeyix) 325219185Sadrian{ 326219185Sadrian#define N(a) (sizeof(a)/sizeof(a[0])) 327219185Sadrian u_int i, keyix; 328219185Sadrian 329219185Sadrian KASSERT(!sc->sc_splitmic, ("key cache split")); 330219185Sadrian /* XXX could optimize */ 331219185Sadrian for (i = 0; i < N(sc->sc_keymap)/4; i++) { 332219185Sadrian u_int8_t b = sc->sc_keymap[i]; 333219185Sadrian if (b != 0xff) { 334219185Sadrian /* 335219185Sadrian * One or more slots in this byte are free. 336219185Sadrian */ 337219185Sadrian keyix = i*NBBY; 338219185Sadrian while (b & 1) { 339219185Sadrian again: 340219185Sadrian keyix++; 341219185Sadrian b >>= 1; 342219185Sadrian } 343219185Sadrian if (isset(sc->sc_keymap, keyix+64)) { 344219185Sadrian /* full pair unavailable */ 345219185Sadrian /* XXX statistic */ 346219185Sadrian if (keyix == (i+1)*NBBY) { 347219185Sadrian /* no slots were appropriate, advance */ 348219185Sadrian continue; 349219185Sadrian } 350219185Sadrian goto again; 351219185Sadrian } 352219185Sadrian setbit(sc->sc_keymap, keyix); 353219185Sadrian setbit(sc->sc_keymap, keyix+64); 354219185Sadrian DPRINTF(sc, ATH_DEBUG_KEYCACHE, 355219185Sadrian "%s: key pair %u,%u\n", 356219185Sadrian __func__, keyix, keyix+64); 357219185Sadrian *txkeyix = *rxkeyix = keyix; 358219185Sadrian return 1; 359219185Sadrian } 360219185Sadrian } 361219185Sadrian DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: out of pair space\n", __func__); 362219185Sadrian return 0; 363219185Sadrian#undef N 364219185Sadrian} 365219185Sadrian 366219185Sadrian/* 367219185Sadrian * Allocate a single key cache slot. 368219185Sadrian */ 369219185Sadrianstatic int 370219185Sadriankey_alloc_single(struct ath_softc *sc, 371219185Sadrian ieee80211_keyix *txkeyix, ieee80211_keyix *rxkeyix) 372219185Sadrian{ 373219185Sadrian#define N(a) (sizeof(a)/sizeof(a[0])) 374219185Sadrian u_int i, keyix; 375219185Sadrian 376243318Sadrian if (sc->sc_hasclrkey == 0) { 377243318Sadrian /* 378243318Sadrian * Map to slot 0 for the AR5210. 379243318Sadrian */ 380243318Sadrian *txkeyix = *rxkeyix = 0; 381243318Sadrian return (1); 382243318Sadrian } 383243318Sadrian 384219185Sadrian /* XXX try i,i+32,i+64,i+32+64 to minimize key pair conflicts */ 385219185Sadrian for (i = 0; i < N(sc->sc_keymap); i++) { 386219185Sadrian u_int8_t b = sc->sc_keymap[i]; 387219185Sadrian if (b != 0xff) { 388219185Sadrian /* 389219185Sadrian * One or more slots are free. 390219185Sadrian */ 391219185Sadrian keyix = i*NBBY; 392219185Sadrian while (b & 1) 393219185Sadrian keyix++, b >>= 1; 394219185Sadrian setbit(sc->sc_keymap, keyix); 395219185Sadrian DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: key %u\n", 396219185Sadrian __func__, keyix); 397219185Sadrian *txkeyix = *rxkeyix = keyix; 398219185Sadrian return 1; 399219185Sadrian } 400219185Sadrian } 401219185Sadrian DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: out of space\n", __func__); 402219185Sadrian return 0; 403219185Sadrian#undef N 404219185Sadrian} 405219185Sadrian 406219185Sadrian/* 407219185Sadrian * Allocate one or more key cache slots for a uniacst key. The 408219185Sadrian * key itself is needed only to identify the cipher. For hardware 409219185Sadrian * TKIP with split cipher+MIC keys we allocate two key cache slot 410219185Sadrian * pairs so that we can setup separate TX and RX MIC keys. Note 411219185Sadrian * that the MIC key for a TKIP key at slot i is assumed by the 412219185Sadrian * hardware to be at slot i+64. This limits TKIP keys to the first 413219185Sadrian * 64 entries. 414219185Sadrian */ 415219185Sadrianint 416219185Sadrianath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, 417219185Sadrian ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) 418219185Sadrian{ 419219185Sadrian struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; 420219185Sadrian 421219185Sadrian /* 422219185Sadrian * Group key allocation must be handled specially for 423219185Sadrian * parts that do not support multicast key cache search 424219185Sadrian * functionality. For those parts the key id must match 425219185Sadrian * the h/w key index so lookups find the right key. On 426219185Sadrian * parts w/ the key search facility we install the sender's 427219185Sadrian * mac address (with the high bit set) and let the hardware 428219185Sadrian * find the key w/o using the key id. This is preferred as 429219185Sadrian * it permits us to support multiple users for adhoc and/or 430219185Sadrian * multi-station operation. 431219185Sadrian */ 432219185Sadrian if (k->wk_keyix != IEEE80211_KEYIX_NONE) { 433219185Sadrian /* 434219185Sadrian * Only global keys should have key index assigned. 435219185Sadrian */ 436219185Sadrian if (!(&vap->iv_nw_keys[0] <= k && 437219185Sadrian k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) { 438219185Sadrian /* should not happen */ 439219185Sadrian DPRINTF(sc, ATH_DEBUG_KEYCACHE, 440219185Sadrian "%s: bogus group key\n", __func__); 441219185Sadrian return 0; 442219185Sadrian } 443219185Sadrian if (vap->iv_opmode != IEEE80211_M_HOSTAP || 444219185Sadrian !(k->wk_flags & IEEE80211_KEY_GROUP) || 445219185Sadrian !sc->sc_mcastkey) { 446219185Sadrian /* 447219185Sadrian * XXX we pre-allocate the global keys so 448219185Sadrian * have no way to check if they've already 449219185Sadrian * been allocated. 450219185Sadrian */ 451219185Sadrian *keyix = *rxkeyix = k - vap->iv_nw_keys; 452219185Sadrian return 1; 453219185Sadrian } 454219185Sadrian /* 455219185Sadrian * Group key and device supports multicast key search. 456219185Sadrian */ 457219185Sadrian k->wk_keyix = IEEE80211_KEYIX_NONE; 458219185Sadrian } 459219185Sadrian 460219185Sadrian /* 461219185Sadrian * We allocate two pair for TKIP when using the h/w to do 462219185Sadrian * the MIC. For everything else, including software crypto, 463219185Sadrian * we allocate a single entry. Note that s/w crypto requires 464219185Sadrian * a pass-through slot on the 5211 and 5212. The 5210 does 465219185Sadrian * not support pass-through cache entries and we map all 466219185Sadrian * those requests to slot 0. 467219185Sadrian */ 468219185Sadrian if (k->wk_flags & IEEE80211_KEY_SWCRYPT) { 469219185Sadrian return key_alloc_single(sc, keyix, rxkeyix); 470219185Sadrian } else if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP && 471219185Sadrian (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) { 472219185Sadrian if (sc->sc_splitmic) 473219185Sadrian return key_alloc_2pair(sc, keyix, rxkeyix); 474219185Sadrian else 475219185Sadrian return key_alloc_pair(sc, keyix, rxkeyix); 476219185Sadrian } else { 477219185Sadrian return key_alloc_single(sc, keyix, rxkeyix); 478219185Sadrian } 479219185Sadrian} 480219185Sadrian 481219185Sadrian/* 482219185Sadrian * Delete an entry in the key cache allocated by ath_key_alloc. 483219185Sadrian */ 484219185Sadrianint 485219185Sadrianath_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) 486219185Sadrian{ 487219185Sadrian struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; 488219185Sadrian struct ath_hal *ah = sc->sc_ah; 489219185Sadrian const struct ieee80211_cipher *cip = k->wk_cipher; 490219185Sadrian u_int keyix = k->wk_keyix; 491219185Sadrian 492219185Sadrian DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: delete key %u\n", __func__, keyix); 493219185Sadrian 494219185Sadrian ath_hal_keyreset(ah, keyix); 495219185Sadrian /* 496219185Sadrian * Handle split tx/rx keying required for TKIP with h/w MIC. 497219185Sadrian */ 498219185Sadrian if (cip->ic_cipher == IEEE80211_CIPHER_TKIP && 499219185Sadrian (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && sc->sc_splitmic) 500219185Sadrian ath_hal_keyreset(ah, keyix+32); /* RX key */ 501219185Sadrian if (keyix >= IEEE80211_WEP_NKID) { 502219185Sadrian /* 503219185Sadrian * Don't touch keymap entries for global keys so 504219185Sadrian * they are never considered for dynamic allocation. 505219185Sadrian */ 506219185Sadrian clrbit(sc->sc_keymap, keyix); 507219185Sadrian if (cip->ic_cipher == IEEE80211_CIPHER_TKIP && 508219185Sadrian (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) { 509219185Sadrian clrbit(sc->sc_keymap, keyix+64); /* TX key MIC */ 510219185Sadrian if (sc->sc_splitmic) { 511219185Sadrian /* +32 for RX key, +32+64 for RX key MIC */ 512219185Sadrian clrbit(sc->sc_keymap, keyix+32); 513219185Sadrian clrbit(sc->sc_keymap, keyix+32+64); 514219185Sadrian } 515219185Sadrian } 516219185Sadrian } 517219185Sadrian return 1; 518219185Sadrian} 519219185Sadrian 520219185Sadrian/* 521219185Sadrian * Set the key cache contents for the specified key. Key cache 522219185Sadrian * slot(s) must already have been allocated by ath_key_alloc. 523219185Sadrian */ 524219185Sadrianint 525219185Sadrianath_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, 526219185Sadrian const u_int8_t mac[IEEE80211_ADDR_LEN]) 527219185Sadrian{ 528219185Sadrian struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; 529219185Sadrian 530227357Sadrian return ath_keyset(sc, vap, k, vap->iv_bss); 531219185Sadrian} 532