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

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