tor

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

aes_openssl.c (7992B)


      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 aes_openssl.c
      9 * \brief Use OpenSSL to implement AES_CTR.
     10 **/
     11 
     12 #define USE_AES_RAW
     13 #define TOR_AES_PRIVATE
     14 
     15 #include "orconfig.h"
     16 #include "lib/crypt_ops/aes.h"
     17 #include "lib/crypt_ops/crypto_util.h"
     18 #include "lib/log/util_bug.h"
     19 #include "lib/arch/bytes.h"
     20 
     21 #ifdef _WIN32 /*wrkard for dtls1.h >= 0.9.8m of "#include <winsock.h>"*/
     22  #include <winsock2.h>
     23  #include <ws2tcpip.h>
     24 #endif
     25 
     26 #include "lib/crypt_ops/compat_openssl.h"
     27 #include <openssl/opensslv.h>
     28 #include "lib/crypt_ops/crypto_openssl_mgt.h"
     29 
     30 DISABLE_GCC_WARNING("-Wredundant-decls")
     31 
     32 #include <stdlib.h>
     33 #include <string.h>
     34 #include <openssl/aes.h>
     35 #include <openssl/evp.h>
     36 #include <openssl/engine.h>
     37 #include <openssl/modes.h>
     38 
     39 ENABLE_GCC_WARNING("-Wredundant-decls")
     40 
     41 #include "lib/log/log.h"
     42 #include "lib/ctime/di_ops.h"
     43 
     44 /* Cached values of our EVP_CIPHER items.  If we don't pre-fetch them,
     45 * then EVP_CipherInit calls EVP_CIPHER_fetch itself,
     46 * which is surprisingly expensive.
     47 */
     48 static const EVP_CIPHER *aes128ctr = NULL;
     49 static const EVP_CIPHER *aes192ctr = NULL;
     50 static const EVP_CIPHER *aes256ctr = NULL;
     51 static const EVP_CIPHER *aes128ecb = NULL;
     52 static const EVP_CIPHER *aes192ecb = NULL;
     53 static const EVP_CIPHER *aes256ecb = NULL;
     54 
     55 #if OPENSSL_VERSION_NUMBER >= OPENSSL_V_NOPATCH(3,0,0) \
     56  && !defined(LIBRESSL_VERSION_NUMBER)
     57 #define RESOLVE_CIPHER(c) \
     58  EVP_CIPHER_fetch(NULL, OBJ_nid2sn(EVP_CIPHER_get_nid(c)), "")
     59 #else
     60 #define RESOLVE_CIPHER(c) (c)
     61 #endif
     62 
     63 /**
     64 * Pre-fetch the versions of every AES cipher with its associated provider.
     65 */
     66 static void
     67 init_ciphers(void)
     68 {
     69  aes128ctr = RESOLVE_CIPHER(EVP_aes_128_ctr());
     70  aes192ctr = RESOLVE_CIPHER(EVP_aes_192_ctr());
     71  aes256ctr = RESOLVE_CIPHER(EVP_aes_256_ctr());
     72  aes128ecb = RESOLVE_CIPHER(EVP_aes_128_ecb());
     73  aes192ecb = RESOLVE_CIPHER(EVP_aes_192_ecb());
     74  aes256ecb = RESOLVE_CIPHER(EVP_aes_256_ecb());
     75 }
     76 #define INIT_CIPHERS() STMT_BEGIN { \
     77    if (PREDICT_UNLIKELY(NULL == aes128ctr)) {  \
     78      init_ciphers();                           \
     79    }                                           \
     80  } STMT_END
     81 
     82 /* We have 2 strategies for getting the AES block cipher: Via OpenSSL's
     83 * AES_encrypt function, or via OpenSSL's EVP_EncryptUpdate function.
     84 *
     85 * If there's any hardware acceleration in play, we want to be using EVP_* so
     86 * we can get it.  Otherwise, we'll want AES_*, which seems to be about 5%
     87 * faster than indirecting through the EVP layer.
     88 */
     89 
     90 /* We have 2 strategies for getting a plug-in counter mode: use our own, or
     91 * use OpenSSL's.
     92 *
     93 * Here we have a counter mode that's faster than the one shipping with
     94 * OpenSSL pre-1.0 (by about 10%!).  But OpenSSL 1.0.0 added a counter mode
     95 * implementation faster than the one here (by about 7%).  So we pick which
     96 * one to used based on the Openssl version above.  (OpenSSL 1.0.0a fixed a
     97 * critical bug in that counter mode implementation, so we need to test to
     98 * make sure that we have a fixed version.)
     99 */
    100 
    101 /* We don't actually define the struct here. */
    102 
    103 aes_cnt_cipher_t *
    104 aes_new_cipher(const uint8_t *key, const uint8_t *iv, int key_bits)
    105 {
    106  INIT_CIPHERS();
    107  EVP_CIPHER_CTX *cipher = EVP_CIPHER_CTX_new();
    108  const EVP_CIPHER *c = NULL;
    109  switch (key_bits) {
    110    case 128: c = aes128ctr; break;
    111    case 192: c = aes192ctr; break;
    112    case 256: c = aes256ctr; break;
    113    default: tor_assert_unreached(); // LCOV_EXCL_LINE
    114  }
    115  EVP_EncryptInit(cipher, c, key, iv);
    116  return (aes_cnt_cipher_t *) cipher;
    117 }
    118 void
    119 aes_cipher_free_(aes_cnt_cipher_t *cipher_)
    120 {
    121  if (!cipher_)
    122    return;
    123  EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
    124  EVP_CIPHER_CTX_reset(cipher);
    125  EVP_CIPHER_CTX_free(cipher);
    126 }
    127 
    128 /** Changes the key of the cipher;
    129 * sets the IV to 0.
    130 */
    131 void
    132 aes_cipher_set_key(aes_cnt_cipher_t *cipher_, const uint8_t *key, int key_bits)
    133 {
    134  EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
    135  uint8_t iv[16] = {0};
    136  const EVP_CIPHER *c = NULL;
    137  switch (key_bits) {
    138    case 128: c = aes128ctr; break;
    139    case 192: c = aes192ctr; break;
    140    case 256: c = aes256ctr; break;
    141    default: tor_assert_unreached(); // LCOV_EXCL_LINE
    142  }
    143 
    144  // No need to call EVP_CIPHER_CTX_Reset here; EncryptInit already
    145  // does it for us.
    146  EVP_EncryptInit(cipher, c, key, iv);
    147 }
    148 /** Change the IV of this stream cipher without changing the key.
    149 *
    150 * Requires that the cipher stream position is at an even multiple of 16 bytes.
    151 */
    152 void
    153 aes_cipher_set_iv_aligned(aes_cnt_cipher_t *cipher_, const uint8_t *iv)
    154 {
    155  EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
    156 #ifdef LIBRESSL_VERSION_NUMBER
    157  EVP_CIPHER_CTX_set_iv(cipher, iv, 16);
    158 #else
    159  // We would have to do this if the cipher's position were not aligned:
    160  // EVP_CIPHER_CTX_set_num(cipher, 0);
    161 
    162  memcpy(EVP_CIPHER_CTX_iv_noconst(cipher), iv, 16);
    163 #endif
    164 }
    165 void
    166 aes_crypt_inplace(aes_cnt_cipher_t *cipher_, char *data, size_t len)
    167 {
    168  int outl;
    169  EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
    170 
    171  tor_assert(len < INT_MAX);
    172 
    173  EVP_EncryptUpdate(cipher, (unsigned char*)data,
    174                    &outl, (unsigned char*)data, (int)len);
    175 }
    176 
    177 /* ========
    178 * Functions for "raw" (ECB) AES.
    179 *
    180 * I'm choosing the name "raw" here because ECB is not a mode;
    181 * it's a disaster.  The only way to use this safely is
    182 * within a real construction.
    183 */
    184 
    185 /**
    186 * Create a new instance of AES using a key of length 'key_bits'
    187 * for raw block encryption.
    188 *
    189 * This is even more low-level than counter-mode, and you should
    190 * only use it with extreme caution.
    191 */
    192 aes_raw_t *
    193 aes_raw_new(const uint8_t *key, int key_bits, bool encrypt)
    194 {
    195  INIT_CIPHERS();
    196  EVP_CIPHER_CTX *cipher = EVP_CIPHER_CTX_new();
    197  tor_assert(cipher);
    198  const EVP_CIPHER *c = NULL;
    199  switch (key_bits) {
    200    case 128: c = aes128ecb; break;
    201    case 192: c = aes192ecb; break;
    202    case 256: c = aes256ecb; break;
    203    default: tor_assert_unreached();
    204  }
    205 
    206  // No need to call EVP_CIPHER_CTX_Reset here; EncryptInit already
    207  // does it for us.
    208  int r = EVP_CipherInit(cipher, c, key, NULL, encrypt);
    209  tor_assert(r == 1);
    210  EVP_CIPHER_CTX_set_padding(cipher, 0);
    211  return (aes_raw_t *)cipher;
    212 }
    213 /**
    214 * Replace the key on an existing aes_raw_t.
    215 *
    216 * This may be faster than freeing and reallocating.
    217 */
    218 void
    219 aes_raw_set_key(aes_raw_t **cipher_, const uint8_t *key,
    220                int key_bits, bool encrypt)
    221 {
    222  const EVP_CIPHER *c = *(EVP_CIPHER**) cipher_;
    223  switch (key_bits) {
    224    case 128: c = aes128ecb; break;
    225    case 192: c = aes192ecb; break;
    226    case 256: c = aes256ecb; break;
    227    default: tor_assert_unreached();
    228  }
    229  aes_raw_t *cipherp = *cipher_;
    230  EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *)cipherp;
    231  int r = EVP_CipherInit(cipher, c, key, NULL, encrypt);
    232  tor_assert(r == 1);
    233  EVP_CIPHER_CTX_set_padding(cipher, 0);
    234 }
    235 
    236 /**
    237 * Release storage held by 'cipher'.
    238 */
    239 void
    240 aes_raw_free_(aes_raw_t *cipher_)
    241 {
    242  if (!cipher_)
    243    return;
    244  EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *)cipher_;
    245 #ifdef OPENSSL_1_1_API
    246  EVP_CIPHER_CTX_reset(cipher);
    247 #else
    248  EVP_CIPHER_CTX_cleanup(cipher);
    249 #endif
    250  EVP_CIPHER_CTX_free(cipher);
    251 }
    252 #define aes_raw_free(cipher) \
    253  FREE_AND_NULL(aes_raw_t, aes_raw_free_, (cipher))
    254 /**
    255 * Encrypt a single 16-byte block with 'cipher',
    256 * which must have been initialized for encryption.
    257 */
    258 void
    259 aes_raw_encrypt(const aes_raw_t *cipher, uint8_t *block)
    260 {
    261  int outl = 16;
    262  int r = EVP_EncryptUpdate((EVP_CIPHER_CTX *)cipher, block, &outl, block, 16);
    263  tor_assert(r == 1);
    264  tor_assert(outl == 16);
    265 }
    266 /**
    267 * Decrypt a single 16-byte block with 'cipher',
    268 * which must have been initialized for decryption.
    269 */
    270 void
    271 aes_raw_decrypt(const aes_raw_t *cipher, uint8_t *block)
    272 {
    273  int outl = 16;
    274  int r = EVP_DecryptUpdate((EVP_CIPHER_CTX *)cipher, block, &outl, block, 16);
    275  tor_assert(r == 1);
    276  tor_assert(outl == 16);
    277 }