2 * Copyright (c) 2019-2021, The Tor Project, Inc. */
3 /* See LICENSE for licensing information */
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
17 * - circuit_list_path_impl()
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.
42 cpath_extend_linked_list(crypt_path_t
**head_ptr
, crypt_path_t
*new_hop
)
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
;
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>. */
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
;
77 /** Verify that cpath <b>cp</b> has all of its invariants
78 * correct. Trigger an assert if anything is invalid.
81 cpath_assert_ok(const crypt_path_t
*cp
)
83 const crypt_path_t
*start
= cp
;
86 cpath_assert_layer_ok(cp
);
87 /* layers must be in sequence of: "open* awaiting? closed*" */
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
);
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.
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);
109 tor_assert(cp
->magic
== CRYPT_PATH_MAGIC
);
112 case CPATH_STATE_OPEN
:
113 relay_crypto_assert_ok(&cp
->pvt_crypto
);
115 case CPATH_STATE_CLOSED
:
116 /*XXXX Assert that there's no handshake_state either. */
117 tor_assert(!cp
->rend_dh_handshake_state
);
119 case CPATH_STATE_AWAITING_KEYS
:
120 /* tor_assert(cp->dh_handshake_state); */
123 log_fn(LOG_ERR
, LD_BUG
, "Unexpected state %d", cp
->state
);
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
)
154 return relay_crypto_init(&cpath
->pvt_crypto
, key_data
, key_data_len
,
158 /** Deallocate space associated with the cpath node <b>victim</b>. */
160 cpath_free(crypt_path_t
*victim
)
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 */
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>. */
180 cpath_crypt_cell(const crypt_path_t
*cpath
, uint8_t *payload
, bool is_decrypt
)
183 relay_crypt_one_payload(cpath
->pvt_crypto
.b_crypto
, payload
);
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>. */
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>. */
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. */
216 cpath_sendme_record_cell_digest(crypt_path_t
*cpath
, bool is_foward_digest
)
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
227 cpath_get_next_non_open_hop(crypt_path_t
*cpath
)
229 crypt_path_t
*hop
= cpath
;
231 if (hop
->state
!= CPATH_STATE_OPEN
)
234 } while (hop
!= cpath
);
238 #ifdef TOR_UNIT_TESTS
240 /** Unittest helper function: Count number of hops in cpath linked list. */
242 cpath_get_n_hops(crypt_path_t
**head_ptr
)
244 unsigned int n_hops
= 0;
255 } while (tmp
!= *head_ptr
);
260 #endif /* defined(TOR_UNIT_TESTS) */