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