svn commit: r336494 - vendor/wpa/dist/src/rsn_supp

Cy Schubert cy at FreeBSD.org
Thu Jul 19 17:37:15 UTC 2018


Author: cy
Date: Thu Jul 19 17:37:13 2018
New Revision: 336494
URL: https://svnweb.freebsd.org/changeset/base/336494

Log:
  Import upline security patch: TDLS: Reject TPK-TK reconfiguration.
  This is also upline git commmit ff89af96e5a35c86f50330d2b86c18323318a60c.
  
  Obtained from:	https://w1.fi/security/2017-1/\
  		rebased-v2.6-0006-TDLS-Reject-TPK-TK-\
  		reconfiguration.patch

Modified:
  vendor/wpa/dist/src/rsn_supp/tdls.c

Modified: vendor/wpa/dist/src/rsn_supp/tdls.c
==============================================================================
--- vendor/wpa/dist/src/rsn_supp/tdls.c	Thu Jul 19 17:34:58 2018	(r336493)
+++ vendor/wpa/dist/src/rsn_supp/tdls.c	Thu Jul 19 17:37:13 2018	(r336494)
@@ -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 
 	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 
 		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, str
 	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, str
 }
 
 
+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


More information about the svn-src-all mailing list