/* * Set the contents of the specified key. * * Locking must be handled by the caller using: * ieee80211_key_update_begin(vap); * ieee80211_key_update_end(vap); */ int ieee80211_crypto_setkey(struct ieee80211vap *vap, struct ieee80211_key *key, const u_int8_t macaddr[IEEE80211_ADDR_LEN], struct ieee80211_node *ni) { const struct ieee80211_cipher *cip = key->wk_cipher; int ret; KASSERT(cip != NULL, ("No cipher!")); IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s: %s keyix %u flags 0x%x mac %s tsc %llu len %u\n", __func__, cip->ic_name, key->wk_keyix, key->wk_flags, ether_sprintf(macaddr), key->wk_keytsc, key->wk_keylen); /* * Give cipher a chance to validate key contents. * XXX should happen before modifying state. */ if (!cip->ic_setkey(key)) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s: cipher %s rejected key index %u len %u flags 0x%x\n", __func__, cip->ic_name, key->wk_keyix, key->wk_keylen, key->wk_flags); vap->iv_stats.is_crypto_setkey_cipher++; return 0; } if (key->wk_keyix == IEEE80211_KEYIX_NONE) { /* XXX nothing allocated, should not happen */ IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s: no key index; should not happen!\n", __func__); vap->iv_stats.is_crypto_setkey_nokey++; return 0; } ret = dev_key_set(vap, key, macaddr); #ifdef ATH_SUPERG_COMP if (ret && ni) { /* Enable decompression only receive key entries */ if (key->wk_flags & IEEE80211_KEY_RECV) { dev_comp_set(vap, ni, 1); } } #endif return ret; }
/* * Remove the specified key. */ int ieee80211_crypto_delkey(struct ieee80211vap *vap, struct ieee80211_key *key, struct ieee80211_node *ni) { int status; #ifdef ATH_SUPERG_COMP /* if valid node entry is present cleanup the compression state */ if (ni) dev_comp_set(vap, ni, 0); #endif ieee80211_key_update_begin(vap); status = _ieee80211_crypto_delkey(vap, key, ni); ieee80211_key_update_end(vap); return status; }