Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/bsd/wpa/dist apply patches from upstream, namely fr...



details:   https://anonhg.NetBSD.org/src/rev/0733e97711ed
branches:  trunk
changeset: 827146:0733e97711ed
user:      spz <spz%NetBSD.org@localhost>
date:      Mon Oct 16 17:36:16 2017 +0000

description:
apply patches from upstream, namely from https://w1.fi/security/2017-1/ :
rebased-v2.6-0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch        02-Oct-2017 16:19       6.1K
rebased-v2.6-0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch    02-Oct-2017 16:19       7.7K
rebased-v2.6-0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch    02-Oct-2017 16:19       6.7K
rebased-v2.6-0004-Prevent-installation-of-an-all-zero-TK.patch
02-Oct-2017 16:19       2.5K
rebased-v2.6-0005-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch
02-Oct-2017 16:19       1.9K
rebased-v2.6-0006-TDLS-Reject-TPK-TK-reconfiguration.patch
02-Oct-2017 16:19       4.2K
rebased-v2.6-0007-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch    02-Oct-2017 16:19       1.6K
rebased-v2.6-0008-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch    02-Oct-2017 16:19       2.7K

for CVE-2017-13077 CVE-2017-13078 CVE-2017-13079 CVE-2017-13080
 CVE-2017-13081 CVE-2017-13082 CVE-2017-13086 CVE-2017-13087 CVE-2017-13088

(see
https://w1.fi/security/2017-1/wpa-packet-number-reuse-with-replayed-messages.txt
for details)

diffstat:

 external/bsd/wpa/dist/src/ap/ieee802_11.c      |   16 ++-
 external/bsd/wpa/dist/src/ap/wpa_auth.c        |   35 +++++-
 external/bsd/wpa/dist/src/ap/wpa_auth.h        |    3 +-
 external/bsd/wpa/dist/src/ap/wpa_auth_ft.c     |   10 +
 external/bsd/wpa/dist/src/ap/wpa_auth_i.h      |    1 +
 external/bsd/wpa/dist/src/common/wpa_common.h  |   12 +
 external/bsd/wpa/dist/src/rsn_supp/tdls.c      |   38 +++++-
 external/bsd/wpa/dist/src/rsn_supp/wpa.c       |  155 ++++++++++++++++--------
 external/bsd/wpa/dist/src/rsn_supp/wpa_ft.c    |    8 +
 external/bsd/wpa/dist/src/rsn_supp/wpa_i.h     |    8 +-
 external/bsd/wpa/dist/wpa_supplicant/wnm_sta.c |    4 +-
 11 files changed, 228 insertions(+), 62 deletions(-)

diffs (truncated from 670 to 300 lines):

diff -r 15e424993571 -r 0733e97711ed external/bsd/wpa/dist/src/ap/ieee802_11.c
--- a/external/bsd/wpa/dist/src/ap/ieee802_11.c Mon Oct 16 17:08:35 2017 +0000
+++ b/external/bsd/wpa/dist/src/ap/ieee802_11.c Mon Oct 16 17:36:16 2017 +0000
@@ -1841,6 +1841,7 @@
 {
        struct ieee80211_ht_capabilities ht_cap;
        struct ieee80211_vht_capabilities vht_cap;
+       int set = 1;
 
        /*
         * Remove the STA entry to ensure the STA PS state gets cleared and
@@ -1848,9 +1849,18 @@
         * FT-over-the-DS, where a station re-associates back to the same AP but
         * skips the authentication flow, or if working with a driver that
         * does not support full AP client state.
+        *
+        * Skip this if the STA has already completed FT reassociation and the
+        * TK has been configured since the TX/RX PN must not be reset to 0 for
+        * the same key.
         */
-       if (!sta->added_unassoc)
+       if (!sta->added_unassoc &&
+           (!(sta->flags & WLAN_STA_AUTHORIZED) ||
+            !wpa_auth_sta_ft_tk_already_set(sta->wpa_sm))) {
                hostapd_drv_sta_remove(hapd, sta->addr);
+               wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED);
+               set = 0;
+       }
 
 #ifdef CONFIG_IEEE80211N
        if (sta->flags & WLAN_STA_HT)
@@ -1873,11 +1883,11 @@
                            sta->flags & WLAN_STA_VHT ? &vht_cap : NULL,
                            sta->flags | WLAN_STA_ASSOC, sta->qosinfo,
                            sta->vht_opmode, sta->p2p_ie ? 1 : 0,
-                           sta->added_unassoc)) {
+                           set)) {
                hostapd_logger(hapd, sta->addr,
                               HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE,
                               "Could not %s STA to kernel driver",
-                              sta->added_unassoc ? "set" : "add");
+                              set ? "set" : "add");
 
                if (sta->added_unassoc) {
                        hostapd_drv_sta_remove(hapd, sta->addr);
diff -r 15e424993571 -r 0733e97711ed external/bsd/wpa/dist/src/ap/wpa_auth.c
--- a/external/bsd/wpa/dist/src/ap/wpa_auth.c   Mon Oct 16 17:08:35 2017 +0000
+++ b/external/bsd/wpa/dist/src/ap/wpa_auth.c   Mon Oct 16 17:36:16 2017 +0000
@@ -1745,6 +1745,9 @@
 #else /* CONFIG_IEEE80211R */
                break;
 #endif /* CONFIG_IEEE80211R */
+       case WPA_DRV_STA_REMOVED:
+               sm->tk_already_set = FALSE;
+               return 0;
        }
 
 #ifdef CONFIG_IEEE80211R
@@ -1898,6 +1901,21 @@
 }
 
 
+static int wpa_auth_sm_ptk_update(struct wpa_state_machine *sm)
+{
+       if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) {
+               wpa_printf(MSG_ERROR,
+                          "WPA: Failed to get random data for ANonce");
+               sm->Disconnect = TRUE;
+               return -1;
+       }
+       wpa_hexdump(MSG_DEBUG, "WPA: Assign new ANonce", sm->ANonce,
+                   WPA_NONCE_LEN);
+       sm->TimeoutCtr = 0;
+       return 0;
+}
+
+
 SM_STATE(WPA_PTK, INITPMK)
 {
        u8 msk[2 * PMK_LEN];
@@ -2455,9 +2473,12 @@
                SM_ENTER(WPA_PTK, AUTHENTICATION);
        else if (sm->ReAuthenticationRequest)
                SM_ENTER(WPA_PTK, AUTHENTICATION2);
-       else if (sm->PTKRequest)
-               SM_ENTER(WPA_PTK, PTKSTART);
-       else switch (sm->wpa_ptk_state) {
+       else if (sm->PTKRequest) {
+               if (wpa_auth_sm_ptk_update(sm) < 0)
+                       SM_ENTER(WPA_PTK, DISCONNECTED);
+               else
+                       SM_ENTER(WPA_PTK, PTKSTART);
+       } else switch (sm->wpa_ptk_state) {
        case WPA_PTK_INITIALIZE:
                break;
        case WPA_PTK_DISCONNECT:
@@ -3250,6 +3271,14 @@
 }
 
 
+int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm)
+{
+       if (!sm || !wpa_key_mgmt_ft(sm->wpa_key_mgmt))
+               return 0;
+       return sm->tk_already_set;
+}
+
+
 int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
                             struct rsn_pmksa_cache_entry *entry)
 {
diff -r 15e424993571 -r 0733e97711ed external/bsd/wpa/dist/src/ap/wpa_auth.h
--- a/external/bsd/wpa/dist/src/ap/wpa_auth.h   Mon Oct 16 17:08:35 2017 +0000
+++ b/external/bsd/wpa/dist/src/ap/wpa_auth.h   Mon Oct 16 17:36:16 2017 +0000
@@ -267,7 +267,7 @@
                 u8 *data, size_t data_len);
 enum wpa_event {
        WPA_AUTH, WPA_ASSOC, WPA_DISASSOC, WPA_DEAUTH, WPA_REAUTH,
-       WPA_REAUTH_EAPOL, WPA_ASSOC_FT
+       WPA_REAUTH_EAPOL, WPA_ASSOC_FT, WPA_DRV_STA_REMOVED
 };
 void wpa_remove_ptk(struct wpa_state_machine *sm);
 int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event);
@@ -280,6 +280,7 @@
 int wpa_auth_get_pairwise(struct wpa_state_machine *sm);
 int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm);
 int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm);
+int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm);
 int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
                             struct rsn_pmksa_cache_entry *entry);
 struct rsn_pmksa_cache_entry *
diff -r 15e424993571 -r 0733e97711ed external/bsd/wpa/dist/src/ap/wpa_auth_ft.c
--- a/external/bsd/wpa/dist/src/ap/wpa_auth_ft.c        Mon Oct 16 17:08:35 2017 +0000
+++ b/external/bsd/wpa/dist/src/ap/wpa_auth_ft.c        Mon Oct 16 17:36:16 2017 +0000
@@ -780,6 +780,14 @@
                return;
        }
 
+       if (sm->tk_already_set) {
+               /* Must avoid TK reconfiguration to prevent clearing of TX/RX
+                * PN in the driver */
+               wpa_printf(MSG_DEBUG,
+                          "FT: Do not re-install same PTK to the driver");
+               return;
+       }
+
        /* FIX: add STA entry to kernel/driver here? The set_key will fail
         * most likely without this.. At the moment, STA entry is added only
         * after association has been completed. This function will be called
@@ -792,6 +800,7 @@
 
        /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
        sm->pairwise_set = TRUE;
+       sm->tk_already_set = TRUE;
 }
 
 
@@ -898,6 +907,7 @@
 
        sm->pairwise = pairwise;
        sm->PTK_valid = TRUE;
+       sm->tk_already_set = FALSE;
        wpa_ft_install_ptk(sm);
 
        buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) +
diff -r 15e424993571 -r 0733e97711ed external/bsd/wpa/dist/src/ap/wpa_auth_i.h
--- a/external/bsd/wpa/dist/src/ap/wpa_auth_i.h Mon Oct 16 17:08:35 2017 +0000
+++ b/external/bsd/wpa/dist/src/ap/wpa_auth_i.h Mon Oct 16 17:36:16 2017 +0000
@@ -65,6 +65,7 @@
        struct wpa_ptk PTK;
        Boolean PTK_valid;
        Boolean pairwise_set;
+       Boolean tk_already_set;
        int keycount;
        Boolean Pair;
        struct wpa_key_replay_counter {
diff -r 15e424993571 -r 0733e97711ed external/bsd/wpa/dist/src/common/wpa_common.h
--- a/external/bsd/wpa/dist/src/common/wpa_common.h     Mon Oct 16 17:08:35 2017 +0000
+++ b/external/bsd/wpa/dist/src/common/wpa_common.h     Mon Oct 16 17:36:16 2017 +0000
@@ -218,8 +218,20 @@
        size_t kck_len;
        size_t kek_len;
        size_t tk_len;
+       int installed; /* 1 if key has already been installed to driver */
 };
 
+struct wpa_gtk {
+       u8 gtk[WPA_GTK_MAX_LEN];
+       size_t gtk_len;
+};
+
+#ifdef CONFIG_IEEE80211W
+struct wpa_igtk {
+       u8 igtk[WPA_IGTK_MAX_LEN];
+       size_t igtk_len;
+};
+#endif /* CONFIG_IEEE80211W */
 
 /* WPA IE version 1
  * 00-50-f2:1 (OUI:OUI type)
diff -r 15e424993571 -r 0733e97711ed external/bsd/wpa/dist/src/rsn_supp/tdls.c
--- a/external/bsd/wpa/dist/src/rsn_supp/tdls.c Mon Oct 16 17:08:35 2017 +0000
+++ b/external/bsd/wpa/dist/src/rsn_supp/tdls.c Mon Oct 16 17:36:16 2017 +0000
@@ -112,6 +112,7 @@
                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 @@
        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 @@
                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 @@
        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 @@
                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 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 @@
        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 @@
                                "TDLS: Failed to get random data for responder nonce");
                        goto error;
                }
+               peer->tk_set = 0; /* A new nonce results in a new TK */



Home | Main Index | Thread Index | Old Index