Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ath/if_ath_keycache.c
| Show First 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | ath_keyset(struct ath_softc *sc, struct ieee80211vap *vap, | ||||
| struct ath_hal *ah = sc->sc_ah; | struct ath_hal *ah = sc->sc_ah; | ||||
| const struct ieee80211_cipher *cip = k->wk_cipher; | const struct ieee80211_cipher *cip = k->wk_cipher; | ||||
| u_int8_t gmac[IEEE80211_ADDR_LEN]; | u_int8_t gmac[IEEE80211_ADDR_LEN]; | ||||
| const u_int8_t *mac; | const u_int8_t *mac; | ||||
| HAL_KEYVAL hk; | HAL_KEYVAL hk; | ||||
| int ret; | int ret; | ||||
| memset(&hk, 0, sizeof(hk)); | memset(&hk, 0, sizeof(hk)); | ||||
| /* | /* | ||||
| * If it's a IGTK key then just plain ignore it; | |||||
| * it's already marked as handled in software and we don't | |||||
| * need a keycache entry for it. | |||||
| */ | |||||
| if (ieee80211_is_key_igtk(vap, k)) { | |||||
| return (1); | |||||
| } | |||||
| /* | |||||
| * Software crypto uses a "clear key" so non-crypto | * Software crypto uses a "clear key" so non-crypto | ||||
| * state kept in the key cache are maintained and | * state kept in the key cache are maintained and | ||||
| * so that rx frames have an entry to match. | * so that rx frames have an entry to match. | ||||
| */ | */ | ||||
| if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) { | if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) { | ||||
| KASSERT(cip->ic_cipher < nitems(ciphermap), | KASSERT(cip->ic_cipher < nitems(ciphermap), | ||||
| ("invalid cipher type %u", cip->ic_cipher)); | ("invalid cipher type %u", cip->ic_cipher)); | ||||
| hk.kv_type = ciphermap[cip->ic_cipher]; | hk.kv_type = ciphermap[cip->ic_cipher]; | ||||
| ▲ Show 20 Lines • Show All 213 Lines • ▼ Show 20 Lines | ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, | ||||
| * the h/w key index so lookups find the right key. On | * the h/w key index so lookups find the right key. On | ||||
| * parts w/ the key search facility we install the sender's | * parts w/ the key search facility we install the sender's | ||||
| * mac address (with the high bit set) and let the hardware | * mac address (with the high bit set) and let the hardware | ||||
| * find the key w/o using the key id. This is preferred as | * find the key w/o using the key id. This is preferred as | ||||
| * it permits us to support multiple users for adhoc and/or | * it permits us to support multiple users for adhoc and/or | ||||
| * multi-station operation. | * multi-station operation. | ||||
| */ | */ | ||||
| if (k->wk_keyix != IEEE80211_KEYIX_NONE) { | if (k->wk_keyix != IEEE80211_KEYIX_NONE) { | ||||
| /* | /* | ||||
| * Skip IGTK keys; they're global but not used | |||||
| * in the normal hardware keyix slots. | |||||
| */ | |||||
| if (ieee80211_is_key_igtk(vap, k)) { | |||||
| DPRINTF(sc, ATH_DEBUG_KEYCACHE, | |||||
| "%s: iGTK key; skipping\n", __func__); | |||||
| *keyix = *rxkeyix = | |||||
| ieee80211_crypto_get_key_igtk_idx(vap, k); | |||||
| return 1; | |||||
| } | |||||
| /* | |||||
| * Only global keys should have key index assigned. | * Only global keys should have key index assigned. | ||||
| */ | */ | ||||
| if (!ieee80211_is_key_global(vap, k)) { | if (!ieee80211_is_key_global(vap, k)) { | ||||
| /* should not happen */ | /* should not happen */ | ||||
| DPRINTF(sc, ATH_DEBUG_KEYCACHE, | DPRINTF(sc, ATH_DEBUG_KEYCACHE, | ||||
| "%s: bogus group key\n", __func__); | "%s: bogus group key\n", __func__); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| /* TODO: bogus BIP key */ | |||||
| if (vap->iv_opmode != IEEE80211_M_HOSTAP || | if (vap->iv_opmode != IEEE80211_M_HOSTAP || | ||||
| !(k->wk_flags & IEEE80211_KEY_GROUP) || | !(k->wk_flags & IEEE80211_KEY_GROUP) || | ||||
| !sc->sc_mcastkey) { | !sc->sc_mcastkey) { | ||||
| /* | /* | ||||
| * XXX we pre-allocate the global keys so | * XXX we pre-allocate the global keys so | ||||
| * have no way to check if they've already | * have no way to check if they've already | ||||
| * been allocated. | * been allocated. | ||||
| */ | */ | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | ath_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) | ||||
| ath_power_set_power_state(sc, HAL_PM_AWAKE); | ath_power_set_power_state(sc, HAL_PM_AWAKE); | ||||
| ath_hal_keyreset(ah, keyix); | ath_hal_keyreset(ah, keyix); | ||||
| /* | /* | ||||
| * Handle split tx/rx keying required for TKIP with h/w MIC. | * Handle split tx/rx keying required for TKIP with h/w MIC. | ||||
| */ | */ | ||||
| if (cip->ic_cipher == IEEE80211_CIPHER_TKIP && | if (cip->ic_cipher == IEEE80211_CIPHER_TKIP && | ||||
| (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && sc->sc_splitmic) | (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && sc->sc_splitmic) | ||||
| ath_hal_keyreset(ah, keyix+32); /* RX key */ | ath_hal_keyreset(ah, keyix+32); /* RX key */ | ||||
| if (keyix >= IEEE80211_WEP_NKID) { | |||||
| /* | |||||
| * Skip BIP keys; key indexes 4 and 5 are valid non-global | |||||
| * keycache entries | |||||
| */ | |||||
| if (ieee80211_is_key_igtk(vap, k)) { | |||||
| DPRINTF(sc, ATH_DEBUG_KEYCACHE, | |||||
| "%s: keyix=%d but igtk key; skipping\n", | |||||
| __func__, | |||||
| keyix); | |||||
| } else if (keyix >= IEEE80211_WEP_NKID) { | |||||
| /* | /* | ||||
| * Don't touch keymap entries for global keys so | * Don't touch keymap entries for global keys so | ||||
| * they are never considered for dynamic allocation. | * they are never considered for dynamic allocation. | ||||
| */ | */ | ||||
| clrbit(sc->sc_keymap, keyix); | clrbit(sc->sc_keymap, keyix); | ||||
| if (cip->ic_cipher == IEEE80211_CIPHER_TKIP && | if (cip->ic_cipher == IEEE80211_CIPHER_TKIP && | ||||
| (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) { | (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) { | ||||
| clrbit(sc->sc_keymap, keyix+64); /* TX key MIC */ | clrbit(sc->sc_keymap, keyix+64); /* TX key MIC */ | ||||
| Show All 23 Lines | |||||