Merge branch 'maint-0.4.8'
[tor.git] / src / core / or / crypt_path.c
blob7673bc306f1be6f9bffebee8e3a017bac2427952
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"
30 #include "core/or/congestion_control_common.h"
32 #include "lib/crypt_ops/crypto_dh.h"
33 #include "lib/crypt_ops/crypto_util.h"
35 #include "core/or/crypt_path_st.h"
36 #include "core/or/cell_st.h"
38 /** Add <b>new_hop</b> to the end of the doubly-linked-list <b>head_ptr</b>.
39 * This function is used to extend cpath by another hop.
41 void
42 cpath_extend_linked_list(crypt_path_t **head_ptr, crypt_path_t *new_hop)
44 if (*head_ptr) {
45 new_hop->next = (*head_ptr);
46 new_hop->prev = (*head_ptr)->prev;
47 (*head_ptr)->prev->next = new_hop;
48 (*head_ptr)->prev = new_hop;
49 } else {
50 *head_ptr = new_hop;
51 new_hop->prev = new_hop->next = new_hop;
55 /** Create a new hop, annotate it with information about its
56 * corresponding router <b>choice</b>, and append it to the
57 * end of the cpath <b>head_ptr</b>. */
58 int
59 cpath_append_hop(crypt_path_t **head_ptr, extend_info_t *choice)
61 crypt_path_t *hop = tor_malloc_zero(sizeof(crypt_path_t));
63 /* link hop into the cpath, at the end. */
64 cpath_extend_linked_list(head_ptr, hop);
66 hop->magic = CRYPT_PATH_MAGIC;
67 hop->state = CPATH_STATE_CLOSED;
69 hop->extend_info = extend_info_dup(choice);
71 hop->package_window = circuit_initial_package_window();
72 hop->deliver_window = CIRCWINDOW_START;
74 return 0;
77 /** Verify that cpath <b>cp</b> has all of its invariants
78 * correct. Trigger an assert if anything is invalid.
80 void
81 cpath_assert_ok(const crypt_path_t *cp)
83 const crypt_path_t *start = cp;
85 do {
86 cpath_assert_layer_ok(cp);
87 /* layers must be in sequence of: "open* awaiting? closed*" */
88 if (cp != start) {
89 if (cp->state == CPATH_STATE_AWAITING_KEYS) {
90 tor_assert(cp->prev->state == CPATH_STATE_OPEN);
91 } else if (cp->state == CPATH_STATE_OPEN) {
92 tor_assert(cp->prev->state == CPATH_STATE_OPEN);
95 cp = cp->next;
96 tor_assert(cp);
97 } while (cp != start);
100 /** Verify that cpath layer <b>cp</b> has all of its invariants
101 * correct. Trigger an assert if anything is invalid.
103 void
104 cpath_assert_layer_ok(const crypt_path_t *cp)
106 // tor_assert(cp->addr); /* these are zero for rendezvous extra-hops */
107 // tor_assert(cp->port);
108 tor_assert(cp);
109 tor_assert(cp->magic == CRYPT_PATH_MAGIC);
110 switch (cp->state)
112 case CPATH_STATE_OPEN:
113 relay_crypto_assert_ok(&cp->pvt_crypto);
114 FALLTHROUGH;
115 case CPATH_STATE_CLOSED:
116 /*XXXX Assert that there's no handshake_state either. */
117 tor_assert(!cp->rend_dh_handshake_state);
118 break;
119 case CPATH_STATE_AWAITING_KEYS:
120 /* tor_assert(cp->dh_handshake_state); */
121 break;
122 default:
123 log_fn(LOG_ERR, LD_BUG, "Unexpected state %d", cp->state);
124 tor_assert(0);
126 tor_assert(cp->package_window >= 0);
127 tor_assert(cp->deliver_window >= 0);
130 /** Initialize cpath-\>{f|b}_{crypto|digest} from the key material in key_data.
132 * If <b>is_hs_v3</b> is set, this cpath will be used for next gen hidden
133 * service circuits and <b>key_data</b> must be at least
134 * HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length.
136 * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL_LEN
137 * bytes, which are used as follows:
138 * - 20 to initialize f_digest
139 * - 20 to initialize b_digest
140 * - 16 to key f_crypto
141 * - 16 to key b_crypto
143 * (If 'reverse' is true, then f_XX and b_XX are swapped.)
145 * Return 0 if init was successful, else -1 if it failed.
148 cpath_init_circuit_crypto(crypt_path_t *cpath,
149 const char *key_data, size_t key_data_len,
150 int reverse, int is_hs_v3)
153 tor_assert(cpath);
154 return relay_crypto_init(&cpath->pvt_crypto, key_data, key_data_len,
155 reverse, is_hs_v3);
158 /** Deallocate space associated with the cpath node <b>victim</b>. */
159 void
160 cpath_free(crypt_path_t *victim)
162 if (!victim)
163 return;
165 relay_crypto_clear(&victim->pvt_crypto);
166 onion_handshake_state_release(&victim->handshake_state);
167 crypto_dh_free(victim->rend_dh_handshake_state);
168 extend_info_free(victim->extend_info);
169 congestion_control_free(victim->ccontrol);
171 memwipe(victim, 0xBB, sizeof(crypt_path_t)); /* poison memory */
172 tor_free(victim);
175 /********************** cpath crypto API *******************************/
177 /** Encrypt or decrypt <b>payload</b> using the crypto of <b>cpath</b>. Actual
178 * operation decided by <b>is_decrypt</b>. */
179 void
180 cpath_crypt_cell(const crypt_path_t *cpath, uint8_t *payload, bool is_decrypt)
182 if (is_decrypt) {
183 relay_crypt_one_payload(cpath->pvt_crypto.b_crypto, payload);
184 } else {
185 relay_crypt_one_payload(cpath->pvt_crypto.f_crypto, payload);
189 /** Getter for the incoming digest of <b>cpath</b>. */
190 struct crypto_digest_t *
191 cpath_get_incoming_digest(const crypt_path_t *cpath)
193 return cpath->pvt_crypto.b_digest;
196 /** Set the right integrity digest on the outgoing <b>cell</b> based on the
197 * cell payload and update the forward digest of <b>cpath</b>. */
198 void
199 cpath_set_cell_forward_digest(crypt_path_t *cpath, cell_t *cell)
201 relay_set_digest(cpath->pvt_crypto.f_digest, cell);
204 /************ cpath sendme API ***************************/
206 /** Return the sendme_digest of this <b>cpath</b>. */
207 uint8_t *
208 cpath_get_sendme_digest(crypt_path_t *cpath)
210 return relay_crypto_get_sendme_digest(&cpath->pvt_crypto);
213 /** Record the cell digest, indicated by is_foward_digest or not, as the
214 * SENDME cell digest. */
215 void
216 cpath_sendme_record_cell_digest(crypt_path_t *cpath, bool is_foward_digest)
218 tor_assert(cpath);
219 relay_crypto_record_sendme_digest(&cpath->pvt_crypto, is_foward_digest);
222 /************ other cpath functions ***************************/
224 /** Return the first non-open hop in cpath, or return NULL if all
225 * hops are open. */
226 crypt_path_t *
227 cpath_get_next_non_open_hop(crypt_path_t *cpath)
229 crypt_path_t *hop = cpath;
230 do {
231 if (hop->state != CPATH_STATE_OPEN)
232 return hop;
233 hop = hop->next;
234 } while (hop != cpath);
235 return NULL;
238 #ifdef TOR_UNIT_TESTS
240 /** Unittest helper function: Count number of hops in cpath linked list. */
241 unsigned int
242 cpath_get_n_hops(crypt_path_t **head_ptr)
244 unsigned int n_hops = 0;
245 crypt_path_t *tmp;
247 if (!*head_ptr) {
248 return 0;
251 tmp = *head_ptr;
252 do {
253 n_hops++;
254 tmp = tmp->next;
255 } while (tmp != *head_ptr);
257 return n_hops;
260 #endif /* defined(TOR_UNIT_TESTS) */