Tor  0.4.8.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. */
36 static void
37 compute_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. */
115 static uint8_t *
116 decrypt_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. */
150 static trn_cell_introduce_encrypted_t *
151 parse_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. */
203 static 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. */
234 static void
235 introduce1_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. */
251 static void
252 introduce1_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. */
271 static void
272 introduce1_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. */
294 static void
295 introduce1_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 and set the INTRODUCE congestion control extension in the given
378  * extensions. */
379 static void
380 build_introduce_cc_extension(trn_extension_t *extensions)
381 {
382  trn_extension_field_t *field = NULL;
383 
384  /* Build CC request extension. */
385  field = trn_extension_field_new();
386  trn_extension_field_set_field_type(field,
387  TRUNNEL_EXT_TYPE_CC_FIELD_REQUEST);
388 
389  /* No payload indicating a request to use congestion control. */
390  trn_extension_field_set_field_len(field, 0);
391 
392  /* Build final extension. */
393  trn_extension_add_fields(extensions, field);
394  trn_extension_set_num(extensions, trn_extension_get_num(extensions) + 1);
395 }
396 
397 /** Using the INTRODUCE1 data, setup the ENCRYPTED section in cell. This means
398  * set it, encrypt it and encode it. */
399 static void
400 introduce1_set_encrypted(trn_cell_introduce1_t *cell,
401  const hs_cell_introduce1_data_t *data)
402 {
403  trn_cell_introduce_encrypted_t *enc_cell;
404  trn_extension_t *ext;
405 
406  tor_assert(cell);
407  tor_assert(data);
408 
409  enc_cell = trn_cell_introduce_encrypted_new();
410  tor_assert(enc_cell);
411 
412  /* Setup extension(s) if any. */
413  ext = trn_extension_new();
414  tor_assert(ext);
415  /* Build congestion control extension is enabled. */
416  if (data->cc_enabled) {
418  }
419  trn_cell_introduce_encrypted_set_extensions(enc_cell, ext);
420 
421  /* Set the rendezvous cookie. */
422  memcpy(trn_cell_introduce_encrypted_getarray_rend_cookie(enc_cell),
424 
425  /* Set the onion public key. */
426  introduce1_set_encrypted_onion_key(enc_cell, data->onion_pk->public_key);
427 
428  /* Set the link specifiers. */
430 
431  /* Set padding. */
432  introduce1_set_encrypted_padding(cell, enc_cell);
433 
434  /* Encrypt and encode it in the cell. */
435  introduce1_encrypt_and_encode(cell, enc_cell, data);
436 
437  /* Cleanup. */
438  trn_cell_introduce_encrypted_free(enc_cell);
439 }
440 
441 /** Set the authentication key in the INTRODUCE1 cell from the given data. */
442 static void
443 introduce1_set_auth_key(trn_cell_introduce1_t *cell,
444  const hs_cell_introduce1_data_t *data)
445 {
446  tor_assert(cell);
447  tor_assert(data);
448  /* There is only one possible type for a non legacy cell. */
449  trn_cell_introduce1_set_auth_key_type(cell,
450  TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519);
451  trn_cell_introduce1_set_auth_key_len(cell, ED25519_PUBKEY_LEN);
452  trn_cell_introduce1_setlen_auth_key(cell, ED25519_PUBKEY_LEN);
453  memcpy(trn_cell_introduce1_getarray_auth_key(cell),
454  data->auth_pk->pubkey, trn_cell_introduce1_getlen_auth_key(cell));
455 }
456 
457 /** Build and add to the given DoS cell extension the given parameter type and
458  * value. */
459 static void
460 build_establish_intro_dos_param(trn_cell_extension_dos_t *dos_ext,
461  uint8_t param_type, uint64_t param_value)
462 {
463  trn_cell_extension_dos_param_t *dos_param =
464  trn_cell_extension_dos_param_new();
465 
466  /* Extra safety. We should never send an unknown parameter type. */
467  tor_assert(param_type == TRUNNEL_DOS_PARAM_TYPE_INTRO2_RATE_PER_SEC ||
468  param_type == TRUNNEL_DOS_PARAM_TYPE_INTRO2_BURST_PER_SEC);
469 
470  trn_cell_extension_dos_param_set_type(dos_param, param_type);
471  trn_cell_extension_dos_param_set_value(dos_param, param_value);
472  trn_cell_extension_dos_add_params(dos_ext, dos_param);
473 
474  /* Not freeing the trunnel object because it is now owned by dos_ext. */
475 }
476 
477 /** Build the DoS defense cell extension and put it in the given extensions
478  * object. Return 0 on success, -1 on failure. (Right now, failure is only
479  * possible if there is a bug.) */
480 static int
482  trn_extension_t *extensions)
483 {
484  ssize_t ret;
485  size_t dos_ext_encoded_len;
486  uint8_t *field_array;
487  trn_extension_field_t *field = NULL;
488  trn_cell_extension_dos_t *dos_ext = NULL;
489 
490  tor_assert(service_config);
491  tor_assert(extensions);
492 
493  /* We are creating a cell extension field of the type DoS. */
494  field = trn_extension_field_new();
495  trn_extension_field_set_field_type(field,
496  TRUNNEL_CELL_EXTENSION_TYPE_DOS);
497 
498  /* Build DoS extension field. We will put in two parameters. */
499  dos_ext = trn_cell_extension_dos_new();
500  trn_cell_extension_dos_set_n_params(dos_ext, 2);
501 
502  /* Build DoS parameter INTRO2 rate per second. */
504  TRUNNEL_DOS_PARAM_TYPE_INTRO2_RATE_PER_SEC,
505  service_config->intro_dos_rate_per_sec);
506  /* Build DoS parameter INTRO2 burst per second. */
508  TRUNNEL_DOS_PARAM_TYPE_INTRO2_BURST_PER_SEC,
509  service_config->intro_dos_burst_per_sec);
510 
511  /* Set the field with the encoded DoS extension. */
512  ret = trn_cell_extension_dos_encoded_len(dos_ext);
513  if (BUG(ret <= 0)) {
514  goto err;
515  }
516  dos_ext_encoded_len = ret;
517  /* Set length field and the field array size length. */
518  trn_extension_field_set_field_len(field, dos_ext_encoded_len);
519  trn_extension_field_setlen_field(field, dos_ext_encoded_len);
520  /* Encode the DoS extension into the cell extension field. */
521  field_array = trn_extension_field_getarray_field(field);
522  ret = trn_cell_extension_dos_encode(field_array,
523  trn_extension_field_getlen_field(field), dos_ext);
524  if (BUG(ret <= 0)) {
525  goto err;
526  }
527  tor_assert(ret == (ssize_t) dos_ext_encoded_len);
528 
529  /* Finally, encode field into the cell extension. */
530  trn_extension_add_fields(extensions, field);
531 
532  /* We've just add an extension field to the cell extensions so increment the
533  * total number. */
534  trn_extension_set_num(extensions, trn_extension_get_num(extensions) + 1);
535 
536  /* Cleanup. DoS extension has been encoded at this point. */
537  trn_cell_extension_dos_free(dos_ext);
538 
539  return 0;
540 
541  err:
542  trn_extension_field_free(field);
543  trn_cell_extension_dos_free(dos_ext);
544  return -1;
545 }
546 
547 /* ========== */
548 /* Public API */
549 /* ========== */
550 
551 /** Allocate and build all the ESTABLISH_INTRO cell extension. The given
552  * extensions pointer is always set to a valid cell extension object. */
553 STATIC trn_extension_t *
555  const hs_service_intro_point_t *ip)
556 {
557  int ret;
558  trn_extension_t *extensions;
559 
560  tor_assert(service_config);
561  tor_assert(ip);
562 
563  extensions = trn_extension_new();
564  trn_extension_set_num(extensions, 0);
565 
566  /* If the defense has been enabled service side (by the operator with a
567  * torrc option) and the intro point does support it. */
568  if (service_config->has_dos_defense_enabled &&
570  /* This function takes care to increment the number of extensions. */
571  ret = build_establish_intro_dos_extension(service_config, extensions);
572  if (ret < 0) {
573  /* Return no extensions on error. */
574  goto end;
575  }
576  }
577 
578  end:
579  return extensions;
580 }
581 
582 /** Build an ESTABLISH_INTRO cell with the given circuit nonce and intro point
583  * object. The encoded cell is put in cell_out that MUST at least be of the
584  * size of RELAY_PAYLOAD_SIZE. Return the encoded cell length on success else
585  * a negative value and cell_out is untouched. */
586 ssize_t
587 hs_cell_build_establish_intro(const char *circ_nonce,
588  const hs_service_config_t *service_config,
589  const hs_service_intro_point_t *ip,
590  uint8_t *cell_out)
591 {
592  ssize_t cell_len = -1;
593  uint16_t sig_len = ED25519_SIG_LEN;
594  trn_cell_establish_intro_t *cell = NULL;
595  trn_extension_t *extensions;
596 
597  tor_assert(circ_nonce);
598  tor_assert(service_config);
599  tor_assert(ip);
600 
601  /* Build the extensions, if any. */
602  extensions = build_establish_intro_extensions(service_config, ip);
603 
604  /* Set extension data. None used here. */
605  cell = trn_cell_establish_intro_new();
606  trn_cell_establish_intro_set_extensions(cell, extensions);
607  /* Set signature size. Array is then allocated in the cell. We need to do
608  * this early so we can use trunnel API to get the signature length. */
609  trn_cell_establish_intro_set_sig_len(cell, sig_len);
610  trn_cell_establish_intro_setlen_sig(cell, sig_len);
611 
612  /* Set AUTH_KEY_TYPE: 2 means ed25519 */
613  trn_cell_establish_intro_set_auth_key_type(cell,
614  TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519);
615 
616  /* Set AUTH_KEY and AUTH_KEY_LEN field. Must also set byte-length of
617  * AUTH_KEY to match */
618  {
619  uint16_t auth_key_len = ED25519_PUBKEY_LEN;
620  trn_cell_establish_intro_set_auth_key_len(cell, auth_key_len);
621  trn_cell_establish_intro_setlen_auth_key(cell, auth_key_len);
622  /* We do this call _after_ setting the length because it's reallocated at
623  * that point only. */
624  uint8_t *auth_key_ptr = trn_cell_establish_intro_getarray_auth_key(cell);
625  memcpy(auth_key_ptr, ip->auth_key_kp.pubkey.pubkey, auth_key_len);
626  }
627 
628  /* Calculate HANDSHAKE_AUTH field (MAC). */
629  {
630  ssize_t tmp_cell_enc_len = 0;
631  ssize_t tmp_cell_mac_offset =
632  sig_len + sizeof(cell->sig_len) +
633  trn_cell_establish_intro_getlen_handshake_mac(cell);
634  uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE] = {0};
635  uint8_t mac[TRUNNEL_SHA3_256_LEN], *handshake_ptr;
636 
637  /* We first encode the current fields we have in the cell so we can
638  * compute the MAC using the raw bytes. */
639  tmp_cell_enc_len = trn_cell_establish_intro_encode(tmp_cell_enc,
640  sizeof(tmp_cell_enc),
641  cell);
642  if (BUG(tmp_cell_enc_len < 0)) {
643  goto done;
644  }
645  /* Sanity check. */
646  tor_assert(tmp_cell_enc_len > tmp_cell_mac_offset);
647 
648  /* Circuit nonce is always DIGEST_LEN according to tor-spec.txt. */
649  crypto_mac_sha3_256(mac, sizeof(mac),
650  (uint8_t *) circ_nonce, DIGEST_LEN,
651  tmp_cell_enc, tmp_cell_enc_len - tmp_cell_mac_offset);
652  handshake_ptr = trn_cell_establish_intro_getarray_handshake_mac(cell);
653  memcpy(handshake_ptr, mac, sizeof(mac));
654 
655  memwipe(mac, 0, sizeof(mac));
656  memwipe(tmp_cell_enc, 0, sizeof(tmp_cell_enc));
657  }
658 
659  /* Calculate the cell signature SIG. */
660  {
661  ssize_t tmp_cell_enc_len = 0;
662  ssize_t tmp_cell_sig_offset = (sig_len + sizeof(cell->sig_len));
663  uint8_t tmp_cell_enc[RELAY_PAYLOAD_SIZE] = {0}, *sig_ptr;
665 
666  /* We first encode the current fields we have in the cell so we can
667  * compute the signature from the raw bytes of the cell. */
668  tmp_cell_enc_len = trn_cell_establish_intro_encode(tmp_cell_enc,
669  sizeof(tmp_cell_enc),
670  cell);
671  if (BUG(tmp_cell_enc_len < 0)) {
672  goto done;
673  }
674 
675  if (ed25519_sign_prefixed(&sig, tmp_cell_enc,
676  tmp_cell_enc_len - tmp_cell_sig_offset,
678  log_warn(LD_BUG, "Unable to make signature for ESTABLISH_INTRO cell.");
679  goto done;
680  }
681  /* Copy the signature into the cell. */
682  sig_ptr = trn_cell_establish_intro_getarray_sig(cell);
683  memcpy(sig_ptr, sig.sig, sig_len);
684 
685  memwipe(tmp_cell_enc, 0, sizeof(tmp_cell_enc));
686  }
687 
688  /* Encode the cell. Can't be bigger than a standard cell. */
689  cell_len = trn_cell_establish_intro_encode(cell_out, RELAY_PAYLOAD_SIZE,
690  cell);
691 
692  done:
693  trn_cell_establish_intro_free(cell);
694  return cell_len;
695 }
696 
697 /** Parse the INTRO_ESTABLISHED cell in the payload of size payload_len. If we
698  * are successful at parsing it, return the length of the parsed cell else a
699  * negative value on error. */
700 ssize_t
701 hs_cell_parse_intro_established(const uint8_t *payload, size_t payload_len)
702 {
703  ssize_t ret;
704  trn_cell_intro_established_t *cell = NULL;
705 
706  tor_assert(payload);
707 
708  /* Try to parse the payload into a cell making sure we do actually have a
709  * valid cell. */
710  ret = trn_cell_intro_established_parse(&cell, payload, payload_len);
711  if (ret >= 0) {
712  /* On success, we do not keep the cell, we just notify the caller that it
713  * was successfully parsed. */
714  trn_cell_intro_established_free(cell);
715  }
716  return ret;
717 }
718 
719 /** For the encrypted INTRO2 cell in <b>encrypted_section</b>, use the crypto
720  * material in <b>data</b> to compute the right ntor keys. Also validate the
721  * INTRO2 MAC to ensure that the keys are the right ones.
722  *
723  * Return NULL on failure to either produce the key material or on MAC
724  * validation. Else return a newly allocated intro keys object. */
727  const uint8_t *encrypted_section,
728  size_t encrypted_section_len)
729 {
730  hs_ntor_intro_cell_keys_t *intro_keys = NULL;
731  hs_ntor_intro_cell_keys_t *intro_keys_result = NULL;
732 
733  /* Build the key material out of the key material found in the cell. */
734  intro_keys = get_introduce2_key_material(data->auth_pk, data->enc_kp,
735  data->n_subcredentials,
736  data->subcredentials,
737  encrypted_section,
738  &data->client_pk);
739  if (intro_keys == NULL) {
740  log_info(LD_REND, "Invalid INTRODUCE2 encrypted data. Unable to "
741  "compute key material");
742  return NULL;
743  }
744 
745  /* Make sure we are not about to underflow. */
746  if (BUG(encrypted_section_len < DIGEST256_LEN)) {
747  return NULL;
748  }
749 
750  /* Validate MAC from the cell and our computed key material. The MAC field
751  * in the cell is at the end of the encrypted section. */
752  intro_keys_result = tor_malloc_zero(sizeof(*intro_keys_result));
753  for (unsigned i = 0; i < data->n_subcredentials; ++i) {
754  uint8_t mac[DIGEST256_LEN];
755 
756  /* The MAC field is at the very end of the ENCRYPTED section. */
757  size_t mac_offset = encrypted_section_len - sizeof(mac);
758  /* Compute the MAC. Use the entire encoded payload with a length up to the
759  * ENCRYPTED section. */
761  data->payload_len - encrypted_section_len,
762  encrypted_section, encrypted_section_len,
763  intro_keys[i].mac_key,
764  sizeof(intro_keys[i].mac_key),
765  mac, sizeof(mac));
766  /* Time-invariant conditional copy: if the MAC is what we expected, then
767  * set intro_keys_result to intro_keys[i]. Otherwise, don't: but don't
768  * leak which one it was! */
769  bool equal = tor_memeq(mac, encrypted_section + mac_offset, sizeof(mac));
770  memcpy_if_true_timei(equal, intro_keys_result, &intro_keys[i],
771  sizeof(*intro_keys_result));
772  }
773 
774  /* We no longer need intro_keys. */
775  memwipe(intro_keys, 0,
777  tor_free(intro_keys);
778 
779  if (safe_mem_is_zero(intro_keys_result, sizeof(*intro_keys_result))) {
780  log_info(LD_REND, "Invalid MAC validation for INTRODUCE2 cell");
781  tor_free(intro_keys_result); /* sets intro_keys_result to NULL */
782  }
783 
784  return intro_keys_result;
785 }
786 
787 /** Parse the given INTRODUCE cell extension. Update the data object
788  * accordingly depending on the extension. */
789 static void
791  const trn_extension_field_t *field)
792 {
793  trn_extension_field_cc_t *cc_field = NULL;
794 
795  tor_assert(data);
796  tor_assert(field);
797 
798  switch (trn_extension_field_get_field_type(field)) {
799  case TRUNNEL_EXT_TYPE_CC_FIELD_REQUEST:
800  /* CC requests, enable it. */
801  data->cc_enabled = 1;
802  data->pv.protocols_known = 1;
804  break;
805  default:
806  break;
807  }
808 
809  trn_extension_field_cc_free(cc_field);
810 }
811 
812 /** Parse the INTRODUCE2 cell using data which contains everything we need to
813  * do so and contains the destination buffers of information we extract and
814  * compute from the cell. Return 0 on success else a negative value. The
815  * service and circ are only used for logging purposes. */
816 ssize_t
818  const origin_circuit_t *circ,
819  const hs_service_t *service)
820 {
821  int ret = -1;
822  time_t elapsed;
823  uint8_t *decrypted = NULL;
824  size_t encrypted_section_len;
825  const uint8_t *encrypted_section;
826  trn_cell_introduce1_t *cell = NULL;
827  trn_cell_introduce_encrypted_t *enc_cell = NULL;
828  hs_ntor_intro_cell_keys_t *intro_keys = NULL;
829 
830  tor_assert(data);
831  tor_assert(circ);
832  tor_assert(service);
833 
834  /* Parse the cell into a decoded data structure pointed by cell_ptr. */
835  if (parse_introduce2_cell(service, circ, data->payload, data->payload_len,
836  &cell) < 0) {
837  goto done;
838  }
839 
840  log_info(LD_REND, "Received a decodable INTRODUCE2 cell on circuit %u "
841  "for service %s. Decoding encrypted section...",
842  TO_CIRCUIT(circ)->n_circ_id,
843  safe_str_client(service->onion_address));
844 
845  encrypted_section = trn_cell_introduce1_getconstarray_encrypted(cell);
846  encrypted_section_len = trn_cell_introduce1_getlen_encrypted(cell);
847 
848  /* Encrypted section must at least contain the CLIENT_PK and MAC which is
849  * defined in section 3.3.2 of the specification. */
850  if (encrypted_section_len < (CURVE25519_PUBKEY_LEN + DIGEST256_LEN)) {
851  log_info(LD_REND, "Invalid INTRODUCE2 encrypted section length "
852  "for service %s. Dropping cell.",
853  safe_str_client(service->onion_address));
854  goto done;
855  }
856 
857  /* Check our replay cache for this introduction point. */
858  if (replaycache_add_test_and_elapsed(data->replay_cache, encrypted_section,
859  encrypted_section_len, &elapsed)) {
860  log_warn(LD_REND, "Possible replay detected! An INTRODUCE2 cell with the "
861  "same ENCRYPTED section was seen %ld seconds ago. "
862  "Dropping cell.", (long int) elapsed);
863  goto done;
864  }
865 
866  /* First bytes of the ENCRYPTED section are the client public key (they are
867  * guaranteed to exist because of the length check above). We are gonna use
868  * the client public key to compute the ntor keys and decrypt the payload:
869  */
870  memcpy(&data->client_pk.public_key, encrypted_section,
872 
873  /* Get the right INTRODUCE2 ntor keys and verify the cell MAC */
874  intro_keys = get_introduce2_keys_and_verify_mac(data, encrypted_section,
875  encrypted_section_len);
876  if (!intro_keys) {
877  log_warn(LD_REND, "Could not get valid INTRO2 keys on circuit %u "
878  "for service %s", TO_CIRCUIT(circ)->n_circ_id,
879  safe_str_client(service->onion_address));
880  goto done;
881  }
882 
883  {
884  /* The ENCRYPTED_DATA section starts just after the CLIENT_PK. */
885  const uint8_t *encrypted_data =
886  encrypted_section + sizeof(data->client_pk);
887  /* It's symmetric encryption so it's correct to use the ENCRYPTED length
888  * for decryption. Computes the length of ENCRYPTED_DATA meaning removing
889  * the CLIENT_PK and MAC length. */
890  size_t encrypted_data_len =
891  encrypted_section_len - (sizeof(data->client_pk) + DIGEST256_LEN);
892 
893  /* This decrypts the ENCRYPTED_DATA section of the cell. */
894  decrypted = decrypt_introduce2(intro_keys->enc_key,
895  encrypted_data, encrypted_data_len);
896  if (decrypted == NULL) {
897  log_info(LD_REND, "Unable to decrypt the ENCRYPTED section of an "
898  "INTRODUCE2 cell on circuit %u for service %s",
899  TO_CIRCUIT(circ)->n_circ_id,
900  safe_str_client(service->onion_address));
901  goto done;
902  }
903 
904  /* Parse this blob into an encrypted cell structure so we can then extract
905  * the data we need out of it. */
906  enc_cell = parse_introduce2_encrypted(decrypted, encrypted_data_len,
907  circ, service);
908  memwipe(decrypted, 0, encrypted_data_len);
909  if (enc_cell == NULL) {
910  goto done;
911  }
912  }
913 
914  /* XXX: Implement client authorization checks. */
915 
916  /* Extract onion key and rendezvous cookie from the cell used for the
917  * rendezvous point circuit e2e encryption. */
918  memcpy(data->onion_pk.public_key,
919  trn_cell_introduce_encrypted_getconstarray_onion_key(enc_cell),
921  memcpy(data->rendezvous_cookie,
922  trn_cell_introduce_encrypted_getconstarray_rend_cookie(enc_cell),
923  sizeof(data->rendezvous_cookie));
924 
925  /* Extract rendezvous link specifiers. */
926  for (size_t idx = 0;
927  idx < trn_cell_introduce_encrypted_get_nspec(enc_cell); idx++) {
928  link_specifier_t *lspec =
929  trn_cell_introduce_encrypted_get_nspecs(enc_cell, idx);
930  if (BUG(!lspec)) {
931  goto done;
932  }
933  link_specifier_t *lspec_dup = link_specifier_dup(lspec);
934  if (BUG(!lspec_dup)) {
935  goto done;
936  }
937  smartlist_add(data->link_specifiers, lspec_dup);
938  }
939 
940  /* Extract any extensions. */
941  const trn_extension_t *extensions =
942  trn_cell_introduce_encrypted_get_extensions(enc_cell);
943  if (extensions != NULL) {
944  for (size_t idx = 0; idx < trn_extension_get_num(extensions); idx++) {
945  const trn_extension_field_t *field =
946  trn_extension_getconst_fields(extensions, idx);
947  if (BUG(field == NULL)) {
948  /* The number of extensions should match the number of fields. */
949  break;
950  }
951  parse_introduce_cell_extension(data, field);
952  }
953  }
954 
955  /* If the client asked for congestion control, but we don't support it,
956  * that's a failure. It should not have asked, based on our descriptor. */
957  if (data->cc_enabled && !congestion_control_enabled()) {
958  goto done;
959  }
960 
961  /* Success. */
962  ret = 0;
963  log_info(LD_REND, "Valid INTRODUCE2 cell. Launching rendezvous circuit.");
964 
965  done:
966  if (intro_keys) {
967  memwipe(intro_keys, 0, sizeof(hs_ntor_intro_cell_keys_t));
968  tor_free(intro_keys);
969  }
970  tor_free(decrypted);
971  trn_cell_introduce_encrypted_free(enc_cell);
972  trn_cell_introduce1_free(cell);
973  return ret;
974 }
975 
976 /** Build a RENDEZVOUS1 cell with the given rendezvous cookie and handshake
977  * info. The encoded cell is put in cell_out and the length of the data is
978  * returned. This can't fail. */
979 ssize_t
980 hs_cell_build_rendezvous1(const uint8_t *rendezvous_cookie,
981  size_t rendezvous_cookie_len,
982  const uint8_t *rendezvous_handshake_info,
983  size_t rendezvous_handshake_info_len,
984  uint8_t *cell_out)
985 {
986  ssize_t cell_len;
987  trn_cell_rendezvous1_t *cell;
988 
989  tor_assert(rendezvous_cookie);
990  tor_assert(rendezvous_handshake_info);
991  tor_assert(cell_out);
992 
993  cell = trn_cell_rendezvous1_new();
994  /* Set the RENDEZVOUS_COOKIE. */
995  memcpy(trn_cell_rendezvous1_getarray_rendezvous_cookie(cell),
996  rendezvous_cookie, rendezvous_cookie_len);
997  /* Set the HANDSHAKE_INFO. */
998  trn_cell_rendezvous1_setlen_handshake_info(cell,
999  rendezvous_handshake_info_len);
1000  memcpy(trn_cell_rendezvous1_getarray_handshake_info(cell),
1001  rendezvous_handshake_info, rendezvous_handshake_info_len);
1002  /* Encoding. */
1003  cell_len = trn_cell_rendezvous1_encode(cell_out, RELAY_PAYLOAD_SIZE, cell);
1004  tor_assert(cell_len > 0);
1005 
1006  trn_cell_rendezvous1_free(cell);
1007  return cell_len;
1008 }
1009 
1010 /** Build an INTRODUCE1 cell from the given data. The encoded cell is put in
1011  * cell_out which must be of at least size RELAY_PAYLOAD_SIZE. On success, the
1012  * encoded length is returned else a negative value and the content of
1013  * cell_out should be ignored. */
1014 ssize_t
1016  uint8_t *cell_out)
1017 {
1018  ssize_t cell_len;
1019  trn_cell_introduce1_t *cell;
1020  trn_extension_t *ext;
1021 
1022  tor_assert(data);
1023  tor_assert(cell_out);
1024 
1025  cell = trn_cell_introduce1_new();
1026  tor_assert(cell);
1027 
1028  /* Set extension data. None are used. */
1029  ext = trn_extension_new();
1030  tor_assert(ext);
1031  trn_extension_set_num(ext, 0);
1032  trn_cell_introduce1_set_extensions(cell, ext);
1033 
1034  /* Set the authentication key. */
1035  introduce1_set_auth_key(cell, data);
1036 
1037  /* Set the encrypted section. This will set, encrypt and encode the
1038  * ENCRYPTED section in the cell. After this, we'll be ready to encode. */
1039  introduce1_set_encrypted(cell, data);
1040 
1041  /* Final encoding. */
1042  cell_len = trn_cell_introduce1_encode(cell_out, RELAY_PAYLOAD_SIZE, cell);
1043 
1044  trn_cell_introduce1_free(cell);
1045  return cell_len;
1046 }
1047 
1048 /** Build an ESTABLISH_RENDEZVOUS cell from the given rendezvous_cookie. The
1049  * encoded cell is put in cell_out which must be of at least
1050  * RELAY_PAYLOAD_SIZE. On success, the encoded length is returned and the
1051  * caller should clear up the content of the cell.
1052  *
1053  * This function can't fail. */
1054 ssize_t
1055 hs_cell_build_establish_rendezvous(const uint8_t *rendezvous_cookie,
1056  uint8_t *cell_out)
1057 {
1058  tor_assert(rendezvous_cookie);
1059  tor_assert(cell_out);
1060 
1061  memcpy(cell_out, rendezvous_cookie, HS_REND_COOKIE_LEN);
1062  return HS_REND_COOKIE_LEN;
1063 }
1064 
1065 /** Handle an INTRODUCE_ACK cell encoded in payload of length payload_len.
1066  * Return the status code on success else a negative value if the cell as not
1067  * decodable. */
1068 int
1069 hs_cell_parse_introduce_ack(const uint8_t *payload, size_t payload_len)
1070 {
1071  int ret = -1;
1072  trn_cell_introduce_ack_t *cell = NULL;
1073 
1074  tor_assert(payload);
1075 
1076  if (trn_cell_introduce_ack_parse(&cell, payload, payload_len) < 0) {
1077  log_info(LD_REND, "Invalid INTRODUCE_ACK cell. Unable to parse it.");
1078  goto end;
1079  }
1080 
1081  ret = trn_cell_introduce_ack_get_status(cell);
1082 
1083  end:
1084  trn_cell_introduce_ack_free(cell);
1085  return ret;
1086 }
1087 
1088 /** Handle a RENDEZVOUS2 cell encoded in payload of length payload_len. On
1089  * success, handshake_info contains the data in the HANDSHAKE_INFO field, and
1090  * 0 is returned. On error, a negative value is returned. */
1091 int
1092 hs_cell_parse_rendezvous2(const uint8_t *payload, size_t payload_len,
1093  uint8_t *handshake_info, size_t handshake_info_len)
1094 {
1095  int ret = -1;
1096  trn_cell_rendezvous2_t *cell = NULL;
1097 
1098  tor_assert(payload);
1099  tor_assert(handshake_info);
1100 
1101  if (trn_cell_rendezvous2_parse(&cell, payload, payload_len) < 0) {
1102  log_info(LD_REND, "Invalid RENDEZVOUS2 cell. Unable to parse it.");
1103  goto end;
1104  }
1105 
1106  /* Static size, we should never have an issue with this else we messed up
1107  * our code flow. */
1108  tor_assert(trn_cell_rendezvous2_getlen_handshake_info(cell) ==
1109  handshake_info_len);
1110  memcpy(handshake_info,
1111  trn_cell_rendezvous2_getconstarray_handshake_info(cell),
1112  handshake_info_len);
1113  ret = 0;
1114 
1115  end:
1116  trn_cell_rendezvous2_free(cell);
1117  return ret;
1118 }
1119 
1120 /** Clear the given INTRODUCE1 data structure data. */
1121 void
1123 {
1124  if (data == NULL) {
1125  return;
1126  }
1127  /* Object in this list have been moved to the cell object when building it
1128  * so they've been freed earlier. We do that in order to avoid duplicating
1129  * them leading to more memory and CPU time being used for nothing. */
1130  smartlist_free(data->link_specifiers);
1131  /* The data object has no ownership of any members. */
1132  memwipe(data, 0, sizeof(hs_cell_introduce1_data_t));
1133 }
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 void build_introduce_cc_extension(trn_extension_t *extensions)
Definition: hs_cell.c:380
ssize_t hs_cell_build_establish_rendezvous(const uint8_t *rendezvous_cookie, uint8_t *cell_out)
Definition: hs_cell.c:1055
static void introduce1_set_encrypted(trn_cell_introduce1_t *cell, const hs_cell_introduce1_data_t *data)
Definition: hs_cell.c:400
static void parse_introduce_cell_extension(hs_cell_introduce2_data_t *data, const trn_extension_field_t *field)
Definition: hs_cell.c:790
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:460
static int build_establish_intro_dos_extension(const hs_service_config_t *service_config, trn_extension_t *extensions)
Definition: hs_cell.c:481
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 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:701
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:587
int hs_cell_parse_introduce_ack(const uint8_t *payload, size_t payload_len)
Definition: hs_cell.c:1069
void hs_cell_introduce1_data_clear(hs_cell_introduce1_data_t *data)
Definition: hs_cell.c:1122
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 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:726
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:980
ssize_t hs_cell_build_introduce1(const hs_cell_introduce1_data_t *data, uint8_t *cell_out)
Definition: hs_cell.c:1015
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:554
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
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:1092
static void introduce1_set_auth_key(trn_cell_introduce1_t *cell, const hs_cell_introduce1_data_t *data)
Definition: hs_cell.c:443
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
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:817
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
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:56
Master header file for Tor-specific functionality.
#define REND_COOKIE_LEN
Definition: or.h:344
#define TO_CIRCUIT(x)
Definition: or.h:836
#define RELAY_PAYLOAD_SIZE
Definition: or.h:485
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
unsigned int cc_enabled
Definition: hs_cell.h:44
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:78
protover_summary_flags_t pv
Definition: hs_cell.h:88
const ed25519_public_key_t * auth_pk
Definition: hs_cell.h:57
const curve25519_keypair_t * enc_kp
Definition: hs_cell.h:61
uint8_t rendezvous_cookie[REND_COOKIE_LEN]
Definition: hs_cell.h:80
replaycache_t * replay_cache
Definition: hs_cell.h:86
unsigned int cc_enabled
Definition: hs_cell.h:90
const struct hs_subcredential_t * subcredentials
Definition: hs_cell.h:69
const uint8_t * payload
Definition: hs_cell.h:71
curve25519_public_key_t client_pk
Definition: hs_cell.h:82
smartlist_t * link_specifiers
Definition: hs_cell.h:84
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
unsigned int supports_congestion_control
Definition: or.h:733
unsigned int protocols_known
Definition: or.h:680
#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