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