Tor 0.4.9.2-alpha-dev
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
hs_cell.c
Go to the documentation of this file.
1/* Copyright (c) 2017-2021, The Tor Project, Inc. */
2/* See LICENSE for licensing information */
3
4/**
5 * \file hs_cell.c
6 * \brief Hidden service API for cell creation and handling.
7 **/
8
9#include "core/or/or.h"
10#include "app/config/config.h"
13
14#include "feature/hs/hs_cell.h"
15#include "feature/hs/hs_ob.h"
16#include "core/crypto/hs_ntor.h"
18
20
21/* Trunnel. */
22#include "trunnel/congestion_control.h"
23#include "trunnel/ed25519_cert.h"
24#include "trunnel/extension.h"
25#include "trunnel/hs/cell_establish_intro.h"
26#include "trunnel/hs/cell_introduce1.h"
27#include "trunnel/hs/cell_rendezvous.h"
28
29/** Compute the MAC of an INTRODUCE cell in mac_out. The encoded_cell param is
30 * the cell content up to the ENCRYPTED section of length encoded_cell_len.
31 * The encrypted param is the start of the ENCRYPTED section of length
32 * encrypted_len. The mac_key is the key needed for the computation of the MAC
33 * derived from the ntor handshake of length mac_key_len.
34 *
35 * The length mac_out_len must be at least DIGEST256_LEN. */
36static void
37compute_introduce_mac(const uint8_t *encoded_cell, size_t encoded_cell_len,
38 const uint8_t *encrypted, size_t encrypted_len,
39 const uint8_t *mac_key, size_t mac_key_len,
40 uint8_t *mac_out, size_t mac_out_len)
41{
42 size_t offset = 0;
43 size_t mac_msg_len;
44 uint8_t mac_msg[RELAY_PAYLOAD_SIZE_MAX] = {0};
45
46 tor_assert(encoded_cell);
47 tor_assert(encrypted);
48 tor_assert(mac_key);
49 tor_assert(mac_out);
50 tor_assert(mac_out_len >= DIGEST256_LEN);
51
52 /* Compute the size of the message which is basically the entire cell until
53 * the MAC field of course. */
54 mac_msg_len = encoded_cell_len + (encrypted_len - DIGEST256_LEN);
55 tor_assert(mac_msg_len <= sizeof(mac_msg));
56
57 /* First, put the encoded cell in the msg. */
58 memcpy(mac_msg, encoded_cell, encoded_cell_len);
59 offset += encoded_cell_len;
60 /* Second, put the CLIENT_PK + ENCRYPTED_DATA but omit the MAC field (which
61 * is junk at this point). */
62 memcpy(mac_msg + offset, encrypted, (encrypted_len - DIGEST256_LEN));
63 offset += (encrypted_len - DIGEST256_LEN);
64 tor_assert(offset == mac_msg_len);
65
66 crypto_mac_sha3_256(mac_out, mac_out_len,
67 mac_key, mac_key_len,
68 mac_msg, mac_msg_len);
69 memwipe(mac_msg, 0, sizeof(mac_msg));
70}
71
72/**
73 * From a set of keys, a list of subcredentials, and the ENCRYPTED section of
74 * an INTRODUCE2 cell, return an array of newly allocated intro cell keys
75 * structures. Finally, the client public key is copied in client_pk. On
76 * error, return NULL.
77 **/
80 const curve25519_keypair_t *enc_key,
81 size_t n_subcredentials,
82 const hs_subcredential_t *subcredentials,
83 const uint8_t *encrypted_section,
84 curve25519_public_key_t *client_pk)
85{
87
88 tor_assert(auth_key);
89 tor_assert(enc_key);
90 tor_assert(n_subcredentials > 0);
91 tor_assert(subcredentials);
92 tor_assert(encrypted_section);
93 tor_assert(client_pk);
94
95 keys = tor_calloc(n_subcredentials, sizeof(hs_ntor_intro_cell_keys_t));
96
97 /* First bytes of the ENCRYPTED section are the client public key. */
98 memcpy(client_pk->public_key, encrypted_section, CURVE25519_PUBKEY_LEN);
99
100 if (hs_ntor_service_get_introduce1_keys_multi(auth_key, enc_key, client_pk,
101 n_subcredentials,
102 subcredentials, keys) < 0) {
103 /* Don't rely on the caller to wipe this on error. */
104 memwipe(client_pk, 0, sizeof(curve25519_public_key_t));
105 tor_free(keys);
106 keys = NULL;
107 }
108 return keys;
109}
110
111/** Using the given encryption key, decrypt the encrypted_section of length
112 * encrypted_section_len of an INTRODUCE2 cell and return a newly allocated
113 * buffer containing the decrypted data. On decryption failure, NULL is
114 * returned. */
115static uint8_t *
116decrypt_introduce2(const uint8_t *enc_key, const uint8_t *encrypted_section,
117 size_t encrypted_section_len)
118{
119 uint8_t *decrypted = NULL;
120 crypto_cipher_t *cipher = NULL;
121
122 tor_assert(enc_key);
123 tor_assert(encrypted_section);
124
125 /* Decrypt ENCRYPTED section. */
126 cipher = crypto_cipher_new_with_bits((char *) enc_key,
128 tor_assert(cipher);
129
130 /* This is symmetric encryption so can't be bigger than the encrypted
131 * section length. */
132 decrypted = tor_malloc_zero(encrypted_section_len);
133 if (crypto_cipher_decrypt(cipher, (char *) decrypted,
134 (const char *) encrypted_section,
135 encrypted_section_len) < 0) {
136 tor_free(decrypted);
137 decrypted = NULL;
138 goto done;
139 }
140
141 done:
142 crypto_cipher_free(cipher);
143 return decrypted;
144}
145
146/** Given a pointer to the decrypted data of the ENCRYPTED section of an
147 * INTRODUCE2 cell of length decrypted_len, parse and validate the cell
148 * content. Return a newly allocated cell structure or NULL on error. The
149 * circuit and service object are only used for logging purposes. */
150static trn_cell_introduce_encrypted_t *
151parse_introduce2_encrypted(const uint8_t *decrypted_data,
152 size_t decrypted_len, const origin_circuit_t *circ,
153 const hs_service_t *service)
154{
155 trn_cell_introduce_encrypted_t *enc_cell = NULL;
156
157 tor_assert(decrypted_data);
158 tor_assert(circ);
159 tor_assert(service);
160
161 if (trn_cell_introduce_encrypted_parse(&enc_cell, decrypted_data,
162 decrypted_len) < 0) {
163 log_info(LD_REND, "Unable to parse the decrypted ENCRYPTED section of "
164 "the INTRODUCE2 cell on circuit %u for service %s",
165 TO_CIRCUIT(circ)->n_circ_id,
166 safe_str_client(service->onion_address));
167 goto err;
168 }
169
170 if (trn_cell_introduce_encrypted_get_onion_key_type(enc_cell) !=
171 TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR) {
172 log_info(LD_REND, "INTRODUCE2 onion key type is invalid. Got %u but "
173 "expected %u on circuit %u for service %s",
174 trn_cell_introduce_encrypted_get_onion_key_type(enc_cell),
175 TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR,
176 TO_CIRCUIT(circ)->n_circ_id,
177 safe_str_client(service->onion_address));
178 goto err;
179 }
180
181 if (trn_cell_introduce_encrypted_getlen_onion_key(enc_cell) !=
183 log_info(LD_REND, "INTRODUCE2 onion key length is invalid. Got %u but "
184 "expected %d on circuit %u for service %s",
185 (unsigned)trn_cell_introduce_encrypted_getlen_onion_key(enc_cell),
186 CURVE25519_PUBKEY_LEN, TO_CIRCUIT(circ)->n_circ_id,
187 safe_str_client(service->onion_address));
188 goto err;
189 }
190 /* XXX: Validate NSPEC field as well. */
191
192 return enc_cell;
193 err:
194 trn_cell_introduce_encrypted_free(enc_cell);
195 return NULL;
196}
197
198/** Parse an INTRODUCE2 cell from payload of size payload_len for the given
199 * service and circuit which are used only for logging purposes. The resulting
200 * parsed cell is put in cell_ptr_out.
201 *
202 * Return 0 on success else a negative value and cell_ptr_out is untouched. */
203static int
205 const origin_circuit_t *circ, const uint8_t *payload,
206 size_t payload_len,
207 trn_cell_introduce1_t **cell_ptr_out)
208{
209 trn_cell_introduce1_t *cell = NULL;
210
211 tor_assert(service);
212 tor_assert(circ);
213 tor_assert(payload);
214 tor_assert(cell_ptr_out);
215
216 /* Parse the cell so we can start cell validation. */
217 if (trn_cell_introduce1_parse(&cell, payload, payload_len) < 0) {
218 log_info(LD_PROTOCOL, "Unable to parse INTRODUCE2 cell on circuit %u "
219 "for service %s",
220 TO_CIRCUIT(circ)->n_circ_id,
221 safe_str_client(service->onion_address));
222 goto err;
223 }
224
225 /* Success. */
226 *cell_ptr_out = cell;
227 return 0;
228 err:
229 return -1;
230}
231
232/** Set the onion public key onion_pk in cell, the encrypted section of an
233 * INTRODUCE1 cell. */
234static void
235introduce1_set_encrypted_onion_key(trn_cell_introduce_encrypted_t *cell,
236 const uint8_t *onion_pk)
237{
238 tor_assert(cell);
239 tor_assert(onion_pk);
240 /* There is only one possible key type for a non legacy cell. */
241 trn_cell_introduce_encrypted_set_onion_key_type(cell,
242 TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR);
243 trn_cell_introduce_encrypted_set_onion_key_len(cell, CURVE25519_PUBKEY_LEN);
244 trn_cell_introduce_encrypted_setlen_onion_key(cell, CURVE25519_PUBKEY_LEN);
245 memcpy(trn_cell_introduce_encrypted_getarray_onion_key(cell), onion_pk,
246 trn_cell_introduce_encrypted_getlen_onion_key(cell));
247}
248
249/** Set the link specifiers in lspecs in cell, the encrypted section of an
250 * INTRODUCE1 cell. */
251static void
252introduce1_set_encrypted_link_spec(trn_cell_introduce_encrypted_t *cell,
253 const smartlist_t *lspecs)
254{
255 tor_assert(cell);
256 tor_assert(lspecs);
257 tor_assert(smartlist_len(lspecs) > 0);
258 tor_assert(smartlist_len(lspecs) <= UINT8_MAX);
259
260 uint8_t lspecs_num = (uint8_t) smartlist_len(lspecs);
261 trn_cell_introduce_encrypted_set_nspec(cell, lspecs_num);
262 /* We aren't duplicating the link specifiers object here which means that
263 * the ownership goes to the trn_cell_introduce_encrypted_t cell and those
264 * object will be freed when the cell is. */
265 SMARTLIST_FOREACH(lspecs, link_specifier_t *, ls,
266 trn_cell_introduce_encrypted_add_nspecs(cell, ls));
267}
268
269/** Set padding in the enc_cell only if needed that is the total length of both
270 * sections are below the minimum required for an INTRODUCE1 cell. */
271static void
272introduce1_set_encrypted_padding(const trn_cell_introduce1_t *cell,
273 trn_cell_introduce_encrypted_t *enc_cell)
274{
275 tor_assert(cell);
276 tor_assert(enc_cell);
277 /* This is the length we expect to have once encoded of the whole cell. */
278 ssize_t full_len = trn_cell_introduce1_encoded_len(cell) +
279 trn_cell_introduce_encrypted_encoded_len(enc_cell);
280 tor_assert(full_len > 0);
281 if (full_len < HS_CELL_INTRODUCE1_MIN_SIZE) {
282 size_t padding = HS_CELL_INTRODUCE1_MIN_SIZE - full_len;
283 trn_cell_introduce_encrypted_setlen_pad(enc_cell, padding);
284 memset(trn_cell_introduce_encrypted_getarray_pad(enc_cell), 0,
285 trn_cell_introduce_encrypted_getlen_pad(enc_cell));
286 }
287}
288
289/** Encrypt the ENCRYPTED payload and encode it in the cell using the enc_cell
290 * and the INTRODUCE1 data.
291 *
292 * This can't fail but it is very important that the caller sets every field
293 * in data so the computation of the INTRODUCE1 keys doesn't fail. */
294static void
295introduce1_encrypt_and_encode(trn_cell_introduce1_t *cell,
296 const trn_cell_introduce_encrypted_t *enc_cell,
297 const hs_cell_introduce1_data_t *data)
298{
299 size_t offset = 0;
300 ssize_t encrypted_len;
301 ssize_t encoded_cell_len, encoded_enc_cell_len;
302 uint8_t encoded_cell[RELAY_PAYLOAD_SIZE_MAX] = {0};
303 uint8_t encoded_enc_cell[RELAY_PAYLOAD_SIZE_MAX] = {0};
304 uint8_t *encrypted = NULL;
305 uint8_t mac[DIGEST256_LEN];
306 crypto_cipher_t *cipher = NULL;
308
309 tor_assert(cell);
310 tor_assert(enc_cell);
311 tor_assert(data);
312
313 /* Encode the cells up to now of what we have to we can perform the MAC
314 * computation on it. */
315 encoded_cell_len = trn_cell_introduce1_encode(encoded_cell,
316 sizeof(encoded_cell), cell);
317 /* We have a much more serious issue if this isn't true. */
318 tor_assert(encoded_cell_len > 0);
319
320 encoded_enc_cell_len =
321 trn_cell_introduce_encrypted_encode(encoded_enc_cell,
322 sizeof(encoded_enc_cell), enc_cell);
323 /* We have a much more serious issue if this isn't true. */
324 tor_assert(encoded_enc_cell_len > 0);
325
326 /* Get the key material for the encryption. */
327 if (hs_ntor_client_get_introduce1_keys(data->auth_pk, data->enc_pk,
328 data->client_kp,
329 data->subcredential, &keys) < 0) {
330 tor_assert_unreached();
331 }
332
333 /* Prepare cipher with the encryption key just computed. */
334 cipher = crypto_cipher_new_with_bits((const char *) keys.enc_key,
335 sizeof(keys.enc_key) * 8);
336 tor_assert(cipher);
337
338 /* Compute the length of the ENCRYPTED section which is the CLIENT_PK,
339 * ENCRYPTED_DATA and MAC length. */
340 encrypted_len = sizeof(data->client_kp->pubkey) + encoded_enc_cell_len +
341 sizeof(mac);
342 tor_assert(encrypted_len < RELAY_PAYLOAD_SIZE_MAX);
343 encrypted = tor_malloc_zero(encrypted_len);
344
345 /* Put the CLIENT_PK first. */
346 memcpy(encrypted, data->client_kp->pubkey.public_key,
347 sizeof(data->client_kp->pubkey.public_key));
348 offset += sizeof(data->client_kp->pubkey.public_key);
349 /* Then encrypt and set the ENCRYPTED_DATA. This can't fail. */
350 crypto_cipher_encrypt(cipher, (char *) encrypted + offset,
351 (const char *) encoded_enc_cell, encoded_enc_cell_len);
352 crypto_cipher_free(cipher);
353 offset += encoded_enc_cell_len;
354 /* Compute MAC from the above and put it in the buffer. This function will
355 * make the adjustment to the encrypted_len to omit the MAC length. */
356 compute_introduce_mac(encoded_cell, encoded_cell_len,
357 encrypted, encrypted_len,
358 keys.mac_key, sizeof(keys.mac_key),
359 mac, sizeof(mac));
360 memcpy(encrypted + offset, mac, sizeof(mac));
361 offset += sizeof(mac);
362 tor_assert(offset == (size_t) encrypted_len);
363
364 /* Set the ENCRYPTED section in the cell. */
365 trn_cell_introduce1_setlen_encrypted(cell, encrypted_len);
366 memcpy(trn_cell_introduce1_getarray_encrypted(cell),
367 encrypted, encrypted_len);
368
369 /* Cleanup. */
370 memwipe(&keys, 0, sizeof(keys));
371 memwipe(mac, 0, sizeof(mac));
372 memwipe(encrypted, 0, sizeof(encrypted_len));
373 memwipe(encoded_enc_cell, 0, sizeof(encoded_enc_cell));
374 tor_free(encrypted);
375}
376
377/** Build the PoW cell extension and put it in the given extensions object.
378 * Return 0 on success, -1 on failure. */
379static int
381 trn_extension_t *extensions)
382{
383 ssize_t ret;
384 size_t pow_ext_encoded_len;
385 uint8_t *field_array;
386 trn_extension_field_t *field = NULL;
387 trn_cell_extension_pow_t *pow_ext = NULL;
388
389 tor_assert(pow_solution);
390 tor_assert(extensions);
391
392 /* We are creating a cell extension field of type PoW solution. */
393 field = trn_extension_field_new();
394 trn_extension_field_set_field_type(field, TRUNNEL_EXT_TYPE_POW);
395
396 /* Build PoW extension field. */
397 pow_ext = trn_cell_extension_pow_new();
398
399 /* Copy PoW solution values into PoW extension cell. */
400
401 /* Equi-X base scheme */
402 trn_cell_extension_pow_set_pow_version(pow_ext, TRUNNEL_POW_VERSION_EQUIX);
403
404 memcpy(trn_cell_extension_pow_getarray_pow_nonce(pow_ext),
405 &pow_solution->nonce, TRUNNEL_POW_NONCE_LEN);
406
407 trn_cell_extension_pow_set_pow_effort(pow_ext, pow_solution->effort);
408
409 memcpy(trn_cell_extension_pow_getarray_pow_seed(pow_ext),
410 pow_solution->seed_head, TRUNNEL_POW_SEED_HEAD_LEN);
411 memcpy(trn_cell_extension_pow_getarray_pow_solution(pow_ext),
412 pow_solution->equix_solution, TRUNNEL_POW_SOLUTION_LEN);
413
414 /* Set the field with the encoded PoW extension. */
415 ret = trn_cell_extension_pow_encoded_len(pow_ext);
416 if (BUG(ret <= 0)) {
417 goto err;
418 }
419 pow_ext_encoded_len = ret;
420
421 /* Set length field and the field array size length. */
422 trn_extension_field_set_field_len(field, pow_ext_encoded_len);
423 trn_extension_field_setlen_field(field, pow_ext_encoded_len);
424 /* Encode the PoW extension into the cell extension field. */
425 field_array = trn_extension_field_getarray_field(field);
426 ret = trn_cell_extension_pow_encode(field_array,
427 trn_extension_field_getlen_field(field), pow_ext);
428 if (BUG(ret <= 0)) {
429 goto err;
430 }
431 tor_assert(ret == (ssize_t)pow_ext_encoded_len);
432
433 /* Finally, encode field into the cell extension. */
434 trn_extension_add_fields(extensions, field);
435
436 /* We've just add an extension field to the cell extensions so increment the
437 * total number. */
438 trn_extension_set_num(extensions, trn_extension_get_num(extensions) + 1);
439
440 /* Cleanup. PoW extension has been encoded at this point. */
441 trn_cell_extension_pow_free(pow_ext);
442
443 return 0;
444
445err:
446 trn_extension_field_free(field);
447 trn_cell_extension_pow_free(pow_ext);
448 return -1;
449}
450
451/** Build and set the INTRODUCE congestion control extension in the given
452 * extensions. */
453static void
454build_introduce_cc_extension(trn_extension_t *extensions)
455{
456 trn_extension_field_t *field = NULL;
457
458 /* Build CC request extension. */
459 field = trn_extension_field_new();
460 trn_extension_field_set_field_type(field,
461 TRUNNEL_EXT_TYPE_CC_REQUEST);
462
463 /* No payload indicating a request to use congestion control. */
464 trn_extension_field_set_field_len(field, 0);
465
466 /* Build final extension. */
467 trn_extension_add_fields(extensions, field);
468 trn_extension_set_num(extensions, trn_extension_get_num(extensions) + 1);
469}
470
471/** Using the INTRODUCE1 data, setup the ENCRYPTED section in cell. This means
472 * set it, encrypt it and encode it. */
473static void
474introduce1_set_encrypted(trn_cell_introduce1_t *cell,
475 const hs_cell_introduce1_data_t *data)
476{
477 trn_cell_introduce_encrypted_t *enc_cell;
478 trn_extension_t *ext;
479
480 tor_assert(cell);
481 tor_assert(data);
482
483 enc_cell = trn_cell_introduce_encrypted_new();
484 tor_assert(enc_cell);
485
486 /* Setup extension(s) if any. */
487 ext = trn_extension_new();
488 tor_assert(ext);
489 /* Build congestion control extension if enabled. */
490 if (data->cc_enabled) {
492 }
493 /* Build PoW extension if present. */
494 if (data->pow_solution) {
496 }
497 trn_cell_introduce_encrypted_set_extensions(enc_cell, ext);
498
499 /* Set the rendezvous cookie. */
500 memcpy(trn_cell_introduce_encrypted_getarray_rend_cookie(enc_cell),
502
503 /* Set the onion public key. */
504 introduce1_set_encrypted_onion_key(enc_cell, data->onion_pk->public_key);
505
506 /* Set the link specifiers. */
508
509 /* Set padding. */
510 introduce1_set_encrypted_padding(cell, enc_cell);
511
512 /* Encrypt and encode it in the cell. */
513 introduce1_encrypt_and_encode(cell, enc_cell, data);
514
515 /* Cleanup. */
516 trn_cell_introduce_encrypted_free(enc_cell);
517}
518
519/** Set the authentication key in the INTRODUCE1 cell from the given data. */
520static void
521introduce1_set_auth_key(trn_cell_introduce1_t *cell,
522 const hs_cell_introduce1_data_t *data)
523{
524 tor_assert(cell);
525 tor_assert(data);
526 /* There is only one possible type for a non legacy cell. */
527 trn_cell_introduce1_set_auth_key_type(cell,
528 TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519);
529 trn_cell_introduce1_set_auth_key_len(cell, ED25519_PUBKEY_LEN);
530 trn_cell_introduce1_setlen_auth_key(cell, ED25519_PUBKEY_LEN);
531 memcpy(trn_cell_introduce1_getarray_auth_key(cell),
532 data->auth_pk->pubkey, trn_cell_introduce1_getlen_auth_key(cell));
533}
534
535/** Build and add to the given DoS cell extension the given parameter type and
536 * value. */
537static void
538build_establish_intro_dos_param(trn_cell_extension_dos_t *dos_ext,
539 uint8_t param_type, uint64_t param_value)
540{
541 trn_cell_extension_dos_param_t *dos_param =
542 trn_cell_extension_dos_param_new();
543
544 /* Extra safety. We should never send an unknown parameter type. */
545 tor_assert(param_type == TRUNNEL_DOS_PARAM_TYPE_INTRO2_RATE_PER_SEC ||
546 param_type == TRUNNEL_DOS_PARAM_TYPE_INTRO2_BURST_PER_SEC);
547
548 trn_cell_extension_dos_param_set_type(dos_param, param_type);
549 trn_cell_extension_dos_param_set_value(dos_param, param_value);
550 trn_cell_extension_dos_add_params(dos_ext, dos_param);
551
552 /* Not freeing the trunnel object because it is now owned by dos_ext. */
553}
554
555/** Build the DoS defense cell extension and put it in the given extensions
556 * object. Return 0 on success, -1 on failure. (Right now, failure is only
557 * possible if there is a bug.) */
558static int
560 trn_extension_t *extensions)
561{
562 ssize_t ret;
563 size_t dos_ext_encoded_len;
564 uint8_t *field_array;
565 trn_extension_field_t *field = NULL;
566 trn_cell_extension_dos_t *dos_ext = NULL;
567
568 tor_assert(service_config);
569 tor_assert(extensions);
570
571 /* We are creating a cell extension field of the type DoS. */
572 field = trn_extension_field_new();
573 trn_extension_field_set_field_type(field,
574 TRUNNEL_CELL_EXTENSION_TYPE_DOS);
575
576 /* Build DoS extension field. We will put in two parameters. */
577 dos_ext = trn_cell_extension_dos_new();
578 trn_cell_extension_dos_set_n_params(dos_ext, 2);
579
580 /* Build DoS parameter INTRO2 rate per second. */
582 TRUNNEL_DOS_PARAM_TYPE_INTRO2_RATE_PER_SEC,
583 service_config->intro_dos_rate_per_sec);
584 /* Build DoS parameter INTRO2 burst per second. */
586 TRUNNEL_DOS_PARAM_TYPE_INTRO2_BURST_PER_SEC,
587 service_config->intro_dos_burst_per_sec);
588
589 /* Set the field with the encoded DoS extension. */
590 ret = trn_cell_extension_dos_encoded_len(dos_ext);
591 if (BUG(ret <= 0)) {
592 goto err;
593 }
594 dos_ext_encoded_len = ret;
595 /* Set length field and the field array size length. */
596 trn_extension_field_set_field_len(field, dos_ext_encoded_len);
597 trn_extension_field_setlen_field(field, dos_ext_encoded_len);
598 /* Encode the DoS extension into the cell extension field. */
599 field_array = trn_extension_field_getarray_field(field);
600 ret = trn_cell_extension_dos_encode(field_array,
601 trn_extension_field_getlen_field(field), dos_ext);
602 if (BUG(ret <= 0)) {
603 goto err;
604 }
605 tor_assert(ret == (ssize_t) dos_ext_encoded_len);
606
607 /* Finally, encode field into the cell extension. */
608 trn_extension_add_fields(extensions, field);
609
610 /* We've just add an extension field to the cell extensions so increment the
611 * total number. */
612 trn_extension_set_num(extensions, trn_extension_get_num(extensions) + 1);
613
614 /* Cleanup. DoS extension has been encoded at this point. */
615 trn_cell_extension_dos_free(dos_ext);
616
617 return 0;
618
619 err:
620 trn_extension_field_free(field);
621 trn_cell_extension_dos_free(dos_ext);
622 return -1;
623}
624
625/* ========== */
626/* Public API */
627/* ========== */
628
629/** Allocate and build all the ESTABLISH_INTRO cell extension. The given
630 * extensions pointer is always set to a valid cell extension object. */
631STATIC trn_extension_t *
633 const hs_service_intro_point_t *ip)
634{
635 int ret;
636 trn_extension_t *extensions;
637
638 tor_assert(service_config);
639 tor_assert(ip);
640
641 extensions = trn_extension_new();
642 trn_extension_set_num(extensions, 0);
643
644 /* If the defense has been enabled service side (by the operator with a
645 * torrc option) and the intro point does support it. */
646 if (service_config->has_dos_defense_enabled &&
648 /* This function takes care to increment the number of extensions. */
649 ret = build_establish_intro_dos_extension(service_config, extensions);
650 if (ret < 0) {
651 /* Return no extensions on error. */
652 goto end;
653 }
654 }
655
656 end:
657 return extensions;
658}
659
660/** Build an ESTABLISH_INTRO cell with the given circuit nonce and intro point
661 * object. The encoded cell is put in cell_out that MUST at least be of the
662 * size of RELAY_PAYLOAD_SIZE. Return the encoded cell length on success else
663 * a negative value and cell_out is untouched. */
664ssize_t
665hs_cell_build_establish_intro(const char *circ_nonce,
666 const hs_service_config_t *service_config,
667 const hs_service_intro_point_t *ip,
668 uint8_t *cell_out)
669{
670 ssize_t cell_len = -1;
671 uint16_t sig_len = ED25519_SIG_LEN;
672 trn_cell_establish_intro_t *cell = NULL;
673 trn_extension_t *extensions;
674
675 tor_assert(circ_nonce);
676 tor_assert(service_config);
677 tor_assert(ip);
678
679 /* Build the extensions, if any. */
680 extensions = build_establish_intro_extensions(service_config, ip);
681
682 /* Set extension data. None used here. */
683 cell = trn_cell_establish_intro_new();
684 trn_cell_establish_intro_set_extensions(cell, extensions);
685 /* Set signature size. Array is then allocated in the cell. We need to do
686 * this early so we can use trunnel API to get the signature length. */
687 trn_cell_establish_intro_set_sig_len(cell, sig_len);
688 trn_cell_establish_intro_setlen_sig(cell, sig_len);
689
690 /* Set AUTH_KEY_TYPE: 2 means ed25519 */
691 trn_cell_establish_intro_set_auth_key_type(cell,
692 TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519);
693
694 /* Set AUTH_KEY and AUTH_KEY_LEN field. Must also set byte-length of
695 * AUTH_KEY to match */
696 {
697 uint16_t auth_key_len = ED25519_PUBKEY_LEN;
698 trn_cell_establish_intro_set_auth_key_len(cell, auth_key_len);
699 trn_cell_establish_intro_setlen_auth_key(cell, auth_key_len);
700 /* We do this call _after_ setting the length because it's reallocated at
701 * that point only. */
702 uint8_t *auth_key_ptr = trn_cell_establish_intro_getarray_auth_key(cell);
703 memcpy(auth_key_ptr, ip->auth_key_kp.pubkey.pubkey, auth_key_len);
704 }
705
706 /* Calculate HANDSHAKE_AUTH field (MAC). */
707 {
708 ssize_t tmp_cell_enc_len = 0;
709 ssize_t tmp_cell_mac_offset =
710 sig_len + sizeof(cell->sig_len) +
711 trn_cell_establish_intro_getlen_handshake_mac(cell);
712 uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE_MAX] = {0};
713 uint8_t mac[TRUNNEL_SHA3_256_LEN], *handshake_ptr;
714
715 /* We first encode the current fields we have in the cell so we can
716 * compute the MAC using the raw bytes. */
717 tmp_cell_enc_len = trn_cell_establish_intro_encode(tmp_cell_enc,
718 sizeof(tmp_cell_enc),
719 cell);
720 if (BUG(tmp_cell_enc_len < 0)) {
721 goto done;
722 }
723 /* Sanity check. */
724 tor_assert(tmp_cell_enc_len > tmp_cell_mac_offset);
725
726 /* Circuit nonce is always DIGEST_LEN according to tor-spec.txt. */
727 crypto_mac_sha3_256(mac, sizeof(mac),
728 (uint8_t *) circ_nonce, DIGEST_LEN,
729 tmp_cell_enc, tmp_cell_enc_len - tmp_cell_mac_offset);
730 handshake_ptr = trn_cell_establish_intro_getarray_handshake_mac(cell);
731 memcpy(handshake_ptr, mac, sizeof(mac));
732
733 memwipe(mac, 0, sizeof(mac));
734 memwipe(tmp_cell_enc, 0, sizeof(tmp_cell_enc));
735 }
736
737 /* Calculate the cell signature SIG. */
738 {
739 ssize_t tmp_cell_enc_len = 0;
740 ssize_t tmp_cell_sig_offset = (sig_len + sizeof(cell->sig_len));
741 uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE_MAX] = {0}, *sig_ptr;
743
744 /* We first encode the current fields we have in the cell so we can
745 * compute the signature from the raw bytes of the cell. */
746 tmp_cell_enc_len = trn_cell_establish_intro_encode(tmp_cell_enc,
747 sizeof(tmp_cell_enc),
748 cell);
749 if (BUG(tmp_cell_enc_len < 0)) {
750 goto done;
751 }
752
753 if (ed25519_sign_prefixed(&sig, tmp_cell_enc,
754 tmp_cell_enc_len - tmp_cell_sig_offset,
756 log_warn(LD_BUG, "Unable to make signature for ESTABLISH_INTRO cell.");
757 goto done;
758 }
759 /* Copy the signature into the cell. */
760 sig_ptr = trn_cell_establish_intro_getarray_sig(cell);
761 memcpy(sig_ptr, sig.sig, sig_len);
762
763 memwipe(tmp_cell_enc, 0, sizeof(tmp_cell_enc));
764 }
765
766 /* Encode the cell. Can't be bigger than a standard cell. */
767 cell_len = trn_cell_establish_intro_encode(cell_out,
769 cell);
770
771 done:
772 trn_cell_establish_intro_free(cell);
773 return cell_len;
774}
775
776/** Parse the INTRO_ESTABLISHED cell in the payload of size payload_len. If we
777 * are successful at parsing it, return the length of the parsed cell else a
778 * negative value on error. */
779ssize_t
780hs_cell_parse_intro_established(const uint8_t *payload, size_t payload_len)
781{
782 ssize_t ret;
783 trn_cell_intro_established_t *cell = NULL;
784
785 tor_assert(payload);
786
787 /* Try to parse the payload into a cell making sure we do actually have a
788 * valid cell. */
789 ret = trn_cell_intro_established_parse(&cell, payload, payload_len);
790 if (ret >= 0) {
791 /* On success, we do not keep the cell, we just notify the caller that it
792 * was successfully parsed. */
793 trn_cell_intro_established_free(cell);
794 }
795 return ret;
796}
797
798/** Parse the cell PoW solution extension. Return 0 on success and data
799 * structure is updated with the PoW effort. Return -1 on any kind of error
800 * including if PoW couldn't be verified. */
801static int
803 const hs_service_intro_point_t *ip,
804 const trn_extension_field_t *field,
806{
807 int ret = -1;
808 trn_cell_extension_pow_t *pow = NULL;
810
811 tor_assert(field);
812 tor_assert(ip);
813
814 if (!service->state.pow_state) {
815 log_info(LD_REND, "Unsolicited PoW solution in INTRODUCE2 request.");
816 goto end;
817 }
818
819 if (trn_cell_extension_pow_parse(&pow,
820 trn_extension_field_getconstarray_field(field),
821 trn_extension_field_getlen_field(field)) < 0) {
822 goto end;
823 }
824
825 /* There is only one version supported at the moment so validate we at least
826 * have that. */
827 if (trn_cell_extension_pow_get_pow_version(pow) !=
828 TRUNNEL_POW_VERSION_EQUIX) {
829 log_debug(LD_REND, "Unsupported PoW version. Malformed INTRODUCE2");
830 goto end;
831 }
832
833 /* Effort E */
834 sol.effort = trn_cell_extension_pow_get_pow_effort(pow);
835 /* Seed C */
836 memcpy(sol.seed_head, trn_cell_extension_pow_getconstarray_pow_seed(pow),
838 /* Nonce N */
839 memcpy(sol.nonce, trn_cell_extension_pow_getconstarray_pow_nonce(pow),
841 /* Solution S */
842 memcpy(sol.equix_solution,
843 trn_cell_extension_pow_getconstarray_pow_solution(pow),
845
846 if (hs_pow_verify(&ip->blinded_id, service->state.pow_state, &sol)) {
847 log_info(LD_REND, "PoW INTRODUCE2 request failed to verify.");
848 goto end;
849 }
850
851 log_info(LD_REND, "PoW INTRODUCE2 request successfully verified.");
852 data->rdv_data.pow_effort = sol.effort;
853
854 /* Successfully parsed and verified the PoW solution */
855 ret = 0;
856
857 end:
858 trn_cell_extension_pow_free(pow);
859 return ret;
860}
861
862/** For the encrypted INTRO2 cell in <b>encrypted_section</b>, use the crypto
863 * material in <b>data</b> to compute the right ntor keys. Also validate the
864 * INTRO2 MAC to ensure that the keys are the right ones.
865 *
866 * Return NULL on failure to either produce the key material or on MAC
867 * validation. Else return a newly allocated intro keys object. */
870 const uint8_t *encrypted_section,
871 size_t encrypted_section_len)
872{
873 hs_ntor_intro_cell_keys_t *intro_keys = NULL;
874 hs_ntor_intro_cell_keys_t *intro_keys_result = NULL;
875
876 /* Build the key material out of the key material found in the cell. */
877 intro_keys = get_introduce2_key_material(data->auth_pk, data->enc_kp,
878 data->n_subcredentials,
879 data->subcredentials,
880 encrypted_section,
881 &data->rdv_data.client_pk);
882 if (intro_keys == NULL) {
883 log_info(LD_REND, "Invalid INTRODUCE2 encrypted data. Unable to "
884 "compute key material");
885 return NULL;
886 }
887
888 /* Make sure we are not about to underflow. */
889 if (BUG(encrypted_section_len < DIGEST256_LEN)) {
890 return NULL;
891 }
892
893 /* Validate MAC from the cell and our computed key material. The MAC field
894 * in the cell is at the end of the encrypted section. */
895 intro_keys_result = tor_malloc_zero(sizeof(*intro_keys_result));
896 for (unsigned i = 0; i < data->n_subcredentials; ++i) {
897 uint8_t mac[DIGEST256_LEN];
898
899 /* The MAC field is at the very end of the ENCRYPTED section. */
900 size_t mac_offset = encrypted_section_len - sizeof(mac);
901 /* Compute the MAC. Use the entire encoded payload with a length up to the
902 * ENCRYPTED section. */
904 data->payload_len - encrypted_section_len,
905 encrypted_section, encrypted_section_len,
906 intro_keys[i].mac_key,
907 sizeof(intro_keys[i].mac_key),
908 mac, sizeof(mac));
909 /* Time-invariant conditional copy: if the MAC is what we expected, then
910 * set intro_keys_result to intro_keys[i]. Otherwise, don't: but don't
911 * leak which one it was! */
912 bool equal = tor_memeq(mac, encrypted_section + mac_offset, sizeof(mac));
913 memcpy_if_true_timei(equal, intro_keys_result, &intro_keys[i],
914 sizeof(*intro_keys_result));
915 }
916
917 /* We no longer need intro_keys. */
918 memwipe(intro_keys, 0,
920 tor_free(intro_keys);
921
922 if (safe_mem_is_zero(intro_keys_result, sizeof(*intro_keys_result))) {
923 log_info(LD_REND, "Invalid MAC validation for INTRODUCE2 cell");
924 tor_free(intro_keys_result); /* sets intro_keys_result to NULL */
925 }
926
927 return intro_keys_result;
928}
929
930/** Parse the given INTRODUCE cell extension. Update the data object
931 * accordingly depending on the extension. Return 0 if it validated
932 * correctly, or return -1 if it is malformed (for example because it
933 * includes a PoW that doesn't verify). */
934static int
936 const hs_service_intro_point_t *ip,
938 const trn_extension_field_t *field)
939{
940 int ret = 0;
941 trn_extension_field_cc_t *cc_field = NULL;
942
943 tor_assert(data);
944 tor_assert(field);
945
946 switch (trn_extension_field_get_field_type(field)) {
947 case TRUNNEL_EXT_TYPE_CC_REQUEST:
948 /* CC requests, enable it. */
949 data->rdv_data.cc_enabled = 1;
950 data->pv.protocols_known = 1;
952 break;
953 case TRUNNEL_EXT_TYPE_POW:
954 /* PoW request. If successful, the effort is put in the data. */
956 field, data) < 0) {
957 log_fn(LOG_PROTOCOL_WARN, LD_REND, "Invalid PoW cell extension.");
958 ret = -1;
959 }
960 break;
961 default:
962 break;
963 }
964
965 trn_extension_field_cc_free(cc_field);
966 return ret;
967}
968
969/** Parse the INTRODUCE2 cell using data which contains everything we need to
970 * do so and contains the destination buffers of information we extract and
971 * compute from the cell. Return 0 on success else a negative value. The
972 * service and circ are only used for logging purposes. */
973ssize_t
975 const origin_circuit_t *circ,
976 const hs_service_t *service,
977 const hs_service_intro_point_t *ip)
978{
979 int ret = -1;
980 time_t elapsed;
981 uint8_t *decrypted = NULL;
982 size_t encrypted_section_len;
983 const uint8_t *encrypted_section;
984 trn_cell_introduce1_t *cell = NULL;
985 trn_cell_introduce_encrypted_t *enc_cell = NULL;
986 hs_ntor_intro_cell_keys_t *intro_keys = NULL;
987
988 tor_assert(data);
989 tor_assert(circ);
990 tor_assert(service);
991
992 /* Parse the cell into a decoded data structure pointed by cell_ptr. */
993 if (parse_introduce2_cell(service, circ, data->payload, data->payload_len,
994 &cell) < 0) {
995 goto done;
996 }
997
998 log_info(LD_REND, "Received a decodable INTRODUCE2 cell on circuit %u "
999 "for service %s. Decoding encrypted section...",
1000 TO_CIRCUIT(circ)->n_circ_id,
1001 safe_str_client(service->onion_address));
1002
1003 encrypted_section = trn_cell_introduce1_getconstarray_encrypted(cell);
1004 encrypted_section_len = trn_cell_introduce1_getlen_encrypted(cell);
1005
1006 /* Encrypted section must at least contain the CLIENT_PK and MAC which is
1007 * defined in section 3.3.2 of the specification. */
1008 if (encrypted_section_len < (CURVE25519_PUBKEY_LEN + DIGEST256_LEN)) {
1009 log_info(LD_REND, "Invalid INTRODUCE2 encrypted section length "
1010 "for service %s. Dropping cell.",
1011 safe_str_client(service->onion_address));
1012 goto done;
1013 }
1014
1015 /* Check our replay cache for this introduction point. */
1016 if (replaycache_add_test_and_elapsed(data->replay_cache, encrypted_section,
1017 encrypted_section_len, &elapsed)) {
1018 log_warn(LD_REND, "Possible replay detected! An INTRODUCE2 cell with the "
1019 "same ENCRYPTED section was seen %ld seconds ago. "
1020 "Dropping cell.", (long int) elapsed);
1021 goto done;
1022 }
1023
1024 /* First bytes of the ENCRYPTED section are the client public key (they are
1025 * guaranteed to exist because of the length check above). We are gonna use
1026 * the client public key to compute the ntor keys and decrypt the payload:
1027 */
1028 memcpy(&data->rdv_data.client_pk.public_key, encrypted_section,
1030
1031 /* Get the right INTRODUCE2 ntor keys and verify the cell MAC */
1032 intro_keys = get_introduce2_keys_and_verify_mac(data, encrypted_section,
1033 encrypted_section_len);
1034 if (!intro_keys) {
1035 log_warn(LD_REND, "Could not get valid INTRO2 keys on circuit %u "
1036 "for service %s", TO_CIRCUIT(circ)->n_circ_id,
1037 safe_str_client(service->onion_address));
1038 goto done;
1039 }
1040
1041 {
1042 /* The ENCRYPTED_DATA section starts just after the CLIENT_PK. */
1043 const uint8_t *encrypted_data =
1044 encrypted_section + sizeof(data->rdv_data.client_pk);
1045 /* It's symmetric encryption so it's correct to use the ENCRYPTED length
1046 * for decryption. Computes the length of ENCRYPTED_DATA meaning removing
1047 * the CLIENT_PK and MAC length. */
1048 size_t encrypted_data_len =
1049 encrypted_section_len -
1050 (sizeof(data->rdv_data.client_pk) + DIGEST256_LEN);
1051
1052 /* This decrypts the ENCRYPTED_DATA section of the cell. */
1053 decrypted = decrypt_introduce2(intro_keys->enc_key,
1054 encrypted_data, encrypted_data_len);
1055 if (decrypted == NULL) {
1056 log_info(LD_REND, "Unable to decrypt the ENCRYPTED section of an "
1057 "INTRODUCE2 cell on circuit %u for service %s",
1058 TO_CIRCUIT(circ)->n_circ_id,
1059 safe_str_client(service->onion_address));
1060 goto done;
1061 }
1062
1063 /* Parse this blob into an encrypted cell structure so we can then extract
1064 * the data we need out of it. */
1065 enc_cell = parse_introduce2_encrypted(decrypted, encrypted_data_len,
1066 circ, service);
1067 memwipe(decrypted, 0, encrypted_data_len);
1068 if (enc_cell == NULL) {
1069 goto done;
1070 }
1071 }
1072
1073 /* XXX: Implement client authorization checks. */
1074
1075 /* Extract onion key and rendezvous cookie from the cell used for the
1076 * rendezvous point circuit e2e encryption. */
1077 memcpy(data->rdv_data.onion_pk.public_key,
1078 trn_cell_introduce_encrypted_getconstarray_onion_key(enc_cell),
1080 memcpy(data->rdv_data.rendezvous_cookie,
1081 trn_cell_introduce_encrypted_getconstarray_rend_cookie(enc_cell),
1082 sizeof(data->rdv_data.rendezvous_cookie));
1083
1084 /* Extract rendezvous link specifiers. */
1085 for (size_t idx = 0;
1086 idx < trn_cell_introduce_encrypted_get_nspec(enc_cell); idx++) {
1087 link_specifier_t *lspec =
1088 trn_cell_introduce_encrypted_get_nspecs(enc_cell, idx);
1089 if (BUG(!lspec)) {
1090 goto done;
1091 }
1092 link_specifier_t *lspec_dup = link_specifier_dup(lspec);
1093 if (BUG(!lspec_dup)) {
1094 goto done;
1095 }
1096 smartlist_add(data->rdv_data.link_specifiers, lspec_dup);
1097 }
1098
1099 /* Extract any extensions. */
1100 const trn_extension_t *extensions =
1101 trn_cell_introduce_encrypted_get_extensions(enc_cell);
1102 if (extensions != NULL) {
1103 for (size_t idx = 0; idx < trn_extension_get_num(extensions); idx++) {
1104 const trn_extension_field_t *field =
1105 trn_extension_getconst_fields(extensions, idx);
1106 if (BUG(field == NULL)) {
1107 /* The number of extensions should match the number of fields. */
1108 break;
1109 }
1110 if (parse_introduce_cell_extension(service, ip, data, field) < 0) {
1111 goto done;
1112 }
1113 }
1114 }
1115
1116 /* If the client asked for congestion control, but we don't support it,
1117 * that's a failure. It should not have asked, based on our descriptor. */
1119 goto done;
1120 }
1121
1122 /* Success. */
1123 ret = 0;
1124 log_info(LD_REND,
1125 "Valid INTRODUCE2 cell. Willing to launch rendezvous circuit.");
1126
1127 done:
1128 if (intro_keys) {
1129 memwipe(intro_keys, 0, sizeof(hs_ntor_intro_cell_keys_t));
1130 tor_free(intro_keys);
1131 }
1132 tor_free(decrypted);
1133 trn_cell_introduce_encrypted_free(enc_cell);
1134 trn_cell_introduce1_free(cell);
1135 return ret;
1136}
1137
1138/** Build a RENDEZVOUS1 cell with the given rendezvous cookie and handshake
1139 * info. The encoded cell is put in cell_out and the length of the data is
1140 * returned. This can't fail. */
1141ssize_t
1142hs_cell_build_rendezvous1(const uint8_t *rendezvous_cookie,
1143 size_t rendezvous_cookie_len,
1144 const uint8_t *rendezvous_handshake_info,
1145 size_t rendezvous_handshake_info_len,
1146 uint8_t *cell_out)
1147{
1148 ssize_t cell_len;
1149 trn_cell_rendezvous1_t *cell;
1150
1151 tor_assert(rendezvous_cookie);
1152 tor_assert(rendezvous_handshake_info);
1153 tor_assert(cell_out);
1154
1155 cell = trn_cell_rendezvous1_new();
1156 /* Set the RENDEZVOUS_COOKIE. */
1157 memcpy(trn_cell_rendezvous1_getarray_rendezvous_cookie(cell),
1158 rendezvous_cookie, rendezvous_cookie_len);
1159 /* Set the HANDSHAKE_INFO. */
1160 trn_cell_rendezvous1_setlen_handshake_info(cell,
1161 rendezvous_handshake_info_len);
1162 memcpy(trn_cell_rendezvous1_getarray_handshake_info(cell),
1163 rendezvous_handshake_info, rendezvous_handshake_info_len);
1164 /* Encoding. */
1165 cell_len = trn_cell_rendezvous1_encode(cell_out,
1167 tor_assert(cell_len > 0);
1168
1169 trn_cell_rendezvous1_free(cell);
1170 return cell_len;
1171}
1172
1173/** Build an INTRODUCE1 cell from the given data. The encoded cell is put in
1174 * cell_out which must be of at least size RELAY_PAYLOAD_SIZE. On success, the
1175 * encoded length is returned else a negative value and the content of
1176 * cell_out should be ignored. */
1177ssize_t
1179 uint8_t *cell_out)
1180{
1181 ssize_t cell_len;
1182 trn_cell_introduce1_t *cell;
1183 trn_extension_t *ext;
1184
1185 tor_assert(data);
1186 tor_assert(cell_out);
1187
1188 cell = trn_cell_introduce1_new();
1189 tor_assert(cell);
1190
1191 /* Set extension data. None are used. */
1192 ext = trn_extension_new();
1193 tor_assert(ext);
1194 trn_extension_set_num(ext, 0);
1195 trn_cell_introduce1_set_extensions(cell, ext);
1196
1197 /* Set the authentication key. */
1198 introduce1_set_auth_key(cell, data);
1199
1200 /* Set the encrypted section. This will set, encrypt and encode the
1201 * ENCRYPTED section in the cell. After this, we'll be ready to encode. */
1202 introduce1_set_encrypted(cell, data);
1203
1204 /* Final encoding. */
1205 cell_len = trn_cell_introduce1_encode(cell_out,
1207
1208 trn_cell_introduce1_free(cell);
1209 return cell_len;
1210}
1211
1212/** Build an ESTABLISH_RENDEZVOUS cell from the given rendezvous_cookie. The
1213 * encoded cell is put in cell_out which must be of at least
1214 * RELAY_PAYLOAD_SIZE. On success, the encoded length is returned and the
1215 * caller should clear up the content of the cell.
1216 *
1217 * This function can't fail. */
1218ssize_t
1219hs_cell_build_establish_rendezvous(const uint8_t *rendezvous_cookie,
1220 uint8_t *cell_out)
1221{
1222 tor_assert(rendezvous_cookie);
1223 tor_assert(cell_out);
1224
1225 memcpy(cell_out, rendezvous_cookie, HS_REND_COOKIE_LEN);
1226 return HS_REND_COOKIE_LEN;
1227}
1228
1229/** Handle an INTRODUCE_ACK cell encoded in payload of length payload_len.
1230 * Return the status code on success else a negative value if the cell as not
1231 * decodable. */
1232int
1233hs_cell_parse_introduce_ack(const uint8_t *payload, size_t payload_len)
1234{
1235 int ret = -1;
1236 trn_cell_introduce_ack_t *cell = NULL;
1237
1238 tor_assert(payload);
1239
1240 if (trn_cell_introduce_ack_parse(&cell, payload, payload_len) < 0) {
1241 log_info(LD_REND, "Invalid INTRODUCE_ACK cell. Unable to parse it.");
1242 goto end;
1243 }
1244
1245 ret = trn_cell_introduce_ack_get_status(cell);
1246
1247 end:
1248 trn_cell_introduce_ack_free(cell);
1249 return ret;
1250}
1251
1252/** Handle a RENDEZVOUS2 cell encoded in payload of length payload_len. On
1253 * success, handshake_info contains the data in the HANDSHAKE_INFO field, and
1254 * 0 is returned. On error, a negative value is returned. */
1255int
1256hs_cell_parse_rendezvous2(const uint8_t *payload, size_t payload_len,
1257 uint8_t *handshake_info, size_t handshake_info_len)
1258{
1259 int ret = -1;
1260 trn_cell_rendezvous2_t *cell = NULL;
1261
1262 tor_assert(payload);
1263 tor_assert(handshake_info);
1264
1265 if (trn_cell_rendezvous2_parse(&cell, payload, payload_len) < 0) {
1266 log_info(LD_REND, "Invalid RENDEZVOUS2 cell. Unable to parse it.");
1267 goto end;
1268 }
1269
1270 /* Static size, we should never have an issue with this else we messed up
1271 * our code flow. */
1272 tor_assert(trn_cell_rendezvous2_getlen_handshake_info(cell) ==
1273 handshake_info_len);
1274 memcpy(handshake_info,
1275 trn_cell_rendezvous2_getconstarray_handshake_info(cell),
1276 handshake_info_len);
1277 ret = 0;
1278
1279 end:
1280 trn_cell_rendezvous2_free(cell);
1281 return ret;
1282}
1283
1284/** Clear the given INTRODUCE1 data structure data. */
1285void
1287{
1288 if (data == NULL) {
1289 return;
1290 }
1291 /* Object in this list have been moved to the cell object when building it
1292 * so they've been freed earlier. We do that in order to avoid duplicating
1293 * them leading to more memory and CPU time being used for nothing. */
1294 smartlist_free(data->link_specifiers);
1295 /* The data object has no ownership of any members. */
1296 memwipe(data, 0, sizeof(hs_cell_introduce1_data_t));
1297}
Header file for config.c.
bool congestion_control_enabled(void)
Public APIs for congestion control.
crypto_cipher_t * crypto_cipher_new_with_bits(const char *key, int bits)
Definition: crypto_cipher.c:54
int crypto_cipher_decrypt(crypto_cipher_t *env, char *to, const char *from, size_t fromlen)
int crypto_cipher_encrypt(crypto_cipher_t *env, char *to, const char *from, size_t fromlen)
Definition: crypto_cipher.c:88
void crypto_mac_sha3_256(uint8_t *mac_out, size_t len_out, const uint8_t *key, size_t key_len, const uint8_t *msg, size_t msg_len)
int ed25519_sign_prefixed(ed25519_signature_t *signature_out, const uint8_t *msg, size_t msg_len, const char *prefix_str, const ed25519_keypair_t *keypair)
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
Common functions for cryptographic routines.
void memcpy_if_true_timei(bool s, void *dest, const void *src, size_t n)
Definition: di_ops.c:296
int tor_memeq(const void *a, const void *b, size_t sz)
Definition: di_ops.c:107
int safe_mem_is_zero(const void *mem, size_t sz)
Definition: di_ops.c:224
#define DIGEST_LEN
Definition: digest_sizes.h:20
#define DIGEST256_LEN
Definition: digest_sizes.h:23
static int handle_introduce2_encrypted_cell_pow_extension(const hs_service_t *service, const hs_service_intro_point_t *ip, const trn_extension_field_t *field, hs_cell_introduce2_data_t *data)
Definition: hs_cell.c:802
static void build_introduce_cc_extension(trn_extension_t *extensions)
Definition: hs_cell.c:454
ssize_t hs_cell_build_establish_rendezvous(const uint8_t *rendezvous_cookie, uint8_t *cell_out)
Definition: hs_cell.c:1219
static void introduce1_set_encrypted(trn_cell_introduce1_t *cell, const hs_cell_introduce1_data_t *data)
Definition: hs_cell.c:474
STATIC trn_extension_t * build_establish_intro_extensions(const hs_service_config_t *service_config, const hs_service_intro_point_t *ip)
Definition: hs_cell.c:632
ssize_t hs_cell_parse_introduce2(hs_cell_introduce2_data_t *data, const origin_circuit_t *circ, const hs_service_t *service, const hs_service_intro_point_t *ip)
Definition: hs_cell.c:974
static void build_establish_intro_dos_param(trn_cell_extension_dos_t *dos_ext, uint8_t param_type, uint64_t param_value)
Definition: hs_cell.c:538
static int build_establish_intro_dos_extension(const hs_service_config_t *service_config, trn_extension_t *extensions)
Definition: hs_cell.c:559
static void compute_introduce_mac(const uint8_t *encoded_cell, size_t encoded_cell_len, const uint8_t *encrypted, size_t encrypted_len, const uint8_t *mac_key, size_t mac_key_len, uint8_t *mac_out, size_t mac_out_len)
Definition: hs_cell.c:37
static hs_ntor_intro_cell_keys_t * get_introduce2_key_material(const ed25519_public_key_t *auth_key, const curve25519_keypair_t *enc_key, size_t n_subcredentials, const hs_subcredential_t *subcredentials, const uint8_t *encrypted_section, curve25519_public_key_t *client_pk)
Definition: hs_cell.c:79
static uint8_t * decrypt_introduce2(const uint8_t *enc_key, const uint8_t *encrypted_section, size_t encrypted_section_len)
Definition: hs_cell.c:116
static void introduce1_set_encrypted_link_spec(trn_cell_introduce_encrypted_t *cell, const smartlist_t *lspecs)
Definition: hs_cell.c:252
static int parse_introduce2_cell(const hs_service_t *service, const origin_circuit_t *circ, const uint8_t *payload, size_t payload_len, trn_cell_introduce1_t **cell_ptr_out)
Definition: hs_cell.c:204
ssize_t hs_cell_parse_intro_established(const uint8_t *payload, size_t payload_len)
Definition: hs_cell.c:780
static int parse_introduce_cell_extension(const hs_service_t *service, const hs_service_intro_point_t *ip, hs_cell_introduce2_data_t *data, const trn_extension_field_t *field)
Definition: hs_cell.c:935
ssize_t hs_cell_build_establish_intro(const char *circ_nonce, const hs_service_config_t *service_config, const hs_service_intro_point_t *ip, uint8_t *cell_out)
Definition: hs_cell.c:665
int hs_cell_parse_introduce_ack(const uint8_t *payload, size_t payload_len)
Definition: hs_cell.c:1233
static trn_cell_introduce_encrypted_t * parse_introduce2_encrypted(const uint8_t *decrypted_data, size_t decrypted_len, const origin_circuit_t *circ, const hs_service_t *service)
Definition: hs_cell.c:151
static hs_ntor_intro_cell_keys_t * get_introduce2_keys_and_verify_mac(hs_cell_introduce2_data_t *data, const uint8_t *encrypted_section, size_t encrypted_section_len)
Definition: hs_cell.c:869
void hs_cell_introduce1_data_clear(hs_cell_introduce1_data_t *data)
Definition: hs_cell.c:1286
static void introduce1_encrypt_and_encode(trn_cell_introduce1_t *cell, const trn_cell_introduce_encrypted_t *enc_cell, const hs_cell_introduce1_data_t *data)
Definition: hs_cell.c:295
ssize_t hs_cell_build_rendezvous1(const uint8_t *rendezvous_cookie, size_t rendezvous_cookie_len, const uint8_t *rendezvous_handshake_info, size_t rendezvous_handshake_info_len, uint8_t *cell_out)
Definition: hs_cell.c:1142
ssize_t hs_cell_build_introduce1(const hs_cell_introduce1_data_t *data, uint8_t *cell_out)
Definition: hs_cell.c:1178
int hs_cell_parse_rendezvous2(const uint8_t *payload, size_t payload_len, uint8_t *handshake_info, size_t handshake_info_len)
Definition: hs_cell.c:1256
static void introduce1_set_auth_key(trn_cell_introduce1_t *cell, const hs_cell_introduce1_data_t *data)
Definition: hs_cell.c:521
static int build_introduce_pow_extension(const hs_pow_solution_t *pow_solution, trn_extension_t *extensions)
Definition: hs_cell.c:380
static void introduce1_set_encrypted_padding(const trn_cell_introduce1_t *cell, trn_cell_introduce_encrypted_t *enc_cell)
Definition: hs_cell.c:272
static void introduce1_set_encrypted_onion_key(trn_cell_introduce_encrypted_t *cell, const uint8_t *onion_pk)
Definition: hs_cell.c:235
Header file containing cell data for the whole HS subsystem.
#define HS_CELL_INTRODUCE1_MIN_SIZE
Definition: hs_cell.h:18
link_specifier_t * link_specifier_dup(const link_specifier_t *src)
Definition: hs_common.c:1751
#define ESTABLISH_INTRO_SIG_PREFIX
Definition: hs_common.h:50
#define HS_REND_COOKIE_LEN
Definition: hs_ident.h:30
int hs_ntor_service_get_introduce1_keys_multi(const struct ed25519_public_key_t *intro_auth_pubkey, const struct curve25519_keypair_t *intro_enc_keypair, const struct curve25519_public_key_t *client_ephemeral_enc_pubkey, size_t n_subcredentials, const hs_subcredential_t *subcredentials, hs_ntor_intro_cell_keys_t *hs_ntor_intro_cell_keys_out)
Definition: hs_ntor.c:470
Header for hs_ntor.c.
Header file for the specific code for onion balance.
int hs_pow_verify(const ed25519_public_key_t *service_blinded_id, const hs_pow_service_state_t *pow_state, const hs_pow_solution_t *pow_solution)
Definition: hs_pow.c:312
#define HS_POW_EQX_SOL_LEN
Definition: hs_pow.h:31
#define HS_POW_NONCE_LEN
Definition: hs_pow.h:29
#define HS_POW_SEED_HEAD_LEN
Definition: hs_pow.h:43
#define log_fn(severity, domain, args,...)
Definition: log.h:283
#define LD_REND
Definition: log.h:84
#define LD_PROTOCOL
Definition: log.h:72
#define LD_BUG
Definition: log.h:86
#define tor_free(p)
Definition: malloc.h:56
Master header file for Tor-specific functionality.
#define REND_COOKIE_LEN
Definition: or.h:401
#define TO_CIRCUIT(x)
Definition: or.h:936
#define RELAY_PAYLOAD_SIZE_MAX
Definition: or.h:567
Origin circuit structure.
int replaycache_add_test_and_elapsed(replaycache_t *r, const void *data, size_t len, time_t *elapsed)
Definition: replaycache.c:195
Header file for replaycache.c.
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
curve25519_public_key_t onion_pk
Definition: hs_cell.h:54
uint8_t rendezvous_cookie[REND_COOKIE_LEN]
Definition: hs_cell.h:56
unsigned int cc_enabled
Definition: hs_cell.h:62
curve25519_public_key_t client_pk
Definition: hs_cell.h:58
smartlist_t * link_specifiers
Definition: hs_cell.h:60
const ed25519_public_key_t * auth_pk
Definition: hs_cell.h:31
const struct hs_subcredential_t * subcredential
Definition: hs_cell.h:35
const hs_pow_solution_t * pow_solution
Definition: hs_cell.h:47
const curve25519_keypair_t * client_kp
Definition: hs_cell.h:41
const curve25519_public_key_t * enc_pk
Definition: hs_cell.h:33
unsigned int cc_enabled
Definition: hs_cell.h:45
const uint8_t * rendezvous_cookie
Definition: hs_cell.h:39
const curve25519_public_key_t * onion_pk
Definition: hs_cell.h:37
smartlist_t * link_specifiers
Definition: hs_cell.h:43
protover_summary_flags_t pv
Definition: hs_cell.h:102
const ed25519_public_key_t * auth_pk
Definition: hs_cell.h:77
const curve25519_keypair_t * enc_kp
Definition: hs_cell.h:81
replaycache_t * replay_cache
Definition: hs_cell.h:100
const struct hs_subcredential_t * subcredentials
Definition: hs_cell.h:89
const uint8_t * payload
Definition: hs_cell.h:91
hs_cell_intro_rdv_data_t rdv_data
Definition: hs_cell.h:98
unsigned int has_dos_defense_enabled
Definition: hs_service.h:265
unsigned int support_intro2_dos_defense
Definition: hs_service.h:98
ed25519_keypair_t auth_key_kp
Definition: hs_service.h:60
ed25519_public_key_t blinded_id
Definition: hs_service.h:67
hs_pow_service_state_t * pow_state
Definition: hs_service.h:311
hs_service_state_t state
Definition: hs_service.h:325
char onion_address[HS_SERVICE_ADDR_LEN_BASE32+1]
Definition: hs_service.h:318
unsigned int supports_congestion_control
Definition: or.h:830
unsigned int protocols_known
Definition: or.h:777
#define STATIC
Definition: testsupport.h:32
#define tor_assert(expr)
Definition: util_bug.h:103
#define ED25519_SIG_LEN
Definition: x25519_sizes.h:34
#define ED25519_PUBKEY_LEN
Definition: x25519_sizes.h:27
#define CURVE25519_PUBKEY_LEN
Definition: x25519_sizes.h:20