Line data Source code
1 : /* Copyright (c) 2001 Matej Pfajfar.
2 : * Copyright (c) 2001-2004, Roger Dingledine.
3 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 : /* See LICENSE for licensing information */
6 :
7 : /**
8 : * \file onion_crypto.c
9 : * \brief Functions to handle different kinds of circuit extension crypto.
10 : *
11 : * In this module, we provide a set of abstractions to create a uniform
12 : * interface over the three circuit extension handshakes that Tor has used
13 : * over the years (TAP, CREATE_FAST, and ntor). These handshakes are
14 : * implemented in onion_tap.c, onion_fast.c, and onion_ntor.c respectively.
15 : *
16 : * All[*] of these handshakes follow a similar pattern: a client, knowing
17 : * some key from the relay it wants to extend through, generates the
18 : * first part of a handshake. A relay receives that handshake, and sends
19 : * a reply. Once the client handles the reply, it knows that it is
20 : * talking to the right relay, and it shares some freshly negotiated key
21 : * material with that relay.
22 : *
23 : * We sometimes call the client's part of the handshake an "onionskin".
24 : * We do this because historically, Onion Routing used a multi-layer
25 : * structure called an "onion" to construct circuits. Each layer of the
26 : * onion contained key material chosen by the client, the identity of
27 : * the next relay in the circuit, and a smaller onion, encrypted with
28 : * the key of the next relay. When we changed Tor to use a telescoping
29 : * circuit extension design, it corresponded to sending each layer of the
30 : * onion separately -- as a series of onionskins.
31 : **/
32 :
33 : #include "core/or/or.h"
34 : #include "core/or/extendinfo.h"
35 : #include "core/crypto/onion_crypto.h"
36 : #include "core/crypto/onion_fast.h"
37 : #include "core/crypto/onion_ntor.h"
38 : #include "core/crypto/onion_tap.h"
39 : #include "feature/relay/router.h"
40 : #include "lib/crypt_ops/crypto_dh.h"
41 : #include "lib/crypt_ops/crypto_util.h"
42 :
43 : #include "core/or/crypt_path_st.h"
44 : #include "core/or/extend_info_st.h"
45 :
46 : /** Return a new server_onion_keys_t object with all of the keys
47 : * and other info we might need to do onion handshakes. (We make a copy of
48 : * our keys for each cpuworker to avoid race conditions with the main thread,
49 : * and to avoid locking) */
50 : server_onion_keys_t *
51 0 : server_onion_keys_new(void)
52 : {
53 0 : server_onion_keys_t *keys = tor_malloc_zero(sizeof(server_onion_keys_t));
54 0 : memcpy(keys->my_identity, router_get_my_id_digest(), DIGEST_LEN);
55 0 : dup_onion_keys(&keys->onion_key, &keys->last_onion_key);
56 0 : keys->curve25519_key_map = construct_ntor_key_map();
57 0 : keys->junk_keypair = tor_malloc_zero(sizeof(curve25519_keypair_t));
58 0 : curve25519_keypair_generate(keys->junk_keypair, 0);
59 0 : return keys;
60 : }
61 : /** Release all storage held in <b>keys</b>. */
62 : void
63 0 : server_onion_keys_free_(server_onion_keys_t *keys)
64 : {
65 0 : if (! keys)
66 : return;
67 :
68 0 : crypto_pk_free(keys->onion_key);
69 0 : crypto_pk_free(keys->last_onion_key);
70 0 : ntor_key_map_free(keys->curve25519_key_map);
71 0 : tor_free(keys->junk_keypair);
72 0 : memwipe(keys, 0, sizeof(server_onion_keys_t));
73 0 : tor_free(keys);
74 : }
75 :
76 : /** Release whatever storage is held in <b>state</b>, depending on its
77 : * type, and clear its pointer. */
78 : void
79 77 : onion_handshake_state_release(onion_handshake_state_t *state)
80 : {
81 77 : switch (state->tag) {
82 77 : case ONION_HANDSHAKE_TYPE_TAP:
83 77 : crypto_dh_free(state->u.tap);
84 77 : state->u.tap = NULL;
85 77 : break;
86 0 : case ONION_HANDSHAKE_TYPE_FAST:
87 0 : fast_handshake_state_free(state->u.fast);
88 0 : state->u.fast = NULL;
89 0 : break;
90 0 : case ONION_HANDSHAKE_TYPE_NTOR:
91 0 : ntor_handshake_state_free(state->u.ntor);
92 0 : state->u.ntor = NULL;
93 0 : break;
94 0 : default:
95 : /* LCOV_EXCL_START
96 : * This state should not even exist. */
97 : log_warn(LD_BUG, "called with unknown handshake state type %d",
98 : (int)state->tag);
99 : tor_fragile_assert();
100 : /* LCOV_EXCL_STOP */
101 : }
102 77 : }
103 :
104 : /** Perform the first step of a circuit-creation handshake of type <b>type</b>
105 : * (one of ONION_HANDSHAKE_TYPE_*): generate the initial "onion skin" in
106 : * <b>onion_skin_out</b>, and store any state information in <b>state_out</b>.
107 : * Return -1 on failure, and the length of the onionskin on acceptance.
108 : */
109 : int
110 5 : onion_skin_create(int type,
111 : const extend_info_t *node,
112 : onion_handshake_state_t *state_out,
113 : uint8_t *onion_skin_out)
114 : {
115 5 : int r = -1;
116 :
117 5 : switch (type) {
118 3 : case ONION_HANDSHAKE_TYPE_TAP:
119 3 : if (!node->onion_key)
120 : return -1;
121 :
122 0 : if (onion_skin_TAP_create(node->onion_key,
123 : &state_out->u.tap,
124 : (char*)onion_skin_out) < 0)
125 : return -1;
126 :
127 : r = TAP_ONIONSKIN_CHALLENGE_LEN;
128 : break;
129 2 : case ONION_HANDSHAKE_TYPE_FAST:
130 2 : if (fast_onionskin_create(&state_out->u.fast, onion_skin_out) < 0)
131 : return -1;
132 :
133 : r = CREATE_FAST_LEN;
134 : break;
135 0 : case ONION_HANDSHAKE_TYPE_NTOR:
136 0 : if (!extend_info_supports_ntor(node))
137 : return -1;
138 0 : if (onion_skin_ntor_create((const uint8_t*)node->identity_digest,
139 0 : &node->curve25519_onion_key,
140 0 : &state_out->u.ntor,
141 : onion_skin_out) < 0)
142 : return -1;
143 :
144 : r = NTOR_ONIONSKIN_LEN;
145 : break;
146 0 : default:
147 : /* LCOV_EXCL_START
148 : * We should never try to create an impossible handshake type. */
149 : log_warn(LD_BUG, "called with unknown handshake state type %d", type);
150 : tor_fragile_assert();
151 : r = -1;
152 : /* LCOV_EXCL_STOP */
153 : }
154 :
155 : if (r > 0)
156 2 : state_out->tag = (uint16_t) type;
157 :
158 : return r;
159 : }
160 :
161 : /* This is the maximum value for keys_out_len passed to
162 : * onion_skin_server_handshake, plus 16. We can make it bigger if needed:
163 : * It just defines how many bytes to stack-allocate. */
164 : #define MAX_KEYS_TMP_LEN 128
165 :
166 : /** Perform the second (server-side) step of a circuit-creation handshake of
167 : * type <b>type</b>, responding to the client request in <b>onion_skin</b>
168 : * using the keys in <b>keys</b>. On success, write our response into
169 : * <b>reply_out</b>, generate <b>keys_out_len</b> bytes worth of key material
170 : * in <b>keys_out_len</b>, a hidden service nonce to <b>rend_nonce_out</b>,
171 : * and return the length of the reply. On failure, return -1.
172 : */
173 : int
174 0 : onion_skin_server_handshake(int type,
175 : const uint8_t *onion_skin, size_t onionskin_len,
176 : const server_onion_keys_t *keys,
177 : uint8_t *reply_out,
178 : uint8_t *keys_out, size_t keys_out_len,
179 : uint8_t *rend_nonce_out)
180 : {
181 0 : int r = -1;
182 :
183 0 : switch (type) {
184 0 : case ONION_HANDSHAKE_TYPE_TAP:
185 0 : if (onionskin_len != TAP_ONIONSKIN_CHALLENGE_LEN)
186 : return -1;
187 0 : if (onion_skin_TAP_server_handshake((const char*)onion_skin,
188 0 : keys->onion_key, keys->last_onion_key,
189 : (char*)reply_out,
190 : (char*)keys_out, keys_out_len)<0)
191 : return -1;
192 0 : r = TAP_ONIONSKIN_REPLY_LEN;
193 0 : memcpy(rend_nonce_out, reply_out+DH1024_KEY_LEN, DIGEST_LEN);
194 : break;
195 0 : case ONION_HANDSHAKE_TYPE_FAST:
196 0 : if (onionskin_len != CREATE_FAST_LEN)
197 : return -1;
198 0 : if (fast_server_handshake(onion_skin, reply_out, keys_out, keys_out_len)<0)
199 : return -1;
200 0 : r = CREATED_FAST_LEN;
201 0 : memcpy(rend_nonce_out, reply_out+DIGEST_LEN, DIGEST_LEN);
202 : break;
203 0 : case ONION_HANDSHAKE_TYPE_NTOR:
204 0 : if (onionskin_len < NTOR_ONIONSKIN_LEN)
205 : return -1;
206 : {
207 0 : size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
208 0 : tor_assert(keys_tmp_len <= MAX_KEYS_TMP_LEN);
209 0 : uint8_t keys_tmp[MAX_KEYS_TMP_LEN];
210 :
211 0 : if (onion_skin_ntor_server_handshake(
212 0 : onion_skin, keys->curve25519_key_map,
213 0 : keys->junk_keypair,
214 0 : keys->my_identity,
215 : reply_out, keys_tmp, keys_tmp_len)<0) {
216 : /* no need to memwipe here, since the output will never be used */
217 0 : return -1;
218 : }
219 :
220 0 : memcpy(keys_out, keys_tmp, keys_out_len);
221 0 : memcpy(rend_nonce_out, keys_tmp+keys_out_len, DIGEST_LEN);
222 0 : memwipe(keys_tmp, 0, sizeof(keys_tmp));
223 0 : r = NTOR_REPLY_LEN;
224 : }
225 0 : break;
226 0 : default:
227 : /* LCOV_EXCL_START
228 : * We should have rejected this far before this point */
229 : log_warn(LD_BUG, "called with unknown handshake state type %d", type);
230 : tor_fragile_assert();
231 : return -1;
232 : /* LCOV_EXCL_STOP */
233 : }
234 :
235 : return r;
236 : }
237 :
238 : /** Perform the final (client-side) step of a circuit-creation handshake of
239 : * type <b>type</b>, using our state in <b>handshake_state</b> and the
240 : * server's response in <b>reply</b>. On success, generate <b>keys_out_len</b>
241 : * bytes worth of key material in <b>keys_out_len</b>, set
242 : * <b>rend_authenticator_out</b> to the "KH" field that can be used to
243 : * establish introduction points at this hop, and return 0. On failure,
244 : * return -1, and set *msg_out to an error message if this is worth
245 : * complaining to the user about. */
246 : int
247 0 : onion_skin_client_handshake(int type,
248 : const onion_handshake_state_t *handshake_state,
249 : const uint8_t *reply, size_t reply_len,
250 : uint8_t *keys_out, size_t keys_out_len,
251 : uint8_t *rend_authenticator_out,
252 : const char **msg_out)
253 : {
254 0 : if (handshake_state->tag != type)
255 : return -1;
256 :
257 0 : switch (type) {
258 0 : case ONION_HANDSHAKE_TYPE_TAP:
259 0 : if (reply_len != TAP_ONIONSKIN_REPLY_LEN) {
260 0 : if (msg_out)
261 0 : *msg_out = "TAP reply was not of the correct length.";
262 0 : return -1;
263 : }
264 0 : if (onion_skin_TAP_client_handshake(handshake_state->u.tap,
265 : (const char*)reply,
266 : (char *)keys_out, keys_out_len,
267 : msg_out) < 0)
268 : return -1;
269 :
270 0 : memcpy(rend_authenticator_out, reply+DH1024_KEY_LEN, DIGEST_LEN);
271 :
272 0 : return 0;
273 0 : case ONION_HANDSHAKE_TYPE_FAST:
274 0 : if (reply_len != CREATED_FAST_LEN) {
275 0 : if (msg_out)
276 0 : *msg_out = "TAP reply was not of the correct length.";
277 0 : return -1;
278 : }
279 0 : if (fast_client_handshake(handshake_state->u.fast, reply,
280 : keys_out, keys_out_len, msg_out) < 0)
281 : return -1;
282 :
283 0 : memcpy(rend_authenticator_out, reply+DIGEST_LEN, DIGEST_LEN);
284 0 : return 0;
285 0 : case ONION_HANDSHAKE_TYPE_NTOR:
286 0 : if (reply_len < NTOR_REPLY_LEN) {
287 0 : if (msg_out)
288 0 : *msg_out = "ntor reply was not of the correct length.";
289 0 : return -1;
290 : }
291 : {
292 0 : size_t keys_tmp_len = keys_out_len + DIGEST_LEN;
293 0 : uint8_t *keys_tmp = tor_malloc(keys_tmp_len);
294 0 : if (onion_skin_ntor_client_handshake(handshake_state->u.ntor,
295 : reply,
296 : keys_tmp, keys_tmp_len, msg_out) < 0) {
297 0 : tor_free(keys_tmp);
298 0 : return -1;
299 : }
300 0 : memcpy(keys_out, keys_tmp, keys_out_len);
301 0 : memcpy(rend_authenticator_out, keys_tmp + keys_out_len, DIGEST_LEN);
302 0 : memwipe(keys_tmp, 0, keys_tmp_len);
303 0 : tor_free(keys_tmp);
304 : }
305 0 : return 0;
306 0 : default:
307 0 : log_warn(LD_BUG, "called with unknown handshake state type %d", type);
308 0 : tor_fragile_assert();
309 : return -1;
310 : }
311 : }
|