tor

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

onion_crypto.c (23301B)


      1 /* Copyright (c) 2001 Matej Pfajfar.
      2 * Copyright (c) 2001-2004, Roger Dingledine.
      3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
      4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
      5 /* See LICENSE for licensing information */
      6 
      7 /**
      8 * \file onion_crypto.c
      9 * \brief Functions to handle different kinds of circuit extension crypto.
     10 *
     11 * In this module, we provide a set of abstractions to create a uniform
     12 * interface over the circuit extension handshakes that Tor has used
     13 * over the years (CREATE_FAST, ntor, hs_ntor, and ntorv3).
     14 * These handshakes are implemented in the onion_*.c modules.
     15 *
     16 * All[*] of these handshakes follow a similar pattern: a client, knowing
     17 * some key from the relay it wants to extend through, generates the
     18 * first part of a handshake. A relay receives that handshake, and sends
     19 * a reply.  Once the client handles the reply, it knows that it is
     20 * talking to the right relay, and it shares some freshly negotiated key
     21 * material with that relay.
     22 *
     23 * We sometimes call the client's part of the handshake an "onionskin".
     24 * We do this because historically, Onion Routing used a multi-layer
     25 * structure called an "onion" to construct circuits. Each layer of the
     26 * onion contained key material chosen by the client, the identity of
     27 * the next relay in the circuit, and a smaller onion, encrypted with
     28 * the key of the next relay.  When we changed Tor to use a telescoping
     29 * circuit extension design, it corresponded to sending each layer of the
     30 * onion separately -- as a series of onionskins.
     31 **/
     32 
     33 #include "core/or/or.h"
     34 #include "core/or/extendinfo.h"
     35 #include "core/crypto/onion_crypto.h"
     36 #include "core/crypto/onion_fast.h"
     37 #include "core/crypto/onion_ntor.h"
     38 #include "core/crypto/onion_ntor_v3.h"
     39 #include "feature/relay/router.h"
     40 #include "lib/crypt_ops/crypto_dh.h"
     41 #include "lib/crypt_ops/crypto_util.h"
     42 #include "feature/relay/routerkeys.h"
     43 #include "core/or/congestion_control_common.h"
     44 #include "core/crypto/relay_crypto.h"
     45 #include "core/or/protover.h"
     46 
     47 #include "core/or/circuitbuild.h"
     48 
     49 #include "core/or/crypt_path_st.h"
     50 #include "core/or/extend_info_st.h"
     51 
     52 #include "trunnel/congestion_control.h"
     53 #include "trunnel/extension.h"
     54 #include "trunnel/subproto_request.h"
     55 
     56 #define EXT_TYPE_SUBPROTO 3
     57 
     58 static const uint8_t NTOR3_CIRC_VERIFICATION[] = "circuit extend";
     59 static const size_t NTOR3_CIRC_VERIFICATION_LEN = 14;
     60 
     61 #define NTOR3_VERIFICATION_ARGS \
     62  NTOR3_CIRC_VERIFICATION, NTOR3_CIRC_VERIFICATION_LEN
     63 
     64 /** Set `params` to a set of defaults.
     65 *
     66 * These defaults will only change later on if we're using a handshake that has
     67 * parameter negotiation. */
     68 static void
     69 circuit_params_init(circuit_params_t *params)
     70 {
     71  memset(params, 0, sizeof(*params));
     72  params->crypto_alg = RELAY_CRYPTO_ALG_TOR1;
     73  params->cell_fmt = RELAY_CELL_FORMAT_V0;
     74 }
     75 
     76 /** Return a new server_onion_keys_t object with all of the keys
     77 * and other info we might need to do onion handshakes.  (We make a copy of
     78 * our keys for each cpuworker to avoid race conditions with the main thread,
     79 * and to avoid locking) */
     80 server_onion_keys_t *
     81 server_onion_keys_new(void)
     82 {
     83  if (!get_master_identity_key())
     84    return NULL;
     85 
     86  server_onion_keys_t *keys = tor_malloc_zero(sizeof(server_onion_keys_t));
     87  memcpy(keys->my_identity, router_get_my_id_digest(), DIGEST_LEN);
     88  ed25519_pubkey_copy(&keys->my_ed_identity, get_master_identity_key());
     89  dup_onion_keys(&keys->onion_key, &keys->last_onion_key);
     90  keys->curve25519_key_map = construct_ntor_key_map();
     91  keys->junk_keypair = tor_malloc_zero(sizeof(curve25519_keypair_t));
     92  curve25519_keypair_generate(keys->junk_keypair, 0);
     93  return keys;
     94 }
     95 /** Release all storage held in <b>keys</b>. */
     96 void
     97 server_onion_keys_free_(server_onion_keys_t *keys)
     98 {
     99  if (! keys)
    100    return;
    101 
    102  crypto_pk_free(keys->onion_key);
    103  crypto_pk_free(keys->last_onion_key);
    104  ntor_key_map_free(keys->curve25519_key_map);
    105  tor_free(keys->junk_keypair);
    106  memwipe(keys, 0, sizeof(server_onion_keys_t));
    107  tor_free(keys);
    108 }
    109 
    110 /** Release whatever storage is held in <b>state</b>, depending on its
    111 * type, and clear its pointer. */
    112 void
    113 onion_handshake_state_release(onion_handshake_state_t *state)
    114 {
    115  switch (state->tag) {
    116  case ONION_HANDSHAKE_TYPE_TAP:
    117    break;
    118  case ONION_HANDSHAKE_TYPE_FAST:
    119    fast_handshake_state_free(state->u.fast);
    120    state->u.fast = NULL;
    121    break;
    122  case ONION_HANDSHAKE_TYPE_NTOR:
    123    ntor_handshake_state_free(state->u.ntor);
    124    state->u.ntor = NULL;
    125    break;
    126  case ONION_HANDSHAKE_TYPE_NTOR_V3:
    127    ntor3_handshake_state_free(state->u.ntor3);
    128    break;
    129  default:
    130    /* LCOV_EXCL_START
    131     * This state should not even exist. */
    132    log_warn(LD_BUG, "called with unknown handshake state type %d",
    133             (int)state->tag);
    134    tor_fragile_assert();
    135    /* LCOV_EXCL_STOP */
    136  }
    137 }
    138 
    139 /** Perform the first step of a circuit-creation handshake of type <b>type</b>
    140 * (one of ONION_HANDSHAKE_TYPE_*): generate the initial "onion skin" in
    141 * <b>onion_skin_out</b> with length of up to <b>onion_skin_out_maxlen</b>,
    142 * and store any state information in <b>state_out</b>.
    143 * Return -1 on failure, and the length of the onionskin on acceptance.
    144 */
    145 int
    146 onion_skin_create(int type,
    147                  const extend_info_t *node,
    148                  onion_handshake_state_t *state_out,
    149                  uint8_t *onion_skin_out,
    150                  size_t onion_skin_out_maxlen)
    151 {
    152  int r = -1;
    153 
    154  circuit_params_init(&state_out->chosen_params);
    155 
    156  switch (type) {
    157  case ONION_HANDSHAKE_TYPE_TAP:
    158    return -1;
    159  case ONION_HANDSHAKE_TYPE_FAST:
    160    if (fast_onionskin_create(&state_out->u.fast, onion_skin_out) < 0)
    161      return -1;
    162 
    163    r = CREATE_FAST_LEN;
    164    break;
    165  case ONION_HANDSHAKE_TYPE_NTOR:
    166    if (onion_skin_out_maxlen < NTOR_ONIONSKIN_LEN)
    167      return -1;
    168   if (!extend_info_supports_ntor(node))
    169      return -1;
    170    if (onion_skin_ntor_create((const uint8_t*)node->identity_digest,
    171                               &node->curve25519_onion_key,
    172                               &state_out->u.ntor,
    173                               onion_skin_out) < 0)
    174      return -1;
    175 
    176    r = NTOR_ONIONSKIN_LEN;
    177    break;
    178  case ONION_HANDSHAKE_TYPE_NTOR_V3:
    179    if (!extend_info_supports_ntor_v3(node)) {
    180      log_warn(LD_BUG, "Chose ntorv3 handshake, but no support at node");
    181      return -1;
    182    }
    183    if (ed25519_public_key_is_zero(&node->ed_identity)) {
    184      log_warn(LD_BUG, "Chose ntorv3 handshake, but no ed id");
    185      return -1;
    186    }
    187    size_t msg_len = 0;
    188    uint8_t *msg = NULL;
    189    if (client_circ_negotiation_message(node, &msg, &msg_len,
    190                                        &state_out->chosen_params) < 0) {
    191      log_warn(LD_BUG, "Could not create circuit negotiation msg");
    192      return -1;
    193    }
    194    uint8_t *onion_skin = NULL;
    195    size_t onion_skin_len = 0;
    196    int status = onion_skin_ntor3_create(
    197                             &node->ed_identity,
    198                             &node->curve25519_onion_key,
    199                             NTOR3_VERIFICATION_ARGS,
    200                             msg, msg_len, /* client message */
    201                             &state_out->u.ntor3,
    202                             &onion_skin, &onion_skin_len);
    203    tor_free(msg);
    204    if (status < 0) {
    205      log_warn(LD_BUG, "onion skin create failed");
    206      return -1;
    207    }
    208    IF_BUG_ONCE(onion_skin_len > onion_skin_out_maxlen) {
    209      tor_free(onion_skin);
    210      return -1;
    211    }
    212    memcpy(onion_skin_out, onion_skin, onion_skin_len);
    213    tor_free(onion_skin);
    214    r = (int) onion_skin_len;
    215    break;
    216 
    217  default:
    218    /* LCOV_EXCL_START
    219     * We should never try to create an impossible handshake type. */
    220    log_warn(LD_BUG, "called with unknown handshake state type %d", type);
    221    tor_fragile_assert();
    222    r = -1;
    223    /* LCOV_EXCL_STOP */
    224  }
    225 
    226  if (r > 0)
    227    state_out->tag = (uint16_t) type;
    228 
    229  return r;
    230 }
    231 
    232 static bool
    233 subproto_requests_in_order(const trn_subproto_request_t *a,
    234                           const trn_subproto_request_t *b)
    235 {
    236  if (a->protocol_id < b->protocol_id) {
    237    return true;
    238  } else if (a->protocol_id == b->protocol_id) {
    239    return (a->proto_cap_number < b->proto_cap_number);
    240  } else {
    241    return false;
    242  }
    243 }
    244 
    245 /**
    246 * Process the SUBPROTO extension, as an OR.
    247 *
    248 * This extension declares one or more subproto capabilities that the
    249 * relay must implement, and tells it to enable them.
    250 */
    251 static int
    252 relay_process_subproto_ext(const trn_extension_t *ext,
    253                           circuit_params_t *params_out)
    254 {
    255  const trn_extension_field_t *field;
    256  trn_subproto_request_ext_t *req = NULL;
    257  int res = -1;
    258 
    259  field = trn_extension_find(ext, EXT_TYPE_SUBPROTO);
    260  if (!field) {
    261    // Nothing to do.
    262    res = 0;
    263    goto done;
    264  }
    265 
    266  const uint8_t *f = trn_extension_field_getconstarray_field(field);
    267  size_t len = trn_extension_field_getlen_field(field);
    268 
    269  if (trn_subproto_request_ext_parse(&req, f, len) < 0) {
    270    goto done;
    271  }
    272 
    273  const trn_subproto_request_t *prev = NULL;
    274  size_t n_requests = trn_subproto_request_ext_getlen_reqs(req);
    275  for (unsigned i = 0; i < n_requests; ++i) {
    276    const trn_subproto_request_t *cur =
    277      trn_subproto_request_ext_getconst_reqs(req, i);
    278    if (prev && !subproto_requests_in_order(prev, cur)) {
    279      // The requests were not properly sorted and deduplicated.
    280      goto done;
    281    }
    282 
    283    if (cur->protocol_id == PRT_RELAY &&
    284        cur->proto_cap_number == PROTOVER_RELAY_CRYPT_CGO) {
    285      params_out->crypto_alg = RELAY_CRYPTO_ALG_CGO_RELAY;
    286      params_out->cell_fmt = RELAY_CELL_FORMAT_V1;
    287    } else {
    288      // Unless a protocol capability is explicitly supported for use
    289      // with this extension, we _must_ reject when it appears.
    290      goto done;
    291    }
    292  }
    293 
    294  res = 0;
    295 
    296 done:
    297  trn_subproto_request_ext_free(req);
    298  return res;
    299 }
    300 
    301 /**
    302 * Takes a param request message from the client, compares it to our
    303 * consensus parameters, and creates a reply message and output
    304 * parameters.
    305 *
    306 * This function runs in a worker thread, so it can only inspect
    307 * arguments and local variables.
    308 *
    309 * Returns 0 if successful.
    310 * Returns -1 on parsing, parameter failure, or reply creation failure.
    311 */
    312 static int
    313 negotiate_v3_ntor_server_circ_params(const uint8_t *param_request_msg,
    314                                     size_t param_request_len,
    315                                     const circuit_params_t *our_ns_params,
    316                                     circuit_params_t *params_out,
    317                                     uint8_t **resp_msg_out,
    318                                     size_t *resp_msg_len_out)
    319 {
    320  int ret = -1;
    321  trn_extension_t *ext = NULL;
    322 
    323  ssize_t len =
    324    trn_extension_parse(&ext, param_request_msg, param_request_len);
    325  if (len < 0) {
    326    goto err;
    327  }
    328 
    329  /* Parse request. */
    330  ret = congestion_control_parse_ext_request(ext);
    331  if (ret < 0) {
    332    goto err;
    333  }
    334  params_out->cc_enabled = ret && our_ns_params->cc_enabled;
    335  ret = relay_process_subproto_ext(ext, params_out);
    336  if (ret < 0) {
    337    goto err;
    338  }
    339 
    340  /* Build the response. */
    341  ret = congestion_control_build_ext_response(our_ns_params, params_out,
    342                                              resp_msg_out, resp_msg_len_out);
    343  if (ret < 0) {
    344    goto err;
    345  }
    346  params_out->sendme_inc_cells = our_ns_params->sendme_inc_cells;
    347 
    348  if (params_out->cell_fmt != RELAY_CELL_FORMAT_V0 &&
    349      !params_out->cc_enabled) {
    350    // The V1 cell format is incompatible with pre-CC circuits,
    351    // since it has no way to encode stream-level SENDME messages.
    352    goto err;
    353  }
    354 
    355  /* Success. */
    356  ret = 0;
    357 
    358 err:
    359  trn_extension_free(ext);
    360  return ret;
    361 }
    362 
    363 /* This is the maximum value for keys_out_len passed to
    364 * onion_skin_server_handshake, plus 20 for the rend_nonce.
    365 * We can make it bigger if needed:
    366 * It just defines how many bytes to stack-allocate. */
    367 #define MAX_KEYS_TMP_LEN (MAX_RELAY_KEY_MATERIAL_LEN + DIGEST_LEN)
    368 
    369 /** Perform the second (server-side) step of a circuit-creation handshake of
    370 * type <b>type</b>, responding to the client request in <b>onion_skin</b>
    371 * using the keys in <b>keys</b>.  On success, write our response into
    372 * <b>reply_out</b>, generate <b>keys_out_len</b> bytes worth of key material
    373 * in <b>keys_out_len</b>, a hidden service nonce to <b>rend_nonce_out</b>,
    374 * and return the length of the reply. On failure, return -1.
    375 *
    376 * Requires that *keys_len_out of bytes are allocated at keys_out;
    377 * adjusts *keys_out_len to the number of bytes actually genarated.
    378 */
    379 int
    380 onion_skin_server_handshake(int type,
    381                      const uint8_t *onion_skin, size_t onionskin_len,
    382                      const server_onion_keys_t *keys,
    383                      const circuit_params_t *our_ns_params,
    384                      uint8_t *reply_out,
    385                      size_t reply_out_maxlen,
    386                      uint8_t *keys_out, size_t *keys_len_out,
    387                      uint8_t *rend_nonce_out,
    388                      circuit_params_t *params_out)
    389 {
    390  int r = -1;
    391 
    392  relay_crypto_alg_t relay_alg = RELAY_CRYPTO_ALG_TOR1;
    393  size_t keys_out_needed = relay_crypto_key_material_len(relay_alg);
    394 
    395  circuit_params_init(params_out);
    396 
    397  switch (type) {
    398  case ONION_HANDSHAKE_TYPE_TAP:
    399    return -1;
    400  case ONION_HANDSHAKE_TYPE_FAST:
    401    if (reply_out_maxlen < CREATED_FAST_LEN)
    402      return -1;
    403    if (onionskin_len != CREATE_FAST_LEN)
    404      return -1;
    405    if (BUG(*keys_len_out < keys_out_needed)) {
    406      return -1;
    407    }
    408    if (fast_server_handshake(onion_skin, reply_out, keys_out,
    409                              keys_out_needed)<0)
    410      return -1;
    411    r = CREATED_FAST_LEN;
    412    memcpy(rend_nonce_out, reply_out+DIGEST_LEN, DIGEST_LEN);
    413    break;
    414  case ONION_HANDSHAKE_TYPE_NTOR:
    415    if (reply_out_maxlen < NTOR_REPLY_LEN)
    416      return -1;
    417    if (onionskin_len < NTOR_ONIONSKIN_LEN)
    418      return -1;
    419    if (BUG(*keys_len_out < keys_out_needed)) {
    420      return -1;
    421    }
    422    {
    423      size_t keys_tmp_len = keys_out_needed + DIGEST_LEN;
    424      tor_assert(keys_tmp_len <= MAX_KEYS_TMP_LEN);
    425      uint8_t keys_tmp[MAX_KEYS_TMP_LEN];
    426 
    427      if (onion_skin_ntor_server_handshake(
    428                                   onion_skin, keys->curve25519_key_map,
    429                                   keys->junk_keypair,
    430                                   keys->my_identity,
    431                                   reply_out, keys_tmp, keys_tmp_len)<0) {
    432        /* no need to memwipe here, since the output will never be used */
    433        return -1;
    434      }
    435 
    436      memcpy(keys_out, keys_tmp, keys_out_needed);
    437      memcpy(rend_nonce_out, keys_tmp+keys_out_needed, DIGEST_LEN);
    438      memwipe(keys_tmp, 0, sizeof(keys_tmp));
    439      r = NTOR_REPLY_LEN;
    440    }
    441    break;
    442  case ONION_HANDSHAKE_TYPE_NTOR_V3: {
    443    uint8_t keys_tmp[MAX_KEYS_TMP_LEN];
    444    uint8_t *client_msg = NULL;
    445    size_t client_msg_len = 0;
    446    uint8_t *reply_msg = NULL;
    447    size_t reply_msg_len = 0;
    448 
    449    ntor3_server_handshake_state_t *state = NULL;
    450 
    451    if (onion_skin_ntor3_server_handshake_part1(
    452               keys->curve25519_key_map,
    453               keys->junk_keypair,
    454               &keys->my_ed_identity,
    455               onion_skin, onionskin_len,
    456               NTOR3_VERIFICATION_ARGS,
    457               &client_msg, &client_msg_len,
    458               &state) < 0) {
    459      return -1;
    460    }
    461 
    462    if (negotiate_v3_ntor_server_circ_params(client_msg,
    463                                             client_msg_len,
    464                                             our_ns_params,
    465                                             params_out,
    466                                             &reply_msg,
    467                                             &reply_msg_len) < 0) {
    468      ntor3_server_handshake_state_free(state);
    469      tor_free(client_msg);
    470      return -1;
    471    }
    472    tor_free(client_msg);
    473    /* Now we know what we negotiated,
    474       so we can use the right lengths. */
    475    relay_alg = params_out->crypto_alg;
    476    keys_out_needed = relay_crypto_key_material_len(relay_alg);
    477 
    478    if (BUG(*keys_len_out < keys_out_needed)) {
    479      return -1;
    480    }
    481    size_t keys_tmp_len = keys_out_needed + DIGEST_LEN;
    482    tor_assert(keys_tmp_len <= MAX_KEYS_TMP_LEN);
    483 
    484    uint8_t *server_handshake = NULL;
    485    size_t server_handshake_len = 0;
    486    if (onion_skin_ntor3_server_handshake_part2(
    487               state,
    488               NTOR3_VERIFICATION_ARGS,
    489               reply_msg, reply_msg_len,
    490               &server_handshake, &server_handshake_len,
    491               keys_tmp, keys_tmp_len) < 0) {
    492      tor_free(reply_msg);
    493      ntor3_server_handshake_state_free(state);
    494      return -1;
    495    }
    496    tor_free(reply_msg);
    497 
    498    if (server_handshake_len > reply_out_maxlen) {
    499      tor_free(server_handshake);
    500      ntor3_server_handshake_state_free(state);
    501      return -1;
    502    }
    503 
    504    memcpy(keys_out, keys_tmp, keys_out_needed);
    505    memcpy(rend_nonce_out, keys_tmp+keys_out_needed, DIGEST_LEN);
    506    memcpy(reply_out, server_handshake, server_handshake_len);
    507    memwipe(keys_tmp, 0, keys_tmp_len);
    508    memwipe(server_handshake, 0, server_handshake_len);
    509    tor_free(server_handshake);
    510    ntor3_server_handshake_state_free(state);
    511 
    512    r = (int) server_handshake_len;
    513  }
    514    break;
    515  default:
    516    /* LCOV_EXCL_START
    517     * We should have rejected this far before this point */
    518    log_warn(LD_BUG, "called with unknown handshake state type %d", type);
    519    tor_fragile_assert();
    520    return -1;
    521    /* LCOV_EXCL_STOP */
    522  }
    523  *keys_len_out = keys_out_needed;
    524 
    525  return r;
    526 }
    527 
    528 /**
    529 * Takes a param response message from the exit, compares it to our
    530 * consensus parameters for sanity, and creates output parameters
    531 * if sane.
    532 *
    533 * Returns -1 on parsing or insane params, 0 if success.
    534 */
    535 static int
    536 negotiate_v3_ntor_client_circ_params(const uint8_t *param_response_msg,
    537                                     size_t param_response_len,
    538                                     circuit_params_t *params_out)
    539 {
    540  int ret = -1;
    541  trn_extension_t *ext = NULL;
    542 
    543  ssize_t len =
    544    trn_extension_parse(&ext, param_response_msg, param_response_len);
    545  if (len < 0) {
    546    goto err;
    547  }
    548 
    549  ret = congestion_control_parse_ext_response(ext,
    550                                              params_out);
    551  if (ret < 0) {
    552    goto err;
    553  }
    554 
    555  /* If congestion control came back enabled, but we didn't ask for it
    556   * because the consensus said no, close the circuit.
    557   *
    558   * This is a fatal error condition for the circuit, because it either
    559   * means that congestion control was disabled by the consensus
    560   * during the handshake, or the exit decided to send us an unsolicited
    561   * congestion control response.
    562   *
    563   * In either case, we cannot proceed on this circuit, and must try a
    564   * new one.
    565   */
    566  if (ret && !congestion_control_enabled()) {
    567    goto err;
    568  }
    569  params_out->cc_enabled = ret;
    570 
    571 err:
    572  trn_extension_free(ext);
    573  return ret;
    574 }
    575 
    576 /** Perform the final (client-side) step of a circuit-creation handshake of
    577 * type <b>type</b>, using our state in <b>handshake_state</b> and the
    578 * server's response in <b>reply</b>. On success, generate an appropriate
    579 * amount of key material in <b>keys_out</b>,
    580 * set <b>keys_out_len</b> to the amount generated, set
    581 * <b>rend_authenticator_out</b> to the "KH" field that can be used to
    582 * establish introduction points at this hop, and return 0. On failure,
    583 * return -1, and set *msg_out to an error message if this is worth
    584 * complaining to the user about.
    585 *
    586 * Requires that *keys_len_out of bytes are allocated at keys_out;
    587 * adjusts *keys_out_len to the number of bytes actually genarated.
    588 */
    589 int
    590 onion_skin_client_handshake(int type,
    591                      const onion_handshake_state_t *handshake_state,
    592                      const uint8_t *reply, size_t reply_len,
    593                      uint8_t *keys_out, size_t *keys_len_out,
    594                      uint8_t *rend_authenticator_out,
    595                      circuit_params_t *params_out,
    596                      const char **msg_out)
    597 {
    598  if (handshake_state->tag != type)
    599    return -1;
    600 
    601  memcpy(params_out, &handshake_state->chosen_params,
    602         sizeof(circuit_params_t));
    603 
    604  // at this point, we know the crypto algorithm we want to use
    605  relay_crypto_alg_t relay_alg = params_out->crypto_alg;
    606  size_t keys_out_needed = relay_crypto_key_material_len(relay_alg);
    607  if (BUG(*keys_len_out < keys_out_needed)) {
    608    return -1;
    609  }
    610  *keys_len_out = keys_out_needed;
    611 
    612  switch (type) {
    613  case ONION_HANDSHAKE_TYPE_TAP:
    614    return -1;
    615  case ONION_HANDSHAKE_TYPE_FAST:
    616    if (reply_len != CREATED_FAST_LEN) {
    617      if (msg_out)
    618        *msg_out = "TAP reply was not of the correct length.";
    619      return -1;
    620    }
    621    if (fast_client_handshake(handshake_state->u.fast, reply,
    622                              keys_out, keys_out_needed, msg_out) < 0)
    623      return -1;
    624 
    625    memcpy(rend_authenticator_out, reply+DIGEST_LEN, DIGEST_LEN);
    626    return 0;
    627  case ONION_HANDSHAKE_TYPE_NTOR:
    628    if (reply_len < NTOR_REPLY_LEN) {
    629      if (msg_out)
    630        *msg_out = "ntor reply was not of the correct length.";
    631      return -1;
    632    }
    633    {
    634      size_t keys_tmp_len = keys_out_needed + DIGEST_LEN;
    635      uint8_t *keys_tmp = tor_malloc(keys_tmp_len);
    636      if (onion_skin_ntor_client_handshake(handshake_state->u.ntor,
    637                                        reply,
    638                                        keys_tmp, keys_tmp_len, msg_out) < 0) {
    639        tor_free(keys_tmp);
    640        return -1;
    641      }
    642      memcpy(keys_out, keys_tmp, keys_out_needed);
    643      memcpy(rend_authenticator_out, keys_tmp + keys_out_needed, DIGEST_LEN);
    644      memwipe(keys_tmp, 0, keys_tmp_len);
    645      tor_free(keys_tmp);
    646    }
    647    return 0;
    648  case ONION_HANDSHAKE_TYPE_NTOR_V3: {
    649    size_t keys_tmp_len = keys_out_needed + DIGEST_LEN;
    650    uint8_t *keys_tmp = tor_malloc(keys_tmp_len);
    651    uint8_t *server_msg = NULL;
    652    size_t server_msg_len = 0;
    653    int r = onion_ntor3_client_handshake(
    654              handshake_state->u.ntor3,
    655              reply, reply_len,
    656              NTOR3_VERIFICATION_ARGS,
    657              keys_tmp, keys_tmp_len,
    658              &server_msg, &server_msg_len);
    659    if (r < 0) {
    660      tor_free(keys_tmp);
    661      tor_free(server_msg);
    662      return -1;
    663    }
    664 
    665    if (negotiate_v3_ntor_client_circ_params(server_msg,
    666                                             server_msg_len,
    667                                             params_out) < 0) {
    668      tor_free(keys_tmp);
    669      tor_free(server_msg);
    670      return -1;
    671    }
    672    tor_free(server_msg);
    673 
    674    memcpy(keys_out, keys_tmp, keys_out_needed);
    675    memcpy(rend_authenticator_out, keys_tmp + keys_out_needed, DIGEST_LEN);
    676    memwipe(keys_tmp, 0, keys_tmp_len);
    677    tor_free(keys_tmp);
    678 
    679    return 0;
    680  }
    681  default:
    682    log_warn(LD_BUG, "called with unknown handshake state type %d", type);
    683    tor_fragile_assert();
    684    return -1;
    685  }
    686 }
    687 
    688 /**
    689 * If there is an extension field of type `ext_type` in `ext`,
    690 * return that field.  Otherwise return NULL.
    691 */
    692 const trn_extension_field_t *
    693 trn_extension_find(const trn_extension_t *ext, uint8_t ext_type)
    694 {
    695  IF_BUG_ONCE(!ext) {
    696    return NULL;
    697  }
    698  size_t n_fields = trn_extension_get_num(ext);
    699  if (n_fields == 0)
    700    return NULL;
    701 
    702  for (unsigned i = 0; i < n_fields; ++i) {
    703    const trn_extension_field_t *field = trn_extension_getconst_fields(ext, i);
    704    IF_BUG_ONCE(field == NULL) {
    705      return NULL;
    706    }
    707    if (trn_extension_field_get_field_type(field) == ext_type) {
    708      return field;
    709    }
    710  }
    711 
    712  return NULL;
    713 }