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