tor  0.4.2.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-2019, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
7 #include "core/or/or.h"
8 #include "core/or/circuitlist.h"
9 #include "core/or/crypt_path.h"
10 #include "app/config/config.h"
13 #include "core/crypto/hs_ntor.h" // for HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN
14 #include "core/or/relay.h"
15 #include "core/crypto/relay_crypto.h"
16 #include "core/or/sendme.h"
17 
18 #include "core/or/cell_st.h"
19 #include "core/or/or_circuit_st.h"
20 #include "core/or/origin_circuit_st.h"
21 
25 void
26 relay_set_digest(crypto_digest_t *digest, cell_t *cell)
27 {
28  char integrity[4];
29  relay_header_t rh;
30 
31  crypto_digest_add_bytes(digest, (char*)cell->payload, CELL_PAYLOAD_SIZE);
32  crypto_digest_get_digest(digest, integrity, 4);
33 // log_fn(LOG_DEBUG,"Putting digest of %u %u %u %u into relay cell.",
34 // integrity[0], integrity[1], integrity[2], integrity[3]);
35  relay_header_unpack(&rh, cell->payload);
36  memcpy(rh.integrity, integrity, 4);
37  relay_header_pack(cell->payload, &rh);
38 }
39 
46 static int
47 relay_digest_matches(crypto_digest_t *digest, cell_t *cell)
48 {
49  uint32_t received_integrity, calculated_integrity;
50  relay_header_t rh;
51  crypto_digest_checkpoint_t backup_digest;
52 
53  crypto_digest_checkpoint(&backup_digest, digest);
54 
55  relay_header_unpack(&rh, cell->payload);
56  memcpy(&received_integrity, rh.integrity, 4);
57  memset(rh.integrity, 0, 4);
58  relay_header_pack(cell->payload, &rh);
59 
60 // log_fn(LOG_DEBUG,"Reading digest of %u %u %u %u from relay cell.",
61 // received_integrity[0], received_integrity[1],
62 // received_integrity[2], received_integrity[3]);
63 
64  crypto_digest_add_bytes(digest, (char*) cell->payload, CELL_PAYLOAD_SIZE);
65  crypto_digest_get_digest(digest, (char*) &calculated_integrity, 4);
66 
67  int rv = 1;
68 
69  if (calculated_integrity != received_integrity) {
70 // log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
71 // (%d vs %d).", received_integrity, calculated_integrity);
72  /* restore digest to its old form */
73  crypto_digest_restore(digest, &backup_digest);
74  /* restore the relay header */
75  memcpy(rh.integrity, &received_integrity, 4);
76  relay_header_pack(cell->payload, &rh);
77  rv = 0;
78  }
79 
80  memwipe(&backup_digest, 0, sizeof(backup_digest));
81  return rv;
82 }
83 
89 void
90 relay_crypt_one_payload(crypto_cipher_t *cipher, uint8_t *in)
91 {
93 }
94 
96 uint8_t *
97 relay_crypto_get_sendme_digest(relay_crypto_t *crypto)
98 {
99  tor_assert(crypto);
100  return crypto->sendme_digest;
101 }
102 
105 void
106 relay_crypto_record_sendme_digest(relay_crypto_t *crypto,
107  bool is_foward_digest)
108 {
109  struct crypto_digest_t *digest;
110 
111  tor_assert(crypto);
112 
113  digest = crypto->b_digest;
114  if (is_foward_digest) {
115  digest = crypto->f_digest;
116  }
117 
118  crypto_digest_get_digest(digest, (char *) crypto->sendme_digest,
119  sizeof(crypto->sendme_digest));
120 }
121 
139 int
140 relay_decrypt_cell(circuit_t *circ, cell_t *cell,
141  cell_direction_t cell_direction,
142  crypt_path_t **layer_hint, char *recognized)
143 {
144  relay_header_t rh;
145 
146  tor_assert(circ);
147  tor_assert(cell);
148  tor_assert(recognized);
149  tor_assert(cell_direction == CELL_DIRECTION_IN ||
150  cell_direction == CELL_DIRECTION_OUT);
151 
152  if (cell_direction == CELL_DIRECTION_IN) {
153  if (CIRCUIT_IS_ORIGIN(circ)) { /* We're at the beginning of the circuit.
154  * We'll want to do layered decrypts. */
155  crypt_path_t *thishop, *cpath = TO_ORIGIN_CIRCUIT(circ)->cpath;
156  thishop = cpath;
157  if (thishop->state != CPATH_STATE_OPEN) {
158  log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
159  "Relay cell before first created cell? Closing.");
160  return -1;
161  }
162  do { /* Remember: cpath is in forward order, that is, first hop first. */
163  tor_assert(thishop);
164 
165  /* decrypt one layer */
166  cpath_crypt_cell(thishop, cell->payload, true);
167 
168  relay_header_unpack(&rh, cell->payload);
169  if (rh.recognized == 0) {
170  /* it's possibly recognized. have to check digest to be sure. */
171  if (relay_digest_matches(cpath_get_incoming_digest(thishop), cell)) {
172  *recognized = 1;
173  *layer_hint = thishop;
174  return 0;
175  }
176  }
177 
178  thishop = thishop->next;
179  } while (thishop != cpath && thishop->state == CPATH_STATE_OPEN);
180  log_fn(LOG_PROTOCOL_WARN, LD_OR,
181  "Incoming cell at client not recognized. Closing.");
182  return -1;
183  } else {
184  relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
185  /* We're in the middle. Encrypt one layer. */
186  relay_crypt_one_payload(crypto->b_crypto, cell->payload);
187  }
188  } else /* cell_direction == CELL_DIRECTION_OUT */ {
189  /* We're in the middle. Decrypt one layer. */
190  relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
191 
192  relay_crypt_one_payload(crypto->f_crypto, cell->payload);
193 
194  relay_header_unpack(&rh, cell->payload);
195  if (rh.recognized == 0) {
196  /* it's possibly recognized. have to check digest to be sure. */
197  if (relay_digest_matches(crypto->f_digest, cell)) {
198  *recognized = 1;
199  return 0;
200  }
201  }
202  }
203  return 0;
204 }
205 
213 void
214 relay_encrypt_cell_outbound(cell_t *cell,
215  origin_circuit_t *circ,
216  crypt_path_t *layer_hint)
217 {
218  crypt_path_t *thishop; /* counter for repeated crypts */
219  cpath_set_cell_forward_digest(layer_hint, cell);
220 
221  /* Record cell digest as the SENDME digest if need be. */
222  sendme_record_sending_cell_digest(TO_CIRCUIT(circ), layer_hint);
223 
224  thishop = layer_hint;
225  /* moving from farthest to nearest hop */
226  do {
227  tor_assert(thishop);
228  log_debug(LD_OR,"encrypting a layer of the relay cell.");
229  cpath_crypt_cell(thishop, cell->payload, false);
230 
231  thishop = thishop->prev;
232  } while (thishop != circ->cpath->prev);
233 }
234 
242 void
243 relay_encrypt_cell_inbound(cell_t *cell,
244  or_circuit_t *or_circ)
245 {
246  relay_set_digest(or_circ->crypto.b_digest, cell);
247 
248  /* Record cell digest as the SENDME digest if need be. */
249  sendme_record_sending_cell_digest(TO_CIRCUIT(or_circ), NULL);
250 
251  /* encrypt one layer */
252  relay_crypt_one_payload(or_circ->crypto.b_crypto, cell->payload);
253 }
254 
259 void
260 relay_crypto_clear(relay_crypto_t *crypto)
261 {
262  if (BUG(!crypto))
263  return;
264  crypto_cipher_free(crypto->f_crypto);
265  crypto_cipher_free(crypto->b_crypto);
266  crypto_digest_free(crypto->f_digest);
267  crypto_digest_free(crypto->b_digest);
268 }
269 
287 int
288 relay_crypto_init(relay_crypto_t *crypto,
289  const char *key_data, size_t key_data_len,
290  int reverse, int is_hs_v3)
291 {
292  crypto_digest_t *tmp_digest;
293  crypto_cipher_t *tmp_crypto;
294  size_t digest_len = 0;
295  size_t cipher_key_len = 0;
296 
297  tor_assert(crypto);
298  tor_assert(key_data);
299  tor_assert(!(crypto->f_crypto || crypto->b_crypto ||
300  crypto->f_digest || crypto->b_digest));
301 
302  /* Basic key size validation */
303  if (is_hs_v3 && BUG(key_data_len != HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN)) {
304  goto err;
305  } else if (!is_hs_v3 && BUG(key_data_len != CPATH_KEY_MATERIAL_LEN)) {
306  goto err;
307  }
308 
309  /* If we are using this crypto for next gen onion services use SHA3-256,
310  otherwise use good ol' SHA1 */
311  if (is_hs_v3) {
312  digest_len = DIGEST256_LEN;
313  cipher_key_len = CIPHER256_KEY_LEN;
314  crypto->f_digest = crypto_digest256_new(DIGEST_SHA3_256);
315  crypto->b_digest = crypto_digest256_new(DIGEST_SHA3_256);
316  } else {
317  digest_len = DIGEST_LEN;
318  cipher_key_len = CIPHER_KEY_LEN;
319  crypto->f_digest = crypto_digest_new();
320  crypto->b_digest = crypto_digest_new();
321  }
322 
323  tor_assert(digest_len != 0);
324  tor_assert(cipher_key_len != 0);
325  const int cipher_key_bits = (int) cipher_key_len * 8;
326 
327  crypto_digest_add_bytes(crypto->f_digest, key_data, digest_len);
328  crypto_digest_add_bytes(crypto->b_digest, key_data+digest_len, digest_len);
329 
330  crypto->f_crypto = crypto_cipher_new_with_bits(key_data+(2*digest_len),
331  cipher_key_bits);
332  if (!crypto->f_crypto) {
333  log_warn(LD_BUG,"Forward cipher initialization failed.");
334  goto err;
335  }
336 
338  key_data+(2*digest_len)+cipher_key_len,
339  cipher_key_bits);
340  if (!crypto->b_crypto) {
341  log_warn(LD_BUG,"Backward cipher initialization failed.");
342  goto err;
343  }
344 
345  if (reverse) {
346  tmp_digest = crypto->f_digest;
347  crypto->f_digest = crypto->b_digest;
348  crypto->b_digest = tmp_digest;
349  tmp_crypto = crypto->f_crypto;
350  crypto->f_crypto = crypto->b_crypto;
351  crypto->b_crypto = tmp_crypto;
352  }
353 
354  return 0;
355  err:
356  relay_crypto_clear(crypto);
357  return -1;
358 }
359 
361 void
362 relay_crypto_assert_ok(const relay_crypto_t *crypto)
363 {
364  tor_assert(crypto->f_crypto);
365  tor_assert(crypto->b_crypto);
366  tor_assert(crypto->f_digest);
367  tor_assert(crypto->b_digest);
368 }
void crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len)
uint8_t payload[CELL_PAYLOAD_SIZE]
Definition: cell_st.h:16
void crypto_digest_get_digest(crypto_digest_t *digest, char *out, size_t out_len)
struct crypt_path_t * next
Definition: crypt_path_st.h:67
Headers for crypto_cipher.c.
Definition: cell_st.h:12
void crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint, const crypto_digest_t *digest)
#define CIRCUIT_IS_ORIGIN(c)
Definition: circuitlist.h:145
void cpath_crypt_cell(const crypt_path_t *cpath, uint8_t *payload, bool is_decrypt)
Definition: crypt_path.c:181
crypt_path_t * cpath
void relay_header_unpack(relay_header_t *dest, const uint8_t *src)
Definition: relay.c:487
struct crypto_cipher_t * f_crypto
crypto_digest_t * crypto_digest256_new(digest_algorithm_t algorithm)
#define TO_CIRCUIT(x)
Definition: or.h:947
Header file for config.c.
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, size_t len)
#define CIPHER_KEY_LEN
Definition: crypto_cipher.h:22
uint16_t recognized
Definition: or.h:639
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:57
uint8_t sendme_digest[DIGEST_LEN]
cell_direction_t
Definition: or.h:482
#define DIGEST256_LEN
Definition: digest_sizes.h:23
struct crypto_digest_t * b_digest
Common functions for cryptographic routines.
tor_assert(buffer)
#define DIGEST_LEN
Definition: digest_sizes.h:20
Master header file for Tor-specific functionality.
void crypto_digest_restore(crypto_digest_t *digest, const crypto_digest_checkpoint_t *checkpoint)
struct crypto_cipher_t * b_crypto
Header file for circuitlist.c.
#define CIPHER256_KEY_LEN
Definition: crypto_cipher.h:26
#define LD_OR
Definition: log.h:89
struct crypt_path_t * prev
Definition: crypt_path_st.h:70
Header file for sendme.c.
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:163
void cpath_set_cell_forward_digest(crypt_path_t *cpath, cell_t *cell)
Definition: crypt_path.c:200
Header file for crypt_path.c.
#define CELL_PAYLOAD_SIZE
Definition: or.h:576
Header file for relay.c.
char integrity[4]
Definition: or.h:641
crypto_cipher_t * crypto_cipher_new_with_bits(const char *key, int bits)
Definition: crypto_cipher.c:54
void relay_header_pack(uint8_t *dest, const relay_header_t *src)
Definition: relay.c:474
uint8_t state
Definition: crypt_path_st.h:63
struct crypto_digest_t * f_digest
#define log_fn(severity, domain, args,...)
Definition: log.h:272
or_circuit_t * TO_OR_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:151
struct crypto_digest_t * cpath_get_incoming_digest(const crypt_path_t *cpath)
Definition: crypt_path.c:192
relay_crypto_t crypto
Definition: or_circuit_st.h:44
#define LD_PROTOCOL
Definition: log.h:69
#define LD_BUG
Definition: log.h:83
crypto_digest_t * crypto_digest_new(void)