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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to