tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

hs_cell.c (48030B)


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