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