Tor  0.4.7.0-alpha-dev
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 #include "core/or/or.h"
13 #include "core/or/circuitlist.h"
14 #include "core/or/crypt_path.h"
15 #include "app/config/config.h"
18 #include "core/crypto/hs_ntor.h" // for HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN
19 #include "core/or/relay.h"
21 #include "core/or/sendme.h"
22 
23 #include "core/or/cell_st.h"
24 #include "core/or/or_circuit_st.h"
26 
27 /** Update digest from the payload of cell. Assign integrity part to
28  * cell.
29  */
30 void
32 {
33  char integrity[4];
34  relay_header_t rh;
35 
36  crypto_digest_add_bytes(digest, (char*)cell->payload, CELL_PAYLOAD_SIZE);
37  crypto_digest_get_digest(digest, integrity, 4);
38 // log_fn(LOG_DEBUG,"Putting digest of %u %u %u %u into relay cell.",
39 // integrity[0], integrity[1], integrity[2], integrity[3]);
40  relay_header_unpack(&rh, cell->payload);
41  memcpy(rh.integrity, integrity, 4);
42  relay_header_pack(cell->payload, &rh);
43 }
44 
45 /** Does the digest for this circuit indicate that this cell is for us?
46  *
47  * Update digest from the payload of cell (with the integrity part set
48  * to 0). If the integrity part is valid, return 1, else restore digest
49  * and cell to their original state and return 0.
50  */
51 static int
52 relay_digest_matches(crypto_digest_t *digest, cell_t *cell)
53 {
54  uint32_t received_integrity, calculated_integrity;
55  relay_header_t rh;
56  crypto_digest_checkpoint_t backup_digest;
57 
58  crypto_digest_checkpoint(&backup_digest, digest);
59 
60  relay_header_unpack(&rh, cell->payload);
61  memcpy(&received_integrity, rh.integrity, 4);
62  memset(rh.integrity, 0, 4);
63  relay_header_pack(cell->payload, &rh);
64 
65 // log_fn(LOG_DEBUG,"Reading digest of %u %u %u %u from relay cell.",
66 // received_integrity[0], received_integrity[1],
67 // received_integrity[2], received_integrity[3]);
68 
69  crypto_digest_add_bytes(digest, (char*) cell->payload, CELL_PAYLOAD_SIZE);
70  crypto_digest_get_digest(digest, (char*) &calculated_integrity, 4);
71 
72  int rv = 1;
73 
74  if (calculated_integrity != received_integrity) {
75 // log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
76 // (%d vs %d).", received_integrity, calculated_integrity);
77  /* restore digest to its old form */
78  crypto_digest_restore(digest, &backup_digest);
79  /* restore the relay header */
80  memcpy(rh.integrity, &received_integrity, 4);
81  relay_header_pack(cell->payload, &rh);
82  rv = 0;
83  }
84 
85  memwipe(&backup_digest, 0, sizeof(backup_digest));
86  return rv;
87 }
88 
89 /** Apply <b>cipher</b> to CELL_PAYLOAD_SIZE bytes of <b>in</b>
90  * (in place).
91  *
92  * Note that we use the same operation for encrypting and for decrypting.
93  */
94 void
95 relay_crypt_one_payload(crypto_cipher_t *cipher, uint8_t *in)
96 {
98 }
99 
100 /** Return the sendme_digest within the <b>crypto</b> object. */
101 uint8_t *
103 {
104  tor_assert(crypto);
105  return crypto->sendme_digest;
106 }
107 
108 /** Record the cell digest, indicated by is_foward_digest or not, as the
109  * SENDME cell digest. */
110 void
112  bool is_foward_digest)
113 {
114  struct crypto_digest_t *digest;
115 
116  tor_assert(crypto);
117 
118  digest = crypto->b_digest;
119  if (is_foward_digest) {
120  digest = crypto->f_digest;
121  }
122 
123  crypto_digest_get_digest(digest, (char *) crypto->sendme_digest,
124  sizeof(crypto->sendme_digest));
125 }
126 
127 /** Do the appropriate en/decryptions for <b>cell</b> arriving on
128  * <b>circ</b> in direction <b>cell_direction</b>.
129  *
130  * If cell_direction == CELL_DIRECTION_IN:
131  * - If we're at the origin (we're the OP), for hops 1..N,
132  * decrypt cell. If recognized, stop.
133  * - Else (we're not the OP), encrypt one hop. Cell is not recognized.
134  *
135  * If cell_direction == CELL_DIRECTION_OUT:
136  * - decrypt one hop. Check if recognized.
137  *
138  * If cell is recognized, set *recognized to 1, and set
139  * *layer_hint to the hop that recognized it.
140  *
141  * Return -1 to indicate that we should mark the circuit for close,
142  * else return 0.
143  */
144 int
146  cell_direction_t cell_direction,
147  crypt_path_t **layer_hint, char *recognized)
148 {
149  relay_header_t rh;
150 
151  tor_assert(circ);
152  tor_assert(cell);
153  tor_assert(recognized);
154  tor_assert(cell_direction == CELL_DIRECTION_IN ||
155  cell_direction == CELL_DIRECTION_OUT);
156 
157  if (cell_direction == CELL_DIRECTION_IN) {
158  if (CIRCUIT_IS_ORIGIN(circ)) { /* We're at the beginning of the circuit.
159  * We'll want to do layered decrypts. */
160  crypt_path_t *thishop, *cpath = TO_ORIGIN_CIRCUIT(circ)->cpath;
161  thishop = cpath;
162  if (thishop->state != CPATH_STATE_OPEN) {
163  log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
164  "Relay cell before first created cell? Closing.");
165  return -1;
166  }
167  do { /* Remember: cpath is in forward order, that is, first hop first. */
168  tor_assert(thishop);
169 
170  /* decrypt one layer */
171  cpath_crypt_cell(thishop, cell->payload, true);
172 
173  relay_header_unpack(&rh, cell->payload);
174  if (rh.recognized == 0) {
175  /* it's possibly recognized. have to check digest to be sure. */
176  if (relay_digest_matches(cpath_get_incoming_digest(thishop), cell)) {
177  *recognized = 1;
178  *layer_hint = thishop;
179  return 0;
180  }
181  }
182 
183  thishop = thishop->next;
184  } while (thishop != cpath && thishop->state == CPATH_STATE_OPEN);
185  log_fn(LOG_PROTOCOL_WARN, LD_OR,
186  "Incoming cell at client not recognized. Closing.");
187  return -1;
188  } else {
189  relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
190  /* We're in the middle. Encrypt one layer. */
191  relay_crypt_one_payload(crypto->b_crypto, cell->payload);
192  }
193  } else /* cell_direction == CELL_DIRECTION_OUT */ {
194  /* We're in the middle. Decrypt one layer. */
195  relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
196 
197  relay_crypt_one_payload(crypto->f_crypto, cell->payload);
198 
199  relay_header_unpack(&rh, cell->payload);
200  if (rh.recognized == 0) {
201  /* it's possibly recognized. have to check digest to be sure. */
202  if (relay_digest_matches(crypto->f_digest, cell)) {
203  *recognized = 1;
204  return 0;
205  }
206  }
207  }
208  return 0;
209 }
210 
211 /**
212  * Encrypt a cell <b>cell</b> that we are creating, and sending outbound on
213  * <b>circ</b> until the hop corresponding to <b>layer_hint</b>.
214  *
215  * The integrity field and recognized field of <b>cell</b>'s relay headers
216  * must be set to zero.
217  */
218 void
220  origin_circuit_t *circ,
221  crypt_path_t *layer_hint)
222 {
223  crypt_path_t *thishop; /* counter for repeated crypts */
224  cpath_set_cell_forward_digest(layer_hint, cell);
225 
226  /* Record cell digest as the SENDME digest if need be. */
227  sendme_record_sending_cell_digest(TO_CIRCUIT(circ), layer_hint);
228 
229  thishop = layer_hint;
230  /* moving from farthest to nearest hop */
231  do {
232  tor_assert(thishop);
233  log_debug(LD_OR,"encrypting a layer of the relay cell.");
234  cpath_crypt_cell(thishop, cell->payload, false);
235 
236  thishop = thishop->prev;
237  } while (thishop != circ->cpath->prev);
238 }
239 
240 /**
241  * Encrypt a cell <b>cell</b> that we are creating, and sending on
242  * <b>circuit</b> to the origin.
243  *
244  * The integrity field and recognized field of <b>cell</b>'s relay headers
245  * must be set to zero.
246  */
247 void
249  or_circuit_t *or_circ)
250 {
251  relay_set_digest(or_circ->crypto.b_digest, cell);
252 
253  /* Record cell digest as the SENDME digest if need be. */
254  sendme_record_sending_cell_digest(TO_CIRCUIT(or_circ), NULL);
255 
256  /* encrypt one layer */
258 }
259 
260 /**
261  * Release all storage held inside <b>crypto</b>, but do not free
262  * <b>crypto</b> itself: it lives inside another object.
263  */
264 void
266 {
267  if (BUG(!crypto))
268  return;
269  crypto_cipher_free(crypto->f_crypto);
270  crypto_cipher_free(crypto->b_crypto);
271  crypto_digest_free(crypto->f_digest);
272  crypto_digest_free(crypto->b_digest);
273 }
274 
275 /** Initialize <b>crypto</b> from the key material in key_data.
276  *
277  * If <b>is_hs_v3</b> is set, this cpath will be used for next gen hidden
278  * service circuits and <b>key_data</b> must be at least
279  * HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length.
280  *
281  * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL_LEN
282  * bytes, which are used as follows:
283  * - 20 to initialize f_digest
284  * - 20 to initialize b_digest
285  * - 16 to key f_crypto
286  * - 16 to key b_crypto
287  *
288  * (If 'reverse' is true, then f_XX and b_XX are swapped.)
289  *
290  * Return 0 if init was successful, else -1 if it failed.
291  */
292 int
294  const char *key_data, size_t key_data_len,
295  int reverse, int is_hs_v3)
296 {
297  crypto_digest_t *tmp_digest;
298  crypto_cipher_t *tmp_crypto;
299  size_t digest_len = 0;
300  size_t cipher_key_len = 0;
301 
302  tor_assert(crypto);
303  tor_assert(key_data);
304  tor_assert(!(crypto->f_crypto || crypto->b_crypto ||
305  crypto->f_digest || crypto->b_digest));
306 
307  /* Basic key size validation */
308  if (is_hs_v3 && BUG(key_data_len != HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN)) {
309  goto err;
310  } else if (!is_hs_v3 && BUG(key_data_len != CPATH_KEY_MATERIAL_LEN)) {
311  goto err;
312  }
313 
314  /* If we are using this crypto for next gen onion services use SHA3-256,
315  otherwise use good ol' SHA1 */
316  if (is_hs_v3) {
317  digest_len = DIGEST256_LEN;
318  cipher_key_len = CIPHER256_KEY_LEN;
319  crypto->f_digest = crypto_digest256_new(DIGEST_SHA3_256);
320  crypto->b_digest = crypto_digest256_new(DIGEST_SHA3_256);
321  } else {
322  digest_len = DIGEST_LEN;
323  cipher_key_len = CIPHER_KEY_LEN;
324  crypto->f_digest = crypto_digest_new();
325  crypto->b_digest = crypto_digest_new();
326  }
327 
328  tor_assert(digest_len != 0);
329  tor_assert(cipher_key_len != 0);
330  const int cipher_key_bits = (int) cipher_key_len * 8;
331 
332  crypto_digest_add_bytes(crypto->f_digest, key_data, digest_len);
333  crypto_digest_add_bytes(crypto->b_digest, key_data+digest_len, digest_len);
334 
335  crypto->f_crypto = crypto_cipher_new_with_bits(key_data+(2*digest_len),
336  cipher_key_bits);
337  if (!crypto->f_crypto) {
338  log_warn(LD_BUG,"Forward cipher initialization failed.");
339  goto err;
340  }
341 
343  key_data+(2*digest_len)+cipher_key_len,
344  cipher_key_bits);
345  if (!crypto->b_crypto) {
346  log_warn(LD_BUG,"Backward cipher initialization failed.");
347  goto err;
348  }
349 
350  if (reverse) {
351  tmp_digest = crypto->f_digest;
352  crypto->f_digest = crypto->b_digest;
353  crypto->b_digest = tmp_digest;
354  tmp_crypto = crypto->f_crypto;
355  crypto->f_crypto = crypto->b_crypto;
356  crypto->b_crypto = tmp_crypto;
357  }
358 
359  return 0;
360  err:
361  relay_crypto_clear(crypto);
362  return -1;
363 }
364 
365 /** Assert that <b>crypto</b> is valid and set. */
366 void
368 {
369  tor_assert(crypto->f_crypto);
370  tor_assert(crypto->b_crypto);
371  tor_assert(crypto->f_digest);
372  tor_assert(crypto->b_digest);
373 }
Fixed-size cell structure.
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:166
or_circuit_t * TO_OR_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:154
Header file for circuitlist.c.
#define CIRCUIT_IS_ORIGIN(c)
Definition: circuitlist.h:147
Header file for config.c.
struct crypto_digest_t * cpath_get_incoming_digest(const crypt_path_t *cpath)
Definition: crypt_path.c:189
void cpath_crypt_cell(const crypt_path_t *cpath, uint8_t *payload, bool is_decrypt)
Definition: crypt_path.c:178
void cpath_set_cell_forward_digest(crypt_path_t *cpath, cell_t *cell)
Definition: crypt_path.c:197
Header file for crypt_path.c.
void crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len)
crypto_cipher_t * crypto_cipher_new_with_bits(const char *key, int bits)
Definition: crypto_cipher.c:54
Headers for crypto_cipher.c.
#define CIPHER_KEY_LEN
Definition: crypto_cipher.h:22
#define CIPHER256_KEY_LEN
Definition: crypto_cipher.h:26
void crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint, const crypto_digest_t *digest)
void crypto_digest_restore(crypto_digest_t *digest, const crypto_digest_checkpoint_t *checkpoint)
void crypto_digest_get_digest(crypto_digest_t *digest, char *out, size_t out_len)
crypto_digest_t * crypto_digest256_new(digest_algorithm_t algorithm)
#define crypto_digest_free(d)
crypto_digest_t * crypto_digest_new(void)
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, size_t len)
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
Common functions for cryptographic routines.
#define DIGEST_LEN
Definition: digest_sizes.h:20
#define DIGEST256_LEN
Definition: digest_sizes.h:23
Header for hs_ntor.c.
#define log_fn(severity, domain, args,...)
Definition: log.h:283
#define LD_PROTOCOL
Definition: log.h:72
#define LD_OR
Definition: log.h:92
#define LD_BUG
Definition: log.h:86
Master header file for Tor-specific functionality.
#define CELL_PAYLOAD_SIZE
Definition: or.h:457
#define TO_CIRCUIT(x)
Definition: or.h:845
cell_direction_t
Definition: or.h:363
@ CELL_DIRECTION_OUT
Definition: or.h:365
@ CELL_DIRECTION_IN
Definition: or.h:364
Origin circuit structure.
void relay_header_pack(uint8_t *dest, const relay_header_t *src)
Definition: relay.c:478
void relay_header_unpack(relay_header_t *dest, const uint8_t *src)
Definition: relay.c:491
Header file for relay.c.
Header for relay_crypto.c.
void relay_encrypt_cell_outbound(cell_t *cell, origin_circuit_t *or_circ, crypt_path_t *layer_hint)
Definition: relay_crypto.c:219
void relay_crypto_assert_ok(const relay_crypto_t *crypto)
Definition: relay_crypto.c:367
int relay_crypto_init(relay_crypto_t *crypto, const char *key_data, size_t key_data_len, int reverse, int is_hs_v3)
Definition: relay_crypto.c:293
void relay_crypto_record_sendme_digest(relay_crypto_t *crypto, bool is_foward_digest)
Definition: relay_crypto.c:111
void relay_set_digest(crypto_digest_t *digest, cell_t *cell)
Definition: relay_crypto.c:31
uint8_t * relay_crypto_get_sendme_digest(relay_crypto_t *crypto)
Definition: relay_crypto.c:102
int relay_decrypt_cell(circuit_t *circ, cell_t *cell, cell_direction_t cell_direction, crypt_path_t **layer_hint, char *recognized)
Definition: relay_crypto.c:145
void relay_crypto_clear(relay_crypto_t *crypto)
Definition: relay_crypto.c:265
void relay_encrypt_cell_inbound(cell_t *cell, or_circuit_t *or_circ)
Definition: relay_crypto.c:248
void relay_crypt_one_payload(crypto_cipher_t *cipher, uint8_t *in)
Definition: relay_crypto.c:95
Header file for sendme.c.
Definition: cell_st.h:17
uint8_t payload[CELL_PAYLOAD_SIZE]
Definition: cell_st.h:21
struct crypt_path_t * prev
Definition: crypt_path_st.h:75
uint8_t state
Definition: crypt_path_st.h:68
struct crypt_path_t * next
Definition: crypt_path_st.h:72
relay_crypto_t crypto
Definition: or_circuit_st.h:46
crypt_path_t * cpath
struct crypto_digest_t * b_digest
struct crypto_digest_t * f_digest
uint8_t sendme_digest[DIGEST_LEN]
struct crypto_cipher_t * f_crypto
struct crypto_cipher_t * b_crypto
uint16_t recognized
Definition: or.h:520
char integrity[4]
Definition: or.h:522
#define tor_assert(expr)
Definition: util_bug.h:102