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"
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.
41 cpath_extend_linked_list(crypt_path_t
**head_ptr
, crypt_path_t
*new_hop
)
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
;
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>. */
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
;
76 /** Verify that cpath <b>cp</b> has all of its invariants
77 * correct. Trigger an assert if anything is invalid.
80 cpath_assert_ok(const crypt_path_t
*cp
)
82 const crypt_path_t
*start
= cp
;
85 cpath_assert_layer_ok(cp
);
86 /* layers must be in sequence of: "open* awaiting? closed*" */
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
);
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.
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);
108 tor_assert(cp
->magic
== CRYPT_PATH_MAGIC
);
111 case CPATH_STATE_OPEN
:
112 relay_crypto_assert_ok(&cp
->pvt_crypto
);
114 case CPATH_STATE_CLOSED
:
115 /*XXXX Assert that there's no handshake_state either. */
116 tor_assert(!cp
->rend_dh_handshake_state
);
118 case CPATH_STATE_AWAITING_KEYS
:
119 /* tor_assert(cp->dh_handshake_state); */
122 log_fn(LOG_ERR
, LD_BUG
, "Unexpected state %d", cp
->state
);
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
)
153 return relay_crypto_init(&cpath
->pvt_crypto
, key_data
, key_data_len
,
157 /** Deallocate space associated with the cpath node <b>victim</b>. */
159 cpath_free(crypt_path_t
*victim
)
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 */
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>. */
178 cpath_crypt_cell(const crypt_path_t
*cpath
, uint8_t *payload
, bool is_decrypt
)
181 relay_crypt_one_payload(cpath
->pvt_crypto
.b_crypto
, payload
);
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>. */
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>. */
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. */
214 cpath_sendme_record_cell_digest(crypt_path_t
*cpath
, bool is_foward_digest
)
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
225 cpath_get_next_non_open_hop(crypt_path_t
*cpath
)
227 crypt_path_t
*hop
= cpath
;
229 if (hop
->state
!= CPATH_STATE_OPEN
)
232 } while (hop
!= cpath
);
236 #ifdef TOR_UNIT_TESTS
238 /** Unittest helper function: Count number of hops in cpath linked list. */
240 cpath_get_n_hops(crypt_path_t
**head_ptr
)
242 unsigned int n_hops
= 0;
253 } while (tmp
!= *head_ptr
);
258 #endif /* defined(TOR_UNIT_TESTS) */