aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2017-09-22 11:03:15 +0300
committerAndreas Blaesius <skate4life@gmx.de>2017-10-21 19:38:54 +0200
commit93e3867f12318c7bf035b2ea5defcf43920de252 (patch)
treef3b82fd57c91f88dbdc7e53fc72d92de4903472d
parent1662d15947987d699e9f1bac67f48e3a5619568e (diff)
downloadandroid_external_wpa_supplicant_8-93e3867f12318c7bf035b2ea5defcf43920de252.tar.gz
android_external_wpa_supplicant_8-93e3867f12318c7bf035b2ea5defcf43920de252.tar.bz2
android_external_wpa_supplicant_8-93e3867f12318c7bf035b2ea5defcf43920de252.zip
TDLS: Reject TPK-TK reconfiguration
Do not try to reconfigure the same TPK-TK to the driver after it has been successfully configured. This is an explicit check to avoid issues related to resetting the TX/RX packet number. There was already a check for this for TPK M2 (retries of that message are ignored completely), so that behavior does not get modified. For TPK M3, the TPK-TK could have been reconfigured, but that was followed by immediate teardown of the link due to an issue in updating the STA entry. Furthermore, for TDLS with any real security (i.e., ignoring open/WEP), the TPK message exchange is protected on the AP path and simple replay attacks are not feasible. As an additional corner case, make sure the local nonce gets updated if the peer uses a very unlikely "random nonce" of all zeros. Change-Id: I899d293ebdf82363700c101b1c8640f15f1d26cc Signed-off-by: Jouni Malinen <j@w1.fi>
-rw-r--r--src/rsn_supp/tdls.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 17e8225c..dae729fc 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -108,6 +108,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;
@@ -185,6 +186,20 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
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) {
@@ -202,12 +217,15 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
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;
}
@@ -653,7 +671,7 @@ static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
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;
os_memset(&peer->tpk, 0, sizeof(peer->tpk));
os_memset(peer->inonce, 0, WPA_NONCE_LEN);
os_memset(peer->rnonce, 0, WPA_NONCE_LEN);
@@ -1054,6 +1072,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);
@@ -1537,6 +1556,19 @@ static int copy_peer_supp_oper_classes(const struct wpa_eapol_ie_parse *kde,
}
+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)
{
@@ -1781,7 +1813,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
@@ -1798,6 +1831,7 @@ skip_rsn:
wpa_tdls_peer_free(sm, peer);
goto error;
}
+ peer->tk_set = 0; /* A new nonce results in a new TK */
}
#if 0