Tor  0.4.7.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"
17 
19 
20 /* Trunnel. */
21 #include "trunnel/ed25519_cert.h"
22 #include "trunnel/hs/cell_common.h"
23 #include "trunnel/hs/cell_establish_intro.h"
24 #include "trunnel/hs/cell_introduce1.h"
25 #include "trunnel/hs/cell_rendezvous.h"
26 
27 /** Compute the MAC of an INTRODUCE cell in mac_out. The encoded_cell param is
28  * the cell content up to the ENCRYPTED section of length encoded_cell_len.
29  * The encrypted param is the start of the ENCRYPTED section of length
30  * encrypted_len. The mac_key is the key needed for the computation of the MAC
31  * derived from the ntor handshake of length mac_key_len.
32  *
33  * The length mac_out_len must be at least DIGEST256_LEN. */
34 static void
35 compute_introduce_mac(const uint8_t *encoded_cell, size_t encoded_cell_len,
36  const uint8_t *encrypted, size_t encrypted_len,
37  const uint8_t *mac_key, size_t mac_key_len,
38  uint8_t *mac_out, size_t mac_out_len)
39 {
40  size_t offset = 0;
41  size_t mac_msg_len;
42  uint8_t mac_msg[RELAY_PAYLOAD_SIZE] = {0};
43 
44  tor_assert(encoded_cell);
45  tor_assert(encrypted);
46  tor_assert(mac_key);
47  tor_assert(mac_out);
48  tor_assert(mac_out_len >= DIGEST256_LEN);
49 
50  /* Compute the size of the message which is basically the entire cell until
51  * the MAC field of course. */
52  mac_msg_len = encoded_cell_len + (encrypted_len - DIGEST256_LEN);
53  tor_assert(mac_msg_len <= sizeof(mac_msg));
54 
55  /* First, put the encoded cell in the msg. */
56  memcpy(mac_msg, encoded_cell, encoded_cell_len);
57  offset += encoded_cell_len;
58  /* Second, put the CLIENT_PK + ENCRYPTED_DATA but omit the MAC field (which
59  * is junk at this point). */
60  memcpy(mac_msg + offset, encrypted, (encrypted_len - DIGEST256_LEN));
61  offset += (encrypted_len - DIGEST256_LEN);
62  tor_assert(offset == mac_msg_len);
63 
64  crypto_mac_sha3_256(mac_out, mac_out_len,
65  mac_key, mac_key_len,
66  mac_msg, mac_msg_len);
67  memwipe(mac_msg, 0, sizeof(mac_msg));
68 }
69 
70 /**
71  * From a set of keys, a list of subcredentials, and the ENCRYPTED section of
72  * an INTRODUCE2 cell, return an array of newly allocated intro cell keys
73  * structures. Finally, the client public key is copied in client_pk. On
74  * error, return NULL.
75  **/
78  const curve25519_keypair_t *enc_key,
79  size_t n_subcredentials,
80  const hs_subcredential_t *subcredentials,
81  const uint8_t *encrypted_section,
82  curve25519_public_key_t *client_pk)
83 {
85 
86  tor_assert(auth_key);
87  tor_assert(enc_key);
88  tor_assert(n_subcredentials > 0);
89  tor_assert(subcredentials);
90  tor_assert(encrypted_section);
91  tor_assert(client_pk);
92 
93  keys = tor_calloc(n_subcredentials, sizeof(hs_ntor_intro_cell_keys_t));
94 
95  /* First bytes of the ENCRYPTED section are the client public key. */
96  memcpy(client_pk->public_key, encrypted_section, CURVE25519_PUBKEY_LEN);
97 
98  if (hs_ntor_service_get_introduce1_keys_multi(auth_key, enc_key, client_pk,
99  n_subcredentials,
100  subcredentials, keys) < 0) {
101  /* Don't rely on the caller to wipe this on error. */
102  memwipe(client_pk, 0, sizeof(curve25519_public_key_t));
103  tor_free(keys);
104  keys = NULL;
105  }
106  return keys;
107 }
108 
109 /** Using the given encryption key, decrypt the encrypted_section of length
110  * encrypted_section_len of an INTRODUCE2 cell and return a newly allocated
111  * buffer containing the decrypted data. On decryption failure, NULL is
112  * returned. */
113 static uint8_t *
114 decrypt_introduce2(const uint8_t *enc_key, const uint8_t *encrypted_section,
115  size_t encrypted_section_len)
116 {
117  uint8_t *decrypted = NULL;
118  crypto_cipher_t *cipher = NULL;
119 
120  tor_assert(enc_key);
121  tor_assert(encrypted_section);
122 
123  /* Decrypt ENCRYPTED section. */
124  cipher = crypto_cipher_new_with_bits((char *) enc_key,
126  tor_assert(cipher);
127 
128  /* This is symmetric encryption so can't be bigger than the encrypted
129  * section length. */
130  decrypted = tor_malloc_zero(encrypted_section_len);
131  if (crypto_cipher_decrypt(cipher, (char *) decrypted,
132  (const char *) encrypted_section,
133  encrypted_section_len) < 0) {
134  tor_free(decrypted);
135  decrypted = NULL;
136  goto done;
137  }
138 
139  done:
140  crypto_cipher_free(cipher);
141  return decrypted;
142 }
143 
144 /** Given a pointer to the decrypted data of the ENCRYPTED section of an
145  * INTRODUCE2 cell of length decrypted_len, parse and validate the cell
146  * content. Return a newly allocated cell structure or NULL on error. The
147  * circuit and service object are only used for logging purposes. */
148 static trn_cell_introduce_encrypted_t *
149 parse_introduce2_encrypted(const uint8_t *decrypted_data,
150  size_t decrypted_len, const origin_circuit_t *circ,
151  const hs_service_t *service)
152 {
153  trn_cell_introduce_encrypted_t *enc_cell = NULL;
154 
155  tor_assert(decrypted_data);
156  tor_assert(circ);
157  tor_assert(service);
158 
159  if (trn_cell_introduce_encrypted_parse(&enc_cell, decrypted_data,
160  decrypted_len) < 0) {
161  log_info(LD_REND, "Unable to parse the decrypted ENCRYPTED section of "
162  "the INTRODUCE2 cell on circuit %u for service %s",
163  TO_CIRCUIT(circ)->n_circ_id,
164  safe_str_client(service->onion_address));
165  goto err;
166  }
167 
168  if (trn_cell_introduce_encrypted_get_onion_key_type(enc_cell) !=
169  TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR) {
170  log_info(LD_REND, "INTRODUCE2 onion key type is invalid. Got %u but "
171  "expected %u on circuit %u for service %s",
172  trn_cell_introduce_encrypted_get_onion_key_type(enc_cell),
173  TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR,
174  TO_CIRCUIT(circ)->n_circ_id,
175  safe_str_client(service->onion_address));
176  goto err;
177  }
178 
179  if (trn_cell_introduce_encrypted_getlen_onion_key(enc_cell) !=
181  log_info(LD_REND, "INTRODUCE2 onion key length is invalid. Got %u but "
182  "expected %d on circuit %u for service %s",
183  (unsigned)trn_cell_introduce_encrypted_getlen_onion_key(enc_cell),
184  CURVE25519_PUBKEY_LEN, TO_CIRCUIT(circ)->n_circ_id,
185  safe_str_client(service->onion_address));
186  goto err;
187  }
188  /* XXX: Validate NSPEC field as well. */
189 
190  return enc_cell;
191  err:
192  trn_cell_introduce_encrypted_free(enc_cell);
193  return NULL;
194 }
195 
196 /** Parse an INTRODUCE2 cell from payload of size payload_len for the given
197  * service and circuit which are used only for logging purposes. The resulting
198  * parsed cell is put in cell_ptr_out.
199  *
200  * Return 0 on success else a negative value and cell_ptr_out is untouched. */
201 static int
203  const origin_circuit_t *circ, const uint8_t *payload,
204  size_t payload_len,
205  trn_cell_introduce1_t **cell_ptr_out)
206 {
207  trn_cell_introduce1_t *cell = NULL;
208 
209  tor_assert(service);
210  tor_assert(circ);
211  tor_assert(payload);
212  tor_assert(cell_ptr_out);
213 
214  /* Parse the cell so we can start cell validation. */
215  if (trn_cell_introduce1_parse(&cell, payload, payload_len) < 0) {
216  log_info(LD_PROTOCOL, "Unable to parse INTRODUCE2 cell on circuit %u "
217  "for service %s",
218  TO_CIRCUIT(circ)->n_circ_id,
219  safe_str_client(service->onion_address));
220  goto err;
221  }
222 
223  /* Success. */
224  *cell_ptr_out = cell;
225  return 0;
226  err:
227  return -1;
228 }
229 
230 /** Set the onion public key onion_pk in cell, the encrypted section of an
231  * INTRODUCE1 cell. */
232 static void
233 introduce1_set_encrypted_onion_key(trn_cell_introduce_encrypted_t *cell,
234  const uint8_t *onion_pk)
235 {
236  tor_assert(cell);
237  tor_assert(onion_pk);
238  /* There is only one possible key type for a non legacy cell. */
239  trn_cell_introduce_encrypted_set_onion_key_type(cell,
240  TRUNNEL_HS_INTRO_ONION_KEY_TYPE_NTOR);
241  trn_cell_introduce_encrypted_set_onion_key_len(cell, CURVE25519_PUBKEY_LEN);
242  trn_cell_introduce_encrypted_setlen_onion_key(cell, CURVE25519_PUBKEY_LEN);
243  memcpy(trn_cell_introduce_encrypted_getarray_onion_key(cell), onion_pk,
244  trn_cell_introduce_encrypted_getlen_onion_key(cell));
245 }
246 
247 /** Set the link specifiers in lspecs in cell, the encrypted section of an
248  * INTRODUCE1 cell. */
249 static void
250 introduce1_set_encrypted_link_spec(trn_cell_introduce_encrypted_t *cell,
251  const smartlist_t *lspecs)
252 {
253  tor_assert(cell);
254  tor_assert(lspecs);
255  tor_assert(smartlist_len(lspecs) > 0);
256  tor_assert(smartlist_len(lspecs) <= UINT8_MAX);
257 
258  uint8_t lspecs_num = (uint8_t) smartlist_len(lspecs);
259  trn_cell_introduce_encrypted_set_nspec(cell, lspecs_num);
260  /* We aren't duplicating the link specifiers object here which means that
261  * the ownership goes to the trn_cell_introduce_encrypted_t cell and those
262  * object will be freed when the cell is. */
263  SMARTLIST_FOREACH(lspecs, link_specifier_t *, ls,
264  trn_cell_introduce_encrypted_add_nspecs(cell, ls));
265 }
266 
267 /** Set padding in the enc_cell only if needed that is the total length of both
268  * sections are below the minimum required for an INTRODUCE1 cell. */
269 static void
270 introduce1_set_encrypted_padding(const trn_cell_introduce1_t *cell,
271  trn_cell_introduce_encrypted_t *enc_cell)
272 {
273  tor_assert(cell);
274  tor_assert(enc_cell);
275  /* This is the length we expect to have once encoded of the whole cell. */
276  ssize_t full_len = trn_cell_introduce1_encoded_len(cell) +
277  trn_cell_introduce_encrypted_encoded_len(enc_cell);
278  tor_assert(full_len > 0);
279  if (full_len < HS_CELL_INTRODUCE1_MIN_SIZE) {
280  size_t padding = HS_CELL_INTRODUCE1_MIN_SIZE - full_len;
281  trn_cell_introduce_encrypted_setlen_pad(enc_cell, padding);
282  memset(trn_cell_introduce_encrypted_getarray_pad(enc_cell), 0,
283  trn_cell_introduce_encrypted_getlen_pad(enc_cell));
284  }
285 }
286 
287 /** Encrypt the ENCRYPTED payload and encode it in the cell using the enc_cell
288  * and the INTRODUCE1 data.
289  *
290  * This can't fail but it is very important that the caller sets every field
291  * in data so the computation of the INTRODUCE1 keys doesn't fail. */
292 static void
293 introduce1_encrypt_and_encode(trn_cell_introduce1_t *cell,
294  const trn_cell_introduce_encrypted_t *enc_cell,
295  const hs_cell_introduce1_data_t *data)
296 {
297  size_t offset = 0;
298  ssize_t encrypted_len;
299  ssize_t encoded_cell_len, encoded_enc_cell_len;
300  uint8_t encoded_cell[RELAY_PAYLOAD_SIZE] = {0};
301  uint8_t encoded_enc_cell[RELAY_PAYLOAD_SIZE] = {0};
302  uint8_t *encrypted = NULL;
303  uint8_t mac[DIGEST256_LEN];
304  crypto_cipher_t *cipher = NULL;
306 
307  tor_assert(cell);
308  tor_assert(enc_cell);
309  tor_assert(data);
310 
311  /* Encode the cells up to now of what we have to we can perform the MAC
312  * computation on it. */
313  encoded_cell_len = trn_cell_introduce1_encode(encoded_cell,
314  sizeof(encoded_cell), cell);
315  /* We have a much more serious issue if this isn't true. */
316  tor_assert(encoded_cell_len > 0);
317 
318  encoded_enc_cell_len =
319  trn_cell_introduce_encrypted_encode(encoded_enc_cell,
320  sizeof(encoded_enc_cell), enc_cell);
321  /* We have a much more serious issue if this isn't true. */
322  tor_assert(encoded_enc_cell_len > 0);
323 
324  /* Get the key material for the encryption. */
325  if (hs_ntor_client_get_introduce1_keys(data->auth_pk, data->enc_pk,
326  data->client_kp,
327  data->subcredential, &keys) < 0) {
328  tor_assert_unreached();
329  }
330 
331  /* Prepare cipher with the encryption key just computed. */
332  cipher = crypto_cipher_new_with_bits((const char *) keys.enc_key,
333  sizeof(keys.enc_key) * 8);
334  tor_assert(cipher);
335 
336  /* Compute the length of the ENCRYPTED section which is the CLIENT_PK,
337  * ENCRYPTED_DATA and MAC length. */
338  encrypted_len = sizeof(data->client_kp->pubkey) + encoded_enc_cell_len +
339  sizeof(mac);
340  tor_assert(encrypted_len < RELAY_PAYLOAD_SIZE);
341  encrypted = tor_malloc_zero(encrypted_len);
342 
343  /* Put the CLIENT_PK first. */
344  memcpy(encrypted, data->client_kp->pubkey.public_key,
345  sizeof(data->client_kp->pubkey.public_key));
346  offset += sizeof(data->client_kp->pubkey.public_key);
347  /* Then encrypt and set the ENCRYPTED_DATA. This can't fail. */
348  crypto_cipher_encrypt(cipher, (char *) encrypted + offset,
349  (const char *) encoded_enc_cell, encoded_enc_cell_len);
350  crypto_cipher_free(cipher);
351  offset += encoded_enc_cell_len;
352  /* Compute MAC from the above and put it in the buffer. This function will
353  * make the adjustment to the encrypted_len to omit the MAC length. */
354  compute_introduce_mac(encoded_cell, encoded_cell_len,
355  encrypted, encrypted_len,
356  keys.mac_key, sizeof(keys.mac_key),
357  mac, sizeof(mac));
358  memcpy(encrypted + offset, mac, sizeof(mac));
359  offset += sizeof(mac);
360  tor_assert(offset == (size_t) encrypted_len);
361 
362  /* Set the ENCRYPTED section in the cell. */
363  trn_cell_introduce1_setlen_encrypted(cell, encrypted_len);
364  memcpy(trn_cell_introduce1_getarray_encrypted(cell),
365  encrypted, encrypted_len);
366 
367  /* Cleanup. */
368  memwipe(&keys, 0, sizeof(keys));
369  memwipe(mac, 0, sizeof(mac));
370  memwipe(encrypted, 0, sizeof(encrypted_len));
371  memwipe(encoded_enc_cell, 0, sizeof(encoded_enc_cell));
372  tor_free(encrypted);
373 }
374 
375 /** Using the INTRODUCE1 data, setup the ENCRYPTED section in cell. This means
376  * set it, encrypt it and encode it. */
377 static void
378 introduce1_set_encrypted(trn_cell_introduce1_t *cell,
379  const hs_cell_introduce1_data_t *data)
380 {
381  trn_cell_introduce_encrypted_t *enc_cell;
382  trn_cell_extension_t *ext;
383 
384  tor_assert(cell);
385  tor_assert(data);
386 
387  enc_cell = trn_cell_introduce_encrypted_new();
388  tor_assert(enc_cell);
389 
390  /* Set extension data. None are used. */
391  ext = trn_cell_extension_new();
392  tor_assert(ext);
393  trn_cell_extension_set_num(ext, 0);
394  trn_cell_introduce_encrypted_set_extensions(enc_cell, ext);
395 
396  /* Set the rendezvous cookie. */
397  memcpy(trn_cell_introduce_encrypted_getarray_rend_cookie(enc_cell),
399 
400  /* Set the onion public key. */
401  introduce1_set_encrypted_onion_key(enc_cell, data->onion_pk->public_key);
402 
403  /* Set the link specifiers. */
405 
406  /* Set padding. */
407  introduce1_set_encrypted_padding(cell, enc_cell);
408 
409  /* Encrypt and encode it in the cell. */
410  introduce1_encrypt_and_encode(cell, enc_cell, data);
411 
412  /* Cleanup. */
413  trn_cell_introduce_encrypted_free(enc_cell);
414 }
415 
416 /** Set the authentication key in the INTRODUCE1 cell from the given data. */
417 static void
418 introduce1_set_auth_key(trn_cell_introduce1_t *cell,
419  const hs_cell_introduce1_data_t *data)
420 {
421  tor_assert(cell);
422  tor_assert(data);
423  /* There is only one possible type for a non legacy cell. */
424  trn_cell_introduce1_set_auth_key_type(cell,
425  TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519);
426  trn_cell_introduce1_set_auth_key_len(cell, ED25519_PUBKEY_LEN);
427  trn_cell_introduce1_setlen_auth_key(cell, ED25519_PUBKEY_LEN);
428  memcpy(trn_cell_introduce1_getarray_auth_key(cell),
429  data->auth_pk->pubkey, trn_cell_introduce1_getlen_auth_key(cell));
430 }
431 
432 /** Build and add to the given DoS cell extension the given parameter type and
433  * value. */
434 static void
435 build_establish_intro_dos_param(trn_cell_extension_dos_t *dos_ext,
436  uint8_t param_type, uint64_t param_value)
437 {
438  trn_cell_extension_dos_param_t *dos_param =
439  trn_cell_extension_dos_param_new();
440 
441  /* Extra safety. We should never send an unknown parameter type. */
442  tor_assert(param_type == TRUNNEL_DOS_PARAM_TYPE_INTRO2_RATE_PER_SEC ||
443  param_type == TRUNNEL_DOS_PARAM_TYPE_INTRO2_BURST_PER_SEC);
444 
445  trn_cell_extension_dos_param_set_type(dos_param, param_type);
446  trn_cell_extension_dos_param_set_value(dos_param, param_value);
447  trn_cell_extension_dos_add_params(dos_ext, dos_param);
448 
449  /* Not freeing the trunnel object because it is now owned by dos_ext. */
450 }
451 
452 /** Build the DoS defense cell extension and put it in the given extensions
453  * object. Return 0 on success, -1 on failure. (Right now, failure is only
454  * possible if there is a bug.) */
455 static int
457  trn_cell_extension_t *extensions)
458 {
459  ssize_t ret;
460  size_t dos_ext_encoded_len;
461  uint8_t *field_array;
462  trn_cell_extension_field_t *field = NULL;
463  trn_cell_extension_dos_t *dos_ext = NULL;
464 
465  tor_assert(service_config);
466  tor_assert(extensions);
467 
468  /* We are creating a cell extension field of the type DoS. */
469  field = trn_cell_extension_field_new();
470  trn_cell_extension_field_set_field_type(field,
471  TRUNNEL_CELL_EXTENSION_TYPE_DOS);
472 
473  /* Build DoS extension field. We will put in two parameters. */
474  dos_ext = trn_cell_extension_dos_new();
475  trn_cell_extension_dos_set_n_params(dos_ext, 2);
476 
477  /* Build DoS parameter INTRO2 rate per second. */
479  TRUNNEL_DOS_PARAM_TYPE_INTRO2_RATE_PER_SEC,
480  service_config->intro_dos_rate_per_sec);
481  /* Build DoS parameter INTRO2 burst per second. */
483  TRUNNEL_DOS_PARAM_TYPE_INTRO2_BURST_PER_SEC,
484  service_config->intro_dos_burst_per_sec);
485 
486  /* Set the field with the encoded DoS extension. */
487  ret = trn_cell_extension_dos_encoded_len(dos_ext);
488  if (BUG(ret <= 0)) {
489  goto err;
490  }
491  dos_ext_encoded_len = ret;
492  /* Set length field and the field array size length. */
493  trn_cell_extension_field_set_field_len(field, dos_ext_encoded_len);
494  trn_cell_extension_field_setlen_field(field, dos_ext_encoded_len);
495  /* Encode the DoS extension into the cell extension field. */
496  field_array = trn_cell_extension_field_getarray_field(field);
497  ret = trn_cell_extension_dos_encode(field_array,
498  trn_cell_extension_field_getlen_field(field), dos_ext);
499  if (BUG(ret <= 0)) {
500  goto err;
501  }
502  tor_assert(ret == (ssize_t) dos_ext_encoded_len);
503 
504  /* Finally, encode field into the cell extension. */
505  trn_cell_extension_add_fields(extensions, field);
506 
507  /* We've just add an extension field to the cell extensions so increment the
508  * total number. */
509  trn_cell_extension_set_num(extensions,
510  trn_cell_extension_get_num(extensions) + 1);
511 
512  /* Cleanup. DoS extension has been encoded at this point. */
513  trn_cell_extension_dos_free(dos_ext);
514 
515  return 0;
516 
517  err:
518  trn_cell_extension_field_free(field);
519  trn_cell_extension_dos_free(dos_ext);
520  return -1;
521 }
522 
523 /* ========== */
524 /* Public API */
525 /* ========== */
526 
527 /** Allocate and build all the ESTABLISH_INTRO cell extension. The given
528  * extensions pointer is always set to a valid cell extension object. */
529 STATIC trn_cell_extension_t *
531  const hs_service_intro_point_t *ip)
532 {
533  int ret;
534  trn_cell_extension_t *extensions;
535 
536  tor_assert(service_config);
537  tor_assert(ip);
538 
539  extensions = trn_cell_extension_new();
540  trn_cell_extension_set_num(extensions, 0);
541 
542  /* If the defense has been enabled service side (by the operator with a
543  * torrc option) and the intro point does support it. */
544  if (service_config->has_dos_defense_enabled &&
546  /* This function takes care to increment the number of extensions. */
547  ret = build_establish_intro_dos_extension(service_config, extensions);
548  if (ret < 0) {
549  /* Return no extensions on error. */
550  goto end;
551  }
552  }
553 
554  end:
555  return extensions;
556 }
557 
558 /** Build an ESTABLISH_INTRO cell with the given circuit nonce and intro point
559  * object. The encoded cell is put in cell_out that MUST at least be of the
560  * size of RELAY_PAYLOAD_SIZE. Return the encoded cell length on success else
561  * a negative value and cell_out is untouched. */
562 ssize_t
563 hs_cell_build_establish_intro(const char *circ_nonce,
564  const hs_service_config_t *service_config,
565  const hs_service_intro_point_t *ip,
566  uint8_t *cell_out)
567 {
568  ssize_t cell_len = -1;
569  uint16_t sig_len = ED25519_SIG_LEN;
570  trn_cell_establish_intro_t *cell = NULL;
571  trn_cell_extension_t *extensions;
572 
573  tor_assert(circ_nonce);
574  tor_assert(service_config);
575  tor_assert(ip);
576 
577  /* Build the extensions, if any. */
578  extensions = build_establish_intro_extensions(service_config, ip);
579 
580  /* Set extension data. None used here. */
581  cell = trn_cell_establish_intro_new();
582  trn_cell_establish_intro_set_extensions(cell, extensions);
583  /* Set signature size. Array is then allocated in the cell. We need to do
584  * this early so we can use trunnel API to get the signature length. */
585  trn_cell_establish_intro_set_sig_len(cell, sig_len);
586  trn_cell_establish_intro_setlen_sig(cell, sig_len);
587 
588  /* Set AUTH_KEY_TYPE: 2 means ed25519 */
589  trn_cell_establish_intro_set_auth_key_type(cell,
590  TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519);
591 
592  /* Set AUTH_KEY and AUTH_KEY_LEN field. Must also set byte-length of
593  * AUTH_KEY to match */
594  {
595  uint16_t auth_key_len = ED25519_PUBKEY_LEN;
596  trn_cell_establish_intro_set_auth_key_len(cell, auth_key_len);
597  trn_cell_establish_intro_setlen_auth_key(cell, auth_key_len);
598  /* We do this call _after_ setting the length because it's reallocated at
599  * that point only. */
600  uint8_t *auth_key_ptr = trn_cell_establish_intro_getarray_auth_key(cell);
601  memcpy(auth_key_ptr, ip->auth_key_kp.pubkey.pubkey, auth_key_len);
602  }
603 
604  /* Calculate HANDSHAKE_AUTH field (MAC). */
605  {
606  ssize_t tmp_cell_enc_len = 0;
607  ssize_t tmp_cell_mac_offset =
608  sig_len + sizeof(cell->sig_len) +
609  trn_cell_establish_intro_getlen_handshake_mac(cell);
610  uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE] = {0};
611  uint8_t mac[TRUNNEL_SHA3_256_LEN], *handshake_ptr;
612 
613  /* We first encode the current fields we have in the cell so we can
614  * compute the MAC using the raw bytes. */
615  tmp_cell_enc_len = trn_cell_establish_intro_encode(tmp_cell_enc,
616  sizeof(tmp_cell_enc),
617  cell);
618  if (BUG(tmp_cell_enc_len < 0)) {
619  goto done;
620  }
621  /* Sanity check. */
622  tor_assert(tmp_cell_enc_len > tmp_cell_mac_offset);
623 
624  /* Circuit nonce is always DIGEST_LEN according to tor-spec.txt. */
625  crypto_mac_sha3_256(mac, sizeof(mac),
626  (uint8_t *) circ_nonce, DIGEST_LEN,
627  tmp_cell_enc, tmp_cell_enc_len - tmp_cell_mac_offset);
628  handshake_ptr = trn_cell_establish_intro_getarray_handshake_mac(cell);
629  memcpy(handshake_ptr, mac, sizeof(mac));
630 
631  memwipe(mac, 0, sizeof(mac));
632  memwipe(tmp_cell_enc, 0, sizeof(tmp_cell_enc));
633  }
634 
635  /* Calculate the cell signature SIG. */
636  {
637  ssize_t tmp_cell_enc_len = 0;
638  ssize_t tmp_cell_sig_offset = (sig_len + sizeof(cell->sig_len));
639  uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE] = {0}, *sig_ptr;
641 
642  /* We first encode the current fields we have in the cell so we can
643  * compute the signature from the raw bytes of the cell. */
644  tmp_cell_enc_len = trn_cell_establish_intro_encode(tmp_cell_enc,
645  sizeof(tmp_cell_enc),
646  cell);
647  if (BUG(tmp_cell_enc_len < 0)) {
648  goto done;
649  }
650 
651  if (ed25519_sign_prefixed(&sig, tmp_cell_enc,
652  tmp_cell_enc_len - tmp_cell_sig_offset,
654  log_warn(LD_BUG, "Unable to make signature for ESTABLISH_INTRO cell.");
655  goto done;
656  }
657  /* Copy the signature into the cell. */
658  sig_ptr = trn_cell_establish_intro_getarray_sig(cell);
659  memcpy(sig_ptr, sig.sig, sig_len);
660 
661  memwipe(tmp_cell_enc, 0, sizeof(tmp_cell_enc));
662  }
663 
664  /* Encode the cell. Can't be bigger than a standard cell. */
665  cell_len = trn_cell_establish_intro_encode(cell_out, RELAY_PAYLOAD_SIZE,
666  cell);
667 
668  done:
669  trn_cell_establish_intro_free(cell);
670  return cell_len;
671 }
672 
673 /** Parse the INTRO_ESTABLISHED cell in the payload of size payload_len. If we
674  * are successful at parsing it, return the length of the parsed cell else a
675  * negative value on error. */
676 ssize_t
677 hs_cell_parse_intro_established(const uint8_t *payload, size_t payload_len)
678 {
679  ssize_t ret;
680  trn_cell_intro_established_t *cell = NULL;
681 
682  tor_assert(payload);
683 
684  /* Try to parse the payload into a cell making sure we do actually have a
685  * valid cell. */
686  ret = trn_cell_intro_established_parse(&cell, payload, payload_len);
687  if (ret >= 0) {
688  /* On success, we do not keep the cell, we just notify the caller that it
689  * was successfully parsed. */
690  trn_cell_intro_established_free(cell);
691  }
692  return ret;
693 }
694 
695 /** For the encrypted INTRO2 cell in <b>encrypted_section</b>, use the crypto
696  * material in <b>data</b> to compute the right ntor keys. Also validate the
697  * INTRO2 MAC to ensure that the keys are the right ones.
698  *
699  * Return NULL on failure to either produce the key material or on MAC
700  * validation. Else return a newly allocated intro keys object. */
703  const uint8_t *encrypted_section,
704  size_t encrypted_section_len)
705 {
706  hs_ntor_intro_cell_keys_t *intro_keys = NULL;
707  hs_ntor_intro_cell_keys_t *intro_keys_result = NULL;
708 
709  /* Build the key material out of the key material found in the cell. */
710  intro_keys = get_introduce2_key_material(data->auth_pk, data->enc_kp,
711  data->n_subcredentials,
712  data->subcredentials,
713  encrypted_section,
714  &data->client_pk);
715  if (intro_keys == NULL) {
716  log_info(LD_REND, "Invalid INTRODUCE2 encrypted data. Unable to "
717  "compute key material");
718  return NULL;
719  }
720 
721  /* Make sure we are not about to underflow. */
722  if (BUG(encrypted_section_len < DIGEST256_LEN)) {
723  return NULL;
724  }
725 
726  /* Validate MAC from the cell and our computed key material. The MAC field
727  * in the cell is at the end of the encrypted section. */
728  intro_keys_result = tor_malloc_zero(sizeof(*intro_keys_result));
729  for (unsigned i = 0; i < data->n_subcredentials; ++i) {
730  uint8_t mac[DIGEST256_LEN];
731 
732  /* The MAC field is at the very end of the ENCRYPTED section. */
733  size_t mac_offset = encrypted_section_len - sizeof(mac);
734  /* Compute the MAC. Use the entire encoded payload with a length up to the
735  * ENCRYPTED section. */
737  data->payload_len - encrypted_section_len,
738  encrypted_section, encrypted_section_len,
739  intro_keys[i].mac_key,
740  sizeof(intro_keys[i].mac_key),
741  mac, sizeof(mac));
742  /* Time-invariant conditional copy: if the MAC is what we expected, then
743  * set intro_keys_result to intro_keys[i]. Otherwise, don't: but don't
744  * leak which one it was! */
745  bool equal = tor_memeq(mac, encrypted_section + mac_offset, sizeof(mac));
746  memcpy_if_true_timei(equal, intro_keys_result, &intro_keys[i],
747  sizeof(*intro_keys_result));
748  }
749 
750  /* We no longer need intro_keys. */
751  memwipe(intro_keys, 0,
753  tor_free(intro_keys);
754 
755  if (safe_mem_is_zero(intro_keys_result, sizeof(*intro_keys_result))) {
756  log_info(LD_REND, "Invalid MAC validation for INTRODUCE2 cell");
757  tor_free(intro_keys_result); /* sets intro_keys_result to NULL */
758  }
759 
760  return intro_keys_result;
761 }
762 
763 /** Parse the INTRODUCE2 cell using data which contains everything we need to
764  * do so and contains the destination buffers of information we extract and
765  * compute from the cell. Return 0 on success else a negative value. The
766  * service and circ are only used for logging purposes. */
767 ssize_t
769  const origin_circuit_t *circ,
770  const hs_service_t *service)
771 {
772  int ret = -1;
773  time_t elapsed;
774  uint8_t *decrypted = NULL;
775  size_t encrypted_section_len;
776  const uint8_t *encrypted_section;
777  trn_cell_introduce1_t *cell = NULL;
778  trn_cell_introduce_encrypted_t *enc_cell = NULL;
779  hs_ntor_intro_cell_keys_t *intro_keys = NULL;
780 
781  tor_assert(data);
782  tor_assert(circ);
783  tor_assert(service);
784 
785  /* Parse the cell into a decoded data structure pointed by cell_ptr. */
786  if (parse_introduce2_cell(service, circ, data->payload, data->payload_len,
787  &cell) < 0) {
788  goto done;
789  }
790 
791  log_info(LD_REND, "Received a decodable INTRODUCE2 cell on circuit %u "
792  "for service %s. Decoding encrypted section...",
793  TO_CIRCUIT(circ)->n_circ_id,
794  safe_str_client(service->onion_address));
795 
796  encrypted_section = trn_cell_introduce1_getconstarray_encrypted(cell);
797  encrypted_section_len = trn_cell_introduce1_getlen_encrypted(cell);
798 
799  /* Encrypted section must at least contain the CLIENT_PK and MAC which is
800  * defined in section 3.3.2 of the specification. */
801  if (encrypted_section_len < (CURVE25519_PUBKEY_LEN + DIGEST256_LEN)) {
802  log_info(LD_REND, "Invalid INTRODUCE2 encrypted section length "
803  "for service %s. Dropping cell.",
804  safe_str_client(service->onion_address));
805  goto done;
806  }
807 
808  /* Check our replay cache for this introduction point. */
809  if (replaycache_add_test_and_elapsed(data->replay_cache, encrypted_section,
810  encrypted_section_len, &elapsed)) {
811  log_warn(LD_REND, "Possible replay detected! An INTRODUCE2 cell with the "
812  "same ENCRYPTED section was seen %ld seconds ago. "
813  "Dropping cell.", (long int) elapsed);
814  goto done;
815  }
816 
817  /* First bytes of the ENCRYPTED section are the client public key (they are
818  * guaranteed to exist because of the length check above). We are gonna use
819  * the client public key to compute the ntor keys and decrypt the payload:
820  */
821  memcpy(&data->client_pk.public_key, encrypted_section,
823 
824  /* Get the right INTRODUCE2 ntor keys and verify the cell MAC */
825  intro_keys = get_introduce2_keys_and_verify_mac(data, encrypted_section,
826  encrypted_section_len);
827  if (!intro_keys) {
828  log_warn(LD_REND, "Could not get valid INTRO2 keys on circuit %u "
829  "for service %s", TO_CIRCUIT(circ)->n_circ_id,
830  safe_str_client(service->onion_address));
831  goto done;
832  }
833 
834  {
835  /* The ENCRYPTED_DATA section starts just after the CLIENT_PK. */
836  const uint8_t *encrypted_data =
837  encrypted_section + sizeof(data->client_pk);
838  /* It's symmetric encryption so it's correct to use the ENCRYPTED length
839  * for decryption. Computes the length of ENCRYPTED_DATA meaning removing
840  * the CLIENT_PK and MAC length. */
841  size_t encrypted_data_len =
842  encrypted_section_len - (sizeof(data->client_pk) + DIGEST256_LEN);
843 
844  /* This decrypts the ENCRYPTED_DATA section of the cell. */
845  decrypted = decrypt_introduce2(intro_keys->enc_key,
846  encrypted_data, encrypted_data_len);
847  if (decrypted == NULL) {
848  log_info(LD_REND, "Unable to decrypt the ENCRYPTED section of an "
849  "INTRODUCE2 cell on circuit %u for service %s",
850  TO_CIRCUIT(circ)->n_circ_id,
851  safe_str_client(service->onion_address));
852  goto done;
853  }
854 
855  /* Parse this blob into an encrypted cell structure so we can then extract
856  * the data we need out of it. */
857  enc_cell = parse_introduce2_encrypted(decrypted, encrypted_data_len,
858  circ, service);
859  memwipe(decrypted, 0, encrypted_data_len);
860  if (enc_cell == NULL) {
861  goto done;
862  }
863  }
864 
865  /* XXX: Implement client authorization checks. */
866 
867  /* Extract onion key and rendezvous cookie from the cell used for the
868  * rendezvous point circuit e2e encryption. */
869  memcpy(data->onion_pk.public_key,
870  trn_cell_introduce_encrypted_getconstarray_onion_key(enc_cell),
872  memcpy(data->rendezvous_cookie,
873  trn_cell_introduce_encrypted_getconstarray_rend_cookie(enc_cell),
874  sizeof(data->rendezvous_cookie));
875 
876  /* Extract rendezvous link specifiers. */
877  for (size_t idx = 0;
878  idx < trn_cell_introduce_encrypted_get_nspec(enc_cell); idx++) {
879  link_specifier_t *lspec =
880  trn_cell_introduce_encrypted_get_nspecs(enc_cell, idx);
881  if (BUG(!lspec)) {
882  goto done;
883  }
884  link_specifier_t *lspec_dup = link_specifier_dup(lspec);
885  if (BUG(!lspec_dup)) {
886  goto done;
887  }
888  smartlist_add(data->link_specifiers, lspec_dup);
889  }
890 
891  /* Success. */
892  ret = 0;
893  log_info(LD_REND, "Valid INTRODUCE2 cell. Launching rendezvous circuit.");
894 
895  done:
896  if (intro_keys) {
897  memwipe(intro_keys, 0, sizeof(hs_ntor_intro_cell_keys_t));
898  tor_free(intro_keys);
899  }
900  tor_free(decrypted);
901  trn_cell_introduce_encrypted_free(enc_cell);
902  trn_cell_introduce1_free(cell);
903  return ret;
904 }
905 
906 /** Build a RENDEZVOUS1 cell with the given rendezvous cookie and handshake
907  * info. The encoded cell is put in cell_out and the length of the data is
908  * returned. This can't fail. */
909 ssize_t
910 hs_cell_build_rendezvous1(const uint8_t *rendezvous_cookie,
911  size_t rendezvous_cookie_len,
912  const uint8_t *rendezvous_handshake_info,
913  size_t rendezvous_handshake_info_len,
914  uint8_t *cell_out)
915 {
916  ssize_t cell_len;
917  trn_cell_rendezvous1_t *cell;
918 
919  tor_assert(rendezvous_cookie);
920  tor_assert(rendezvous_handshake_info);
921  tor_assert(cell_out);
922 
923  cell = trn_cell_rendezvous1_new();
924  /* Set the RENDEZVOUS_COOKIE. */
925  memcpy(trn_cell_rendezvous1_getarray_rendezvous_cookie(cell),
926  rendezvous_cookie, rendezvous_cookie_len);
927  /* Set the HANDSHAKE_INFO. */
928  trn_cell_rendezvous1_setlen_handshake_info(cell,
929  rendezvous_handshake_info_len);
930  memcpy(trn_cell_rendezvous1_getarray_handshake_info(cell),
931  rendezvous_handshake_info, rendezvous_handshake_info_len);
932  /* Encoding. */
933  cell_len = trn_cell_rendezvous1_encode(cell_out, RELAY_PAYLOAD_SIZE, cell);
934  tor_assert(cell_len > 0);
935 
936  trn_cell_rendezvous1_free(cell);
937  return cell_len;
938 }
939 
940 /** Build an INTRODUCE1 cell from the given data. The encoded cell is put in
941  * cell_out which must be of at least size RELAY_PAYLOAD_SIZE. On success, the
942  * encoded length is returned else a negative value and the content of
943  * cell_out should be ignored. */
944 ssize_t
946  uint8_t *cell_out)
947 {
948  ssize_t cell_len;
949  trn_cell_introduce1_t *cell;
950  trn_cell_extension_t *ext;
951 
952  tor_assert(data);
953  tor_assert(cell_out);
954 
955  cell = trn_cell_introduce1_new();
956  tor_assert(cell);
957 
958  /* Set extension data. None are used. */
959  ext = trn_cell_extension_new();
960  tor_assert(ext);
961  trn_cell_extension_set_num(ext, 0);
962  trn_cell_introduce1_set_extensions(cell, ext);
963 
964  /* Set the authentication key. */
965  introduce1_set_auth_key(cell, data);
966 
967  /* Set the encrypted section. This will set, encrypt and encode the
968  * ENCRYPTED section in the cell. After this, we'll be ready to encode. */
969  introduce1_set_encrypted(cell, data);
970 
971  /* Final encoding. */
972  cell_len = trn_cell_introduce1_encode(cell_out, RELAY_PAYLOAD_SIZE, cell);
973 
974  trn_cell_introduce1_free(cell);
975  return cell_len;
976 }
977 
978 /** Build an ESTABLISH_RENDEZVOUS cell from the given rendezvous_cookie. The
979  * encoded cell is put in cell_out which must be of at least
980  * RELAY_PAYLOAD_SIZE. On success, the encoded length is returned and the
981  * caller should clear up the content of the cell.
982  *
983  * This function can't fail. */
984 ssize_t
985 hs_cell_build_establish_rendezvous(const uint8_t *rendezvous_cookie,
986  uint8_t *cell_out)
987 {
988  tor_assert(rendezvous_cookie);
989  tor_assert(cell_out);
990 
991  memcpy(cell_out, rendezvous_cookie, HS_REND_COOKIE_LEN);
992  return HS_REND_COOKIE_LEN;
993 }
994 
995 /** Handle an INTRODUCE_ACK cell encoded in payload of length payload_len.
996  * Return the status code on success else a negative value if the cell as not
997  * decodable. */
998 int
999 hs_cell_parse_introduce_ack(const uint8_t *payload, size_t payload_len)
1000 {
1001  int ret = -1;
1002  trn_cell_introduce_ack_t *cell = NULL;
1003 
1004  tor_assert(payload);
1005 
1006  if (trn_cell_introduce_ack_parse(&cell, payload, payload_len) < 0) {
1007  log_info(LD_REND, "Invalid INTRODUCE_ACK cell. Unable to parse it.");
1008  goto end;
1009  }
1010 
1011  ret = trn_cell_introduce_ack_get_status(cell);
1012 
1013  end:
1014  trn_cell_introduce_ack_free(cell);
1015  return ret;
1016 }
1017 
1018 /** Handle a RENDEZVOUS2 cell encoded in payload of length payload_len. On
1019  * success, handshake_info contains the data in the HANDSHAKE_INFO field, and
1020  * 0 is returned. On error, a negative value is returned. */
1021 int
1022 hs_cell_parse_rendezvous2(const uint8_t *payload, size_t payload_len,
1023  uint8_t *handshake_info, size_t handshake_info_len)
1024 {
1025  int ret = -1;
1026  trn_cell_rendezvous2_t *cell = NULL;
1027 
1028  tor_assert(payload);
1029  tor_assert(handshake_info);
1030 
1031  if (trn_cell_rendezvous2_parse(&cell, payload, payload_len) < 0) {
1032  log_info(LD_REND, "Invalid RENDEZVOUS2 cell. Unable to parse it.");
1033  goto end;
1034  }
1035 
1036  /* Static size, we should never have an issue with this else we messed up
1037  * our code flow. */
1038  tor_assert(trn_cell_rendezvous2_getlen_handshake_info(cell) ==
1039  handshake_info_len);
1040  memcpy(handshake_info,
1041  trn_cell_rendezvous2_getconstarray_handshake_info(cell),
1042  handshake_info_len);
1043  ret = 0;
1044 
1045  end:
1046  trn_cell_rendezvous2_free(cell);
1047  return ret;
1048 }
1049 
1050 /** Clear the given INTRODUCE1 data structure data. */
1051 void
1053 {
1054  if (data == NULL) {
1055  return;
1056  }
1057  /* Object in this list have been moved to the cell object when building it
1058  * so they've been freed earlier. We do that in order to avoid duplicating
1059  * them leading to more memory and CPU time being used for nothing. */
1060  smartlist_free(data->link_specifiers);
1061  /* The data object has no ownership of any members. */
1062  memwipe(data, 0, sizeof(hs_cell_introduce1_data_t));
1063 }
Header file for config.c.
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 trn_cell_extension_t * build_establish_intro_extensions(const hs_service_config_t *service_config, const hs_service_intro_point_t *ip)
Definition: hs_cell.c:530
ssize_t hs_cell_build_establish_rendezvous(const uint8_t *rendezvous_cookie, uint8_t *cell_out)
Definition: hs_cell.c:985
static void introduce1_set_encrypted(trn_cell_introduce1_t *cell, const hs_cell_introduce1_data_t *data)
Definition: hs_cell.c:378
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:435
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:35
static void introduce1_set_encrypted_link_spec(trn_cell_introduce_encrypted_t *cell, const smartlist_t *lspecs)
Definition: hs_cell.c:250
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:202
ssize_t hs_cell_parse_intro_established(const uint8_t *payload, size_t payload_len)
Definition: hs_cell.c:677
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:563
int hs_cell_parse_introduce_ack(const uint8_t *payload, size_t payload_len)
Definition: hs_cell.c:999
static int build_establish_intro_dos_extension(const hs_service_config_t *service_config, trn_cell_extension_t *extensions)
Definition: hs_cell.c:456
void hs_cell_introduce1_data_clear(hs_cell_introduce1_data_t *data)
Definition: hs_cell.c:1052
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:77
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:702
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:293
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:910
ssize_t hs_cell_build_introduce1(const hs_cell_introduce1_data_t *data, uint8_t *cell_out)
Definition: hs_cell.c:945
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:149
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:1022
static void introduce1_set_auth_key(trn_cell_introduce1_t *cell, const hs_cell_introduce1_data_t *data)
Definition: hs_cell.c:418
static void introduce1_set_encrypted_padding(const trn_cell_introduce1_t *cell, trn_cell_introduce_encrypted_t *enc_cell)
Definition: hs_cell.c:270
static void introduce1_set_encrypted_onion_key(trn_cell_introduce_encrypted_t *cell, const uint8_t *onion_pk)
Definition: hs_cell.c:233
ssize_t hs_cell_parse_introduce2(hs_cell_introduce2_data_t *data, const origin_circuit_t *circ, const hs_service_t *service)
Definition: hs_cell.c:768
static uint8_t * decrypt_introduce2(const uint8_t *enc_key, const uint8_t *encrypted_section, size_t encrypted_section_len)
Definition: hs_cell.c:114
Header file containing cell data for the whole HS subsystem.
#define HS_CELL_INTRODUCE1_MIN_SIZE
Definition: hs_cell.h:17
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.
#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:52
Master header file for Tor-specific functionality.
#define REND_COOKIE_LEN
Definition: or.h:341
#define TO_CIRCUIT(x)
Definition: or.h:845
#define RELAY_PAYLOAD_SIZE
Definition: or.h:486
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)
const ed25519_public_key_t * auth_pk
Definition: hs_cell.h:30
const struct hs_subcredential_t * subcredential
Definition: hs_cell.h:34
const curve25519_keypair_t * client_kp
Definition: hs_cell.h:40
const curve25519_public_key_t * enc_pk
Definition: hs_cell.h:32
const uint8_t * rendezvous_cookie
Definition: hs_cell.h:38
const curve25519_public_key_t * onion_pk
Definition: hs_cell.h:36
smartlist_t * link_specifiers
Definition: hs_cell.h:42
curve25519_public_key_t onion_pk
Definition: hs_cell.h:76
const ed25519_public_key_t * auth_pk
Definition: hs_cell.h:55
const curve25519_keypair_t * enc_kp
Definition: hs_cell.h:59
uint8_t rendezvous_cookie[REND_COOKIE_LEN]
Definition: hs_cell.h:78
replaycache_t * replay_cache
Definition: hs_cell.h:84
const struct hs_subcredential_t * subcredentials
Definition: hs_cell.h:67
const uint8_t * payload
Definition: hs_cell.h:69
curve25519_public_key_t client_pk
Definition: hs_cell.h:80
smartlist_t * link_specifiers
Definition: hs_cell.h:82
unsigned int has_dos_defense_enabled
Definition: hs_service.h:256
unsigned int support_intro2_dos_defense
Definition: hs_service.h:89
ed25519_keypair_t auth_key_kp
Definition: hs_service.h:55
char onion_address[HS_SERVICE_ADDR_LEN_BASE32+1]
Definition: hs_service.h:300
#define STATIC
Definition: testsupport.h:32
#define tor_assert(expr)
Definition: util_bug.h:102
#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