Commit eed8e22f authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville

ath9k_common: use allocated key cache entries for multi BSS crypto support

This patch replaces the buggy 'ath9k: Group Key fix for VAPs' change.

For AP mode group keys, use the BSSID as lookup mac address, with
the multicast keysearch bit set.
For IBSS mode, use the peer's MAC address with multicast keysearch.
For STA mode, keep using the group key slots.
Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 1d0bb42d
...@@ -211,10 +211,14 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) ...@@ -211,10 +211,14 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
return -1; return -1;
} }
static int ath_reserve_key_cache_slot(struct ath_common *common) static int ath_reserve_key_cache_slot(struct ath_common *common,
enum ieee80211_key_alg alg)
{ {
int i; int i;
if (alg == ALG_TKIP)
return ath_reserve_key_cache_slot_tkip(common);
/* First, try to find slots that would not be available for TKIP. */ /* First, try to find slots that would not be available for TKIP. */
if (common->splitmic) { if (common->splitmic) {
for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
...@@ -283,6 +287,7 @@ int ath9k_cmn_key_config(struct ath_common *common, ...@@ -283,6 +287,7 @@ int ath9k_cmn_key_config(struct ath_common *common,
struct ath_hw *ah = common->ah; struct ath_hw *ah = common->ah;
struct ath9k_keyval hk; struct ath9k_keyval hk;
const u8 *mac = NULL; const u8 *mac = NULL;
u8 gmac[ETH_ALEN];
int ret = 0; int ret = 0;
int idx; int idx;
...@@ -306,9 +311,23 @@ int ath9k_cmn_key_config(struct ath_common *common, ...@@ -306,9 +311,23 @@ int ath9k_cmn_key_config(struct ath_common *common,
memcpy(hk.kv_val, key->key, key->keylen); memcpy(hk.kv_val, key->key, key->keylen);
if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
/* For now, use the default keys for broadcast keys. This may switch (vif->type) {
* need to change with virtual interfaces. */ case NL80211_IFTYPE_AP:
idx = key->keyidx; memcpy(gmac, vif->addr, ETH_ALEN);
gmac[0] |= 0x01;
mac = gmac;
idx = ath_reserve_key_cache_slot(common, key->alg);
break;
case NL80211_IFTYPE_ADHOC:
memcpy(gmac, sta->addr, ETH_ALEN);
gmac[0] |= 0x01;
mac = gmac;
idx = ath_reserve_key_cache_slot(common, key->alg);
break;
default:
idx = key->keyidx;
break;
}
} else if (key->keyidx) { } else if (key->keyidx) {
if (WARN_ON(!sta)) if (WARN_ON(!sta))
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -325,14 +344,12 @@ int ath9k_cmn_key_config(struct ath_common *common, ...@@ -325,14 +344,12 @@ int ath9k_cmn_key_config(struct ath_common *common,
return -EOPNOTSUPP; return -EOPNOTSUPP;
mac = sta->addr; mac = sta->addr;
if (key->alg == ALG_TKIP) idx = ath_reserve_key_cache_slot(common, key->alg);
idx = ath_reserve_key_cache_slot_tkip(common);
else
idx = ath_reserve_key_cache_slot(common);
if (idx < 0)
return -ENOSPC; /* no free key cache entries */
} }
if (idx < 0)
return -ENOSPC; /* no free key cache entries */
if (key->alg == ALG_TKIP) if (key->alg == ALG_TKIP)
ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
vif->type == NL80211_IFTYPE_AP); vif->type == NL80211_IFTYPE_AP);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment