Tor 0.4.9.0-alpha-dev
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] = {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] = {0};
303 uint8_t encoded_enc_cell[RELAY_PAYLOAD_SIZE] = {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);
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] = {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] = {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, RELAY_PAYLOAD_SIZE,
768 cell);
769
770 done:
771 trn_cell_establish_intro_free(cell);
772 return cell_len;
773}
774
775/** Parse the INTRO_ESTABLISHED cell in the payload of size payload_len. If we
776 * are successful at parsing it, return the length of the parsed cell else a
777 * negative value on error. */
778ssize_t
779hs_cell_parse_intro_established(const uint8_t *payload, size_t payload_len)
780{
781 ssize_t ret;
782 trn_cell_intro_established_t *cell = NULL;
783
784 tor_assert(payload);
785
786 /* Try to parse the payload into a cell making sure we do actually have a
787 * valid cell. */
788 ret = trn_cell_intro_established_parse(&cell, payload, payload_len);
789 if (ret >= 0) {
790 /* On success, we do not keep the cell, we just notify the caller that it
791 * was successfully parsed. */
792 trn_cell_intro_established_free(cell);
793 }
794 return ret;
795}
796
797/** Parse the cell PoW solution extension. Return 0 on success and data
798 * structure is updated with the PoW effort. Return -1 on any kind of error
799 * including if PoW couldn't be verified. */
800static int
802 const hs_service_intro_point_t *ip,
803 const trn_extension_field_t *field,
805{
806 int ret = -1;
807 trn_cell_extension_pow_t *pow = NULL;
809
810 tor_assert(field);
811 tor_assert(ip);
812
813 if (!service->state.pow_state) {
814 log_info(LD_REND, "Unsolicited PoW solution in INTRODUCE2 request.");
815 goto end;
816 }
817
818 if (trn_cell_extension_pow_parse(&pow,
819 trn_extension_field_getconstarray_field(field),
820 trn_extension_field_getlen_field(field)) < 0) {
821 goto end;
822 }
823
824 /* There is only one version supported at the moment so validate we at least
825 * have that. */
826 if (trn_cell_extension_pow_get_pow_version(pow) !=
827 TRUNNEL_POW_VERSION_EQUIX) {
828 log_debug(LD_REND, "Unsupported PoW version. Malformed INTRODUCE2");
829 goto end;
830 }
831
832 /* Effort E */
833 sol.effort = trn_cell_extension_pow_get_pow_effort(pow);
834 /* Seed C */
835 memcpy(sol.seed_head, trn_cell_extension_pow_getconstarray_pow_seed(pow),
837 /* Nonce N */
838 memcpy(sol.nonce, trn_cell_extension_pow_getconstarray_pow_nonce(pow),
840 /* Solution S */
841 memcpy(sol.equix_solution,
842 trn_cell_extension_pow_getconstarray_pow_solution(pow),
844
845 if (hs_pow_verify(&ip->blinded_id, service->state.pow_state, &sol)) {
846 log_info(LD_REND, "PoW INTRODUCE2 request failed to verify.");
847 goto end;
848 }
849
850 log_info(LD_REND, "PoW INTRODUCE2 request successfully verified.");
851 data->rdv_data.pow_effort = sol.effort;
852
853 /* Successfully parsed and verified the PoW solution */
854 ret = 0;
855
856 end:
857 trn_cell_extension_pow_free(pow);
858 return ret;
859}
860
861/** For the encrypted INTRO2 cell in <b>encrypted_section</b>, use the crypto
862 * material in <b>data</b> to compute the right ntor keys. Also validate the
863 * INTRO2 MAC to ensure that the keys are the right ones.
864 *
865 * Return NULL on failure to either produce the key material or on MAC
866 * validation. Else return a newly allocated intro keys object. */
869 const uint8_t *encrypted_section,
870 size_t encrypted_section_len)
871{
872 hs_ntor_intro_cell_keys_t *intro_keys = NULL;
873 hs_ntor_intro_cell_keys_t *intro_keys_result = NULL;
874
875 /* Build the key material out of the key material found in the cell. */
876 intro_keys = get_introduce2_key_material(data->auth_pk, data->enc_kp,
877 data->n_subcredentials,
878 data->subcredentials,
879 encrypted_section,
880 &data->rdv_data.client_pk);
881 if (intro_keys == NULL) {
882 log_info(LD_REND, "Invalid INTRODUCE2 encrypted data. Unable to "
883 "compute key material");
884 return NULL;
885 }
886
887 /* Make sure we are not about to underflow. */
888 if (BUG(encrypted_section_len < DIGEST256_LEN)) {
889 return NULL;
890 }
891
892 /* Validate MAC from the cell and our computed key material. The MAC field
893 * in the cell is at the end of the encrypted section. */
894 intro_keys_result = tor_malloc_zero(sizeof(*intro_keys_result));
895 for (unsigned i = 0; i < data->n_subcredentials; ++i) {
896 uint8_t mac[DIGEST256_LEN];
897
898 /* The MAC field is at the very end of the ENCRYPTED section. */
899 size_t mac_offset = encrypted_section_len - sizeof(mac);
900 /* Compute the MAC. Use the entire encoded payload with a length up to the
901 * ENCRYPTED section. */
903 data->payload_len - encrypted_section_len,
904 encrypted_section, encrypted_section_len,
905 intro_keys[i].mac_key,
906 sizeof(intro_keys[i].mac_key),
907 mac, sizeof(mac));
908 /* Time-invariant conditional copy: if the MAC is what we expected, then
909 * set intro_keys_result to intro_keys[i]. Otherwise, don't: but don't
910 * leak which one it was! */
911 bool equal = tor_memeq(mac, encrypted_section + mac_offset, sizeof(mac));
912 memcpy_if_true_timei(equal, intro_keys_result, &intro_keys[i],
913 sizeof(*intro_keys_result));
914 }
915
916 /* We no longer need intro_keys. */
917 memwipe(intro_keys, 0,
919 tor_free(intro_keys);
920
921 if (safe_mem_is_zero(intro_keys_result, sizeof(*intro_keys_result))) {
922 log_info(LD_REND, "Invalid MAC validation for INTRODUCE2 cell");
923 tor_free(intro_keys_result); /* sets intro_keys_result to NULL */
924 }
925
926 return intro_keys_result;
927}
928
929/** Parse the given INTRODUCE cell extension. Update the data object
930 * accordingly depending on the extension. Return 0 if it validated
931 * correctly, or return -1 if it is malformed (for example because it
932 * includes a PoW that doesn't verify). */
933static int
935 const hs_service_intro_point_t *ip,
937 const trn_extension_field_t *field)
938{
939 int ret = 0;
940 trn_extension_field_cc_t *cc_field = NULL;
941
942 tor_assert(data);
943 tor_assert(field);
944
945 switch (trn_extension_field_get_field_type(field)) {
946 case TRUNNEL_EXT_TYPE_CC_REQUEST:
947 /* CC requests, enable it. */
948 data->rdv_data.cc_enabled = 1;
949 data->pv.protocols_known = 1;
951 break;
952 case TRUNNEL_EXT_TYPE_POW:
953 /* PoW request. If successful, the effort is put in the data. */
955 field, data) < 0) {
956 log_fn(LOG_PROTOCOL_WARN, LD_REND, "Invalid PoW cell extension.");
957 ret = -1;
958 }
959 break;
960 default:
961 break;
962 }
963
964 trn_extension_field_cc_free(cc_field);
965 return ret;
966}
967
968/** Parse the INTRODUCE2 cell using data which contains everything we need to
969 * do so and contains the destination buffers of information we extract and
970 * compute from the cell. Return 0 on success else a negative value. The
971 * service and circ are only used for logging purposes. */
972ssize_t
974 const origin_circuit_t *circ,
975 const hs_service_t *service,
976 const hs_service_intro_point_t *ip)
977{
978 int ret = -1;
979 time_t elapsed;
980 uint8_t *decrypted = NULL;
981 size_t encrypted_section_len;
982 const uint8_t *encrypted_section;
983 trn_cell_introduce1_t *cell = NULL;
984 trn_cell_introduce_encrypted_t *enc_cell = NULL;
985 hs_ntor_intro_cell_keys_t *intro_keys = NULL;
986
987 tor_assert(data);
988 tor_assert(circ);
989 tor_assert(service);
990
991 /* Parse the cell into a decoded data structure pointed by cell_ptr. */
992 if (parse_introduce2_cell(service, circ, data->payload, data->payload_len,
993 &cell) < 0) {
994 goto done;
995 }
996
997 log_info(LD_REND, "Received a decodable INTRODUCE2 cell on circuit %u "
998 "for service %s. Decoding encrypted section...",
999 TO_CIRCUIT(circ)->n_circ_id,
1000 safe_str_client(service->onion_address));
1001
1002 encrypted_section = trn_cell_introduce1_getconstarray_encrypted(cell);
1003 encrypted_section_len = trn_cell_introduce1_getlen_encrypted(cell);
1004
1005 /* Encrypted section must at least contain the CLIENT_PK and MAC which is
1006 * defined in section 3.3.2 of the specification. */
1007 if (encrypted_section_len < (CURVE25519_PUBKEY_LEN + DIGEST256_LEN)) {
1008 log_info(LD_REND, "Invalid INTRODUCE2 encrypted section length "
1009 "for service %s. Dropping cell.",
1010 safe_str_client(service->onion_address));
1011 goto done;
1012 }
1013
1014 /* Check our replay cache for this introduction point. */
1015 if (replaycache_add_test_and_elapsed(data->replay_cache, encrypted_section,
1016 encrypted_section_len, &elapsed)) {
1017 log_warn(LD_REND, "Possible replay detected! An INTRODUCE2 cell with the "
1018 "same ENCRYPTED section was seen %ld seconds ago. "
1019 "Dropping cell.", (long int) elapsed);
1020 goto done;
1021 }
1022
1023 /* First bytes of the ENCRYPTED section are the client public key (they are
1024 * guaranteed to exist because of the length check above). We are gonna use
1025 * the client public key to compute the ntor keys and decrypt the payload:
1026 */
1027 memcpy(&data->rdv_data.client_pk.public_key, encrypted_section,
1029
1030 /* Get the right INTRODUCE2 ntor keys and verify the cell MAC */
1031 intro_keys = get_introduce2_keys_and_verify_mac(data, encrypted_section,
1032 encrypted_section_len);
1033 if (!intro_keys) {
1034 log_warn(LD_REND, "Could not get valid INTRO2 keys on circuit %u "
1035 "for service %s", TO_CIRCUIT(circ)->n_circ_id,
1036 safe_str_client(service->onion_address));
1037 goto done;
1038 }
1039
1040 {
1041 /* The ENCRYPTED_DATA section starts just after the CLIENT_PK. */
1042 const uint8_t *encrypted_data =
1043 encrypted_section + sizeof(data->rdv_data.client_pk);
1044 /* It's symmetric encryption so it's correct to use the ENCRYPTED length
1045 * for decryption. Computes the length of ENCRYPTED_DATA meaning removing
1046 * the CLIENT_PK and MAC length. */
1047 size_t encrypted_data_len =
1048 encrypted_section_len -
1049 (sizeof(data->rdv_data.client_pk) + DIGEST256_LEN);
1050
1051 /* This decrypts the ENCRYPTED_DATA section of the cell. */
1052 decrypted = decrypt_introduce2(intro_keys->enc_key,
1053 encrypted_data, encrypted_data_len);
1054 if (decrypted == NULL) {
1055 log_info(LD_REND, "Unable to decrypt the ENCRYPTED section of an "
1056 "INTRODUCE2 cell on circuit %u for service %s",
1057 TO_CIRCUIT(circ)->n_circ_id,
1058 safe_str_client(service->onion_address));
1059 goto done;
1060 }
1061
1062 /* Parse this blob into an encrypted cell structure so we can then extract
1063 * the data we need out of it. */
1064 enc_cell = parse_introduce2_encrypted(decrypted, encrypted_data_len,
1065 circ, service);
1066 memwipe(decrypted, 0, encrypted_data_len);
1067 if (enc_cell == NULL) {
1068 goto done;
1069 }
1070 }
1071
1072 /* XXX: Implement client authorization checks. */
1073
1074 /* Extract onion key and rendezvous cookie from the cell used for the
1075 * rendezvous point circuit e2e encryption. */
1076 memcpy(data->rdv_data.onion_pk.public_key,
1077 trn_cell_introduce_encrypted_getconstarray_onion_key(enc_cell),
1079 memcpy(data->rdv_data.rendezvous_cookie,
1080 trn_cell_introduce_encrypted_getconstarray_rend_cookie(enc_cell),
1081 sizeof(data->rdv_data.rendezvous_cookie));
1082
1083 /* Extract rendezvous link specifiers. */
1084 for (size_t idx = 0;
1085 idx < trn_cell_introduce_encrypted_get_nspec(enc_cell); idx++) {
1086 link_specifier_t *lspec =
1087 trn_cell_introduce_encrypted_get_nspecs(enc_cell, idx);
1088 if (BUG(!lspec)) {
1089 goto done;
1090 }
1091 link_specifier_t *lspec_dup = link_specifier_dup(lspec);
1092 if (BUG(!lspec_dup)) {
1093 goto done;
1094 }
1095 smartlist_add(data->rdv_data.link_specifiers, lspec_dup);
1096 }
1097
1098 /* Extract any extensions. */
1099 const trn_extension_t *extensions =
1100 trn_cell_introduce_encrypted_get_extensions(enc_cell);
1101 if (extensions != NULL) {
1102 for (size_t idx = 0; idx < trn_extension_get_num(extensions); idx++) {
1103 const trn_extension_field_t *field =
1104 trn_extension_getconst_fields(extensions, idx);
1105 if (BUG(field == NULL)) {
1106 /* The number of extensions should match the number of fields. */
1107 break;
1108 }
1109 if (parse_introduce_cell_extension(service, ip, data, field) < 0) {
1110 goto done;
1111 }
1112 }
1113 }
1114
1115 /* If the client asked for congestion control, but we don't support it,
1116 * that's a failure. It should not have asked, based on our descriptor. */
1118 goto done;
1119 }
1120
1121 /* Success. */
1122 ret = 0;
1123 log_info(LD_REND,
1124 "Valid INTRODUCE2 cell. Willing to launch rendezvous circuit.");
1125
1126 done:
1127 if (intro_keys) {
1128 memwipe(intro_keys, 0, sizeof(hs_ntor_intro_cell_keys_t));
1129 tor_free(intro_keys);
1130 }
1131 tor_free(decrypted);
1132 trn_cell_introduce_encrypted_free(enc_cell);
1133 trn_cell_introduce1_free(cell);
1134 return ret;
1135}
1136
1137/** Build a RENDEZVOUS1 cell with the given rendezvous cookie and handshake
1138 * info. The encoded cell is put in cell_out and the length of the data is
1139 * returned. This can't fail. */
1140ssize_t
1141hs_cell_build_rendezvous1(const uint8_t *rendezvous_cookie,
1142 size_t rendezvous_cookie_len,
1143 const uint8_t *rendezvous_handshake_info,
1144 size_t rendezvous_handshake_info_len,
1145 uint8_t *cell_out)
1146{
1147 ssize_t cell_len;
1148 trn_cell_rendezvous1_t *cell;
1149
1150 tor_assert(rendezvous_cookie);
1151 tor_assert(rendezvous_handshake_info);
1152 tor_assert(cell_out);
1153
1154 cell = trn_cell_rendezvous1_new();
1155 /* Set the RENDEZVOUS_COOKIE. */
1156 memcpy(trn_cell_rendezvous1_getarray_rendezvous_cookie(cell),
1157 rendezvous_cookie, rendezvous_cookie_len);
1158 /* Set the HANDSHAKE_INFO. */
1159 trn_cell_rendezvous1_setlen_handshake_info(cell,
1160 rendezvous_handshake_info_len);
1161 memcpy(trn_cell_rendezvous1_getarray_handshake_info(cell),
1162 rendezvous_handshake_info, rendezvous_handshake_info_len);
1163 /* Encoding. */
1164 cell_len = trn_cell_rendezvous1_encode(cell_out, RELAY_PAYLOAD_SIZE, cell);
1165 tor_assert(cell_len > 0);
1166
1167 trn_cell_rendezvous1_free(cell);
1168 return cell_len;
1169}
1170
1171/** Build an INTRODUCE1 cell from the given data. The encoded cell is put in
1172 * cell_out which must be of at least size RELAY_PAYLOAD_SIZE. On success, the
1173 * encoded length is returned else a negative value and the content of
1174 * cell_out should be ignored. */
1175ssize_t
1177 uint8_t *cell_out)
1178{
1179 ssize_t cell_len;
1180 trn_cell_introduce1_t *cell;
1181 trn_extension_t *ext;
1182
1183 tor_assert(data);
1184 tor_assert(cell_out);
1185
1186 cell = trn_cell_introduce1_new();
1187 tor_assert(cell);
1188
1189 /* Set extension data. None are used. */
1190 ext = trn_extension_new();
1191 tor_assert(ext);
1192 trn_extension_set_num(ext, 0);
1193 trn_cell_introduce1_set_extensions(cell, ext);
1194
1195 /* Set the authentication key. */
1196 introduce1_set_auth_key(cell, data);
1197
1198 /* Set the encrypted section. This will set, encrypt and encode the
1199 * ENCRYPTED section in the cell. After this, we'll be ready to encode. */
1200 introduce1_set_encrypted(cell, data);
1201
1202 /* Final encoding. */
1203 cell_len = trn_cell_introduce1_encode(cell_out, RELAY_PAYLOAD_SIZE, cell);
1204
1205 trn_cell_introduce1_free(cell);
1206 return cell_len;
1207}
1208
1209/** Build an ESTABLISH_RENDEZVOUS cell from the given rendezvous_cookie. The
1210 * encoded cell is put in cell_out which must be of at least
1211 * RELAY_PAYLOAD_SIZE. On success, the encoded length is returned and the
1212 * caller should clear up the content of the cell.
1213 *
1214 * This function can't fail. */
1215ssize_t
1216hs_cell_build_establish_rendezvous(const uint8_t *rendezvous_cookie,
1217 uint8_t *cell_out)
1218{
1219 tor_assert(rendezvous_cookie);
1220 tor_assert(cell_out);
1221
1222 memcpy(cell_out, rendezvous_cookie, HS_REND_COOKIE_LEN);
1223 return HS_REND_COOKIE_LEN;
1224}
1225
1226/** Handle an INTRODUCE_ACK cell encoded in payload of length payload_len.
1227 * Return the status code on success else a negative value if the cell as not
1228 * decodable. */
1229int
1230hs_cell_parse_introduce_ack(const uint8_t *payload, size_t payload_len)
1231{
1232 int ret = -1;
1233 trn_cell_introduce_ack_t *cell = NULL;
1234
1235 tor_assert(payload);
1236
1237 if (trn_cell_introduce_ack_parse(&cell, payload, payload_len) < 0) {
1238 log_info(LD_REND, "Invalid INTRODUCE_ACK cell. Unable to parse it.");
1239 goto end;
1240 }
1241
1242 ret = trn_cell_introduce_ack_get_status(cell);
1243
1244 end:
1245 trn_cell_introduce_ack_free(cell);
1246 return ret;
1247}
1248
1249/** Handle a RENDEZVOUS2 cell encoded in payload of length payload_len. On
1250 * success, handshake_info contains the data in the HANDSHAKE_INFO field, and
1251 * 0 is returned. On error, a negative value is returned. */
1252int
1253hs_cell_parse_rendezvous2(const uint8_t *payload, size_t payload_len,
1254 uint8_t *handshake_info, size_t handshake_info_len)
1255{
1256 int ret = -1;
1257 trn_cell_rendezvous2_t *cell = NULL;
1258
1259 tor_assert(payload);
1260 tor_assert(handshake_info);
1261
1262 if (trn_cell_rendezvous2_parse(&cell, payload, payload_len) < 0) {
1263 log_info(LD_REND, "Invalid RENDEZVOUS2 cell. Unable to parse it.");
1264 goto end;
1265 }
1266
1267 /* Static size, we should never have an issue with this else we messed up
1268 * our code flow. */
1269 tor_assert(trn_cell_rendezvous2_getlen_handshake_info(cell) ==
1270 handshake_info_len);
1271 memcpy(handshake_info,
1272 trn_cell_rendezvous2_getconstarray_handshake_info(cell),
1273 handshake_info_len);
1274 ret = 0;
1275
1276 end:
1277 trn_cell_rendezvous2_free(cell);
1278 return ret;
1279}
1280
1281/** Clear the given INTRODUCE1 data structure data. */
1282void
1284{
1285 if (data == NULL) {
1286 return;
1287 }
1288 /* Object in this list have been moved to the cell object when building it
1289 * so they've been freed earlier. We do that in order to avoid duplicating
1290 * them leading to more memory and CPU time being used for nothing. */
1291 smartlist_free(data->link_specifiers);
1292 /* The data object has no ownership of any members. */
1293 memwipe(data, 0, sizeof(hs_cell_introduce1_data_t));
1294}
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:801
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:1216
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:973
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:779
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:934
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:1230
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:868
void hs_cell_introduce1_data_clear(hs_cell_introduce1_data_t *data)
Definition: hs_cell.c:1283
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:1141
ssize_t hs_cell_build_introduce1(const hs_cell_introduce1_data_t *data, uint8_t *cell_out)
Definition: hs_cell.c:1176
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:1253
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:353
#define TO_CIRCUIT(x)
Definition: or.h:848
#define RELAY_PAYLOAD_SIZE
Definition: or.h:494
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:742
unsigned int protocols_known
Definition: or.h:689
#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