aboutsummaryrefslogtreecommitdiff
path: root/net/mac80211/key.c
AgeCommit message (Collapse)Author
2008-02-29mac80211: fix key replacing, hw accelJohannes Berg
Even though I thought about it a lot and had also tested it, some of my recent changes in the key code broke replacing keys, making the kernel oops because a key is removed from a list while not on it. This patch fixes that using the list as an indication whether or not the key is on it (an empty list means it's not on any list.) Also, this patch fixes hw accel enabling, the check for not doing hw accel when the interface is down was lost and is restored by this. Additionally, move adding the key to the list into the function __ieee80211_key_replace() for more consistency. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
2008-02-29mac80211: split ieee80211_key_alloc/freeJohannes Berg
In order to RCU-ify sta_info, we need to be able to allocate a key without linking it to an sdata/sta structure (because allocation cannot be done in an rcu critical section). This patch splits up ieee80211_key_alloc() and updates all users appropriately. While at it, this patch fixes a number of race conditions such as finally making key replacement atomic, unfortunately at the expense of more complex code. Note that this patch documents /existing/ bugs with sta info and key interaction, there is currently a race condition when a sta info is freed without holding the RTNL. This will finally be fixed by a followup patch. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
2008-01-28mac80211: move interface type to vif structureJohannes Berg
Drivers that support mixed AP/STA operation may well need to know the type of a virtual interface when iterating over them. The easiest way to support that is to move the interface type variable into the vif structure. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
2007-10-10[MAC80211]: remove ALG_NONEJohannes Berg
This "algorithm" is used only internally and is not useful. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Cc: Michael Buesch <mb@bu3sch.de> Acked-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2007-10-10[PATCH] mac80211: remove crypto algorithm typedefJohannes Berg
The typedef is not required, we can just use "enum ieee80211_key_alg" instead of "ieee80211_key_alg" Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
2007-10-10[NET]: Introduce and use print_mac() and DECLARE_MAC_BUF()Joe Perches
This is nicer than the MAC_FMT stuff. Signed-off-by: Joe Perches <joe@perches.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2007-10-10[MAC80211]: remove HW_KEY_IDX_INVALIDJohannes Berg
This patch makes the mac80211/driver interface rely only on the IEEE80211_TXCTL_DO_NOT_ENCRYPT flag to signal to the driver whether a frame should be encrypted or not, since mac80211 internally no longer relies on HW_KEY_IDX_INVALID either this removes it, changes the key index to be a u8 in all places and makes the full range of the value available to drivers. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2007-10-10[MAC80211]: remove set_key_idx callbackJohannes Berg
No existing drivers use this callback, hence there's no telling how it might be used. In fact, it is unlikely to be of much use as-is because the default key index isn't something that the driver can do much with without knowing which interface it was for etc. And if it needs the key index for the transmitted frame, it can get it by keeping a reference to the key_conf structure and looking it up by hw_key_idx. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2007-10-10[MAC80211]: fix race conditions with keysJohannes Berg
During receive processing, we select the key long before using it and because there's no locking it is possible that we kfree() the key after having selected it but before using it for crypto operations. Obviously, this is bad. Secondly, during transmit processing, there are two possible races: We have a similar race between select_key() and using it for encryption, but we also have a race here between select_key() and hardware encryption (both when a key is removed.) This patch solves these issues by using RCU: when a key is to be freed, we first remove the pointer from the appropriate places (sdata->keys, sdata->default_key, sta->key) using rcu_assign_pointer() and then synchronize_rcu(). Then, we can safely kfree() the key and remove it from the hardware. There's a window here where the hardware may still be using it for decryption, but we can't work around that without having two hardware callbacks, one to disable the key for RX and one to disable it for TX; but the worst thing that will happen is that we receive a packet decrypted that we don't find a key for any more and then drop it. When we add a key, we first need to upload it to the hardware and then, using rcu_assign_pointer() again, link it into our structures. In the code using keys (TX/RX paths) we use rcu_dereference() to get the key and enclose the whole tx/rx section in a rcu_read_lock() ... rcu_read_unlock() block. Because we've uploaded the key to hardware before linking it into internal structures, we can guarantee that it is valid once get to into tx(). One possible race condition remains, however: when we have hardware acceleration enabled and the driver shuts down the queues, we end up queueing the frame. If now somebody removes the key, the key will be removed from hwaccel and then then driver will be asked to encrypt the frame with a key index that has been removed. Hence, drivers will need to be aware that the hw_key_index they are passed might not be under all circumstances. Most drivers will, however, simply ignore that condition and encrypt the frame with the selected key anyway, this only results in a frame being encrypted with a wrong key or dropped (rightfully) because the key was not valid. There isn't much we can do about it unless we want to walk the pending frame queue every time a key is removed and remove all frames that used it. This race condition, however, will most likely be solved once we add multiqueue support to mac80211 because then frames will be queued further up the stack instead of after being processed. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2007-10-10[MAC80211]: rework key handlingJohannes Berg
This moves all the key handling code out from ieee80211_ioctl.c into key.c and also does the following changes including documentation updates in mac80211.h: 1) Turn off hardware acceleration for keys when the interface is down. This is necessary because otherwise monitor interfaces could be decrypting frames for other interfaces that are down at the moment. Also, it should go some way towards better suspend/resume support, in any case the routines used here could be used for that as well. Additionally, this makes the driver interface nicer, keys for a specific local MAC address are only ever present while an interface with that MAC address is enabled. 2) Change driver set_key() callback interface to allow only return values of -ENOSPC, -EOPNOTSUPP and 0, warn on all other return values. This allows debugging the stack when a driver notices it's handed a key while it is down. 3) Invert the flag meaning to KEY_FLAG_UPLOADED_TO_HARDWARE. 4) Remove REMOVE_ALL_KEYS command as it isn't used nor do we want to use it, we'll use DISABLE_KEY for each key. It is hard to use REMOVE_ALL_KEYS because we can handle multiple virtual interfaces with different key configuration, so we'd have to keep track of a lot of state for this and that isn't worth it. 5) Warn when disabling a key fails, it musn't. 6) Remove IEEE80211_HW_NO_TKIP_WMM_HWACCEL in favour of per-key IEEE80211_KEY_FLAG_WMM_STA to let driver sort it out itself. 7) Tell driver that a (non-WEP) key is used only for transmission by using an all-zeroes station MAC address when configuring. 8) Change the set_key() callback to have access to the local MAC address the key is being added for. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2007-10-10[MAC80211]: remove krefs for keysJohannes Berg
they aren't really refcounted anyway Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2007-10-10[MAC80211]: embed key conf in key, fix driver interfaceJohannes Berg
This patch embeds the struct ieee80211_key_conf into struct ieee80211_key and thus avoids allocations and having data present twice. This required some more changes: 1) The removal of the IEEE80211_KEY_DEFAULT_TX_KEY key flag. This flag isn't used by drivers nor should it be since we have a set_key_idx() callback. Maybe that callback needs to be extended to include the key conf, but only a driver that requires it will tell. 2) The removal of the IEEE80211_KEY_DEFAULT_WEP_ONLY key flag. This flag is global, so it shouldn't be passed in the key conf structure. Pass it to the function instead. Also, this patch removes the AID parameter to the set_key() callback because it is currently unused and the hardware currently cannot know about the AID anyway. I suspect this was used with some hardware that actually selected the AID itself, but that functionality was removed. Additionally, I've removed the ALG_NULL key algorithm since we have ALG_NONE. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2007-10-10[MAC80211]: split out some key functions from ieee80211.cJohannes Berg
into a new file key.c which doesn't have much code right now but it makes ieee80211.c easier to read. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Jiri Benc <jbenc@suse.cz> Signed-off-by: John W. Linville <linville@tuxdriver.com>