You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
4.2 KiB
132 lines
4.2 KiB
From 6c4bed4f47d1960ec04981a9d50e5076aea5223d Mon Sep 17 00:00:00 2001 |
|
From: Jouni Malinen <j@w1.fi> |
|
Date: Fri, 22 Sep 2017 11:03:15 +0300 |
|
Subject: [PATCH 6/8] TDLS: Reject TPK-TK reconfiguration |
|
|
|
Do not try to reconfigure the same TPK-TK to the driver after it has |
|
been successfully configured. This is an explicit check to avoid issues |
|
related to resetting the TX/RX packet number. There was already a check |
|
for this for TPK M2 (retries of that message are ignored completely), so |
|
that behavior does not get modified. |
|
|
|
For TPK M3, the TPK-TK could have been reconfigured, but that was |
|
followed by immediate teardown of the link due to an issue in updating |
|
the STA entry. Furthermore, for TDLS with any real security (i.e., |
|
ignoring open/WEP), the TPK message exchange is protected on the AP path |
|
and simple replay attacks are not feasible. |
|
|
|
As an additional corner case, make sure the local nonce gets updated if |
|
the peer uses a very unlikely "random nonce" of all zeros. |
|
|
|
Signed-off-by: Jouni Malinen <j@w1.fi> |
|
--- |
|
src/rsn_supp/tdls.c | 38 ++++++++++++++++++++++++++++++++++++-- |
|
1 file changed, 36 insertions(+), 2 deletions(-) |
|
|
|
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c |
|
index e424168..9eb9738 100644 |
|
--- a/src/rsn_supp/tdls.c |
|
+++ b/src/rsn_supp/tdls.c |
|
@@ -112,6 +112,7 @@ struct wpa_tdls_peer { |
|
u8 tk[16]; /* TPK-TK; assuming only CCMP will be used */ |
|
} tpk; |
|
int tpk_set; |
|
+ int tk_set; /* TPK-TK configured to the driver */ |
|
int tpk_success; |
|
int tpk_in_progress; |
|
|
|
@@ -192,6 +193,20 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) |
|
u8 rsc[6]; |
|
enum wpa_alg alg; |
|
|
|
+ if (peer->tk_set) { |
|
+ /* |
|
+ * This same TPK-TK has already been configured to the driver |
|
+ * and this new configuration attempt (likely due to an |
|
+ * unexpected retransmitted frame) would result in clearing |
|
+ * the TX/RX sequence number which can break security, so must |
|
+ * not allow that to happen. |
|
+ */ |
|
+ wpa_printf(MSG_INFO, "TDLS: TPK-TK for the peer " MACSTR |
|
+ " has already been configured to the driver - do not reconfigure", |
|
+ MAC2STR(peer->addr)); |
|
+ return -1; |
|
+ } |
|
+ |
|
os_memset(rsc, 0, 6); |
|
|
|
switch (peer->cipher) { |
|
@@ -209,12 +224,15 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) |
|
return -1; |
|
} |
|
|
|
+ wpa_printf(MSG_DEBUG, "TDLS: Configure pairwise key for peer " MACSTR, |
|
+ MAC2STR(peer->addr)); |
|
if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1, |
|
rsc, sizeof(rsc), peer->tpk.tk, key_len) < 0) { |
|
wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the " |
|
"driver"); |
|
return -1; |
|
} |
|
+ peer->tk_set = 1; |
|
return 0; |
|
} |
|
|
|
@@ -696,7 +714,7 @@ static void wpa_tdls_peer_clear(struct wpa_sm *sm, struct wpa_tdls_peer *peer) |
|
peer->cipher = 0; |
|
peer->qos_info = 0; |
|
peer->wmm_capable = 0; |
|
- peer->tpk_set = peer->tpk_success = 0; |
|
+ peer->tk_set = peer->tpk_set = peer->tpk_success = 0; |
|
peer->chan_switch_enabled = 0; |
|
os_memset(&peer->tpk, 0, sizeof(peer->tpk)); |
|
os_memset(peer->inonce, 0, WPA_NONCE_LEN); |
|
@@ -1159,6 +1177,7 @@ skip_rsnie: |
|
wpa_tdls_peer_free(sm, peer); |
|
return -1; |
|
} |
|
+ peer->tk_set = 0; /* A new nonce results in a new TK */ |
|
wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake", |
|
peer->inonce, WPA_NONCE_LEN); |
|
os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN); |
|
@@ -1751,6 +1770,19 @@ static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer, |
|
} |
|
|
|
|
|
+static int tdls_nonce_set(const u8 *nonce) |
|
+{ |
|
+ int i; |
|
+ |
|
+ for (i = 0; i < WPA_NONCE_LEN; i++) { |
|
+ if (nonce[i]) |
|
+ return 1; |
|
+ } |
|
+ |
|
+ return 0; |
|
+} |
|
+ |
|
+ |
|
static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, |
|
const u8 *buf, size_t len) |
|
{ |
|
@@ -2004,7 +2036,8 @@ skip_rsn: |
|
peer->rsnie_i_len = kde.rsn_ie_len; |
|
peer->cipher = cipher; |
|
|
|
- if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0) { |
|
+ if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0 || |
|
+ !tdls_nonce_set(peer->inonce)) { |
|
/* |
|
* There is no point in updating the RNonce for every obtained |
|
* TPK M1 frame (e.g., retransmission due to timeout) with the |
|
@@ -2020,6 +2053,7 @@ skip_rsn: |
|
"TDLS: Failed to get random data for responder nonce"); |
|
goto error; |
|
} |
|
+ peer->tk_set = 0; /* A new nonce results in a new TK */ |
|
} |
|
|
|
#if 0 |
|
-- |
|
2.7.4 |
|
|
|
|