tor

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

relay_crypto.c (11896B)


      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 relay_crypto.h
      9 * @brief Header for relay_crypto.c
     10 **/
     11 
     12 // For access to cpath pvt_crypto field.
     13 #define CRYPT_PATH_PRIVATE
     14 
     15 #include "core/or/or.h"
     16 #include "core/or/circuitlist.h"
     17 #include "core/or/crypt_path.h"
     18 #include "app/config/config.h"
     19 #include "lib/crypt_ops/crypto_cipher.h"
     20 #include "lib/crypt_ops/crypto_util.h"
     21 #include "core/crypto/relay_crypto.h"
     22 #include "core/crypto/relay_crypto_tor1.h"
     23 #include "core/or/sendme.h"
     24 
     25 #include "core/or/or_circuit_st.h"
     26 #include "core/or/origin_circuit_st.h"
     27 
     28 #define CGO_AES_BITS 128
     29 
     30 /** Return the sendme tag within the <b>crypto</b> object,
     31 * along with its length.
     32 *
     33 * This is the digest from the most recent cell that we originated
     34 * or recognized, _in either direction_.
     35 * Calls to any encryption function on `crypto` may invalidate
     36 * this digest.
     37 */
     38 const uint8_t *
     39 relay_crypto_get_sendme_tag(relay_crypto_t *crypto,
     40                            size_t *len_out)
     41 {
     42  tor_assert(crypto);
     43  switch (crypto->kind) {
     44    case RCK_TOR1:
     45      *len_out = SENDME_TAG_LEN_TOR1;
     46      return crypto->c.tor1.sendme_digest;
     47    case RCK_CGO:
     48      *len_out = SENDME_TAG_LEN_CGO;
     49      return crypto->c.cgo.last_tag;
     50  }
     51  tor_assert_unreached();
     52 }
     53 
     54 /** Return the length of SENDME tags generated by `crypto`. */
     55 size_t
     56 relay_crypto_sendme_tag_len(const relay_crypto_t *crypto)
     57 {
     58  tor_assert(crypto);
     59  switch (crypto->kind) {
     60    case RCK_TOR1:
     61      return SENDME_TAG_LEN_TOR1;
     62    case RCK_CGO:
     63      return SENDME_TAG_LEN_CGO;
     64  }
     65  tor_assert_unreached();
     66 }
     67 
     68 /**
     69 * Handle a single layer of client-side backward encryption
     70 * with crypto of an arbitary type.
     71 */
     72 static inline bool
     73 relay_crypt_client_backward(relay_crypto_t *crypto, cell_t *cell)
     74 {
     75  switch (crypto->kind) {
     76    case RCK_TOR1:
     77      return tor1_crypt_client_backward(&crypto->c.tor1, cell);
     78    case RCK_CGO: {
     79      const uint8_t *tag = NULL;
     80      cgo_crypt_client_backward(crypto->c.cgo.back, cell, &tag);
     81      if (tag != NULL) {
     82        memcpy(crypto->c.cgo.last_tag, tag, SENDME_TAG_LEN_CGO);
     83        return true;
     84      } else {
     85        return false;
     86      }
     87    }
     88  }
     89  tor_assert_unreached();
     90 }
     91 
     92 /**
     93 * Handle a relay-side forward encryption
     94 * with crypto of an arbitary type.
     95 */
     96 static inline bool
     97 relay_crypt_relay_forward(relay_crypto_t *crypto, cell_t *cell)
     98 {
     99  switch (crypto->kind) {
    100    case RCK_TOR1:
    101      return tor1_crypt_relay_forward(&crypto->c.tor1, cell);
    102    case RCK_CGO: {
    103      const uint8_t *tag = NULL;
    104      cgo_crypt_relay_forward(crypto->c.cgo.fwd, cell, &tag);
    105      if (tag != NULL) {
    106        memcpy(crypto->c.cgo.last_tag, tag, SENDME_TAG_LEN_CGO);
    107        return true;
    108      } else {
    109        return false;
    110      }
    111    }
    112  }
    113  tor_assert_unreached();
    114 }
    115 
    116 /**
    117 * Handle relay-side backward encryption with crypto of an arbitary type.
    118 */
    119 static inline void
    120 relay_crypt_relay_backward(relay_crypto_t *crypto, cell_t *cell)
    121 {
    122  switch (crypto->kind) {
    123    case RCK_TOR1:
    124      tor1_crypt_relay_backward(&crypto->c.tor1, cell);
    125      break;
    126    case RCK_CGO: {
    127      cgo_crypt_relay_backward(crypto->c.cgo.back, cell);
    128      break;
    129    }
    130  }
    131 }
    132 
    133 /** Do the appropriate en/decryptions for <b>cell</b> arriving on
    134 * <b>circ</b> in direction <b>cell_direction</b>.
    135 *
    136 * If cell_direction == CELL_DIRECTION_IN:
    137 *   - If we're at the origin (we're the OP), for hops 1..N,
    138 *     decrypt cell. If recognized, stop.
    139 *   - Else (we're not the OP), encrypt one hop. Cell is not recognized.
    140 *
    141 * If cell_direction == CELL_DIRECTION_OUT:
    142 *   - decrypt one hop. Check if recognized.
    143 *
    144 * If cell is recognized, set *recognized to 1, and set
    145 * *layer_hint to the hop that recognized it.
    146 *
    147 * Return -1 to indicate that we should mark the circuit for close,
    148 * else return 0.
    149 */
    150 int
    151 relay_decrypt_cell(circuit_t *circ, cell_t *cell,
    152                   cell_direction_t cell_direction,
    153                   crypt_path_t **layer_hint, char *recognized)
    154 {
    155  tor_assert(circ);
    156  tor_assert(cell);
    157  tor_assert(recognized);
    158  tor_assert(cell_direction == CELL_DIRECTION_IN ||
    159             cell_direction == CELL_DIRECTION_OUT);
    160 
    161  if (cell_direction == CELL_DIRECTION_IN) {
    162    if (CIRCUIT_IS_ORIGIN(circ)) { /* We're at the beginning of the circuit.
    163                                    * We'll want to do layered decrypts. */
    164      crypt_path_t *thishop, *cpath = TO_ORIGIN_CIRCUIT(circ)->cpath;
    165      thishop = cpath;
    166      if (thishop->state != CPATH_STATE_OPEN) {
    167        log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
    168               "Relay cell before first created cell? Closing.");
    169        return -1;
    170      }
    171      do { /* Remember: cpath is in forward order, that is, first hop first. */
    172        tor_assert(thishop);
    173 
    174        bool rec = relay_crypt_client_backward(&thishop->pvt_crypto, cell);
    175        if (rec) {
    176          *recognized = 1;
    177          *layer_hint = thishop;
    178          return 0;
    179        }
    180        thishop = thishop->next;
    181      } while (thishop != cpath && thishop->state == CPATH_STATE_OPEN);
    182      log_fn(LOG_PROTOCOL_WARN, LD_OR,
    183             "Incoming cell at client not recognized. Closing.");
    184      return -1;
    185    } else {
    186      /* We're in the middle. Encrypt one layer. */
    187      relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
    188      relay_crypt_relay_backward(crypto, cell);
    189    }
    190  } else /* cell_direction == CELL_DIRECTION_OUT */ {
    191    /* We're in the middle. Decrypt one layer. */
    192    relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
    193 
    194    bool rec = relay_crypt_relay_forward(crypto, cell);
    195    if (rec) {
    196      *recognized = 1;
    197      return 0;
    198    }
    199  }
    200  return 0;
    201 }
    202 
    203 /** Originate a client cell with a relay_crypt_t of arbitrary type. */
    204 static inline void
    205 relay_crypt_client_originate(relay_crypto_t *crypto, cell_t *cell)
    206 {
    207  switch (crypto->kind) {
    208    case RCK_TOR1:
    209      tor1_crypt_client_originate(&crypto->c.tor1, cell);
    210      break;
    211    case RCK_CGO: {
    212      const uint8_t *tag = NULL;
    213      cgo_crypt_client_originate(crypto->c.cgo.fwd, cell, &tag);
    214      tor_assert(tag);
    215      memcpy(crypto->c.cgo.last_tag, tag, SENDME_TAG_LEN_CGO);
    216      break;
    217    }
    218  }
    219 }
    220 
    221 /** Perform forward-direction client encryption with a relay_crypt_t
    222 * of arbitrary type. */
    223 static inline void
    224 relay_crypt_client_forward(relay_crypto_t *crypto, cell_t *cell)
    225 {
    226  switch (crypto->kind) {
    227    case RCK_TOR1:
    228      tor1_crypt_client_forward(&crypto->c.tor1, cell);
    229      break;
    230    case RCK_CGO:
    231      cgo_crypt_client_forward(crypto->c.cgo.fwd, cell);
    232      break;
    233  }
    234 }
    235 
    236 /**
    237 * Encrypt a cell <b>cell</b> that we are creating, and sending outbound on
    238 * <b>circ</b> until the hop corresponding to <b>layer_hint</b>.
    239 *
    240 * The integrity field and recognized field of <b>cell</b>'s relay headers
    241 * must be set to zero.
    242 */
    243 void
    244 relay_encrypt_cell_outbound(cell_t *cell,
    245                            origin_circuit_t *circ,
    246                            crypt_path_t *layer_hint)
    247 {
    248  crypt_path_t *thishop = layer_hint;
    249 
    250  relay_crypt_client_originate(&thishop->pvt_crypto, cell);
    251  thishop = thishop->prev;
    252 
    253  while (thishop != circ->cpath->prev) {
    254    relay_crypt_client_forward(&thishop->pvt_crypto, cell);
    255    thishop = thishop->prev;
    256  }
    257 }
    258 
    259 /**
    260 * Encrypt a cell <b>cell</b> that we are creating, and sending on
    261 * <b>circuit</b> to the origin.
    262 *
    263 * The integrity field and recognized field of <b>cell</b>'s relay headers
    264 * must be set to zero.
    265 */
    266 void
    267 relay_encrypt_cell_inbound(cell_t *cell,
    268                           or_circuit_t *or_circ)
    269 {
    270  relay_crypto_t *crypto = &or_circ->crypto;
    271  switch (crypto->kind) {
    272    case RCK_TOR1:
    273      tor1_crypt_relay_originate(&crypto->c.tor1, cell);
    274      break;
    275    case RCK_CGO: {
    276      const uint8_t *tag = NULL;
    277      cgo_crypt_relay_originate(crypto->c.cgo.back, cell, &tag);
    278      tor_assert(tag);
    279      memcpy(&crypto->c.cgo.last_tag, tag, SENDME_TAG_LEN_CGO);
    280      break;
    281    }
    282  }
    283 }
    284 
    285 /**
    286 * Release all storage held inside <b>crypto</b>, but do not free
    287 * <b>crypto</b> itself: it lives inside another object.
    288 */
    289 void
    290 relay_crypto_clear(relay_crypto_t *crypto)
    291 {
    292  switch (crypto->kind) {
    293    case RCK_TOR1:
    294      tor1_crypt_clear(&crypto->c.tor1);
    295      break;
    296    case RCK_CGO:
    297      cgo_crypt_free(crypto->c.cgo.fwd);
    298      cgo_crypt_free(crypto->c.cgo.back);
    299      break;
    300  }
    301 }
    302 
    303 static int
    304 cgo_pair_init(cgo_pair_t *pair, bool is_relay,
    305              const uint8_t *key_material, size_t key_data_len)
    306 {
    307  memset(pair, 0, sizeof(*pair));
    308  const int aes_bits = CGO_AES_BITS;
    309  const size_t single_cgo_len = cgo_key_material_len(aes_bits);
    310  if (BUG(key_data_len != single_cgo_len * 2)) {
    311    return -1;
    312  }
    313 
    314  cgo_mode_t fwd_mode, back_mode;
    315  if (is_relay) {
    316    fwd_mode = CGO_MODE_RELAY_FORWARD;
    317    back_mode = CGO_MODE_RELAY_BACKWARD;
    318  } else {
    319    fwd_mode = CGO_MODE_CLIENT_FORWARD;
    320    back_mode = CGO_MODE_CLIENT_BACKWARD;
    321  }
    322 
    323  pair->fwd = cgo_crypt_new(fwd_mode, aes_bits,
    324                            key_material, single_cgo_len);
    325  pair->back = cgo_crypt_new(back_mode, aes_bits,
    326                             key_material + single_cgo_len, single_cgo_len);
    327 
    328  return 0;
    329 }
    330 
    331 /** Initialize <b>crypto</b> from the key material in key_data.
    332 *
    333 * If <b>is_hs_v3</b> is set, this cpath will be used for next gen hidden
    334 * service circuits and <b>key_data</b> must be at least
    335 * HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length.
    336 *
    337 * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL_LEN
    338 * bytes, which are used as follows:
    339 *   - 20 to initialize f_digest
    340 *   - 20 to initialize b_digest
    341 *   - 16 to key f_crypto
    342 *   - 16 to key b_crypto
    343 *
    344 * (If 'reverse' is true, then f_XX and b_XX are swapped.)
    345 *
    346 * Return 0 if init was successful, else -1 if it failed.
    347 */
    348 int
    349 relay_crypto_init(relay_crypto_alg_t alg,
    350                  relay_crypto_t *crypto,
    351                  const char *key_data, size_t key_data_len)
    352 {
    353  switch (alg) {
    354    /* Tor1 cases: the booleans are "reverse" and "is_hs_v3". */
    355    case RELAY_CRYPTO_ALG_TOR1:
    356      crypto->kind = RCK_TOR1;
    357      return tor1_crypt_init(&crypto->c.tor1, key_data, key_data_len,
    358                             false, false);
    359    case RELAY_CRYPTO_ALG_TOR1_HSC:
    360      crypto->kind = RCK_TOR1;
    361      return tor1_crypt_init(&crypto->c.tor1, key_data, key_data_len,
    362                             false, true);
    363    case RELAY_CRYPTO_ALG_TOR1_HSS:
    364      crypto->kind = RCK_TOR1;
    365      return tor1_crypt_init(&crypto->c.tor1, key_data, key_data_len,
    366                             true, true);
    367    case RELAY_CRYPTO_ALG_CGO_CLIENT:
    368      crypto->kind = RCK_CGO;
    369      return cgo_pair_init(&crypto->c.cgo, false,
    370                           (const uint8_t *)key_data, key_data_len);
    371    case RELAY_CRYPTO_ALG_CGO_RELAY:
    372      crypto->kind = RCK_CGO;
    373      return cgo_pair_init(&crypto->c.cgo, true,
    374                           (const uint8_t *)key_data, key_data_len);
    375  }
    376  tor_assert_unreached();
    377 }
    378 
    379 /** Return the amount of key material we need to initialize
    380 * the given relay crypto algorithm.
    381 *
    382 * Return -1 if the algorithm is unrecognized.
    383 */
    384 ssize_t
    385 relay_crypto_key_material_len(relay_crypto_alg_t alg)
    386 {
    387  switch (alg) {
    388    case RELAY_CRYPTO_ALG_TOR1:
    389      return tor1_key_material_len(false);
    390    case RELAY_CRYPTO_ALG_TOR1_HSC:
    391    case RELAY_CRYPTO_ALG_TOR1_HSS:
    392      return tor1_key_material_len(true);
    393    case RELAY_CRYPTO_ALG_CGO_CLIENT:
    394    case RELAY_CRYPTO_ALG_CGO_RELAY:
    395      return cgo_key_material_len(CGO_AES_BITS) * 2;
    396  }
    397  return -1;
    398 }
    399 
    400 /** Assert that <b>crypto</b> is valid and set. */
    401 void
    402 relay_crypto_assert_ok(const relay_crypto_t *crypto)
    403 {
    404  switch (crypto->kind) {
    405    case RCK_TOR1:
    406      tor1_crypt_assert_ok(&crypto->c.tor1);
    407      break;
    408    case RCK_CGO:
    409      break;
    410  }
    411 }