Tor 0.4.9.0-alpha-dev
relay_crypto.c
1/* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
5/* See LICENSE for licensing information */
6
7/**
8 * @file relay_crypto.h
9 * @brief Header for relay_crypto.c
10 **/
11
12#include "core/or/or.h"
13#include "core/or/circuitlist.h"
14#include "core/or/crypt_path.h"
15#include "app/config/config.h"
18#include "core/crypto/hs_ntor.h" // for HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN
19#include "core/or/relay.h"
21#include "core/or/sendme.h"
22
23#include "core/or/cell_st.h"
24#include "core/or/or_circuit_st.h"
26
27/** Update digest from the payload of cell. Assign integrity part to
28 * cell.
29 */
30void
32{
33 char integrity[4];
35
37 crypto_digest_get_digest(digest, integrity, 4);
38// log_fn(LOG_DEBUG,"Putting digest of %u %u %u %u into relay cell.",
39// integrity[0], integrity[1], integrity[2], integrity[3]);
40 relay_header_unpack(&rh, cell->payload);
41 memcpy(rh.integrity, integrity, 4);
42 relay_header_pack(cell->payload, &rh);
43}
44
45/** Does the digest for this circuit indicate that this cell is for us?
46 *
47 * Update digest from the payload of cell (with the integrity part set
48 * to 0). If the integrity part is valid, return 1, else restore digest
49 * and cell to their original state and return 0.
50 */
51static int
52relay_digest_matches(crypto_digest_t *digest, cell_t *cell)
53{
54 uint32_t received_integrity, calculated_integrity;
56 crypto_digest_checkpoint_t backup_digest;
57
58 crypto_digest_checkpoint(&backup_digest, digest);
59
60 relay_header_unpack(&rh, cell->payload);
61 memcpy(&received_integrity, rh.integrity, 4);
62 memset(rh.integrity, 0, 4);
63 relay_header_pack(cell->payload, &rh);
64
65// log_fn(LOG_DEBUG,"Reading digest of %u %u %u %u from relay cell.",
66// received_integrity[0], received_integrity[1],
67// received_integrity[2], received_integrity[3]);
68
70 crypto_digest_get_digest(digest, (char*) &calculated_integrity, 4);
71
72 int rv = 1;
73
74 if (calculated_integrity != received_integrity) {
75// log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
76// (%d vs %d).", received_integrity, calculated_integrity);
77 /* restore digest to its old form */
78 crypto_digest_restore(digest, &backup_digest);
79 /* restore the relay header */
80 memcpy(rh.integrity, &received_integrity, 4);
81 relay_header_pack(cell->payload, &rh);
82 rv = 0;
83 }
84
85 memwipe(&backup_digest, 0, sizeof(backup_digest));
86 return rv;
87}
88
89/** Apply <b>cipher</b> to CELL_PAYLOAD_SIZE bytes of <b>in</b>
90 * (in place).
91 *
92 * Note that we use the same operation for encrypting and for decrypting.
93 */
94void
95relay_crypt_one_payload(crypto_cipher_t *cipher, uint8_t *in)
96{
98}
99
100/** Return the sendme_digest within the <b>crypto</b> object. */
101uint8_t *
103{
104 tor_assert(crypto);
105 return crypto->sendme_digest;
106}
107
108/** Record the cell digest, indicated by is_foward_digest or not, as the
109 * SENDME cell digest. */
110void
112 bool is_foward_digest)
113{
114 struct crypto_digest_t *digest;
115
116 tor_assert(crypto);
117
118 digest = crypto->b_digest;
119 if (is_foward_digest) {
120 digest = crypto->f_digest;
121 }
122
123 crypto_digest_get_digest(digest, (char *) crypto->sendme_digest,
124 sizeof(crypto->sendme_digest));
125}
126
127/** Do the appropriate en/decryptions for <b>cell</b> arriving on
128 * <b>circ</b> in direction <b>cell_direction</b>.
129 *
130 * If cell_direction == CELL_DIRECTION_IN:
131 * - If we're at the origin (we're the OP), for hops 1..N,
132 * decrypt cell. If recognized, stop.
133 * - Else (we're not the OP), encrypt one hop. Cell is not recognized.
134 *
135 * If cell_direction == CELL_DIRECTION_OUT:
136 * - decrypt one hop. Check if recognized.
137 *
138 * If cell is recognized, set *recognized to 1, and set
139 * *layer_hint to the hop that recognized it.
140 *
141 * Return -1 to indicate that we should mark the circuit for close,
142 * else return 0.
143 */
144int
146 cell_direction_t cell_direction,
147 crypt_path_t **layer_hint, char *recognized)
148{
150
151 tor_assert(circ);
152 tor_assert(cell);
153 tor_assert(recognized);
154 tor_assert(cell_direction == CELL_DIRECTION_IN ||
155 cell_direction == CELL_DIRECTION_OUT);
156
157 if (cell_direction == CELL_DIRECTION_IN) {
158 if (CIRCUIT_IS_ORIGIN(circ)) { /* We're at the beginning of the circuit.
159 * We'll want to do layered decrypts. */
160 crypt_path_t *thishop, *cpath = TO_ORIGIN_CIRCUIT(circ)->cpath;
161 thishop = cpath;
162 if (thishop->state != CPATH_STATE_OPEN) {
163 log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
164 "Relay cell before first created cell? Closing.");
165 return -1;
166 }
167 do { /* Remember: cpath is in forward order, that is, first hop first. */
168 tor_assert(thishop);
169
170 /* decrypt one layer */
171 cpath_crypt_cell(thishop, cell->payload, true);
172
173 relay_header_unpack(&rh, cell->payload);
174 if (rh.recognized == 0) {
175 /* it's possibly recognized. have to check digest to be sure. */
176 if (relay_digest_matches(cpath_get_incoming_digest(thishop), cell)) {
177 *recognized = 1;
178 *layer_hint = thishop;
179 return 0;
180 }
181 }
182
183 thishop = thishop->next;
184 } while (thishop != cpath && thishop->state == CPATH_STATE_OPEN);
185 log_fn(LOG_PROTOCOL_WARN, LD_OR,
186 "Incoming cell at client not recognized. Closing.");
187 return -1;
188 } else {
189 relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
190 /* We're in the middle. Encrypt one layer. */
192 }
193 } else /* cell_direction == CELL_DIRECTION_OUT */ {
194 /* We're in the middle. Decrypt one layer. */
195 relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
196
198
199 relay_header_unpack(&rh, cell->payload);
200 if (rh.recognized == 0) {
201 /* it's possibly recognized. have to check digest to be sure. */
202 if (relay_digest_matches(crypto->f_digest, cell)) {
203 *recognized = 1;
204 return 0;
205 }
206 }
207 }
208 return 0;
209}
210
211/**
212 * Encrypt a cell <b>cell</b> that we are creating, and sending outbound on
213 * <b>circ</b> until the hop corresponding to <b>layer_hint</b>.
214 *
215 * The integrity field and recognized field of <b>cell</b>'s relay headers
216 * must be set to zero.
217 */
218void
220 origin_circuit_t *circ,
221 crypt_path_t *layer_hint)
222{
223 crypt_path_t *thishop; /* counter for repeated crypts */
224 cpath_set_cell_forward_digest(layer_hint, cell);
225
226 /* Record cell digest as the SENDME digest if need be. */
227 sendme_record_sending_cell_digest(TO_CIRCUIT(circ), layer_hint);
228
229 thishop = layer_hint;
230 /* moving from farthest to nearest hop */
231 do {
232 tor_assert(thishop);
233 log_debug(LD_OR,"encrypting a layer of the relay cell.");
234 cpath_crypt_cell(thishop, cell->payload, false);
235
236 thishop = thishop->prev;
237 } while (thishop != circ->cpath->prev);
238}
239
240/**
241 * Encrypt a cell <b>cell</b> that we are creating, and sending on
242 * <b>circuit</b> to the origin.
243 *
244 * The integrity field and recognized field of <b>cell</b>'s relay headers
245 * must be set to zero.
246 */
247void
249 or_circuit_t *or_circ)
250{
251 relay_set_digest(or_circ->crypto.b_digest, cell);
252
253 /* Record cell digest as the SENDME digest if need be. */
254 sendme_record_sending_cell_digest(TO_CIRCUIT(or_circ), NULL);
255
256 /* encrypt one layer */
258}
259
260/**
261 * Release all storage held inside <b>crypto</b>, but do not free
262 * <b>crypto</b> itself: it lives inside another object.
263 */
264void
266{
267 if (BUG(!crypto))
268 return;
269 crypto_cipher_free(crypto->f_crypto);
270 crypto_cipher_free(crypto->b_crypto);
273}
274
275/** Initialize <b>crypto</b> from the key material in key_data.
276 *
277 * If <b>is_hs_v3</b> is set, this cpath will be used for next gen hidden
278 * service circuits and <b>key_data</b> must be at least
279 * HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length.
280 *
281 * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL_LEN
282 * bytes, which are used as follows:
283 * - 20 to initialize f_digest
284 * - 20 to initialize b_digest
285 * - 16 to key f_crypto
286 * - 16 to key b_crypto
287 *
288 * (If 'reverse' is true, then f_XX and b_XX are swapped.)
289 *
290 * Return 0 if init was successful, else -1 if it failed.
291 */
292int
294 const char *key_data, size_t key_data_len,
295 int reverse, int is_hs_v3)
296{
297 crypto_digest_t *tmp_digest;
298 crypto_cipher_t *tmp_crypto;
299 size_t digest_len = 0;
300 size_t cipher_key_len = 0;
301
302 tor_assert(crypto);
303 tor_assert(key_data);
304 tor_assert(!(crypto->f_crypto || crypto->b_crypto ||
305 crypto->f_digest || crypto->b_digest));
306
307 /* Basic key size validation */
308 if (is_hs_v3 && BUG(key_data_len != HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN)) {
309 goto err;
310 } else if (!is_hs_v3 && BUG(key_data_len != CPATH_KEY_MATERIAL_LEN)) {
311 goto err;
312 }
313
314 /* If we are using this crypto for next gen onion services use SHA3-256,
315 otherwise use good ol' SHA1 */
316 if (is_hs_v3) {
317 digest_len = DIGEST256_LEN;
318 cipher_key_len = CIPHER256_KEY_LEN;
319 crypto->f_digest = crypto_digest256_new(DIGEST_SHA3_256);
320 crypto->b_digest = crypto_digest256_new(DIGEST_SHA3_256);
321 } else {
322 digest_len = DIGEST_LEN;
323 cipher_key_len = CIPHER_KEY_LEN;
324 crypto->f_digest = crypto_digest_new();
325 crypto->b_digest = crypto_digest_new();
326 }
327
328 tor_assert(digest_len != 0);
329 tor_assert(cipher_key_len != 0);
330 const int cipher_key_bits = (int) cipher_key_len * 8;
331
332 crypto_digest_add_bytes(crypto->f_digest, key_data, digest_len);
333 crypto_digest_add_bytes(crypto->b_digest, key_data+digest_len, digest_len);
334
335 crypto->f_crypto = crypto_cipher_new_with_bits(key_data+(2*digest_len),
336 cipher_key_bits);
337 if (!crypto->f_crypto) {
338 log_warn(LD_BUG,"Forward cipher initialization failed.");
339 goto err;
340 }
341
343 key_data+(2*digest_len)+cipher_key_len,
344 cipher_key_bits);
345 if (!crypto->b_crypto) {
346 log_warn(LD_BUG,"Backward cipher initialization failed.");
347 goto err;
348 }
349
350 if (reverse) {
351 tmp_digest = crypto->f_digest;
352 crypto->f_digest = crypto->b_digest;
353 crypto->b_digest = tmp_digest;
354 tmp_crypto = crypto->f_crypto;
355 crypto->f_crypto = crypto->b_crypto;
356 crypto->b_crypto = tmp_crypto;
357 }
358
359 return 0;
360 err:
361 relay_crypto_clear(crypto);
362 return -1;
363}
364
365/** Assert that <b>crypto</b> is valid and set. */
366void
368{
369 tor_assert(crypto->f_crypto);
370 tor_assert(crypto->b_crypto);
371 tor_assert(crypto->f_digest);
372 tor_assert(crypto->b_digest);
373}
Fixed-size cell structure.
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:185
or_circuit_t * TO_OR_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:173
Header file for circuitlist.c.
#define CIRCUIT_IS_ORIGIN(c)
Definition: circuitlist.h:154
Header file for config.c.
struct crypto_digest_t * cpath_get_incoming_digest(const crypt_path_t *cpath)
Definition: crypt_path.c:191
void cpath_crypt_cell(const crypt_path_t *cpath, uint8_t *payload, bool is_decrypt)
Definition: crypt_path.c:180
void cpath_set_cell_forward_digest(crypt_path_t *cpath, cell_t *cell)
Definition: crypt_path.c:199
Header file for crypt_path.c.
crypto_cipher_t * crypto_cipher_new_with_bits(const char *key, int bits)
Definition: crypto_cipher.c:54
void crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len)
Headers for crypto_cipher.c.
#define CIPHER_KEY_LEN
Definition: crypto_cipher.h:22
#define CIPHER256_KEY_LEN
Definition: crypto_cipher.h:26
void crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint, const crypto_digest_t *digest)
void crypto_digest_restore(crypto_digest_t *digest, const crypto_digest_checkpoint_t *checkpoint)
void crypto_digest_get_digest(crypto_digest_t *digest, char *out, size_t out_len)
#define crypto_digest_free(d)
crypto_digest_t * crypto_digest256_new(digest_algorithm_t algorithm)
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, size_t len)
crypto_digest_t * crypto_digest_new(void)
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
Common functions for cryptographic routines.
#define DIGEST_LEN
Definition: digest_sizes.h:20
#define DIGEST256_LEN
Definition: digest_sizes.h:23
Header for hs_ntor.c.
#define log_fn(severity, domain, args,...)
Definition: log.h:283
#define LD_PROTOCOL
Definition: log.h:72
#define LD_OR
Definition: log.h:92
#define LD_BUG
Definition: log.h:86
Master header file for Tor-specific functionality.
#define CELL_PAYLOAD_SIZE
Definition: or.h:465
#define TO_CIRCUIT(x)
Definition: or.h:848
cell_direction_t
Definition: or.h:375
@ CELL_DIRECTION_OUT
Definition: or.h:377
@ CELL_DIRECTION_IN
Definition: or.h:376
Origin circuit structure.
void relay_header_pack(uint8_t *dest, const relay_header_t *src)
Definition: relay.c:498
void relay_header_unpack(relay_header_t *dest, const uint8_t *src)
Definition: relay.c:511
Header file for relay.c.
Header for relay_crypto.c.
void relay_encrypt_cell_outbound(cell_t *cell, origin_circuit_t *or_circ, crypt_path_t *layer_hint)
Definition: relay_crypto.c:219
uint8_t * relay_crypto_get_sendme_digest(relay_crypto_t *crypto)
Definition: relay_crypto.c:102
void relay_crypto_assert_ok(const relay_crypto_t *crypto)
Definition: relay_crypto.c:367
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:293
void relay_crypto_record_sendme_digest(relay_crypto_t *crypto, bool is_foward_digest)
Definition: relay_crypto.c:111
void relay_set_digest(crypto_digest_t *digest, cell_t *cell)
Definition: relay_crypto.c:31
int relay_decrypt_cell(circuit_t *circ, cell_t *cell, cell_direction_t cell_direction, crypt_path_t **layer_hint, char *recognized)
Definition: relay_crypto.c:145
void relay_crypto_clear(relay_crypto_t *crypto)
Definition: relay_crypto.c:265
void relay_encrypt_cell_inbound(cell_t *cell, or_circuit_t *or_circ)
Definition: relay_crypto.c:248
void relay_crypt_one_payload(crypto_cipher_t *cipher, uint8_t *in)
Definition: relay_crypto.c:95
Header file for sendme.c.
Definition: cell_st.h:17
uint8_t payload[CELL_PAYLOAD_SIZE]
Definition: cell_st.h:21
struct crypt_path_t * prev
Definition: crypt_path_st.h:80
uint8_t state
Definition: crypt_path_st.h:73
struct crypt_path_t * next
Definition: crypt_path_st.h:77
relay_crypto_t crypto
Definition: or_circuit_st.h:54
crypt_path_t * cpath
struct crypto_digest_t * b_digest
struct crypto_digest_t * f_digest
uint8_t sendme_digest[DIGEST_LEN]
struct crypto_cipher_t * f_crypto
struct crypto_cipher_t * b_crypto
uint16_t recognized
Definition: or.h:528
char integrity[4]
Definition: or.h:530
#define tor_assert(expr)
Definition: util_bug.h:103