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