/* TX key goes at first index, RX key at +32. */
memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); if (!ath_hw_set_keycache_entry(common, keyix, hk, NULL)) { /* TX MIC entry failed. No need to proceed further */
ath_err(common, "Setting TX MIC Key Failed\n"); return0;
}
staticint ath_reserve_key_cache_slot_tkip(struct ath_common *common)
{ int i;
for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { if (test_bit(i, common->keymap) ||
test_bit(i + 64, common->keymap)) continue; /* At least one part of TKIP key allocated */ if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) &&
(test_bit(i + 32, common->keymap) ||
test_bit(i + 64 + 32, common->keymap))) continue; /* At least one part of TKIP key allocated */
/* Found a free slot for a TKIP key */ return i;
} return -1;
}
staticint ath_reserve_key_cache_slot(struct ath_common *common,
u32 cipher)
{ int i;
if (cipher == WLAN_CIPHER_SUITE_TKIP) return ath_reserve_key_cache_slot_tkip(common);
/* First, try to find slots that would not be available for TKIP. */ if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { if (!test_bit(i, common->keymap) &&
(test_bit(i + 32, common->keymap) ||
test_bit(i + 64, common->keymap) ||
test_bit(i + 64 + 32, common->keymap))) return i; if (!test_bit(i + 32, common->keymap) &&
(test_bit(i, common->keymap) ||
test_bit(i + 64, common->keymap) ||
test_bit(i + 64 + 32, common->keymap))) return i + 32; if (!test_bit(i + 64, common->keymap) &&
(test_bit(i , common->keymap) ||
test_bit(i + 32, common->keymap) ||
test_bit(i + 64 + 32, common->keymap))) return i + 64; if (!test_bit(i + 64 + 32, common->keymap) &&
(test_bit(i, common->keymap) ||
test_bit(i + 32, common->keymap) ||
test_bit(i + 64, common->keymap))) return i + 64 + 32;
}
} else { for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { if (!test_bit(i, common->keymap) &&
test_bit(i + 64, common->keymap)) return i; if (test_bit(i, common->keymap) &&
!test_bit(i + 64, common->keymap)) return i + 64;
}
}
/* No partially used TKIP slots, pick any available slot */ for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) { /* Do not allow slots that could be needed for TKIP group keys *tobeused.Thislimitationcouldberemovedifweknowthat
* TKIP will not be used. */ if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) continue; if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) continue; if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) continue;
}
if (!test_bit(i, common->keymap)) return i; /* Found a free slot for a key */
}
/* No free slot found */ return -1;
}
/* *ConfigureencryptionintheHW.
*/ int ath_key_config(struct ath_common *common, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key)
{ struct ath_keyval hk; const u8 *mac = NULL;
u8 gmac[ETH_ALEN]; int ret = 0; int idx;
memset(&hk, 0, sizeof(hk));
switch (key->cipher) { case0:
hk.kv_type = ATH_CIPHER_CLR; break; case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104:
hk.kv_type = ATH_CIPHER_WEP; break; case WLAN_CIPHER_SUITE_TKIP:
hk.kv_type = ATH_CIPHER_TKIP; break; case WLAN_CIPHER_SUITE_CCMP:
hk.kv_type = ATH_CIPHER_AES_CCM; break; default: return -EOPNOTSUPP;
}
hk.kv_len = key->keylen; if (key->keylen)
memcpy(&hk.kv_values, key->key, key->keylen);
if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { switch (vif->type) { case NL80211_IFTYPE_AP:
memcpy(gmac, vif->addr, ETH_ALEN);
gmac[0] |= 0x01;
mac = gmac;
idx = ath_reserve_key_cache_slot(common, key->cipher); break; case NL80211_IFTYPE_ADHOC: if (!sta) {
idx = key->keyidx; break;
}
memcpy(gmac, sta->addr, ETH_ALEN);
gmac[0] |= 0x01;
mac = gmac;
idx = ath_reserve_key_cache_slot(common, key->cipher); break; default:
idx = key->keyidx; break;
}
} elseif (key->keyidx) { if (WARN_ON(!sta)) return -EOPNOTSUPP;
mac = sta->addr;
if (vif->type != NL80211_IFTYPE_AP) { /* Only keyidx 0 should be used with unicast key, but
* allow this for client mode for now. */
idx = key->keyidx;
} else return -EIO;
} else { if (WARN_ON(!sta)) return -EOPNOTSUPP;
mac = sta->addr;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.