]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Remove AES support for old OpenSSLs
authorNick Mathewson <nickm@torproject.org>
Sun, 18 May 2025 14:34:43 +0000 (10:34 -0400)
committerNick Mathewson <nickm@torproject.org>
Wed, 21 May 2025 17:00:03 +0000 (13:00 -0400)
src/lib/crypt_ops/aes.h
src/lib/crypt_ops/aes_nss.c
src/lib/crypt_ops/aes_openssl.c
src/lib/crypt_ops/crypto_openssl_mgt.c
src/test/test_crypto.c

index cee14b18389f36a08f396bea37daef46114f7ed5..da79d7bcbd249230f810e796dabd081dfee3f7a8 100644 (file)
@@ -29,9 +29,6 @@ void aes_cipher_free_(aes_cnt_cipher_t *cipher);
   FREE_AND_NULL(aes_cnt_cipher_t, aes_cipher_free_, (cipher))
 void aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len);
 
-int evaluate_evp_for_aes(int force_value);
-int evaluate_ctr_for_aes(void);
-
 #ifdef USE_AES_RAW
 typedef struct aes_raw_t aes_raw_t;
 
index ab72c12fe123a5a10ebcb52f45092f9bcdfd05d5..a3266e5bf47377259df5f5e23bb5335136dcdd8b 100644 (file)
@@ -141,19 +141,6 @@ aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data_, size_t len_)
   tor_assert(result_len == len);
 }
 
-int
-evaluate_evp_for_aes(int force_value)
-{
-  (void)force_value;
-  return 0;
-}
-
-int
-evaluate_ctr_for_aes(void)
-{
-  return 0;
-}
-
 aes_raw_t *
 aes_raw_new(const uint8_t *key, int key_bits, bool encrypt)
 {
index 270712be87b83a7840e7bb03ed0a96ae51317015..fd481b8758791589e2013220866cd212904feb67 100644 (file)
@@ -41,37 +41,6 @@ ENABLE_GCC_WARNING("-Wredundant-decls")
 #include "lib/log/log.h"
 #include "lib/ctime/di_ops.h"
 
-#ifdef OPENSSL_NO_ENGINE
-/* Android's OpenSSL seems to have removed all of its Engine support. */
-#define DISABLE_ENGINES
-#endif
-
-/* We have five strategies for implementing AES counter mode.
- *
- * Best with x86 and x86_64: Use EVP_aes_*_ctr() and EVP_EncryptUpdate().
- * This is possible with OpenSSL 1.0.1, where the counter-mode implementation
- * can use bit-sliced or vectorized AES or AESNI as appropriate.
- *
- * Otherwise: Pick the best possible AES block implementation that OpenSSL
- * gives us, and the best possible counter-mode implementation, and combine
- * them.
- */
-#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_NOPATCH(1,1,0)
-
-/* With newer OpenSSL versions, the older fallback modes don't compile.  So
- * don't use them, even if we lack specific acceleration. */
-
-#define USE_EVP_AES_CTR
-
-#elif OPENSSL_VERSION_NUMBER >= OPENSSL_V_NOPATCH(1,0,1) &&               \
-  (defined(__i386) || defined(__i386__) || defined(_M_IX86) ||          \
-   defined(__x86_64) || defined(__x86_64__) ||                          \
-   defined(_M_AMD64) || defined(_M_X64) || defined(__INTEL__))
-
-#define USE_EVP_AES_CTR
-
-#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_NOPATCH(1,1,0) || ... */
-
 /* Cached values of our EVP_CIPHER items.  If we don't pre-fetch them,
  * then EVP_CipherInit calls EVP_CIPHER_fetch itself,
  * which is surprisingly expensive.
@@ -129,8 +98,6 @@ init_ciphers(void)
  * make sure that we have a fixed version.)
  */
 
-#ifdef USE_EVP_AES_CTR
-
 /* We don't actually define the struct here. */
 
 aes_cnt_cipher_t *
@@ -206,253 +173,6 @@ aes_crypt_inplace(aes_cnt_cipher_t *cipher_, char *data, size_t len)
   EVP_EncryptUpdate(cipher, (unsigned char*)data,
                     &outl, (unsigned char*)data, (int)len);
 }
-int
-evaluate_evp_for_aes(int force_val)
-{
-  (void) force_val;
-  log_info(LD_CRYPTO, "This version of OpenSSL has a known-good EVP "
-           "counter-mode implementation. Using it.");
-  return 0;
-}
-int
-evaluate_ctr_for_aes(void)
-{
-  return 0;
-}
-#else /* !defined(USE_EVP_AES_CTR) */
-
-/*======================================================================*/
-/* Interface to AES code, and counter implementation */
-
-/** Implements an AES counter-mode cipher. */
-struct aes_cnt_cipher_t {
-/** This next element (however it's defined) is the AES key. */
-  union {
-    EVP_CIPHER_CTX evp;
-    AES_KEY aes;
-  } key;
-
-#if !defined(WORDS_BIGENDIAN)
-#define USING_COUNTER_VARS
-  /** These four values, together, implement a 128-bit counter, with
-   * counter0 as the low-order word and counter3 as the high-order word. */
-  uint32_t counter3;
-  uint32_t counter2;
-  uint32_t counter1;
-  uint32_t counter0;
-#endif /* !defined(WORDS_BIGENDIAN) */
-
-  union {
-    /** The counter, in big-endian order, as bytes. */
-    uint8_t buf[16];
-    /** The counter, in big-endian order, as big-endian words.  Note that
-     * on big-endian platforms, this is redundant with counter3...0,
-     * so we just use these values instead. */
-    uint32_t buf32[4];
-  } ctr_buf;
-
-  /** The encrypted value of ctr_buf. */
-  uint8_t buf[16];
-  /** Our current stream position within buf. */
-  unsigned int pos;
-
-  /** True iff we're using the evp implementation of this cipher. */
-  uint8_t using_evp;
-};
-
-/** True iff we should prefer the EVP implementation for AES, either because
- * we're testing it or because we have hardware acceleration configured */
-static int should_use_EVP = 0;
-
-/** Check whether we should use the EVP interface for AES. If <b>force_val</b>
- * is nonnegative, we use use EVP iff it is true.  Otherwise, we use EVP
- * if there is an engine enabled for aes-ecb. */
-int
-evaluate_evp_for_aes(int force_val)
-{
-  ENGINE *e;
-
-  if (force_val >= 0) {
-    should_use_EVP = force_val;
-    return 0;
-  }
-#ifdef DISABLE_ENGINES
-  should_use_EVP = 0;
-#else
-  e = ENGINE_get_cipher_engine(NID_aes_128_ecb);
-
-  if (e) {
-    log_info(LD_CRYPTO, "AES engine \"%s\" found; using EVP_* functions.",
-               ENGINE_get_name(e));
-    should_use_EVP = 1;
-  } else {
-    log_info(LD_CRYPTO, "No AES engine found; using AES_* functions.");
-    should_use_EVP = 0;
-  }
-#endif /* defined(DISABLE_ENGINES) */
-
-  return 0;
-}
-
-/** Test the OpenSSL counter mode implementation to see whether it has the
- * counter-mode bug from OpenSSL 1.0.0. If the implementation works, then
- * we will use it for future encryption/decryption operations.
- *
- * We can't just look at the OpenSSL version, since some distributions update
- * their OpenSSL packages without changing the version number.
- **/
-int
-evaluate_ctr_for_aes(void)
-{
-  /* Result of encrypting an all-zero block with an all-zero 128-bit AES key.
-   * This should be the same as encrypting an all-zero block with an all-zero
-   * 128-bit AES key in counter mode, starting at position 0 of the stream.
-   */
-  static const unsigned char encrypt_zero[] =
-    "\x66\xe9\x4b\xd4\xef\x8a\x2c\x3b\x88\x4c\xfa\x59\xca\x34\x2b\x2e";
-  unsigned char zero[16];
-  unsigned char output[16];
-  unsigned char ivec[16];
-  unsigned char ivec_tmp[16];
-  unsigned int pos, i;
-  AES_KEY key;
-  memset(zero, 0, sizeof(zero));
-  memset(ivec, 0, sizeof(ivec));
-  AES_set_encrypt_key(zero, 128, &key);
-
-  pos = 0;
-  /* Encrypting a block one byte at a time should make the error manifest
-   * itself for known bogus openssl versions. */
-  for (i=0; i<16; ++i)
-    AES_ctr128_encrypt(&zero[i], &output[i], 1, &key, ivec, ivec_tmp, &pos);
-
-  if (fast_memneq(output, encrypt_zero, 16)) {
-    /* Counter mode is buggy */
-    /* LCOV_EXCL_START */
-    log_err(LD_CRYPTO, "This OpenSSL has a buggy version of counter mode; "
-                  "quitting tor.");
-    exit(1); // exit ok: openssl is broken.
-    /* LCOV_EXCL_STOP */
-  }
-  return 0;
-}
-
-#if !defined(USING_COUNTER_VARS)
-#define COUNTER(c, n) ((c)->ctr_buf.buf32[3-(n)])
-#else
-#define COUNTER(c, n) ((c)->counter ## n)
-#endif
-
-static void aes_set_key(aes_cnt_cipher_t *cipher, const uint8_t *key,
-                        int key_bits);
-static void aes_set_iv(aes_cnt_cipher_t *cipher, const uint8_t *iv);
-
-/**
- * Return a newly allocated counter-mode AES128 cipher implementation,
- * using the 128-bit key <b>key</b> and the 128-bit IV <b>iv</b>.
- */
-aes_cnt_cipher_t*
-aes_new_cipher(const uint8_t *key, const uint8_t *iv, int bits)
-{
-  aes_cnt_cipher_t* result = tor_malloc_zero(sizeof(aes_cnt_cipher_t));
-
-  aes_set_key(result, key, bits);
-  aes_set_iv(result, iv);
-
-  return result;
-}
-
-/** Set the key of <b>cipher</b> to <b>key</b>, which is
- * <b>key_bits</b> bits long (must be 128, 192, or 256).  Also resets
- * the counter to 0.
- */
-static void
-aes_set_key(aes_cnt_cipher_t *cipher, const uint8_t *key, int key_bits)
-{
-  if (should_use_EVP) {
-    const EVP_CIPHER *c = 0;
-    switch (key_bits) {
-      case 128: c = aes128ecb; break;
-      case 192: c = aes192ecb; break;
-      case 256: c = aes256ecb; break;
-      default: tor_assert(0); // LCOV_EXCL_LINE
-    }
-    EVP_EncryptInit(&cipher->key.evp, c, key, NULL);
-    cipher->using_evp = 1;
-  } else {
-    AES_set_encrypt_key(key, key_bits,&cipher->key.aes);
-    cipher->using_evp = 0;
-  }
-
-#ifdef USING_COUNTER_VARS
-  cipher->counter0 = 0;
-  cipher->counter1 = 0;
-  cipher->counter2 = 0;
-  cipher->counter3 = 0;
-#endif /* defined(USING_COUNTER_VARS) */
-
-  memset(cipher->ctr_buf.buf, 0, sizeof(cipher->ctr_buf.buf));
-
-  cipher->pos = 0;
-
-  memset(cipher->buf, 0, sizeof(cipher->buf));
-}
-
-/** Release storage held by <b>cipher</b>
- */
-void
-aes_cipher_free_(aes_cnt_cipher_t *cipher)
-{
-  if (!cipher)
-    return;
-  if (cipher->using_evp) {
-    EVP_CIPHER_CTX_cleanup(&cipher->key.evp);
-  }
-  memwipe(cipher, 0, sizeof(aes_cnt_cipher_t));
-  tor_free(cipher);
-}
-
-#if defined(USING_COUNTER_VARS)
-#define UPDATE_CTR_BUF(c, n) STMT_BEGIN                 \
-  (c)->ctr_buf.buf32[3-(n)] = htonl((c)->counter ## n); \
-  STMT_END
-#else
-#define UPDATE_CTR_BUF(c, n)
-#endif /* defined(USING_COUNTER_VARS) */
-
-/** Encrypt <b>len</b> bytes from <b>input</b>, storing the results in place.
- * Uses the key in <b>cipher</b>, and advances the counter by <b>len</b> bytes
- * as it encrypts.
- */
-void
-aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len)
-{
-  /* Note that the "128" below refers to the length of the counter,
-   * not the length of the AES key. */
-  if (cipher->using_evp) {
-    /* In openssl 1.0.0, there's an if'd out EVP_aes_128_ctr in evp.h.  If
-     * it weren't disabled, it might be better just to use that.
-     */
-    CRYPTO_ctr128_encrypt((const unsigned char *)data,
-                          (unsigned char *)data,
-                          len,
-                          &cipher->key.evp,
-                          cipher->ctr_buf.buf,
-                          cipher->buf,
-                          &cipher->pos,
-                          evp_block128_fn);
-  } else {
-    AES_ctr128_encrypt((const unsigned char *)data,
-                       (unsigned char *)data,
-                       len,
-                       &cipher->key.aes,
-                       cipher->ctr_buf.buf,
-                       cipher->buf,
-                       &cipher->pos);
-  }
-}
-
-#endif /* defined(USE_EVP_AES_CTR) */
 
 /* ========
  * Functions for "raw" (ECB) AES.
index 426283f47ab9867d30c3e7a235d6b2820ff29950..b89167a5ecd50dc423162bb5570d5302ac48025d 100644 (file)
@@ -323,9 +323,6 @@ crypto_openssl_late_init(int useAccel, const char *accelName,
       return -1;
   }
 
-  evaluate_evp_for_aes(-1);
-  evaluate_ctr_for_aes();
-
   return 0;
 }
 
index 1281545e29ddfc772f97cb7dbbadc8b5d5e09a18..700c9679f9a19fce570b8193c7aeb98b906b3543 100644 (file)
@@ -259,14 +259,12 @@ test_crypto_openssl_version(void *arg)
 static void
 test_crypto_aes128(void *arg)
 {
+  (void)arg;
   char *data1 = NULL, *data2 = NULL, *data3 = NULL;
   crypto_cipher_t *env1 = NULL, *env2 = NULL;
   int i, j;
   char *mem_op_hex_tmp=NULL;
   char key[CIPHER_KEY_LEN];
-  int use_evp = !strcmp(arg,"evp");
-  evaluate_evp_for_aes(use_evp);
-  evaluate_ctr_for_aes();
 
   data1 = tor_malloc(1024);
   data2 = tor_malloc(1024);
@@ -1634,14 +1632,12 @@ test_crypto_formats(void *arg)
 static void
 test_crypto_aes_iv(void *arg)
 {
+  (void)arg;
   char *plain, *encrypted1, *encrypted2, *decrypted1, *decrypted2;
   char plain_1[1], plain_15[15], plain_16[16], plain_17[17];
   char key1[16], key2[16];
   ssize_t encrypted_size, decrypted_size;
 
-  int use_evp = !strcmp(arg,"evp");
-  evaluate_evp_for_aes(use_evp);
-
   plain = tor_malloc(4095);
   encrypted1 = tor_malloc(4095 + 1 + 16);
   encrypted2 = tor_malloc(4095 + 1 + 16);
@@ -3454,8 +3450,7 @@ test_crypto_aes_cnt_set_iv(void *arg)
 struct testcase_t crypto_tests[] = {
   CRYPTO_LEGACY(formats),
   { "openssl_version", test_crypto_openssl_version, TT_FORK, NULL, NULL },
-  { "aes_AES", test_crypto_aes128, TT_FORK, &passthrough_setup, (void*)"aes" },
-  { "aes_EVP", test_crypto_aes128, TT_FORK, &passthrough_setup, (void*)"evp" },
+  { "aes_AES", test_crypto_aes128, TT_FORK, NULL, NULL },
   { "aes128_ctr_testvec", test_crypto_aes_ctr_testvec, 0,
     &passthrough_setup, (void*)"128" },
   { "aes192_ctr_testvec", test_crypto_aes_ctr_testvec, 0,
@@ -3476,10 +3471,7 @@ struct testcase_t crypto_tests[] = {
   { "sha3_xof", test_crypto_sha3_xof, TT_FORK, NULL, NULL},
   { "mac_sha3", test_crypto_mac_sha3, TT_FORK, NULL, NULL},
   CRYPTO_LEGACY(dh),
-  { "aes_iv_AES", test_crypto_aes_iv, TT_FORK, &passthrough_setup,
-    (void*)"aes" },
-  { "aes_iv_EVP", test_crypto_aes_iv, TT_FORK, &passthrough_setup,
-    (void*)"evp" },
+  { "aes_iv_EVP", test_crypto_aes_iv, TT_FORK, NULL, NULL },
   CRYPTO_LEGACY(base32_decode),
   { "kdf_TAP", test_crypto_kdf_TAP, 0, NULL, NULL },
   { "hkdf_sha256", test_crypto_hkdf_sha256, 0, NULL, NULL },