Commit 1ed3811c authored by Helmut Schaa's avatar Helmut Schaa Committed by John W. Linville

rt2x00: Fix rt2800 key assignment in multi bssid setups

When setting up multiple BSSIDs in AP mode on an rt2800pci device we
previously used the STAs AID to select an appropriate key slot. But
since the AID is per VIF we can end up with two STAs having the same AID
and thus using the same key index. This resulted in one STA overwriting
the key information of another STA.

Fix this by simply searching for the next unused entry in the pairwise
key table.

Also bring the key table init in sync with deleting keys by initializing
the key table entries to 0 instead of 1.
Signed-off-by: default avatarHelmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 4df10c8c
...@@ -1101,27 +1101,44 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, ...@@ -1101,27 +1101,44 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
} }
EXPORT_SYMBOL_GPL(rt2800_config_shared_key); EXPORT_SYMBOL_GPL(rt2800_config_shared_key);
static inline int rt2800_find_pairwise_keyslot(struct rt2x00_dev *rt2x00dev)
{
int idx;
u32 offset, reg;
/*
* Search for the first free pairwise key entry and return the
* corresponding index.
*
* Make sure the WCID starts _after_ the last possible shared key
* entry (>32).
*
* Since parts of the pairwise key table might be shared with
* the beacon frame buffers 6 & 7 we should only write into the
* first 222 entries.
*/
for (idx = 33; idx <= 222; idx++) {
offset = MAC_WCID_ATTR_ENTRY(idx);
rt2800_register_read(rt2x00dev, offset, &reg);
if (!reg)
return idx;
}
return -1;
}
int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_crypto *crypto, struct rt2x00lib_crypto *crypto,
struct ieee80211_key_conf *key) struct ieee80211_key_conf *key)
{ {
struct hw_key_entry key_entry; struct hw_key_entry key_entry;
u32 offset; u32 offset;
int idx;
if (crypto->cmd == SET_KEY) { if (crypto->cmd == SET_KEY) {
/* idx = rt2800_find_pairwise_keyslot(rt2x00dev);
* 1 pairwise key is possible per AID, this means that the AID if (idx < 0)
* equals our hw_key_idx. Make sure the WCID starts _after_ the
* last possible shared key entry.
*
* Since parts of the pairwise key table might be shared with
* the beacon frame buffers 6 & 7 we should only write into the
* first 222 entries.
*/
if (crypto->aid > (222 - 32))
return -ENOSPC; return -ENOSPC;
key->hw_key_idx = idx;
key->hw_key_idx = 32 + crypto->aid;
memcpy(key_entry.key, crypto->key, memcpy(key_entry.key, crypto->key,
sizeof(key_entry.key)); sizeof(key_entry.key));
...@@ -2458,7 +2475,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) ...@@ -2458,7 +2475,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i), rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
wcid, sizeof(wcid)); wcid, sizeof(wcid));
rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 1); rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 0);
rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
} }
......
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