aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2014-01-02 21:46:21 (GMT)
committerJouni Malinen <j@w1.fi>2014-01-02 21:49:38 (GMT)
commit2f30cac36f9209b0b2849b5e12931cc9e98b8a76 (patch)
tree8a1427cb32afbf3bc1dd90f593c37373aa34d350 /wpa_supplicant
parent466bcf99c342aed22952c079dcceed52d5738892 (diff)
downloadhostap-2f30cac36f9209b0b2849b5e12931cc9e98b8a76.zip
hostap-2f30cac36f9209b0b2849b5e12931cc9e98b8a76.tar.gz
hostap-2f30cac36f9209b0b2849b5e12931cc9e98b8a76.tar.bz2
Avoid unnecessary key clearing operations
Track set_key operations per-key index and clear keys on disconnection only if the key was set (or may have been set which is the case for the first operation after wpa_supplicant start). Signed-hostap: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/driver_i.h13
-rw-r--r--wpa_supplicant/events.c1
-rw-r--r--wpa_supplicant/wpa_supplicant.c36
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h3
4 files changed, 26 insertions, 27 deletions
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 0faa70a..0691b6c 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -117,11 +117,16 @@ static inline int wpa_drv_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid)
static inline int wpa_drv_set_key(struct wpa_supplicant *wpa_s,
enum wpa_alg alg, const u8 *addr,
int key_idx, int set_tx,
- const u8 *seq, size_t seq_len,
- const u8 *key, size_t key_len)
-{
+ const u8 *seq, size_t seq_len,
+ const u8 *key, size_t key_len)
+{
+ if (alg != WPA_ALG_NONE) {
+ if (key_idx >= 0 && key_idx <= 6)
+ wpa_s->keys_cleared &= ~BIT(key_idx);
+ else
+ wpa_s->keys_cleared = 0;
+ }
if (wpa_s->driver->set_key) {
- wpa_s->keys_cleared = 0;
return wpa_s->driver->set_key(wpa_s->ifname, wpa_s->drv_priv,
alg, addr, key_idx, set_tx,
seq, seq_len, key, key_len);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 1eb03cc..f8b3d9f 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2163,7 +2163,6 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s,
wpas_notify_disconnect_reason(wpa_s);
if (wpa_supplicant_dynamic_keys(wpa_s)) {
wpa_dbg(wpa_s, MSG_DEBUG, "Disconnect event - remove keys");
- wpa_s->keys_cleared = 0;
wpa_clear_keys(wpa_s, wpa_s->bssid);
}
last_ssid = wpa_s->current_ssid;
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 31e71f1..48fe00c 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -495,29 +495,23 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
*/
void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
{
- if (wpa_s->keys_cleared) {
- /* Some drivers (e.g., ndiswrapper & NDIS drivers) seem to have
- * timing issues with keys being cleared just before new keys
- * are set or just after association or something similar. This
- * shows up in group key handshake failing often because of the
- * client not receiving the first encrypted packets correctly.
- * Skipping some of the extra key clearing steps seems to help
- * in completing group key handshake more reliably. */
- wpa_dbg(wpa_s, MSG_DEBUG, "No keys have been configured - "
- "skip key clearing");
- return;
- }
+ int i, max;
- /* MLME-DELETEKEYS.request */
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
#ifdef CONFIG_IEEE80211W
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
- wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
+ max = 6;
+#else /* CONFIG_IEEE80211W */
+ max = 4;
#endif /* CONFIG_IEEE80211W */
- if (addr) {
+
+ /* MLME-DELETEKEYS.request */
+ for (i = 0; i < max; i++) {
+ if (wpa_s->keys_cleared & BIT(i))
+ continue;
+ wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, i, 0, NULL, 0,
+ NULL, 0);
+ }
+ if (!(wpa_s->keys_cleared & BIT(0)) && addr &&
+ !is_zero_ether_addr(addr)) {
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
0);
/* MLME-SETPROTECTION.request(None) */
@@ -526,7 +520,7 @@ void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
MLME_SETPROTECTION_PROTECT_TYPE_NONE,
MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
}
- wpa_s->keys_cleared = 1;
+ wpa_s->keys_cleared = (u32) -1;
}
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 8563b18..a1931bb 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -432,7 +432,8 @@ struct wpa_supplicant {
unsigned char last_eapol_src[ETH_ALEN];
- int keys_cleared;
+ unsigned int keys_cleared; /* bitfield of key indexes that the driver is
+ * known not to be configured with a key */
struct wpa_blacklist *blacklist;