Tor 0.4.9.8
Loading...
Searching...
No Matches
relay_crypto.c
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 relay_crypto.h
9 * @brief Header for relay_crypto.c
10 **/
11
12// For access to cpath pvt_crypto field.
13#define CRYPT_PATH_PRIVATE
14
15#include "core/or/or.h"
16#include "core/or/circuitlist.h"
17#include "core/or/crypt_path.h"
18#include "app/config/config.h"
22#include "core/crypto/relay_crypto_tor1.h"
23#include "core/or/sendme.h"
24
25#include "core/or/or_circuit_st.h"
26#include "core/or/cell_st.h"
28
29#define CGO_AES_BITS 128
30
31/** Return the sendme tag within the <b>crypto</b> object,
32 * along with its length.
33 *
34 * This is the digest from the most recent cell that we originated
35 * or recognized, _in either direction_.
36 * Calls to any encryption function on `crypto` may invalidate
37 * this digest.
38 */
39const uint8_t *
40relay_crypto_get_sendme_tag(relay_crypto_t *crypto,
41 size_t *len_out)
42{
43 tor_assert(crypto);
44 switch (crypto->kind) {
45 case RCK_TOR1:
46 *len_out = SENDME_TAG_LEN_TOR1;
47 return crypto->c.tor1.sendme_digest;
48 case RCK_CGO:
49 *len_out = SENDME_TAG_LEN_CGO;
50 return crypto->c.cgo.last_tag;
51 }
52 tor_assert_unreached();
53}
54
55/** Return the length of SENDME tags generated by `crypto`. */
56size_t
57relay_crypto_sendme_tag_len(const relay_crypto_t *crypto)
58{
59 tor_assert(crypto);
60 switch (crypto->kind) {
61 case RCK_TOR1:
63 case RCK_CGO:
64 return SENDME_TAG_LEN_CGO;
65 }
66 tor_assert_unreached();
67}
68
69/**
70 * Handle a single layer of client-side backward encryption
71 * with crypto of an arbitary type.
72 */
73static inline bool
74relay_crypt_client_backward(relay_crypto_t *crypto, cell_t *cell)
75{
76 switch (crypto->kind) {
77 case RCK_TOR1:
78 return tor1_crypt_client_backward(&crypto->c.tor1, cell);
79 case RCK_CGO: {
80 const uint8_t *tag = NULL;
81 cgo_crypt_client_backward(crypto->c.cgo.back, cell, &tag);
82 if (tag != NULL) {
83 memcpy(crypto->c.cgo.last_tag, tag, SENDME_TAG_LEN_CGO);
84 return true;
85 } else {
86 return false;
87 }
88 }
89 }
90 tor_assert_unreached();
91}
92
93/**
94 * Handle a relay-side forward encryption
95 * with crypto of an arbitary type.
96 */
97static inline bool
98relay_crypt_relay_forward(relay_crypto_t *crypto, cell_t *cell)
99{
100 switch (crypto->kind) {
101 case RCK_TOR1:
102 return tor1_crypt_relay_forward(&crypto->c.tor1, cell);
103 case RCK_CGO: {
104 const uint8_t *tag = NULL;
105 cgo_crypt_relay_forward(crypto->c.cgo.fwd, cell, &tag);
106 if (tag != NULL) {
107 memcpy(crypto->c.cgo.last_tag, tag, SENDME_TAG_LEN_CGO);
108 return true;
109 } else {
110 return false;
111 }
112 }
113 }
114 tor_assert_unreached();
115}
116
117/**
118 * Handle relay-side backward encryption with crypto of an arbitary type.
119 */
120static inline void
121relay_crypt_relay_backward(relay_crypto_t *crypto, cell_t *cell)
122{
123 switch (crypto->kind) {
124 case RCK_TOR1:
125 tor1_crypt_relay_backward(&crypto->c.tor1, cell);
126 break;
127 case RCK_CGO: {
128 cgo_crypt_relay_backward(crypto->c.cgo.back, cell);
129 break;
130 }
131 }
132}
133
134/** Do the appropriate en/decryptions for <b>cell</b> arriving on
135 * <b>circ</b> in direction <b>cell_direction</b>.
136 *
137 * If cell_direction == CELL_DIRECTION_IN:
138 * - If we're at the origin (we're the OP), for hops 1..N,
139 * decrypt cell. If recognized, stop.
140 * - Else (we're not the OP), encrypt one hop. Cell is not recognized.
141 *
142 * If cell_direction == CELL_DIRECTION_OUT:
143 * - decrypt one hop. Check if recognized.
144 *
145 * If cell is recognized, set *recognized to 1, and set
146 * *layer_hint to the hop that recognized it.
147 *
148 * Return -1 to indicate that we should mark the circuit for close,
149 * else return 0.
150 */
151int
152relay_decrypt_cell(circuit_t *circ, cell_t *cell,
153 cell_direction_t cell_direction,
154 crypt_path_t **layer_hint, char *recognized)
155{
156 tor_assert(circ);
157 tor_assert(cell);
158 tor_assert(recognized);
159 tor_assert(cell_direction == CELL_DIRECTION_IN ||
160 cell_direction == CELL_DIRECTION_OUT);
161
162 if (cell_direction == CELL_DIRECTION_IN) {
163 if (CIRCUIT_IS_ORIGIN(circ)) { /* We're at the beginning of the circuit.
164 * We'll want to do layered decrypts. */
165 crypt_path_t *thishop, *cpath = TO_ORIGIN_CIRCUIT(circ)->cpath;
166 thishop = cpath;
167 if (thishop->state != CPATH_STATE_OPEN) {
168 log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
169 "Relay cell before first created cell? Closing.");
170 return -1;
171 }
172 do { /* Remember: cpath is in forward order, that is, first hop first. */
173 tor_assert(thishop);
174
175 bool rec = relay_crypt_client_backward(&thishop->pvt_crypto, cell);
176 if (rec) {
177 *recognized = 1;
178 *layer_hint = thishop;
179 return 0;
180 }
181 thishop = thishop->next;
182 } while (thishop != cpath && thishop->state == CPATH_STATE_OPEN);
183 log_fn(LOG_PROTOCOL_WARN, LD_OR,
184 "Incoming cell at client not recognized. Closing.");
185 return -1;
186 } else {
187 /* We're in the middle. Encrypt one layer. */
188 relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
189 relay_crypt_relay_backward(crypto, cell);
190 }
191 } else /* cell_direction == CELL_DIRECTION_OUT */ {
192 /* We're in the middle. Decrypt one layer. */
193 relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
194
195 bool rec = relay_crypt_relay_forward(crypto, cell);
196 if (rec) {
197 *recognized = 1;
198 return 0;
199 }
200 }
201 return 0;
202}
203
204/** Originate a client cell with a relay_crypt_t of arbitrary type. */
205static inline void
206relay_crypt_client_originate(relay_crypto_t *crypto, cell_t *cell)
207{
208 switch (crypto->kind) {
209 case RCK_TOR1:
210 tor1_crypt_client_originate(&crypto->c.tor1, cell);
211 break;
212 case RCK_CGO: {
213 const uint8_t *tag = NULL;
214 cgo_crypt_client_originate(crypto->c.cgo.fwd, cell, &tag);
215 tor_assert(tag);
216 memcpy(crypto->c.cgo.last_tag, tag, SENDME_TAG_LEN_CGO);
217 break;
218 }
219 }
220}
221
222/** Perform forward-direction client encryption with a relay_crypt_t
223 * of arbitrary type. */
224static inline void
225relay_crypt_client_forward(relay_crypto_t *crypto, cell_t *cell)
226{
227 switch (crypto->kind) {
228 case RCK_TOR1:
229 tor1_crypt_client_forward(&crypto->c.tor1, cell);
230 break;
231 case RCK_CGO:
232 cgo_crypt_client_forward(crypto->c.cgo.fwd, cell);
233 break;
234 }
235}
236
237/**
238 * Encrypt a cell <b>cell</b> that we are creating, and sending outbound on
239 * <b>circ</b> until the hop corresponding to <b>layer_hint</b>.
240 *
241 * The integrity field and recognized field of <b>cell</b>'s relay headers
242 * must be set to zero.
243 */
244void
245relay_encrypt_cell_outbound(cell_t *cell,
246 origin_circuit_t *circ,
247 crypt_path_t *layer_hint)
248{
249 crypt_path_t *thishop = layer_hint;
250
251 relay_crypt_client_originate(&thishop->pvt_crypto, cell);
252 thishop = thishop->prev;
253
254 while (thishop != circ->cpath->prev) {
255 relay_crypt_client_forward(&thishop->pvt_crypto, cell);
256 thishop = thishop->prev;
257 }
258}
259
260/**
261 * Encrypt a cell <b>cell</b> that we are creating, and sending on
262 * <b>circuit</b> to the origin.
263 *
264 * The integrity field and recognized field of <b>cell</b>'s relay headers
265 * must be set to zero.
266 *
267 * Returns 0 on success, -1 on error.
268 */
269int
270relay_encrypt_cell_inbound(cell_t *cell,
271 or_circuit_t *or_circ)
272{
273 relay_crypto_t *crypto = &or_circ->crypto;
274 switch (crypto->kind) {
275 case RCK_TOR1:
276 tor1_crypt_relay_originate(&crypto->c.tor1, cell);
277 return 0;
278 case RCK_CGO: {
279 const uint8_t *tag = NULL;
280 cgo_crypt_relay_originate(crypto->c.cgo.back, cell, &tag);
281 tor_assert(tag);
282 memcpy(&crypto->c.cgo.last_tag, tag, SENDME_TAG_LEN_CGO);
283 return 0;
284 }
285 default:
286 /* Do not silently accept unknown crypto algs as a no-op.
287 * This mitigates the heap spray vector used in #41243.
288 * (heap spray vectors in Tor are rare, so this is worthwhile). */
290 memwipe(cell, 0, sizeof(*cell));
291 return -1;
292 }
293}
294
295/**
296 * Release all storage held inside <b>crypto</b>, but do not free
297 * <b>crypto</b> itself: it lives inside another object.
298 */
299void
300relay_crypto_clear(relay_crypto_t *crypto)
301{
302 switch (crypto->kind) {
303 case RCK_TOR1:
304 tor1_crypt_clear(&crypto->c.tor1);
305 break;
306 case RCK_CGO:
307 cgo_crypt_free(crypto->c.cgo.fwd);
308 cgo_crypt_free(crypto->c.cgo.back);
309 break;
310 }
311}
312
313static int
314cgo_pair_init(cgo_pair_t *pair, bool is_relay,
315 const uint8_t *key_material, size_t key_data_len)
316{
317 memset(pair, 0, sizeof(*pair));
318 const int aes_bits = CGO_AES_BITS;
319 const size_t single_cgo_len = cgo_key_material_len(aes_bits);
320 if (BUG(key_data_len != single_cgo_len * 2)) {
321 return -1;
322 }
323
324 cgo_mode_t fwd_mode, back_mode;
325 if (is_relay) {
326 fwd_mode = CGO_MODE_RELAY_FORWARD;
327 back_mode = CGO_MODE_RELAY_BACKWARD;
328 } else {
329 fwd_mode = CGO_MODE_CLIENT_FORWARD;
330 back_mode = CGO_MODE_CLIENT_BACKWARD;
331 }
332
333 pair->fwd = cgo_crypt_new(fwd_mode, aes_bits,
334 key_material, single_cgo_len);
335 pair->back = cgo_crypt_new(back_mode, aes_bits,
336 key_material + single_cgo_len, single_cgo_len);
337
338 return 0;
339}
340
341/** Initialize <b>crypto</b> from the key material in key_data.
342 *
343 * If <b>is_hs_v3</b> is set, this cpath will be used for next gen hidden
344 * service circuits and <b>key_data</b> must be at least
345 * HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length.
346 *
347 * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL_LEN
348 * bytes, which are used as follows:
349 * - 20 to initialize f_digest
350 * - 20 to initialize b_digest
351 * - 16 to key f_crypto
352 * - 16 to key b_crypto
353 *
354 * (If 'reverse' is true, then f_XX and b_XX are swapped.)
355 *
356 * Return 0 if init was successful, else -1 if it failed.
357 */
358int
359relay_crypto_init(relay_crypto_alg_t alg,
360 relay_crypto_t *crypto,
361 const char *key_data, size_t key_data_len)
362{
363 switch (alg) {
364 /* Tor1 cases: the booleans are "reverse" and "is_hs_v3". */
366 crypto->kind = RCK_TOR1;
367 return tor1_crypt_init(&crypto->c.tor1, key_data, key_data_len,
368 false, false);
370 crypto->kind = RCK_TOR1;
371 return tor1_crypt_init(&crypto->c.tor1, key_data, key_data_len,
372 false, true);
374 crypto->kind = RCK_TOR1;
375 return tor1_crypt_init(&crypto->c.tor1, key_data, key_data_len,
376 true, true);
378 crypto->kind = RCK_CGO;
379 return cgo_pair_init(&crypto->c.cgo, false,
380 (const uint8_t *)key_data, key_data_len);
382 crypto->kind = RCK_CGO;
383 return cgo_pair_init(&crypto->c.cgo, true,
384 (const uint8_t *)key_data, key_data_len);
385 }
386 tor_assert_unreached();
387}
388
389/** Return the amount of key material we need to initialize
390 * the given relay crypto algorithm.
391 *
392 * Return -1 if the algorithm is unrecognized.
393 */
394ssize_t
395relay_crypto_key_material_len(relay_crypto_alg_t alg)
396{
397 switch (alg) {
399 return tor1_key_material_len(false);
402 return tor1_key_material_len(true);
405 return cgo_key_material_len(CGO_AES_BITS) * 2;
406 }
407 return -1;
408}
409
410/** Assert that <b>crypto</b> is valid and set. */
411void
412relay_crypto_assert_ok(const relay_crypto_t *crypto)
413{
414 switch (crypto->kind) {
415 case RCK_TOR1:
416 tor1_crypt_assert_ok(&crypto->c.tor1);
417 break;
418 case RCK_CGO:
419 break;
420 }
421}
Fixed-size cell structure.
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
or_circuit_t * TO_OR_CIRCUIT(circuit_t *x)
Header file for circuitlist.c.
#define CIRCUIT_IS_ORIGIN(c)
Header file for config.c.
Header file for crypt_path.c.
Headers for crypto_cipher.c.
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition crypto_util.c:55
Common functions for cryptographic routines.
#define log_fn(severity, domain, args,...)
Definition log.h:283
#define LD_PROTOCOL
Definition log.h:72
#define LD_OR
Definition log.h:92
Master header file for Tor-specific functionality.
#define SENDME_TAG_LEN_TOR1
Definition or.h:459
#define SENDME_TAG_LEN_CGO
Definition or.h:461
cell_direction_t
Definition or.h:427
@ CELL_DIRECTION_OUT
Definition or.h:429
@ CELL_DIRECTION_IN
Definition or.h:428
Origin circuit structure.
Header for relay_crypto.c.
relay_crypto_alg_t
@ RELAY_CRYPTO_ALG_TOR1_HSS
@ RELAY_CRYPTO_ALG_TOR1_HSC
@ RELAY_CRYPTO_ALG_TOR1
@ RELAY_CRYPTO_ALG_CGO_RELAY
@ RELAY_CRYPTO_ALG_CGO_CLIENT
void cgo_crypt_relay_originate(cgo_crypt_t *cgo, cell_t *cell, const uint8_t **tag_out)
void cgo_crypt_client_forward(cgo_crypt_t *cgo, cell_t *cell)
void cgo_crypt_relay_backward(cgo_crypt_t *cgo, cell_t *cell)
size_t cgo_key_material_len(int aesbits)
void cgo_crypt_relay_forward(cgo_crypt_t *cgo, cell_t *cell, const uint8_t **recognized_tag_out)
cgo_crypt_t * cgo_crypt_new(cgo_mode_t mode, int aesbits, const uint8_t *keys, size_t keylen)
void cgo_crypt_client_originate(cgo_crypt_t *cgo, cell_t *cell, const uint8_t **tag_out)
void cgo_crypt_client_backward(cgo_crypt_t *cgo, cell_t *cell, const uint8_t **recognized_tag_out)
void tor1_crypt_client_forward(tor1_crypt_t *tor1, cell_t *cell)
void tor1_crypt_assert_ok(const tor1_crypt_t *crypto)
void tor1_crypt_relay_backward(tor1_crypt_t *tor1, cell_t *cell)
void tor1_crypt_relay_originate(tor1_crypt_t *tor1, cell_t *cell)
int tor1_crypt_init(tor1_crypt_t *crypto, const char *key_data, size_t key_data_len, int reverse, int is_hs_v3)
void tor1_crypt_client_originate(tor1_crypt_t *tor1, cell_t *cell)
bool tor1_crypt_client_backward(tor1_crypt_t *tor1, cell_t *cell)
size_t tor1_key_material_len(bool is_hs)
bool tor1_crypt_relay_forward(tor1_crypt_t *tor1, cell_t *cell)
Header file for sendme.c.
struct crypt_path_t * prev
struct crypt_path_t * next
relay_crypto_t crypto
crypt_path_t * cpath
uint8_t sendme_digest[DIGEST_LEN]
#define tor_assert(expr)
Definition util_bug.h:103
#define tor_fragile_assert()
Definition util_bug.h:278