summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-02-26 11:18:46 +0200
committerJohn W. Linville <linville@tuxdriver.com>2009-03-05 14:39:31 -0500
commit3f53dd64f192450cb331c0fecfc26ca952fb242f (patch)
tree6659f9fe8abf6514d07ed70a9018207080daf74a
parent998a5a7d6aabe7e450759e0d82c8a79afd5a97ff (diff)
ath9k: Fix hw crypto configuration for TKIP in AP mode
Incorrect Michael MIC key (RX, should have been TX) was set for the group key in AP mode. This resulted in all broadcast frames triggering Michael MIC errors and eventual TKIP countermeasures. The change here sets the correct Michael MIC key based on whether the local end is the authenticator (well, AP for now). Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Tested-by: Pat Erley <pat-lkml@erley.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath9k/main.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 659ed07f28e..fd6cc7348a4 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -648,8 +648,8 @@ static int ath_keyset(struct ath_softc *sc, u16 keyix,
}
static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
- struct ath9k_keyval *hk,
- const u8 *addr)
+ struct ath9k_keyval *hk, const u8 *addr,
+ bool authenticator)
{
const u8 *key_rxmic;
const u8 *key_txmic;
@@ -659,7 +659,13 @@ static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
if (addr == NULL) {
/* Group key installation */
- memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+ if (authenticator) {
+ memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
+ memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
+ } else {
+ memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+ memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
+ }
return ath_keyset(sc, keyix, hk, addr);
}
if (!sc->splitmic) {
@@ -769,6 +775,7 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc)
}
static int ath_key_config(struct ath_softc *sc,
+ struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
@@ -828,7 +835,8 @@ static int ath_key_config(struct ath_softc *sc,
}
if (key->alg == ALG_TKIP)
- ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac);
+ ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac,
+ vif->type == NL80211_IFTYPE_AP);
else
ret = ath_keyset(sc, idx, &hk, mac);
@@ -2481,7 +2489,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
switch (cmd) {
case SET_KEY:
- ret = ath_key_config(sc, sta, key);
+ ret = ath_key_config(sc, vif, sta, key);
if (ret >= 0) {
key->hw_key_idx = ret;
/* push IV and Michael MIC generation to stack */