TDLS: Fix key configuration with current mac80211

A kernel commit ("mac80211: fix FT roaming") started validating that the
STA entry is marked associated when adding a key. While this is needed
to fix some FT use cases with hardware crypto, it has a side effect of
breaking TDLS key configuration. Work around this by trying to
re-configure the key for the direct link after the STA entry has been
set with all information. In addition, try to tear down the link if
anything goes wrong in key configuration (if both attempts fail) or
enabling the link in the driver.

Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2013-04-03 18:39:10 +03:00
parent 88c8bf311e
commit 75fa7d19a4

View File

@ -86,6 +86,7 @@ static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer);
struct wpa_tdls_peer {
struct wpa_tdls_peer *next;
unsigned int reconfig_key:1;
int initiator; /* whether this end was initiator for TDLS setup */
u8 addr[ETH_ALEN]; /* other end MAC address */
u8 inonce[WPA_NONCE_LEN]; /* Initiator Nonce */
@ -616,6 +617,7 @@ static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
MAC2STR(peer->addr));
eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
peer->reconfig_key = 0;
peer->initiator = 0;
os_free(peer->sm_tmr.buf);
peer->sm_tmr.buf = NULL;
@ -1751,7 +1753,7 @@ error:
}
static void wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
static int wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
{
peer->tpk_success = 1;
eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
@ -1775,13 +1777,22 @@ static void wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
}
/* add supported rates, capabilities, and qos_info to the TDLS peer */
wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
peer->supp_rates, peer->supp_rates_len,
peer->ht_capabilities, peer->vht_capabilities,
peer->qos_info, peer->ext_capab,
peer->ext_capab_len);
if (wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
peer->supp_rates, peer->supp_rates_len,
peer->ht_capabilities,
peer->vht_capabilities,
peer->qos_info, peer->ext_capab,
peer->ext_capab_len) < 0)
return -1;
wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
if (peer->reconfig_key && wpa_tdls_set_key(sm, peer) < 0) {
wpa_printf(MSG_INFO, "TDLS: Could not configure key to the "
"driver");
return -1;
}
peer->reconfig_key = 0;
return wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
}
@ -1800,6 +1811,7 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
int ielen;
u16 status;
const u8 *pos;
int ret;
wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Response / TPK M2 "
"(Peer " MACSTR ")", MAC2STR(src_addr));
@ -1992,7 +2004,15 @@ static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
return -1;
}
wpa_tdls_set_key(sm, peer);
if (wpa_tdls_set_key(sm, peer) < 0) {
/*
* Some drivers may not be able to config the key prior to full
* STA entry having been configured.
*/
wpa_printf(MSG_DEBUG, "TDLS: Try to configure TPK again after "
"STA entry is complete");
peer->reconfig_key = 1;
}
skip_rsn:
peer->dtoken = dtoken;
@ -2001,9 +2021,13 @@ skip_rsn:
"TPK Handshake Message 3");
wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer);
wpa_tdls_enable_link(sm, peer);
return 0;
ret = wpa_tdls_enable_link(sm, peer);
if (ret < 0) {
wpa_printf(MSG_DEBUG, "TDLS: Could not enable link");
wpa_tdls_do_teardown(sm, peer,
WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 1);
}
return ret;
error:
wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken,
@ -2026,6 +2050,7 @@ static int wpa_tdls_process_tpk_m3(struct wpa_sm *sm, const u8 *src_addr,
u16 status;
const u8 *pos;
u32 lifetime;
int ret;
wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Confirm / TPK M3 "
"(Peer " MACSTR ")", MAC2STR(src_addr));
@ -2136,13 +2161,24 @@ static int wpa_tdls_process_tpk_m3(struct wpa_sm *sm, const u8 *src_addr,
return -1;
}
if (wpa_tdls_set_key(sm, peer) < 0)
return -1;
if (wpa_tdls_set_key(sm, peer) < 0) {
/*
* Some drivers may not be able to config the key prior to full
* STA entry having been configured.
*/
wpa_printf(MSG_DEBUG, "TDLS: Try to configure TPK again after "
"STA entry is complete");
peer->reconfig_key = 1;
}
skip_rsn:
wpa_tdls_enable_link(sm, peer);
return 0;
ret = wpa_tdls_enable_link(sm, peer);
if (ret < 0) {
wpa_printf(MSG_DEBUG, "TDLS: Could not enable link");
wpa_tdls_do_teardown(sm, peer,
WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 1);
}
return ret;
}