Annotation of /trunk/wpa_supplicant/patches/0006-TDLS-Reject-TPK-TK-reconfiguration.patch
Parent Directory | Revision Log
Revision 2999 -
(hide annotations)
(download)
Tue Oct 17 10:55:21 2017 UTC (6 years, 11 months ago) by niro
File size: 4309 byte(s)
Tue Oct 17 10:55:21 2017 UTC (6 years, 11 months ago) by niro
File size: 4309 byte(s)
-krackattack patches
1 | niro | 2999 | From 6c4bed4f47d1960ec04981a9d50e5076aea5223d 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 e424168..9eb9738 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 | @@ -696,7 +714,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 | @@ -1159,6 +1177,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 | @@ -1751,6 +1770,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 | @@ -2004,7 +2036,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 | @@ -2020,6 +2053,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 |