Blame SOURCES/rh1495527-0006-TDLS-Reject-TPK-TK-reconfiguration.patch

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