123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- From: Jouni Malinen <j@w1.fi>
- Date: Fri, 22 Sep 2017 11:03:15 +0300
- Subject: [PATCH] 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.
- Signed-off-by: Jouni Malinen <j@w1.fi>
- ---
- --- a/src/rsn_supp/tdls.c
- +++ b/src/rsn_supp/tdls.c
- @@ -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_s
- 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_s
- 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 w
- 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 w
- }
-
-
- +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
|