tor

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

crypt_path.c (6013B)


      1 /*
      2 * Copyright (c) 2019-2021, The Tor Project, Inc. */
      3 /* See LICENSE for licensing information */
      4 
      5 /**
      6 * \file crypt_path.c
      7 *
      8 * \brief Functions dealing with layered circuit encryption. This file aims to
      9 *   provide an API around the crypt_path_t structure which holds crypto
     10 *   information about a specific hop of a circuit.
     11 *
     12 * TODO: We should eventually move all functions dealing and manipulating
     13 *   crypt_path_t to this file, so that eventually we encapsulate more and more
     14 *   of crypt_path_t. Here are some more functions that can be moved here with
     15 *   some more effort:
     16 *
     17 *   - circuit_list_path_impl()
     18 **/
     19 
     20 #define CRYPT_PATH_PRIVATE
     21 
     22 #include "core/or/or.h"
     23 #include "core/or/crypt_path.h"
     24 
     25 #include "core/crypto/relay_crypto.h"
     26 #include "core/crypto/onion_crypto.h"
     27 #include "core/or/circuitbuild.h"
     28 #include "core/or/circuitlist.h"
     29 #include "core/or/extendinfo.h"
     30 #include "core/or/congestion_control_common.h"
     31 
     32 #include "lib/crypt_ops/crypto_dh.h"
     33 #include "lib/crypt_ops/crypto_util.h"
     34 
     35 #include "core/or/crypt_path_st.h"
     36 #include "core/or/cell_st.h"
     37 
     38 /** Add <b>new_hop</b> to the end of the doubly-linked-list <b>head_ptr</b>.
     39 * This function is used to extend cpath by another hop.
     40 */
     41 void
     42 cpath_extend_linked_list(crypt_path_t **head_ptr, crypt_path_t *new_hop)
     43 {
     44  if (*head_ptr) {
     45    new_hop->next = (*head_ptr);
     46    new_hop->prev = (*head_ptr)->prev;
     47    (*head_ptr)->prev->next = new_hop;
     48    (*head_ptr)->prev = new_hop;
     49  } else {
     50    *head_ptr = new_hop;
     51    new_hop->prev = new_hop->next = new_hop;
     52  }
     53 }
     54 
     55 /** Create a new hop, annotate it with information about its
     56 * corresponding router <b>choice</b>, and append it to the
     57 * end of the cpath <b>head_ptr</b>. */
     58 int
     59 cpath_append_hop(crypt_path_t **head_ptr, extend_info_t *choice)
     60 {
     61  crypt_path_t *hop = tor_malloc_zero(sizeof(crypt_path_t));
     62 
     63  /* link hop into the cpath, at the end. */
     64  cpath_extend_linked_list(head_ptr, hop);
     65 
     66  hop->magic = CRYPT_PATH_MAGIC;
     67  hop->state = CPATH_STATE_CLOSED;
     68 
     69  hop->extend_info = extend_info_dup(choice);
     70 
     71  hop->package_window = circuit_initial_package_window();
     72  hop->deliver_window = CIRCWINDOW_START;
     73 
     74  // This can get changed later on by circuit negotiation.
     75  hop->relay_cell_format = RELAY_CELL_FORMAT_V0;
     76 
     77  return 0;
     78 }
     79 
     80 /** Verify that cpath <b>cp</b> has all of its invariants
     81 * correct. Trigger an assert if anything is invalid.
     82 */
     83 void
     84 cpath_assert_ok(const crypt_path_t *cp)
     85 {
     86  const crypt_path_t *start = cp;
     87 
     88  do {
     89    cpath_assert_layer_ok(cp);
     90    /* layers must be in sequence of: "open* awaiting? closed*" */
     91    if (cp != start) {
     92      if (cp->state == CPATH_STATE_AWAITING_KEYS) {
     93        tor_assert(cp->prev->state == CPATH_STATE_OPEN);
     94      } else if (cp->state == CPATH_STATE_OPEN) {
     95        tor_assert(cp->prev->state == CPATH_STATE_OPEN);
     96      }
     97    }
     98    cp = cp->next;
     99    tor_assert(cp);
    100  } while (cp != start);
    101 }
    102 
    103 /** Verify that cpath layer <b>cp</b> has all of its invariants
    104 * correct. Trigger an assert if anything is invalid.
    105 */
    106 void
    107 cpath_assert_layer_ok(const crypt_path_t *cp)
    108 {
    109 //  tor_assert(cp->addr); /* these are zero for rendezvous extra-hops */
    110 //  tor_assert(cp->port);
    111  tor_assert(cp);
    112  tor_assert(cp->magic == CRYPT_PATH_MAGIC);
    113  switch (cp->state)
    114    {
    115    case CPATH_STATE_OPEN:
    116      relay_crypto_assert_ok(&cp->pvt_crypto);
    117      FALLTHROUGH;
    118    case CPATH_STATE_CLOSED:
    119      break;
    120    case CPATH_STATE_AWAITING_KEYS:
    121      break;
    122    default:
    123      log_fn(LOG_ERR, LD_BUG, "Unexpected state %d", cp->state);
    124      tor_assert(0);
    125    }
    126  tor_assert(cp->package_window >= 0);
    127  tor_assert(cp->deliver_window >= 0);
    128 }
    129 
    130 /** Initialize cpath-\>{f|b}_{crypto|digest} from the key material in key_data.
    131 *
    132 * If <b>is_hs_v3</b> is set, this cpath will be used for next gen hidden
    133 * service circuits and <b>key_data</b> must be at least
    134 * HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length.
    135 *
    136 * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL_LEN
    137 * bytes, which are used as follows:
    138 *   - 20 to initialize f_digest
    139 *   - 20 to initialize b_digest
    140 *   - 16 to key f_crypto
    141 *   - 16 to key b_crypto
    142 *
    143 * (If 'reverse' is true, then f_XX and b_XX are swapped.)
    144 *
    145 * Return 0 if init was successful, else -1 if it failed.
    146 */
    147 int
    148 cpath_init_circuit_crypto(relay_crypto_alg_t alg,
    149                          crypt_path_t *cpath,
    150                          const char *key_data, size_t key_data_len)
    151 {
    152 
    153  tor_assert(cpath);
    154  return relay_crypto_init(alg, &cpath->pvt_crypto, key_data, key_data_len);
    155 }
    156 
    157 /** Deallocate space associated with the cpath node <b>victim</b>. */
    158 void
    159 cpath_free(crypt_path_t *victim)
    160 {
    161  if (!victim)
    162    return;
    163 
    164  relay_crypto_clear(&victim->pvt_crypto);
    165  onion_handshake_state_release(&victim->handshake_state);
    166  extend_info_free(victim->extend_info);
    167  congestion_control_free(victim->ccontrol);
    168 
    169  memwipe(victim, 0xBB, sizeof(crypt_path_t)); /* poison memory */
    170  tor_free(victim);
    171 }
    172 
    173 /************ cpath sendme API ***************************/
    174 
    175 /** Return the sendme tag of this <b>cpath</b>,
    176 * along with its length. */
    177 const uint8_t *
    178 cpath_get_sendme_tag(crypt_path_t *cpath, size_t *len_out)
    179 {
    180  return relay_crypto_get_sendme_tag(&cpath->pvt_crypto, len_out);
    181 }
    182 
    183 /************ other cpath functions ***************************/
    184 
    185 /** Return the first non-open hop in cpath, or return NULL if all
    186 * hops are open. */
    187 crypt_path_t *
    188 cpath_get_next_non_open_hop(crypt_path_t *cpath)
    189 {
    190  crypt_path_t *hop = cpath;
    191  do {
    192    if (hop->state != CPATH_STATE_OPEN)
    193      return hop;
    194    hop = hop->next;
    195  } while (hop != cpath);
    196  return NULL;
    197 }
    198 
    199 #ifdef TOR_UNIT_TESTS
    200 
    201 /** Unittest helper function: Count number of hops in cpath linked list. */
    202 unsigned int
    203 cpath_get_n_hops(crypt_path_t **head_ptr)
    204 {
    205  unsigned int n_hops = 0;
    206  crypt_path_t *tmp;
    207 
    208  if (!*head_ptr) {
    209    return 0;
    210  }
    211 
    212  tmp = *head_ptr;
    213  do {
    214    n_hops++;
    215    tmp = tmp->next;
    216  } while (tmp != *head_ptr);
    217 
    218  return n_hops;
    219 }
    220 
    221 #endif /* defined(TOR_UNIT_TESTS) */