tor

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

relay_crypto_cgo.c (16353B)


      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-2025, The Tor Project, Inc. */
      5 /* See LICENSE for licensing information */
      6 
      7 /**
      8 * \file relay_crypto_cgo.c
      9 * \brief Implementation for counter galois onion encryption.
     10 **/
     11 
     12 #define RELAY_CRYPTO_CGO_PRIVATE
     13 #define USE_AES_RAW
     14 
     15 #include "orconfig.h"
     16 #include "core/or/or.h"
     17 #include "lib/crypt_ops/aes.h"
     18 #include "ext/polyval/polyval.h"
     19 #include "lib/crypt_ops/crypto_util.h"
     20 #include "lib/log/util_bug.h"
     21 #include "lib/arch/bytes.h"
     22 #include "ext/polyval/polyval.h"
     23 #include "core/crypto/relay_crypto_cgo.h"
     24 #include "core/crypto/relay_crypto.h"
     25 #include "core/or/cell_st.h"
     26 
     27 #if 0
     28 // XXXX debugging.
     29 #include "lib/encoding/binascii.h"
     30 #include <stdio.h>
     31 #endif
     32 
     33 #include <string.h>
     34 
     35 static int
     36 cgo_et_keylen(int aesbits)
     37 {
     38  return (aesbits / 8) + POLYVAL_KEY_LEN;
     39 }
     40 
     41 /** Initialize an instance of the tweakable block cipher,
     42 * using an 'aesbits'-bit AES key.
     43 *
     44 * The total key material used from 'key' will be
     45 * (aesbits / 8) + 16.
     46 *
     47 * This will be initialized for encryption or decryption depending
     48 * on the value of 'encrypt'
     49 */
     50 STATIC int
     51 cgo_et_init(cgo_et_t *et, int aesbits, bool encrypt,
     52            const uint8_t *key)
     53 {
     54  size_t aes_key_bytes = aesbits / 8;
     55  et->kb = aes_raw_new(key, aesbits, encrypt);
     56  if (et->kb == NULL)
     57    return -1;
     58  polyvalx_init(&et->ku, key + aes_key_bytes);
     59  return 0;
     60 }
     61 /** Replace the key on an existing, already initialized cgo_et_t.
     62 *
     63 * Does fewer allocations than a clear+init. */
     64 STATIC void
     65 cgo_et_set_key(cgo_et_t *et, int aesbits, bool encrypt,
     66               const uint8_t *key)
     67 {
     68  size_t aes_key_bytes = aesbits / 8;
     69  aes_raw_set_key(&et->kb, key, aesbits, encrypt);
     70  polyvalx_init(&et->ku, key + aes_key_bytes);
     71 }
     72 
     73 /** Helper: Compute polyval(KU, H | CMD | X_R). */
     74 static inline void
     75 compute_et_mask(polyvalx_t *pvk, const et_tweak_t tweak, uint8_t *t_out)
     76 {
     77  // block 0: tweak.h
     78  // block 1: one byte of command, first 15 bytes of x_r
     79  // block 2...: remainder of x_r, zero-padded.
     80  polyvalx_reset(pvk);
     81  uint8_t block1[16];
     82  block1[0] = tweak.uiv.cmd;
     83  memcpy(block1+1, tweak.x_r, 15);
     84  polyvalx_add_block(pvk, tweak.uiv.h);
     85  polyvalx_add_block(pvk, block1);
     86  polyvalx_add_zpad(pvk, tweak.x_r + 15, ET_TWEAK_LEN_X_R - 15);
     87  polyvalx_get_tag(pvk, t_out);
     88 }
     89 /** XOR the 16 byte block from inp into out. */
     90 static void
     91 xor_block(uint8_t *out, const uint8_t *inp)
     92 {
     93  for (int i = 0; i < 16; ++i)
     94    out[i] ^= inp[i];
     95 }
     96 
     97 /**
     98 * Encrypt the 16-byte block in 'block'.
     99 */
    100 STATIC void
    101 cgo_et_encrypt(cgo_et_t *et, const et_tweak_t tweak,
    102               uint8_t *block)
    103 {
    104  uint8_t mask[16];
    105  compute_et_mask(&et->ku, tweak, mask);
    106  xor_block(block, mask);
    107  aes_raw_encrypt(et->kb, block);
    108  xor_block(block, mask);
    109 }
    110 /**
    111 * Decrypt the 16-byte b lock in 'block'
    112 */
    113 STATIC void
    114 cgo_et_decrypt(cgo_et_t *et, const et_tweak_t tweak,
    115               uint8_t *block)
    116 {
    117  uint8_t mask[16];
    118  compute_et_mask(&et->ku, tweak, mask);
    119  xor_block(block, mask);
    120  aes_raw_decrypt(et->kb, block);
    121  xor_block(block, mask);
    122 }
    123 /**
    124 * Release any storage held in 'et'.
    125 *
    126 * This _doesn't_ wipe 'et'; that's done from a higher-level function.
    127 */
    128 STATIC void
    129 cgo_et_clear(cgo_et_t *et)
    130 {
    131  aes_raw_free(et->kb);
    132 }
    133 
    134 static int
    135 cgo_prf_keylen(int aesbits)
    136 {
    137  return (aesbits / 8) + POLYVAL_KEY_LEN;
    138 }
    139 
    140 /**
    141 * Initialize a psedorandom function from a given key.
    142 * Uses an internal 'aesbits'-bit AES key.
    143 *
    144 * The total key material used from 'key' will be
    145 * (aesbits / 8) + 16.
    146 */
    147 STATIC int
    148 cgo_prf_init(cgo_prf_t *prf, int aesbits,
    149             const uint8_t *key)
    150 {
    151  const uint8_t iv[16] = {0};
    152  size_t aes_key_bytes = aesbits / 8;
    153  memset(prf,0, sizeof(*prf));
    154  prf->k = aes_new_cipher(key, iv, aesbits);
    155  polyval_key_init(&prf->b, key + aes_key_bytes);
    156  return 0;
    157 }
    158 /** Replace the key on an existing cgo_prf_t.
    159 *
    160 * Does fewer allocations than a clear+init. */
    161 STATIC void
    162 cgo_prf_set_key(cgo_prf_t *prf, int aesbits,
    163                const uint8_t *key)
    164 {
    165  size_t aes_key_bytes = aesbits / 8;
    166  aes_cipher_set_key(prf->k, key, aesbits);
    167  polyval_key_init(&prf->b, key + aes_key_bytes);
    168 }
    169 /**
    170 * Compute the PRF's results on 'input', for position t=0,
    171 * XOR it into 'data'.
    172 *
    173 * 'input' must be PRF_INPUT_LEN bytes long.
    174 *
    175 * 'data' must be PRF_T0_DATA_LEN bytes long.
    176 */
    177 STATIC void
    178 cgo_prf_xor_t0(cgo_prf_t *prf, const uint8_t *input,
    179               uint8_t *data)
    180 {
    181  uint8_t hash[16];
    182  polyval_t pv;
    183  polyval_init_from_key(&pv, &prf->b);
    184  polyval_add_block(&pv, input);
    185  polyval_get_tag(&pv, hash);
    186  hash[15] &= 0xC0; // Clear the low six bits.
    187 
    188  aes_cipher_set_iv_aligned(prf->k, hash);
    189  aes_crypt_inplace(prf->k, (char*) data, PRF_T0_DATA_LEN);
    190 
    191  // Re-align the cipher.
    192  //
    193  // This approach is faster than EVP_CIPHER_set_num!
    194  const int ns = 16 - (PRF_T0_DATA_LEN & 0xf);
    195  // We're not using the hash for anything, so it's okay to overwrite
    196  aes_crypt_inplace(prf->k, (char*)hash,  ns);
    197 }
    198 /**
    199 * Generate 'n' bytes of the PRF's results on 'input', for position t=1,
    200 * and store them into 'buf'.
    201 *
    202 * 'input' must be PRF_INPUT_LEN bytes long.
    203 */
    204 STATIC void
    205 cgo_prf_gen_t1(cgo_prf_t *prf, const uint8_t *input,
    206               uint8_t *buf, size_t n)
    207 {
    208  #define T1_OFFSET 31
    209  uint8_t hash[16];
    210  polyval_t pv;
    211  polyval_init_from_key(&pv, &prf->b);
    212  polyval_add_block(&pv, input);
    213  polyval_get_tag(&pv, hash);
    214  hash[15] &= 0xC0; // Clear the low six bits.
    215  hash[15] += T1_OFFSET; // Can't overflow!
    216 
    217  memset(buf, 0, n);
    218  aes_cipher_set_iv_aligned(prf->k, hash);
    219  aes_crypt_inplace(prf->k, (char*)buf, n);
    220 
    221  // Re-align the cipher.
    222  size_t ns = 16-(n&0x0f);
    223  if (ns) {
    224    // We're not using the hash for anything, so it's okay to overwrite
    225    aes_crypt_inplace(prf->k, (char*) hash, ns);
    226  }
    227 }
    228 /**
    229 * Release any storage held in 'prf'.
    230 *
    231 * This _doesn't_ wipe 'prf'; that's done from a higher-level function.
    232 */
    233 STATIC void
    234 cgo_prf_clear(cgo_prf_t *prf)
    235 {
    236  aes_cipher_free(prf->k);
    237 }
    238 
    239 static int
    240 cgo_uiv_keylen(int aesbits)
    241 {
    242  return cgo_et_keylen(aesbits) + cgo_prf_keylen(aesbits);
    243 }
    244 
    245 /**
    246 * Initialize the 'uiv' wide-block cipher, using 'aesbits'-bit
    247 * AES keys internally.
    248 *
    249 * Initializes for encryption or decryption depending on the value of
    250 * 'encrypt'.
    251 *
    252 * The total key material used from 'key' will be
    253 * (aesbits / 8) * 2 + 32.
    254 */
    255 STATIC int
    256 cgo_uiv_init(cgo_uiv_t *uiv, int aesbits, bool encrypt,
    257             const uint8_t *key)
    258 {
    259  size_t aes_key_bytes = aesbits / 8;
    260  if (cgo_et_init(&uiv->j, aesbits, encrypt, key) < 0)
    261    return -1;
    262  if (cgo_prf_init(&uiv->s, aesbits, key + aes_key_bytes + POLYVAL_KEY_LEN)<0)
    263    return -1;
    264 #ifdef TOR_UNIT_TESTS
    265  /* Testing only: copy the keys so we can test UIV_UPDATE function. */
    266  size_t total_key_len = aes_key_bytes * 2 + POLYVAL_KEY_LEN * 2;
    267  tor_assert(total_key_len <= sizeof(uiv->uiv_keys_));
    268  memset(uiv->uiv_keys_, 0, sizeof(uiv->uiv_keys_));
    269  memcpy(uiv->uiv_keys_, key, total_key_len);
    270 #endif
    271  return 0;
    272 }
    273 /**
    274 * Encrypt 'cell_body', with the provided tweak.
    275 *
    276 * The cell body must be UIV_BLOCK_LEN bytes long.
    277 */
    278 STATIC void
    279 cgo_uiv_encrypt(cgo_uiv_t *uiv, const uiv_tweak_t tweak, uint8_t *cell_body)
    280 {
    281  uint8_t *X_L = cell_body;
    282  uint8_t *X_R = cell_body + 16;
    283 
    284  const et_tweak_t et_tweak = {
    285    .uiv = tweak,
    286    .x_r = X_R,
    287  };
    288  cgo_et_encrypt(&uiv->j, et_tweak, X_L);
    289  cgo_prf_xor_t0(&uiv->s, X_L, X_R);
    290 }
    291 /**
    292 * Decrypt 'cell_body', with the provided tweak.
    293 *
    294 * The cell body must be UIV_BLOCK_LEN bytes long.
    295 */
    296 STATIC void
    297 cgo_uiv_decrypt(cgo_uiv_t *uiv, const uiv_tweak_t tweak, uint8_t *cell_body)
    298 {
    299  uint8_t *X_L = cell_body;
    300  uint8_t *X_R = cell_body + 16;
    301 
    302  const et_tweak_t et_tweak = {
    303    .uiv = tweak,
    304    .x_r = X_R,
    305  };
    306  cgo_prf_xor_t0(&uiv->s, X_L, X_R);
    307  cgo_et_decrypt(&uiv->j, et_tweak, X_L);
    308 }
    309 /**
    310 * Irreversibly ransform the keys of this UIV+, and the provided nonce,
    311 * using the nonce as input.
    312 *
    313 * The nonce must be 16 bytes long.
    314 */
    315 STATIC void
    316 cgo_uiv_update(cgo_uiv_t *uiv, int aesbits, bool encrypt, uint8_t *nonce)
    317 {
    318  size_t aes_bytes = aesbits / 8;
    319  size_t single_key_len = aes_bytes + POLYVAL_KEY_LEN;
    320  size_t total_key_len = single_key_len * 2 + 16;
    321  // Note: We could store this on the stack, but stack-protector
    322  // wouldn't like that.
    323  uint8_t *new_keys = tor_malloc(total_key_len);
    324 
    325  cgo_prf_gen_t1(&uiv->s, nonce, new_keys, total_key_len);
    326 
    327  cgo_et_set_key(&uiv->j, aesbits, encrypt, new_keys);
    328  cgo_prf_set_key(&uiv->s, aesbits, new_keys + single_key_len);
    329 
    330  memcpy(nonce, new_keys + single_key_len * 2, 16);
    331 
    332 #ifdef TOR_UNIT_TESTS
    333  /* Testing only: copy the keys so we can test UIV_UPDATE function. */
    334  memset(uiv->uiv_keys_, 0, sizeof(uiv->uiv_keys_));
    335  memcpy(uiv->uiv_keys_, new_keys, total_key_len);
    336 #endif
    337 
    338  // This is key material, so we should really discard it.
    339  memwipe(new_keys, 0, total_key_len);
    340  tor_free(new_keys);
    341 }
    342 /**
    343 * Release any storage held in 'prf'.
    344 *
    345 * This _doesn't_ wipe 'prf'; that's done from a higher-level function.
    346 */
    347 STATIC void
    348 cgo_uiv_clear(cgo_uiv_t *uiv)
    349 {
    350  cgo_et_clear(&uiv->j);
    351  cgo_prf_clear(&uiv->s);
    352 }
    353 
    354 /* ====================
    355 * High level counter galois onion implementations.
    356 */
    357 
    358 /**
    359 * Return the total number of bytes needed to initialize a cgo_crypt_t.
    360 */
    361 size_t
    362 cgo_key_material_len(int aesbits)
    363 {
    364  tor_assert(aesbits == 128 || aesbits == 192 || aesbits == 256);
    365  size_t r = (cgo_uiv_keylen(aesbits) + SENDME_TAG_LEN_CGO);
    366  tor_assert(r * 2 <= MAX_RELAY_KEY_MATERIAL_LEN);
    367  return r;
    368 }
    369 
    370 /**
    371 * Instantiate a CGO authenticated encryption object from the provided
    372 * 'keylen' bytes in 'keys'.
    373 *
    374 * 'keylen' must equal 'cgo_key_material_len(aesbits)'.
    375 *
    376 * The client and relay must have two cgo_crypt_t objects each:
    377 * one for the forward direction, and one for the reverse direction.
    378 */
    379 cgo_crypt_t *
    380 cgo_crypt_new(cgo_mode_t mode, int aesbits, const uint8_t *keys, size_t keylen)
    381 {
    382  tor_assert(keylen == cgo_key_material_len(aesbits));
    383  const uint8_t *end_of_keys = keys + keylen;
    384  // Relays encrypt; clients decrypt.
    385  // Don't reverse this: UIV+ is only non-malleable for _encryption_.
    386  bool encrypt = (mode == CGO_MODE_RELAY_BACKWARD ||
    387                  mode == CGO_MODE_RELAY_FORWARD);
    388  int r;
    389 
    390  cgo_crypt_t *cgo = tor_malloc_zero(sizeof(cgo_crypt_t));
    391  r = cgo_uiv_init(&cgo->uiv, aesbits, encrypt, keys);
    392  tor_assert(r == 0);
    393  keys += cgo_uiv_keylen(aesbits);
    394  memcpy(cgo->nonce, keys, SENDME_TAG_LEN_CGO);
    395  keys += SENDME_TAG_LEN_CGO;
    396  tor_assert(keys == end_of_keys);
    397 
    398  cgo->aes_bytes = aesbits / 8;
    399 
    400  return cgo;
    401 }
    402 /**
    403 * Clean up 'cgo' and free it.
    404 */
    405 void
    406 cgo_crypt_free_(cgo_crypt_t *cgo)
    407 {
    408  if (!cgo)
    409    return;
    410  cgo_uiv_clear(&cgo->uiv);
    411  memwipe(cgo, 0, sizeof(cgo_crypt_t));
    412  tor_free(cgo);
    413 }
    414 
    415 /**
    416 * Internal: Run the UIV Update operation on our UIV+ instance.
    417 */
    418 static void
    419 cgo_crypt_update(cgo_crypt_t *cgo, cgo_mode_t mode)
    420 {
    421  bool encrypt = (mode == CGO_MODE_RELAY_BACKWARD ||
    422                  mode == CGO_MODE_RELAY_FORWARD);
    423  cgo_uiv_update(&cgo->uiv, cgo->aes_bytes * 8, encrypt, cgo->nonce);
    424 }
    425 
    426 /**
    427 * Forward CGO encryption operation at a relay:
    428 * process an outbound cell from the client.
    429 *
    430 * If the cell is for this relay, set *'recognized_tag_out'
    431 * to point to a SENDME_TAG_LEN_CGO value that should be used
    432 * if we want to acknowledge this cell with an authenticated SENDME.
    433 *
    434 * The value of 'recognized_tag_out' will become invalid
    435 * as soon as any change is made to this 'cgo' object,
    436 * or to the cell; if you need it, you should copy it immediately.
    437 *
    438 * If the cell is not for this relay, set *'recognized_tag_out' to NULL.
    439 */
    440 void
    441 cgo_crypt_relay_forward(cgo_crypt_t *cgo, cell_t *cell,
    442                        const uint8_t **recognized_tag_out)
    443 {
    444  uiv_tweak_t h = {
    445    .h = cgo->tprime,
    446    .cmd = cell->command,
    447  };
    448  memcpy(cgo->last_tag_relay_fwd, cell->payload, SENDME_TAG_LEN_CGO);
    449  cgo_uiv_encrypt(&cgo->uiv, h, cell->payload);
    450  memcpy(cgo->tprime, cell->payload, SENDME_TAG_LEN_CGO);
    451  if (tor_memeq(cell->payload, cgo->nonce, SENDME_TAG_LEN_CGO)) {
    452    cgo_crypt_update(cgo, CGO_MODE_RELAY_FORWARD);
    453    *recognized_tag_out = cgo->last_tag_relay_fwd;
    454  } else {
    455    *recognized_tag_out = NULL;
    456  }
    457 }
    458 
    459 /**
    460 * Backward CGO encryption operation at a relay:
    461 * process an inbound cell from another relay, for the client.
    462 */
    463 void
    464 cgo_crypt_relay_backward(cgo_crypt_t *cgo, cell_t *cell)
    465 {
    466  uiv_tweak_t h = {
    467    .h = cgo->tprime,
    468    .cmd = cell->command,
    469  };
    470  cgo_uiv_encrypt(&cgo->uiv, h, cell->payload);
    471  memcpy(cgo->tprime, cell->payload, SENDME_TAG_LEN_CGO);
    472 }
    473 
    474 /**
    475 * Backward CGO encryption operation at a relay:
    476 * encrypt an inbound message that we are originating, for the client.
    477 *
    478 * The provided cell must have its command value set,
    479 * and should have the first SENDME_TAG_LEN_CGO bytes of its payload unused.
    480 *
    481 * Set '*tag_out' to a value that we should expect
    482 * if we want an authenticated SENDME for this cell.
    483 *
    484 * The value of 'recognized_tag_out' will become invalid
    485 * as soon as any change is made to this 'cgo' object,
    486 * or to the cell; if you need it, you should copy it immediately.
    487 */
    488 void
    489 cgo_crypt_relay_originate(cgo_crypt_t *cgo, cell_t *cell,
    490                          const uint8_t **tag_out)
    491 {
    492  uiv_tweak_t h = {
    493    .h = cgo->tprime,
    494    .cmd = cell->command,
    495  };
    496  memcpy(cell->payload, cgo->nonce, SENDME_TAG_LEN_CGO);
    497  cgo_uiv_encrypt(&cgo->uiv, h, cell->payload);
    498  memcpy(&cgo->tprime, cell->payload, SENDME_TAG_LEN_CGO);
    499  memcpy(&cgo->nonce, cell->payload, SENDME_TAG_LEN_CGO);
    500  if (tag_out) {
    501    // tor_assert(tor_memeq(cgo->tprime, cell->payload, SENDME_TAG_LEN_CGO));
    502    *tag_out = cgo->tprime;
    503  }
    504  cgo_crypt_update(cgo, CGO_MODE_RELAY_BACKWARD);
    505 }
    506 
    507 /**
    508 * Forward CGO encryption at a client:
    509 * process a cell for a non-destination hop.
    510 **/
    511 void
    512 cgo_crypt_client_forward(cgo_crypt_t *cgo, cell_t *cell)
    513 {
    514  uint8_t tprime_new[SENDME_TAG_LEN_CGO];
    515  memcpy(tprime_new, cell->payload, SENDME_TAG_LEN_CGO);
    516  uiv_tweak_t h = {
    517    .h = cgo->tprime,
    518    .cmd = cell->command,
    519  };
    520  cgo_uiv_decrypt(&cgo->uiv, h, cell->payload);
    521  memcpy(cgo->tprime, tprime_new, SENDME_TAG_LEN_CGO);
    522 }
    523 
    524 /**
    525 * Forward CGO encryption at a client:
    526 * originate a cell for a given target hop.
    527 *
    528 * The provided cell must have its command value set,
    529 * and should have the first SENDME_TAG_LEN_CGO bytes of its payload unused.
    530 *
    531 * Set '*tag_out' to a value that we should expect
    532 * if we want an authenticated SENDME for this cell.
    533 *
    534 * The value of 'recognized_tag_out' will become invalid
    535 * as soon as any change is made to this 'cgo' object,
    536 * or to the cell; if you need it, you should copy it immediately.
    537 */
    538 void
    539 cgo_crypt_client_originate(cgo_crypt_t *cgo, cell_t *cell,
    540                           const uint8_t **tag_out)
    541 {
    542  memcpy(cell->payload, cgo->nonce, SENDME_TAG_LEN_CGO);
    543  cgo_crypt_client_forward(cgo, cell);
    544  cgo_crypt_update(cgo, CGO_MODE_CLIENT_FORWARD);
    545  *tag_out = cell->payload;
    546 }
    547 
    548 /**
    549 * Backward CGO encryption operation at a rclient.
    550 * process an inbound cell from a relay.
    551 *
    552 * If the cell originated from this this relay, set *'recognized_tag_out'
    553 * to point to a SENDME_TAG_LEN_CGO value that should be used
    554 * if we want to acknowledge this cell with an authenticated SENDME.
    555 *
    556 * The value of 'recognized_tag_out' will become invalid
    557 * as soon as any change is made to this 'cgo' object,
    558 * or to the cell; if you need it, you should copy it immediately.
    559 *
    560 * If the cell is not from this relay, set *'recognized_tag_out' to NULL.
    561 */
    562 void
    563 cgo_crypt_client_backward(cgo_crypt_t *cgo, cell_t *cell,
    564                          const uint8_t **recognized_tag_out)
    565 {
    566  uiv_tweak_t h = {
    567    .h = cgo->tprime,
    568    .cmd = cell->command,
    569  };
    570  uint8_t t_orig[SENDME_TAG_LEN_CGO];
    571  memcpy(t_orig, cell->payload, SENDME_TAG_LEN_CGO);
    572 
    573  cgo_uiv_decrypt(&cgo->uiv, h, cell->payload);
    574  memcpy(cgo->tprime, t_orig, SENDME_TAG_LEN_CGO);
    575  if (tor_memeq(cell->payload, cgo->nonce, SENDME_TAG_LEN_CGO)) {
    576    memcpy(cgo->nonce, t_orig, SENDME_TAG_LEN_CGO);
    577    cgo_crypt_update(cgo, CGO_MODE_CLIENT_BACKWARD);
    578    // tor_assert(tor_memeq(cgo->tprime, t_orig, SENDME_TAG_LEN_CGO));
    579    *recognized_tag_out = cgo->tprime;
    580  } else {
    581    *recognized_tag_out = NULL;
    582  }
    583 }