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>
This commit is contained in:
parent
466bcf99c3
commit
2f30cac36f
4 changed files with 26 additions and 27 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
max = 6;
|
||||
#else /* CONFIG_IEEE80211W */
|
||||
max = 4;
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
/* 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);
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
if (addr) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue