Back to index

tor  0.2.3.19-rc
aes.c
Go to the documentation of this file.
00001 /* Copyright (c) 2001, Matej Pfajfar.
00002  * Copyright (c) 2001-2004, Roger Dingledine.
00003  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
00004  * Copyright (c) 2007-2012, The Tor Project, Inc. */
00005 /* See LICENSE for licensing information */
00006 
00012 #include "orconfig.h"
00013 
00014 #ifdef _WIN32 /*wrkard for dtls1.h >= 0.9.8m of "#include <winsock.h>"*/
00015  #ifndef _WIN32_WINNT
00016  #define _WIN32_WINNT 0x0501
00017  #endif
00018  #define WIN32_LEAN_AND_MEAN
00019  #if defined(_MSC_VER) && (_MSC_VER < 1300)
00020     #include <winsock.h>
00021  #else
00022     #include <winsock2.h>
00023     #include <ws2tcpip.h>
00024  #endif
00025 #endif
00026 
00027 #include <openssl/opensslv.h>
00028 #include <assert.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <openssl/aes.h>
00032 #include <openssl/evp.h>
00033 #include <openssl/engine.h>
00034 #include "crypto.h"
00035 #if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,0,0)
00036 /* See comments about which counter mode implementation to use below. */
00037 #include <openssl/modes.h>
00038 #define CAN_USE_OPENSSL_CTR
00039 #endif
00040 #include "compat.h"
00041 #include "aes.h"
00042 #include "util.h"
00043 #include "torlog.h"
00044 
00045 #ifdef ANDROID
00046 /* Android's OpenSSL seems to have removed all of its Engine support. */
00047 #define DISABLE_ENGINES
00048 #endif
00049 
00050 /* We have five strategies for implementing AES counter mode.
00051  *
00052  * Best with x86 and x86_64: Use EVP_aes_ctr128() and EVP_EncryptUpdate().
00053  * This is possible with OpenSSL 1.0.1, where the counter-mode implementation
00054  * can use bit-sliced or vectorized AES or AESNI as appropriate.
00055  *
00056  * Otherwise: Pick the best possible AES block implementation that OpenSSL
00057  * gives us, and the best possible counter-mode implementation, and combine
00058  * them.
00059  */
00060 #if OPENSSL_VERSION_NUMBER >= OPENSSL_V_NOPATCH(1,0,1) &&               \
00061   (defined(__i386) || defined(__i386__) || defined(_M_IX86) ||          \
00062    defined(__x86_64) || defined(__x86_64__) ||                          \
00063    defined(_M_AMD64) || defined(_M_X64) || defined(__INTEL__))          \
00064 
00065 #define USE_EVP_AES_CTR
00066 
00067 #endif
00068 
00069 /* We have 2 strategies for getting the AES block cipher: Via OpenSSL's
00070  * AES_encrypt function, or via OpenSSL's EVP_EncryptUpdate function.
00071  *
00072  * If there's any hardware acceleration in play, we want to be using EVP_* so
00073  * we can get it.  Otherwise, we'll want AES_*, which seems to be about 5%
00074  * faster than indirecting through the EVP layer.
00075  */
00076 
00077 /* We have 2 strategies for getting a plug-in counter mode: use our own, or
00078  * use OpenSSL's.
00079  *
00080  * Here we have a counter mode that's faster than the one shipping with
00081  * OpenSSL pre-1.0 (by about 10%!).  But OpenSSL 1.0.0 added a counter mode
00082  * implementation faster than the one here (by about 7%).  So we pick which
00083  * one to used based on the Openssl version above.  (OpenSSL 1.0.0a fixed a
00084  * critical bug in that counter mode implementation, so we need to test to
00085  * make sure that we have a fixed version.)
00086  */
00087 
00088 #ifdef USE_EVP_AES_CTR
00089 
00090 struct aes_cnt_cipher {
00091   EVP_CIPHER_CTX evp;
00092 };
00093 
00094 aes_cnt_cipher_t *
00095 aes_new_cipher(const char *key, const char *iv)
00096 {
00097   aes_cnt_cipher_t *cipher;
00098   cipher = tor_malloc_zero(sizeof(aes_cnt_cipher_t));
00099   EVP_EncryptInit(&cipher->evp, EVP_aes_128_ctr(),
00100                   (const unsigned char*)key, (const unsigned char *)iv);
00101   return cipher;
00102 }
00103 void
00104 aes_cipher_free(aes_cnt_cipher_t *cipher)
00105 {
00106   if (!cipher)
00107     return;
00108   EVP_CIPHER_CTX_cleanup(&cipher->evp);
00109   memset(cipher, 0, sizeof(aes_cnt_cipher_t));
00110   tor_free(cipher);
00111 }
00112 void
00113 aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len,
00114           char *output)
00115 {
00116   int outl;
00117 
00118   tor_assert(len < INT_MAX);
00119 
00120   EVP_EncryptUpdate(&cipher->evp, (unsigned char*)output,
00121                     &outl, (const unsigned char *)input, (int)len);
00122 }
00123 void
00124 aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len)
00125 {
00126   int outl;
00127 
00128   tor_assert(len < INT_MAX);
00129 
00130   EVP_EncryptUpdate(&cipher->evp, (unsigned char*)data,
00131                     &outl, (unsigned char*)data, (int)len);
00132 }
00133 int
00134 evaluate_evp_for_aes(int force_val)
00135 {
00136   (void) force_val;
00137   log_notice(LD_CRYPTO, "This version of OpenSSL has a known-good EVP "
00138              "counter-mode implementation. Using it.");
00139   return 0;
00140 }
00141 int
00142 evaluate_ctr_for_aes(void)
00143 {
00144   return 0;
00145 }
00146 #else
00147 
00148 /*======================================================================*/
00149 /* Interface to AES code, and counter implementation */
00150 
00152 struct aes_cnt_cipher {
00154   union {
00155     EVP_CIPHER_CTX evp;
00156     AES_KEY aes;
00157   } key;
00158 
00159 #if !defined(WORDS_BIGENDIAN)
00160 #define USING_COUNTER_VARS
00161 
00163   uint32_t counter3;
00164   uint32_t counter2;
00165   uint32_t counter1;
00166   uint32_t counter0;
00167 #endif
00168 
00169   union {
00171     uint8_t buf[16];
00175     uint32_t buf32[4];
00176   } ctr_buf;
00177 
00179   uint8_t buf[16];
00181   unsigned int pos;
00182 
00184   uint8_t using_evp;
00185 };
00186 
00189 static int should_use_EVP = 0;
00190 
00191 #ifdef CAN_USE_OPENSSL_CTR
00192 
00194 static int should_use_openssl_CTR = 0;
00195 #endif
00196 
00200 int
00201 evaluate_evp_for_aes(int force_val)
00202 {
00203   ENGINE *e;
00204 
00205   if (force_val >= 0) {
00206     should_use_EVP = force_val;
00207     return 0;
00208   }
00209 #ifdef DISABLE_ENGINES
00210   should_use_EVP = 0;
00211 #else
00212   e = ENGINE_get_cipher_engine(NID_aes_128_ecb);
00213 
00214   if (e) {
00215     log_notice(LD_CRYPTO, "AES engine \"%s\" found; using EVP_* functions.",
00216                ENGINE_get_name(e));
00217     should_use_EVP = 1;
00218   } else {
00219     log_notice(LD_CRYPTO, "No AES engine found; using AES_* functions.");
00220     should_use_EVP = 0;
00221   }
00222 #endif
00223 
00224   return 0;
00225 }
00226 
00234 int
00235 evaluate_ctr_for_aes(void)
00236 {
00237 #ifdef CAN_USE_OPENSSL_CTR
00238   /* Result of encrypting an all-zero block with an all-zero 128-bit AES key.
00239    * This should be the same as encrypting an all-zero block with an all-zero
00240    * 128-bit AES key in counter mode, starting at position 0 of the stream.
00241    */
00242   static const unsigned char encrypt_zero[] =
00243     "\x66\xe9\x4b\xd4\xef\x8a\x2c\x3b\x88\x4c\xfa\x59\xca\x34\x2b\x2e";
00244   unsigned char zero[16];
00245   unsigned char output[16];
00246   unsigned char ivec[16];
00247   unsigned char ivec_tmp[16];
00248   unsigned int pos, i;
00249   AES_KEY key;
00250   memset(zero, 0, sizeof(zero));
00251   memset(ivec, 0, sizeof(ivec));
00252   AES_set_encrypt_key(zero, 128, &key);
00253 
00254   pos = 0;
00255   /* Encrypting a block one byte at a time should make the error manifest
00256    * itself for known bogus openssl versions. */
00257   for (i=0; i<16; ++i)
00258     AES_ctr128_encrypt(&zero[i], &output[i], 1, &key, ivec, ivec_tmp, &pos);
00259 
00260   if (memcmp(output, encrypt_zero, 16)) {
00261     /* Counter mode is buggy */
00262     log_notice(LD_CRYPTO, "This OpenSSL has a buggy version of counter mode; "
00263                "not using it.");
00264   } else {
00265     /* Counter mode is okay */
00266     log_notice(LD_CRYPTO, "This OpenSSL has a good implementation of counter "
00267                "mode; using it.");
00268     should_use_openssl_CTR = 1;
00269   }
00270 #else
00271   log_notice(LD_CRYPTO, "This version of OpenSSL has a slow implementation of "
00272              "counter mode; not using it.");
00273 #endif
00274   return 0;
00275 }
00276 
00277 #if !defined(USING_COUNTER_VARS)
00278 #define COUNTER(c, n) ((c)->ctr_buf.buf32[3-(n)])
00279 #else
00280 #define COUNTER(c, n) ((c)->counter ## n)
00281 #endif
00282 
00287 static INLINE void
00288 _aes_fill_buf(aes_cnt_cipher_t *cipher)
00289 {
00290   /* We don't currently use OpenSSL's counter mode implementation because:
00291    *  1) some versions have known bugs
00292    *  2) its attitude towards IVs is not our own
00293    *  3) changing the counter position was not trivial, last time I looked.
00294    * None of these issues are insurmountable in principle.
00295    */
00296 
00297   if (cipher->using_evp) {
00298     int outl=16, inl=16;
00299     EVP_EncryptUpdate(&cipher->key.evp, cipher->buf, &outl,
00300                       cipher->ctr_buf.buf, inl);
00301   } else {
00302     AES_encrypt(cipher->ctr_buf.buf, cipher->buf, &cipher->key.aes);
00303   }
00304 }
00305 
00306 static void aes_set_key(aes_cnt_cipher_t *cipher, const char *key,
00307                         int key_bits);
00308 static void aes_set_iv(aes_cnt_cipher_t *cipher, const char *iv);
00309 
00314 aes_cnt_cipher_t*
00315 aes_new_cipher(const char *key, const char *iv)
00316 {
00317   aes_cnt_cipher_t* result = tor_malloc_zero(sizeof(aes_cnt_cipher_t));
00318 
00319   aes_set_key(result, key, 128);
00320   aes_set_iv(result, iv);
00321 
00322   return result;
00323 }
00324 
00329 static void
00330 aes_set_key(aes_cnt_cipher_t *cipher, const char *key, int key_bits)
00331 {
00332   if (should_use_EVP) {
00333     const EVP_CIPHER *c;
00334     switch (key_bits) {
00335       case 128: c = EVP_aes_128_ecb(); break;
00336       case 192: c = EVP_aes_192_ecb(); break;
00337       case 256: c = EVP_aes_256_ecb(); break;
00338       default: tor_assert(0);
00339     }
00340     EVP_EncryptInit(&cipher->key.evp, c, (const unsigned char*)key, NULL);
00341     cipher->using_evp = 1;
00342   } else {
00343     AES_set_encrypt_key((const unsigned char *)key, key_bits, &cipher->key.aes);
00344     cipher->using_evp = 0;
00345   }
00346 
00347 #ifdef USING_COUNTER_VARS
00348   cipher->counter0 = 0;
00349   cipher->counter1 = 0;
00350   cipher->counter2 = 0;
00351   cipher->counter3 = 0;
00352 #endif
00353 
00354   memset(cipher->ctr_buf.buf, 0, sizeof(cipher->ctr_buf.buf));
00355 
00356   cipher->pos = 0;
00357 
00358 #ifdef CAN_USE_OPENSSL_CTR
00359   if (should_use_openssl_CTR)
00360     memset(cipher->buf, 0, sizeof(cipher->buf));
00361   else
00362 #endif
00363     _aes_fill_buf(cipher);
00364 }
00365 
00368 void
00369 aes_cipher_free(aes_cnt_cipher_t *cipher)
00370 {
00371   if (!cipher)
00372     return;
00373   if (cipher->using_evp) {
00374     EVP_CIPHER_CTX_cleanup(&cipher->key.evp);
00375   }
00376   memset(cipher, 0, sizeof(aes_cnt_cipher_t));
00377   tor_free(cipher);
00378 }
00379 
00380 #if defined(USING_COUNTER_VARS)
00381 #define UPDATE_CTR_BUF(c, n) STMT_BEGIN                 \
00382   (c)->ctr_buf.buf32[3-(n)] = htonl((c)->counter ## n); \
00383   STMT_END
00384 #else
00385 #define UPDATE_CTR_BUF(c, n)
00386 #endif
00387 
00388 #ifdef CAN_USE_OPENSSL_CTR
00389 /* Helper function to use EVP with openssl's counter-mode wrapper. */
00390 static void evp_block128_fn(const uint8_t in[16],
00391                             uint8_t out[16],
00392                             const void *key)
00393 {
00394   EVP_CIPHER_CTX *ctx = (void*)key;
00395   int inl=16, outl=16;
00396   EVP_EncryptUpdate(ctx, out, &outl, in, inl);
00397 }
00398 #endif
00399 
00404 void
00405 aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len,
00406           char *output)
00407 {
00408 #ifdef CAN_USE_OPENSSL_CTR
00409   if (should_use_openssl_CTR) {
00410     if (cipher->using_evp) {
00411       /* In openssl 1.0.0, there's an if'd out EVP_aes_128_ctr in evp.h.  If
00412        * it weren't disabled, it might be better just to use that.
00413        */
00414       CRYPTO_ctr128_encrypt((const unsigned char *)input,
00415                             (unsigned char *)output,
00416                             len,
00417                             &cipher->key.evp,
00418                             cipher->ctr_buf.buf,
00419                             cipher->buf,
00420                             &cipher->pos,
00421                             evp_block128_fn);
00422     } else {
00423       AES_ctr128_encrypt((const unsigned char *)input,
00424                          (unsigned char *)output,
00425                          len,
00426                          &cipher->key.aes,
00427                          cipher->ctr_buf.buf,
00428                          cipher->buf,
00429                          &cipher->pos);
00430     }
00431     return;
00432   }
00433   else
00434 #endif
00435   {
00436     int c = cipher->pos;
00437     if (PREDICT_UNLIKELY(!len)) return;
00438 
00439     while (1) {
00440       do {
00441         if (len-- == 0) { cipher->pos = c; return; }
00442         *(output++) = *(input++) ^ cipher->buf[c];
00443       } while (++c != 16);
00444       cipher->pos = c = 0;
00445       if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 0))) {
00446         if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 1))) {
00447           if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 2))) {
00448             ++COUNTER(cipher, 3);
00449             UPDATE_CTR_BUF(cipher, 3);
00450           }
00451           UPDATE_CTR_BUF(cipher, 2);
00452         }
00453         UPDATE_CTR_BUF(cipher, 1);
00454       }
00455       UPDATE_CTR_BUF(cipher, 0);
00456       _aes_fill_buf(cipher);
00457     }
00458   }
00459 }
00460 
00465 void
00466 aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len)
00467 {
00468 #ifdef CAN_USE_OPENSSL_CTR
00469   if (should_use_openssl_CTR) {
00470     aes_crypt(cipher, data, len, data);
00471     return;
00472   }
00473   else
00474 #endif
00475   {
00476     int c = cipher->pos;
00477     if (PREDICT_UNLIKELY(!len)) return;
00478 
00479     while (1) {
00480       do {
00481         if (len-- == 0) { cipher->pos = c; return; }
00482         *(data++) ^= cipher->buf[c];
00483       } while (++c != 16);
00484       cipher->pos = c = 0;
00485       if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 0))) {
00486         if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 1))) {
00487           if (PREDICT_UNLIKELY(! ++COUNTER(cipher, 2))) {
00488             ++COUNTER(cipher, 3);
00489             UPDATE_CTR_BUF(cipher, 3);
00490           }
00491           UPDATE_CTR_BUF(cipher, 2);
00492         }
00493         UPDATE_CTR_BUF(cipher, 1);
00494       }
00495       UPDATE_CTR_BUF(cipher, 0);
00496       _aes_fill_buf(cipher);
00497     }
00498   }
00499 }
00500 
00503 static void
00504 aes_set_iv(aes_cnt_cipher_t *cipher, const char *iv)
00505 {
00506 #ifdef USING_COUNTER_VARS
00507   cipher->counter3 = ntohl(get_uint32(iv));
00508   cipher->counter2 = ntohl(get_uint32(iv+4));
00509   cipher->counter1 = ntohl(get_uint32(iv+8));
00510   cipher->counter0 = ntohl(get_uint32(iv+12));
00511 #endif
00512   cipher->pos = 0;
00513   memcpy(cipher->ctr_buf.buf, iv, 16);
00514 
00515 #ifdef CAN_USE_OPENSSL_CTR
00516   if (!should_use_openssl_CTR)
00517 #endif
00518     _aes_fill_buf(cipher);
00519 }
00520 
00521 #endif