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