Add "Heartbeat" to the start of several heartbeat messages.
[tor.git] / src / core / or / crypt_path.c
blob29356d7c2a79a1dff7f59f74e57dc9083472d128
1 /*
2 * Copyright (c) 2019-2021, The Tor Project, Inc. */
3 /* See LICENSE for licensing information */
5 /**
6 * \file crypt_path.c
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.
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:
17 * - circuit_list_path_impl()
18 **/
20 #define CRYPT_PATH_PRIVATE
22 #include "core/or/or.h"
23 #include "core/or/crypt_path.h"
25 #include "core/crypto/relay_crypto.h"
26 #include "core/crypto/onion_crypto.h"
27 #include "core/or/circuitbuild.h"
28 #include "core/or/circuitlist.h"
29 #include "core/or/extendinfo.h"
31 #include "lib/crypt_ops/crypto_dh.h"
32 #include "lib/crypt_ops/crypto_util.h"
34 #include "core/or/crypt_path_st.h"
35 #include "core/or/cell_st.h"
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.
40 void
41 cpath_extend_linked_list(crypt_path_t **head_ptr, crypt_path_t *new_hop)
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;
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
58 cpath_append_hop(crypt_path_t **head_ptr, extend_info_t *choice)
60 crypt_path_t *hop = tor_malloc_zero(sizeof(crypt_path_t));
62 /* link hop into the cpath, at the end. */
63 cpath_extend_linked_list(head_ptr, hop);
65 hop->magic = CRYPT_PATH_MAGIC;
66 hop->state = CPATH_STATE_CLOSED;
68 hop->extend_info = extend_info_dup(choice);
70 hop->package_window = circuit_initial_package_window();
71 hop->deliver_window = CIRCWINDOW_START;
73 return 0;
76 /** Verify that cpath <b>cp</b> has all of its invariants
77 * correct. Trigger an assert if anything is invalid.
79 void
80 cpath_assert_ok(const crypt_path_t *cp)
82 const crypt_path_t *start = cp;
84 do {
85 cpath_assert_layer_ok(cp);
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);
94 cp = cp->next;
95 tor_assert(cp);
96 } while (cp != start);
99 /** Verify that cpath layer <b>cp</b> has all of its invariants
100 * correct. Trigger an assert if anything is invalid.
102 void
103 cpath_assert_layer_ok(const crypt_path_t *cp)
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)
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. */
116 tor_assert(!cp->rend_dh_handshake_state);
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);
125 tor_assert(cp->package_window >= 0);
126 tor_assert(cp->deliver_window >= 0);
129 /** Initialize cpath-\>{f|b}_{crypto|digest} from the key material in key_data.
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.
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
142 * (If 'reverse' is true, then f_XX and b_XX are swapped.)
144 * Return 0 if init was successful, else -1 if it failed.
147 cpath_init_circuit_crypto(crypt_path_t *cpath,
148 const char *key_data, size_t key_data_len,
149 int reverse, int is_hs_v3)
152 tor_assert(cpath);
153 return relay_crypto_init(&cpath->pvt_crypto, key_data, key_data_len,
154 reverse, is_hs_v3);
157 /** Deallocate space associated with the cpath node <b>victim</b>. */
158 void
159 cpath_free(crypt_path_t *victim)
161 if (!victim)
162 return;
164 relay_crypto_clear(&victim->pvt_crypto);
165 onion_handshake_state_release(&victim->handshake_state);
166 crypto_dh_free(victim->rend_dh_handshake_state);
167 extend_info_free(victim->extend_info);
169 memwipe(victim, 0xBB, sizeof(crypt_path_t)); /* poison memory */
170 tor_free(victim);
173 /********************** cpath crypto API *******************************/
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)
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);
187 /** Getter for the incoming digest of <b>cpath</b>. */
188 struct crypto_digest_t *
189 cpath_get_incoming_digest(const crypt_path_t *cpath)
191 return cpath->pvt_crypto.b_digest;
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
197 cpath_set_cell_forward_digest(crypt_path_t *cpath, cell_t *cell)
199 relay_set_digest(cpath->pvt_crypto.f_digest, cell);
202 /************ cpath sendme API ***************************/
204 /** Return the sendme_digest of this <b>cpath</b>. */
205 uint8_t *
206 cpath_get_sendme_digest(crypt_path_t *cpath)
208 return relay_crypto_get_sendme_digest(&cpath->pvt_crypto);
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)
216 tor_assert(cpath);
217 relay_crypto_record_sendme_digest(&cpath->pvt_crypto, is_foward_digest);
220 /************ other cpath functions ***************************/
222 /** Return the first non-open hop in cpath, or return NULL if all
223 * hops are open. */
224 crypt_path_t *
225 cpath_get_next_non_open_hop(crypt_path_t *cpath)
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;
236 #ifdef TOR_UNIT_TESTS
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)
242 unsigned int n_hops = 0;
243 crypt_path_t *tmp;
245 if (!*head_ptr) {
246 return 0;
249 tmp = *head_ptr;
250 do {
251 n_hops++;
252 tmp = tmp->next;
253 } while (tmp != *head_ptr);
255 return n_hops;
258 #endif /* defined(TOR_UNIT_TESTS) */