Tor  0.4.6.0-alpha-dev
crypt_path.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2020, The Tor Project, Inc. */
3 /* See LICENSE for licensing information */
4 
5 /**
6  * \file crypt_path.c
7  *
8  * \brief Functions dealing with layered circuit encryption. This file aims to
9  * provide an API around the crypt_path_t structure which holds crypto
10  * information about a specific hop of a circuit.
11  *
12  * TODO: We should eventually move all functions dealing and manipulating
13  * crypt_path_t to this file, so that eventually we encapsulate more and more
14  * of crypt_path_t. Here are some more functions that can be moved here with
15  * some more effort:
16  *
17  * - circuit_list_path_impl()
18  * - Functions dealing with cpaths in HSv2 create_rend_cpath() and
19  * create_rend_cpath_legacy()
20  * - The cpath related parts of rend_service_receive_introduction() and
21  * rend_client_send_introduction().
22  **/
23 
24 #define CRYPT_PATH_PRIVATE
25 
26 #include "core/or/or.h"
27 #include "core/or/crypt_path.h"
28 
31 #include "core/or/circuitbuild.h"
32 #include "core/or/circuitlist.h"
33 #include "core/or/extendinfo.h"
34 
37 
38 #include "core/or/crypt_path_st.h"
39 #include "core/or/cell_st.h"
40 
41 /** Add <b>new_hop</b> to the end of the doubly-linked-list <b>head_ptr</b>.
42  * This function is used to extend cpath by another hop.
43  */
44 void
46 {
47  if (*head_ptr) {
48  new_hop->next = (*head_ptr);
49  new_hop->prev = (*head_ptr)->prev;
50  (*head_ptr)->prev->next = new_hop;
51  (*head_ptr)->prev = new_hop;
52  } else {
53  *head_ptr = new_hop;
54  new_hop->prev = new_hop->next = new_hop;
55  }
56 }
57 
58 /** Create a new hop, annotate it with information about its
59  * corresponding router <b>choice</b>, and append it to the
60  * end of the cpath <b>head_ptr</b>. */
61 int
63 {
64  crypt_path_t *hop = tor_malloc_zero(sizeof(crypt_path_t));
65 
66  /* link hop into the cpath, at the end. */
67  cpath_extend_linked_list(head_ptr, hop);
68 
69  hop->magic = CRYPT_PATH_MAGIC;
70  hop->state = CPATH_STATE_CLOSED;
71 
72  hop->extend_info = extend_info_dup(choice);
73 
76 
77  return 0;
78 }
79 
80 /** Verify that cpath <b>cp</b> has all of its invariants
81  * correct. Trigger an assert if anything is invalid.
82  */
83 void
85 {
86  const crypt_path_t *start = cp;
87 
88  do {
90  /* layers must be in sequence of: "open* awaiting? closed*" */
91  if (cp != start) {
92  if (cp->state == CPATH_STATE_AWAITING_KEYS) {
93  tor_assert(cp->prev->state == CPATH_STATE_OPEN);
94  } else if (cp->state == CPATH_STATE_OPEN) {
95  tor_assert(cp->prev->state == CPATH_STATE_OPEN);
96  }
97  }
98  cp = cp->next;
99  tor_assert(cp);
100  } while (cp != start);
101 }
102 
103 /** Verify that cpath layer <b>cp</b> has all of its invariants
104  * correct. Trigger an assert if anything is invalid.
105  */
106 void
108 {
109 // tor_assert(cp->addr); /* these are zero for rendezvous extra-hops */
110 // tor_assert(cp->port);
111  tor_assert(cp);
112  tor_assert(cp->magic == CRYPT_PATH_MAGIC);
113  switch (cp->state)
114  {
115  case CPATH_STATE_OPEN:
116  relay_crypto_assert_ok(&cp->pvt_crypto);
117  FALLTHROUGH;
118  case CPATH_STATE_CLOSED:
119  /*XXXX Assert that there's no handshake_state either. */
121  break;
122  case CPATH_STATE_AWAITING_KEYS:
123  /* tor_assert(cp->dh_handshake_state); */
124  break;
125  default:
126  log_fn(LOG_ERR, LD_BUG, "Unexpected state %d", cp->state);
127  tor_assert(0);
128  }
129  tor_assert(cp->package_window >= 0);
130  tor_assert(cp->deliver_window >= 0);
131 }
132 
133 /** Initialize cpath->{f|b}_{crypto|digest} from the key material in key_data.
134  *
135  * If <b>is_hs_v3</b> is set, this cpath will be used for next gen hidden
136  * service circuits and <b>key_data</b> must be at least
137  * HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length.
138  *
139  * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL_LEN
140  * bytes, which are used as follows:
141  * - 20 to initialize f_digest
142  * - 20 to initialize b_digest
143  * - 16 to key f_crypto
144  * - 16 to key b_crypto
145  *
146  * (If 'reverse' is true, then f_XX and b_XX are swapped.)
147  *
148  * Return 0 if init was successful, else -1 if it failed.
149  */
150 int
152  const char *key_data, size_t key_data_len,
153  int reverse, int is_hs_v3)
154 {
155 
156  tor_assert(cpath);
157  return relay_crypto_init(&cpath->pvt_crypto, key_data, key_data_len,
158  reverse, is_hs_v3);
159 }
160 
161 /** Deallocate space associated with the cpath node <b>victim</b>. */
162 void
164 {
165  if (!victim)
166  return;
167 
168  relay_crypto_clear(&victim->pvt_crypto);
170  crypto_dh_free(victim->rend_dh_handshake_state);
171  extend_info_free(victim->extend_info);
172 
173  memwipe(victim, 0xBB, sizeof(crypt_path_t)); /* poison memory */
174  tor_free(victim);
175 }
176 
177 /********************** cpath crypto API *******************************/
178 
179 /** Encrypt or decrypt <b>payload</b> using the crypto of <b>cpath</b>. Actual
180  * operation decided by <b>is_decrypt</b>. */
181 void
182 cpath_crypt_cell(const crypt_path_t *cpath, uint8_t *payload, bool is_decrypt)
183 {
184  if (is_decrypt) {
185  relay_crypt_one_payload(cpath->pvt_crypto.b_crypto, payload);
186  } else {
187  relay_crypt_one_payload(cpath->pvt_crypto.f_crypto, payload);
188  }
189 }
190 
191 /** Getter for the incoming digest of <b>cpath</b>. */
192 struct crypto_digest_t *
194 {
195  return cpath->pvt_crypto.b_digest;
196 }
197 
198 /** Set the right integrity digest on the outgoing <b>cell</b> based on the
199  * cell payload and update the forward digest of <b>cpath</b>. */
200 void
202 {
203  relay_set_digest(cpath->pvt_crypto.f_digest, cell);
204 }
205 
206 /************ cpath sendme API ***************************/
207 
208 /** Return the sendme_digest of this <b>cpath</b>. */
209 uint8_t *
211 {
212  return relay_crypto_get_sendme_digest(&cpath->pvt_crypto);
213 }
214 
215 /** Record the cell digest, indicated by is_foward_digest or not, as the
216  * SENDME cell digest. */
217 void
218 cpath_sendme_record_cell_digest(crypt_path_t *cpath, bool is_foward_digest)
219 {
220  tor_assert(cpath);
221  relay_crypto_record_sendme_digest(&cpath->pvt_crypto, is_foward_digest);
222 }
223 
224 /************ other cpath functions ***************************/
225 
226 /** Return the first non-open hop in cpath, or return NULL if all
227  * hops are open. */
228 crypt_path_t *
230 {
231  crypt_path_t *hop = cpath;
232  do {
233  if (hop->state != CPATH_STATE_OPEN)
234  return hop;
235  hop = hop->next;
236  } while (hop != cpath);
237  return NULL;
238 }
239 
240 #ifdef TOR_UNIT_TESTS
241 
242 /** Unittest helper function: Count number of hops in cpath linked list. */
243 unsigned int
244 cpath_get_n_hops(crypt_path_t **head_ptr)
245 {
246  unsigned int n_hops = 0;
247  crypt_path_t *tmp;
248 
249  if (!*head_ptr) {
250  return 0;
251  }
252 
253  tmp = *head_ptr;
254  do {
255  n_hops++;
256  tmp = tmp->next;
257  } while (tmp != *head_ptr);
258 
259  return n_hops;
260 }
261 
262 #endif /* defined(TOR_UNIT_TESTS) */
log_fn
#define log_fn(severity, domain, args,...)
Definition: log.h:283
tor_free
#define tor_free(p)
Definition: malloc.h:52
memwipe
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
crypt_path_t::package_window
int package_window
Definition: crypt_path_st.h:78
relay_crypto_get_sendme_digest
uint8_t * relay_crypto_get_sendme_digest(relay_crypto_t *crypto)
Definition: relay_crypto.c:102
tor_assert
#define tor_assert(expr)
Definition: util_bug.h:102
LD_BUG
#define LD_BUG
Definition: log.h:86
relay_crypt_one_payload
void relay_crypt_one_payload(crypto_cipher_t *cipher, uint8_t *in)
Definition: relay_crypto.c:95
crypt_path_t::state
uint8_t state
Definition: crypt_path_st.h:68
crypt_path_t::handshake_state
onion_handshake_state_t handshake_state
Definition: crypt_path_st.h:52
cpath_crypt_cell
void cpath_crypt_cell(const crypt_path_t *cpath, uint8_t *payload, bool is_decrypt)
Definition: crypt_path.c:182
cpath_sendme_record_cell_digest
void cpath_sendme_record_cell_digest(crypt_path_t *cpath, bool is_foward_digest)
Definition: crypt_path.c:218
crypto_digest_t
Definition: crypto_digest_nss.c:166
crypt_path.h
Header file for crypt_path.c.
crypt_path_t
Definition: crypt_path_st.h:47
cell_t
Definition: cell_st.h:17
crypto_util.h
Common functions for cryptographic routines.
relay_crypto_init
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
circuitlist.h
Header file for circuitlist.c.
crypt_path_st.h
Path structures for origin circuits.
cpath_assert_ok
void cpath_assert_ok(const crypt_path_t *cp)
Definition: crypt_path.c:84
cpath_free
void cpath_free(crypt_path_t *victim)
Definition: crypt_path.c:163
crypt_path_t::deliver_window
int deliver_window
Definition: crypt_path_st.h:80
crypto_dh.h
Headers for crypto_dh.c.
crypt_path_t::rend_dh_handshake_state
struct crypto_dh_t * rend_dh_handshake_state
Definition: crypt_path_st.h:55
relay_set_digest
void relay_set_digest(crypto_digest_t *digest, cell_t *cell)
Definition: relay_crypto.c:31
cpath_extend_linked_list
void cpath_extend_linked_list(crypt_path_t **head_ptr, crypt_path_t *new_hop)
Definition: crypt_path.c:45
extendinfo.h
Header for core/or/extendinfo.c.
cpath_get_incoming_digest
struct crypto_digest_t * cpath_get_incoming_digest(const crypt_path_t *cpath)
Definition: crypt_path.c:193
CIRCWINDOW_START
#define CIRCWINDOW_START
Definition: or.h:502
relay_crypto_record_sendme_digest
void relay_crypto_record_sendme_digest(relay_crypto_t *crypto, bool is_foward_digest)
Definition: relay_crypto.c:111
relay_crypto_assert_ok
void relay_crypto_assert_ok(const relay_crypto_t *crypto)
Definition: relay_crypto.c:367
circuitbuild.h
Header file for circuitbuild.c.
cpath_init_circuit_crypto
int cpath_init_circuit_crypto(crypt_path_t *cpath, const char *key_data, size_t key_data_len, int reverse, int is_hs_v3)
Definition: crypt_path.c:151
crypt_path_t::prev
struct crypt_path_t * prev
Definition: crypt_path_st.h:75
cpath_append_hop
int cpath_append_hop(crypt_path_t **head_ptr, extend_info_t *choice)
Definition: crypt_path.c:62
crypt_path_t::extend_info
extend_info_t * extend_info
Definition: crypt_path_st.h:61
relay_crypto.h
Header for relay_crypto.c.
onion_crypto.h
Header file for onion_crypto.c.
LOG_ERR
#define LOG_ERR
Definition: log.h:56
cell_st.h
Fixed-size cell structure.
crypt_path_t::next
struct crypt_path_t * next
Definition: crypt_path_st.h:72
extend_info_dup
extend_info_t * extend_info_dup(extend_info_t *info)
Definition: extendinfo.c:180
cpath_get_sendme_digest
uint8_t * cpath_get_sendme_digest(crypt_path_t *cpath)
Definition: crypt_path.c:210
cpath_assert_layer_ok
void cpath_assert_layer_ok(const crypt_path_t *cp)
Definition: crypt_path.c:107
relay_crypto_clear
void relay_crypto_clear(relay_crypto_t *crypto)
Definition: relay_crypto.c:265
cpath_set_cell_forward_digest
void cpath_set_cell_forward_digest(crypt_path_t *cpath, cell_t *cell)
Definition: crypt_path.c:201
circuit_initial_package_window
int32_t circuit_initial_package_window(void)
Definition: circuitlist.c:977
cpath_get_next_non_open_hop
crypt_path_t * cpath_get_next_non_open_hop(crypt_path_t *cpath)
Definition: crypt_path.c:229
onion_handshake_state_release
void onion_handshake_state_release(onion_handshake_state_t *state)
Definition: onion_crypto.c:79
extend_info_t
Definition: extend_info_st.h:27
or.h
Master header file for Tor-specific functionality.