]>
Commit | Line | Data |
---|---|---|
d7d57745 MT |
1 | From 1b198fae80a4c97ecf358fe825c0488d6ac0e65e Mon Sep 17 00:00:00 2001 |
2 | From: Jouni Malinen <j@w1.fi> | |
3 | Date: Fri, 22 Sep 2017 11:03:15 +0300 | |
4 | Subject: [PATCH 6/8] TDLS: Reject TPK-TK reconfiguration | |
5 | ||
6 | Do not try to reconfigure the same TPK-TK to the driver after it has | |
7 | been successfully configured. This is an explicit check to avoid issues | |
8 | related to resetting the TX/RX packet number. There was already a check | |
9 | for this for TPK M2 (retries of that message are ignored completely), so | |
10 | that behavior does not get modified. | |
11 | ||
12 | For TPK M3, the TPK-TK could have been reconfigured, but that was | |
13 | followed by immediate teardown of the link due to an issue in updating | |
14 | the STA entry. Furthermore, for TDLS with any real security (i.e., | |
15 | ignoring open/WEP), the TPK message exchange is protected on the AP path | |
16 | and simple replay attacks are not feasible. | |
17 | ||
18 | As an additional corner case, make sure the local nonce gets updated if | |
19 | the peer uses a very unlikely "random nonce" of all zeros. | |
20 | ||
21 | Signed-off-by: Jouni Malinen <j@w1.fi> | |
22 | --- | |
23 | src/rsn_supp/tdls.c | 38 ++++++++++++++++++++++++++++++++++++-- | |
24 | 1 file changed, 36 insertions(+), 2 deletions(-) | |
25 | ||
26 | diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c | |
27 | index 7c95bed..5e350ed 100644 | |
28 | --- a/src/rsn_supp/tdls.c | |
29 | +++ b/src/rsn_supp/tdls.c | |
30 | @@ -112,6 +112,7 @@ struct wpa_tdls_peer { | |
31 | u8 tk[16]; /* TPK-TK; assuming only CCMP will be used */ | |
32 | } tpk; | |
33 | int tpk_set; | |
34 | + int tk_set; /* TPK-TK configured to the driver */ | |
35 | int tpk_success; | |
36 | int tpk_in_progress; | |
37 | ||
38 | @@ -192,6 +193,20 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) | |
39 | u8 rsc[6]; | |
40 | enum wpa_alg alg; | |
41 | ||
42 | + if (peer->tk_set) { | |
43 | + /* | |
44 | + * This same TPK-TK has already been configured to the driver | |
45 | + * and this new configuration attempt (likely due to an | |
46 | + * unexpected retransmitted frame) would result in clearing | |
47 | + * the TX/RX sequence number which can break security, so must | |
48 | + * not allow that to happen. | |
49 | + */ | |
50 | + wpa_printf(MSG_INFO, "TDLS: TPK-TK for the peer " MACSTR | |
51 | + " has already been configured to the driver - do not reconfigure", | |
52 | + MAC2STR(peer->addr)); | |
53 | + return -1; | |
54 | + } | |
55 | + | |
56 | os_memset(rsc, 0, 6); | |
57 | ||
58 | switch (peer->cipher) { | |
59 | @@ -209,12 +224,15 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) | |
60 | return -1; | |
61 | } | |
62 | ||
63 | + wpa_printf(MSG_DEBUG, "TDLS: Configure pairwise key for peer " MACSTR, | |
64 | + MAC2STR(peer->addr)); | |
65 | if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1, | |
66 | rsc, sizeof(rsc), peer->tpk.tk, key_len) < 0) { | |
67 | wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the " | |
68 | "driver"); | |
69 | return -1; | |
70 | } | |
71 | + peer->tk_set = 1; | |
72 | return 0; | |
73 | } | |
74 | ||
75 | @@ -693,7 +711,7 @@ static void wpa_tdls_peer_clear(struct wpa_sm *sm, struct wpa_tdls_peer *peer) | |
76 | peer->cipher = 0; | |
77 | peer->qos_info = 0; | |
78 | peer->wmm_capable = 0; | |
79 | - peer->tpk_set = peer->tpk_success = 0; | |
80 | + peer->tk_set = peer->tpk_set = peer->tpk_success = 0; | |
81 | peer->chan_switch_enabled = 0; | |
82 | os_memset(&peer->tpk, 0, sizeof(peer->tpk)); | |
83 | os_memset(peer->inonce, 0, WPA_NONCE_LEN); | |
84 | @@ -1156,6 +1174,7 @@ skip_rsnie: | |
85 | wpa_tdls_peer_free(sm, peer); | |
86 | return -1; | |
87 | } | |
88 | + peer->tk_set = 0; /* A new nonce results in a new TK */ | |
89 | wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake", | |
90 | peer->inonce, WPA_NONCE_LEN); | |
91 | os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN); | |
92 | @@ -1749,6 +1768,19 @@ static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer, | |
93 | } | |
94 | ||
95 | ||
96 | +static int tdls_nonce_set(const u8 *nonce) | |
97 | +{ | |
98 | + int i; | |
99 | + | |
100 | + for (i = 0; i < WPA_NONCE_LEN; i++) { | |
101 | + if (nonce[i]) | |
102 | + return 1; | |
103 | + } | |
104 | + | |
105 | + return 0; | |
106 | +} | |
107 | + | |
108 | + | |
109 | static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, | |
110 | const u8 *buf, size_t len) | |
111 | { | |
112 | @@ -2002,7 +2034,8 @@ skip_rsn: | |
113 | peer->rsnie_i_len = kde.rsn_ie_len; | |
114 | peer->cipher = cipher; | |
115 | ||
116 | - if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0) { | |
117 | + if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0 || | |
118 | + !tdls_nonce_set(peer->inonce)) { | |
119 | /* | |
120 | * There is no point in updating the RNonce for every obtained | |
121 | * TPK M1 frame (e.g., retransmission due to timeout) with the | |
122 | @@ -2018,6 +2051,7 @@ skip_rsn: | |
123 | "TDLS: Failed to get random data for responder nonce"); | |
124 | goto error; | |
125 | } | |
126 | + peer->tk_set = 0; /* A new nonce results in a new TK */ | |
127 | } | |
128 | ||
129 | #if 0 | |
130 | -- | |
131 | 2.7.4 | |
132 |