tor

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

crypto_cipher.c (5512B)


      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 crypto_cipher.c
      9 * \brief Symmetric cryptography (low-level) with AES.
     10 **/
     11 
     12 #include "orconfig.h"
     13 
     14 #include "lib/crypt_ops/crypto_cipher.h"
     15 #include "lib/crypt_ops/crypto_rand.h"
     16 #include "lib/crypt_ops/crypto_util.h"
     17 
     18 #include "lib/log/log.h"
     19 #include "lib/log/util_bug.h"
     20 #include "lib/cc/torint.h"
     21 #include "lib/crypt_ops/aes.h"
     22 
     23 #include <string.h>
     24 
     25 /** Allocate and return a new symmetric cipher using the provided key and iv.
     26 * The key is <b>bits</b> bits long; the IV is CIPHER_IV_LEN bytes.  Both
     27 * must be provided. Key length must be 128, 192, or 256 */
     28 crypto_cipher_t *
     29 crypto_cipher_new_with_iv_and_bits(const uint8_t *key,
     30                                   const uint8_t *iv,
     31                                   int bits)
     32 {
     33  tor_assert(key);
     34  tor_assert(iv);
     35 
     36  return aes_new_cipher((const uint8_t*)key, (const uint8_t*)iv, bits);
     37 }
     38 
     39 /** Allocate and return a new symmetric cipher using the provided key and iv.
     40 * The key is CIPHER_KEY_LEN bytes; the IV is CIPHER_IV_LEN bytes.  Both
     41 * must be provided.
     42 */
     43 crypto_cipher_t *
     44 crypto_cipher_new_with_iv(const char *key, const char *iv)
     45 {
     46  return crypto_cipher_new_with_iv_and_bits((uint8_t*)key, (uint8_t*)iv,
     47                                            128);
     48 }
     49 
     50 /** Return a new crypto_cipher_t with the provided <b>key</b> and an IV of all
     51 * zero bytes and key length <b>bits</b>.  Key length must be 128, 192, or
     52 * 256. */
     53 crypto_cipher_t *
     54 crypto_cipher_new_with_bits(const char *key, int bits)
     55 {
     56  char zeroiv[CIPHER_IV_LEN];
     57  memset(zeroiv, 0, sizeof(zeroiv));
     58  return crypto_cipher_new_with_iv_and_bits((uint8_t*)key, (uint8_t*)zeroiv,
     59                                            bits);
     60 }
     61 
     62 /** Return a new crypto_cipher_t with the provided <b>key</b> (of
     63 * CIPHER_KEY_LEN bytes) and an IV of all zero bytes.  */
     64 crypto_cipher_t *
     65 crypto_cipher_new(const char *key)
     66 {
     67  return crypto_cipher_new_with_bits(key, 128);
     68 }
     69 
     70 /** Free a symmetric cipher.
     71 */
     72 void
     73 crypto_cipher_free_(crypto_cipher_t *env)
     74 {
     75  if (!env)
     76    return;
     77 
     78  aes_cipher_free(env);
     79 }
     80 
     81 /* symmetric crypto */
     82 
     83 /** Encrypt <b>fromlen</b> bytes from <b>from</b> using the cipher
     84 * <b>env</b>; on success, store the result to <b>to</b> and return 0.
     85 * Does not check for failure.
     86 */
     87 int
     88 crypto_cipher_encrypt(crypto_cipher_t *env, char *to,
     89                      const char *from, size_t fromlen)
     90 {
     91  tor_assert(env);
     92  tor_assert(env);
     93  tor_assert(from);
     94  tor_assert(fromlen);
     95  tor_assert(to);
     96  tor_assert(fromlen < SIZE_T_CEILING);
     97 
     98  memcpy(to, from, fromlen);
     99  aes_crypt_inplace(env, to, fromlen);
    100  return 0;
    101 }
    102 
    103 /** Decrypt <b>fromlen</b> bytes from <b>from</b> using the cipher
    104 * <b>env</b>; on success, store the result to <b>to</b> and return 0.
    105 * Does not check for failure.
    106 */
    107 int
    108 crypto_cipher_decrypt(crypto_cipher_t *env, char *to,
    109                      const char *from, size_t fromlen)
    110 {
    111  tor_assert(env);
    112  tor_assert(from);
    113  tor_assert(to);
    114  tor_assert(fromlen < SIZE_T_CEILING);
    115 
    116  memcpy(to, from, fromlen);
    117  aes_crypt_inplace(env, to, fromlen);
    118  return 0;
    119 }
    120 
    121 /** Encrypt <b>len</b> bytes on <b>from</b> using the cipher in <b>env</b>;
    122 * on success. Does not check for failure.
    123 */
    124 void
    125 crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len)
    126 {
    127  tor_assert(len < SIZE_T_CEILING);
    128  aes_crypt_inplace(env, buf, len);
    129 }
    130 
    131 /** Encrypt <b>fromlen</b> bytes (at least 1) from <b>from</b> with the key in
    132 * <b>key</b> to the buffer in <b>to</b> of length
    133 * <b>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> plus
    134 * CIPHER_IV_LEN bytes for the initialization vector. On success, return the
    135 * number of bytes written, on failure, return -1.
    136 */
    137 int
    138 crypto_cipher_encrypt_with_iv(const char *key,
    139                              char *to, size_t tolen,
    140                              const char *from, size_t fromlen)
    141 {
    142  crypto_cipher_t *cipher;
    143  tor_assert(from);
    144  tor_assert(to);
    145  tor_assert(fromlen < INT_MAX);
    146 
    147  if (fromlen < 1)
    148    return -1;
    149  if (tolen < fromlen + CIPHER_IV_LEN)
    150    return -1;
    151 
    152  char iv[CIPHER_IV_LEN];
    153  crypto_rand(iv, sizeof(iv));
    154  cipher = crypto_cipher_new_with_iv(key, iv);
    155 
    156  memcpy(to, iv, CIPHER_IV_LEN);
    157  crypto_cipher_encrypt(cipher, to+CIPHER_IV_LEN, from, fromlen);
    158  crypto_cipher_free(cipher);
    159  memwipe(iv, 0, sizeof(iv));
    160  return (int)(fromlen + CIPHER_IV_LEN);
    161 }
    162 
    163 /** Decrypt <b>fromlen</b> bytes (at least 1+CIPHER_IV_LEN) from <b>from</b>
    164 * with the key in <b>key</b> to the buffer in <b>to</b> of length
    165 * <b>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> minus
    166 * CIPHER_IV_LEN bytes for the initialization vector. On success, return the
    167 * number of bytes written, on failure, return -1.
    168 */
    169 int
    170 crypto_cipher_decrypt_with_iv(const char *key,
    171                              char *to, size_t tolen,
    172                              const char *from, size_t fromlen)
    173 {
    174  crypto_cipher_t *cipher;
    175  tor_assert(key);
    176  tor_assert(from);
    177  tor_assert(to);
    178  tor_assert(fromlen < INT_MAX);
    179 
    180  if (fromlen <= CIPHER_IV_LEN)
    181    return -1;
    182  if (tolen < fromlen - CIPHER_IV_LEN)
    183    return -1;
    184 
    185  cipher = crypto_cipher_new_with_iv(key, from);
    186 
    187  crypto_cipher_encrypt(cipher, to, from+CIPHER_IV_LEN, fromlen-CIPHER_IV_LEN);
    188  crypto_cipher_free(cipher);
    189  return (int)(fromlen - CIPHER_IV_LEN);
    190 }