tor  0.4.0.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-2018, 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 "app/config/config.h"
12 #include "core/crypto/hs_ntor.h" // for HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN
13 #include "core/or/relay.h"
14 #include "core/crypto/relay_crypto.h"
15 
16 #include "core/or/cell_st.h"
17 #include "core/or/or_circuit_st.h"
18 #include "core/or/origin_circuit_st.h"
19 
23 static void
24 relay_set_digest(crypto_digest_t *digest, cell_t *cell)
25 {
26  char integrity[4];
27  relay_header_t rh;
28 
29  crypto_digest_add_bytes(digest, (char*)cell->payload, CELL_PAYLOAD_SIZE);
30  crypto_digest_get_digest(digest, integrity, 4);
31 // log_fn(LOG_DEBUG,"Putting digest of %u %u %u %u into relay cell.",
32 // integrity[0], integrity[1], integrity[2], integrity[3]);
33  relay_header_unpack(&rh, cell->payload);
34  memcpy(rh.integrity, integrity, 4);
35  relay_header_pack(cell->payload, &rh);
36 }
37 
44 static int
45 relay_digest_matches(crypto_digest_t *digest, cell_t *cell)
46 {
47  uint32_t received_integrity, calculated_integrity;
48  relay_header_t rh;
49  crypto_digest_checkpoint_t backup_digest;
50 
51  crypto_digest_checkpoint(&backup_digest, digest);
52 
53  relay_header_unpack(&rh, cell->payload);
54  memcpy(&received_integrity, rh.integrity, 4);
55  memset(rh.integrity, 0, 4);
56  relay_header_pack(cell->payload, &rh);
57 
58 // log_fn(LOG_DEBUG,"Reading digest of %u %u %u %u from relay cell.",
59 // received_integrity[0], received_integrity[1],
60 // received_integrity[2], received_integrity[3]);
61 
62  crypto_digest_add_bytes(digest, (char*) cell->payload, CELL_PAYLOAD_SIZE);
63  crypto_digest_get_digest(digest, (char*) &calculated_integrity, 4);
64 
65  int rv = 1;
66 
67  if (calculated_integrity != received_integrity) {
68 // log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
69 // (%d vs %d).", received_integrity, calculated_integrity);
70  /* restore digest to its old form */
71  crypto_digest_restore(digest, &backup_digest);
72  /* restore the relay header */
73  memcpy(rh.integrity, &received_integrity, 4);
74  relay_header_pack(cell->payload, &rh);
75  rv = 0;
76  }
77 
78  memwipe(&backup_digest, 0, sizeof(backup_digest));
79  return rv;
80 }
81 
87 static void
88 relay_crypt_one_payload(crypto_cipher_t *cipher, uint8_t *in)
89 {
91 }
92 
110 int
111 relay_decrypt_cell(circuit_t *circ, cell_t *cell,
112  cell_direction_t cell_direction,
113  crypt_path_t **layer_hint, char *recognized)
114 {
115  relay_header_t rh;
116 
117  tor_assert(circ);
118  tor_assert(cell);
119  tor_assert(recognized);
120  tor_assert(cell_direction == CELL_DIRECTION_IN ||
121  cell_direction == CELL_DIRECTION_OUT);
122 
123  if (cell_direction == CELL_DIRECTION_IN) {
124  if (CIRCUIT_IS_ORIGIN(circ)) { /* We're at the beginning of the circuit.
125  * We'll want to do layered decrypts. */
126  crypt_path_t *thishop, *cpath = TO_ORIGIN_CIRCUIT(circ)->cpath;
127  thishop = cpath;
128  if (thishop->state != CPATH_STATE_OPEN) {
129  log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
130  "Relay cell before first created cell? Closing.");
131  return -1;
132  }
133  do { /* Remember: cpath is in forward order, that is, first hop first. */
134  tor_assert(thishop);
135 
136  /* decrypt one layer */
137  relay_crypt_one_payload(thishop->crypto.b_crypto, cell->payload);
138 
139  relay_header_unpack(&rh, cell->payload);
140  if (rh.recognized == 0) {
141  /* it's possibly recognized. have to check digest to be sure. */
142  if (relay_digest_matches(thishop->crypto.b_digest, cell)) {
143  *recognized = 1;
144  *layer_hint = thishop;
145  return 0;
146  }
147  }
148 
149  thishop = thishop->next;
150  } while (thishop != cpath && thishop->state == CPATH_STATE_OPEN);
151  log_fn(LOG_PROTOCOL_WARN, LD_OR,
152  "Incoming cell at client not recognized. Closing.");
153  return -1;
154  } else {
155  relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
156  /* We're in the middle. Encrypt one layer. */
157  relay_crypt_one_payload(crypto->b_crypto, cell->payload);
158  }
159  } else /* cell_direction == CELL_DIRECTION_OUT */ {
160  /* We're in the middle. Decrypt one layer. */
161  relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
162 
163  relay_crypt_one_payload(crypto->f_crypto, cell->payload);
164 
165  relay_header_unpack(&rh, cell->payload);
166  if (rh.recognized == 0) {
167  /* it's possibly recognized. have to check digest to be sure. */
168  if (relay_digest_matches(crypto->f_digest, cell)) {
169  *recognized = 1;
170  return 0;
171  }
172  }
173  }
174  return 0;
175 }
176 
184 void
185 relay_encrypt_cell_outbound(cell_t *cell,
186  origin_circuit_t *circ,
187  crypt_path_t *layer_hint)
188 {
189  crypt_path_t *thishop; /* counter for repeated crypts */
190  relay_set_digest(layer_hint->crypto.f_digest, cell);
191 
192  thishop = layer_hint;
193  /* moving from farthest to nearest hop */
194  do {
195  tor_assert(thishop);
196  log_debug(LD_OR,"encrypting a layer of the relay cell.");
197  relay_crypt_one_payload(thishop->crypto.f_crypto, cell->payload);
198 
199  thishop = thishop->prev;
200  } while (thishop != circ->cpath->prev);
201 }
202 
210 void
211 relay_encrypt_cell_inbound(cell_t *cell,
212  or_circuit_t *or_circ)
213 {
214  relay_set_digest(or_circ->crypto.b_digest, cell);
215  /* encrypt one layer */
216  relay_crypt_one_payload(or_circ->crypto.b_crypto, cell->payload);
217 }
218 
223 void
224 relay_crypto_clear(relay_crypto_t *crypto)
225 {
226  if (BUG(!crypto))
227  return;
228  crypto_cipher_free(crypto->f_crypto);
229  crypto_cipher_free(crypto->b_crypto);
230  crypto_digest_free(crypto->f_digest);
231  crypto_digest_free(crypto->b_digest);
232 }
233 
251 int
252 relay_crypto_init(relay_crypto_t *crypto,
253  const char *key_data, size_t key_data_len,
254  int reverse, int is_hs_v3)
255 {
256  crypto_digest_t *tmp_digest;
257  crypto_cipher_t *tmp_crypto;
258  size_t digest_len = 0;
259  size_t cipher_key_len = 0;
260 
261  tor_assert(crypto);
262  tor_assert(key_data);
263  tor_assert(!(crypto->f_crypto || crypto->b_crypto ||
264  crypto->f_digest || crypto->b_digest));
265 
266  /* Basic key size validation */
267  if (is_hs_v3 && BUG(key_data_len != HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN)) {
268  goto err;
269  } else if (!is_hs_v3 && BUG(key_data_len != CPATH_KEY_MATERIAL_LEN)) {
270  goto err;
271  }
272 
273  /* If we are using this crypto for next gen onion services use SHA3-256,
274  otherwise use good ol' SHA1 */
275  if (is_hs_v3) {
276  digest_len = DIGEST256_LEN;
277  cipher_key_len = CIPHER256_KEY_LEN;
278  crypto->f_digest = crypto_digest256_new(DIGEST_SHA3_256);
279  crypto->b_digest = crypto_digest256_new(DIGEST_SHA3_256);
280  } else {
281  digest_len = DIGEST_LEN;
282  cipher_key_len = CIPHER_KEY_LEN;
283  crypto->f_digest = crypto_digest_new();
284  crypto->b_digest = crypto_digest_new();
285  }
286 
287  tor_assert(digest_len != 0);
288  tor_assert(cipher_key_len != 0);
289  const int cipher_key_bits = (int) cipher_key_len * 8;
290 
291  crypto_digest_add_bytes(crypto->f_digest, key_data, digest_len);
292  crypto_digest_add_bytes(crypto->b_digest, key_data+digest_len, digest_len);
293 
294  crypto->f_crypto = crypto_cipher_new_with_bits(key_data+(2*digest_len),
295  cipher_key_bits);
296  if (!crypto->f_crypto) {
297  log_warn(LD_BUG,"Forward cipher initialization failed.");
298  goto err;
299  }
300 
302  key_data+(2*digest_len)+cipher_key_len,
303  cipher_key_bits);
304  if (!crypto->b_crypto) {
305  log_warn(LD_BUG,"Backward cipher initialization failed.");
306  goto err;
307  }
308 
309  if (reverse) {
310  tmp_digest = crypto->f_digest;
311  crypto->f_digest = crypto->b_digest;
312  crypto->b_digest = tmp_digest;
313  tmp_crypto = crypto->f_crypto;
314  crypto->f_crypto = crypto->b_crypto;
315  crypto->b_crypto = tmp_crypto;
316  }
317 
318  return 0;
319  err:
320  relay_crypto_clear(crypto);
321  return -1;
322 }
323 
325 void
326 relay_crypto_assert_ok(const relay_crypto_t *crypto)
327 {
328  tor_assert(crypto->f_crypto);
329  tor_assert(crypto->b_crypto);
330  tor_assert(crypto->f_digest);
331  tor_assert(crypto->b_digest);
332 }
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, size_t len)
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
struct crypt_path_t * next
Definition: crypt_path_st.h:58
Headers for crypto_cipher.c.
void crypto_digest_restore(crypto_digest_t *digest, const crypto_digest_checkpoint_t *checkpoint)
Definition: cell_st.h:12
#define CIRCUIT_IS_ORIGIN(c)
Definition: circuitlist.h:143
crypt_path_t * cpath
void relay_header_unpack(relay_header_t *dest, const uint8_t *src)
Definition: relay.c:489
crypto_digest_t * crypto_digest_new(void)
struct crypto_cipher_t * f_crypto
Header file for config.c.
#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
cell_direction_t
Definition: or.h:482
void crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint, const crypto_digest_t *digest)
#define DIGEST256_LEN
Definition: digest_sizes.h:23
struct crypto_digest_t * b_digest
relay_crypto_t crypto
Definition: crypt_path_st.h:34
Common functions for cryptographic routines.
tor_assert(buffer)
#define DIGEST_LEN
Definition: digest_sizes.h:20
void crypto_digest_get_digest(crypto_digest_t *digest, char *out, size_t out_len)
Master header file for Tor-specific functionality.
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:88
struct crypt_path_t * prev
Definition: crypt_path_st.h:61
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:163
#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:476
uint8_t state
Definition: crypt_path_st.h:54
struct crypto_digest_t * f_digest
#define log_fn(severity, domain, args,...)
Definition: log.h:255
or_circuit_t * TO_OR_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:151
relay_crypto_t crypto
Definition: or_circuit_st.h:49
#define LD_PROTOCOL
Definition: log.h:68
#define LD_BUG
Definition: log.h:82
crypto_digest_t * crypto_digest256_new(digest_algorithm_t algorithm)