23#include "lib/crypt_ops/compat_openssl.h"
24#include <openssl/opensslv.h>
27DISABLE_GCC_WARNING(
"-Wredundant-decls")
31#include <openssl/aes.h>
32#include <openssl/evp.h>
33#include <openssl/engine.h>
34#include <openssl/modes.h>
36ENABLE_GCC_WARNING(
"-Wredundant-decls")
38#include "lib/log/log.h"
41#ifdef OPENSSL_NO_ENGINE
43#define DISABLE_ENGINES
56#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_NOPATCH(1,1,0)
61#define USE_EVP_AES_CTR
63#elif OPENSSL_VERSION_NUMBER >= OPENSSL_V_NOPATCH(1,0,1) && \
64 (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
65 defined(__x86_64) || defined(__x86_64__) || \
66 defined(_M_AMD64) || defined(_M_X64) || defined(__INTEL__))
68#define USE_EVP_AES_CTR
96aes_new_cipher(
const uint8_t *key,
const uint8_t *iv,
int key_bits)
98 EVP_CIPHER_CTX *cipher = EVP_CIPHER_CTX_new();
99 const EVP_CIPHER *c = NULL;
101 case 128: c = EVP_aes_128_ctr();
break;
102 case 192: c = EVP_aes_192_ctr();
break;
103 case 256: c = EVP_aes_256_ctr();
break;
104 default: tor_assert_unreached();
106 EVP_EncryptInit(cipher, c, key, iv);
107 return (aes_cnt_cipher_t *) cipher;
110aes_cipher_free_(aes_cnt_cipher_t *cipher_)
114 EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
115 EVP_CIPHER_CTX_reset(cipher);
116 EVP_CIPHER_CTX_free(cipher);
119aes_crypt_inplace(aes_cnt_cipher_t *cipher_,
char *data,
size_t len)
122 EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
126 EVP_EncryptUpdate(cipher, (
unsigned char*)data,
127 &outl, (
unsigned char*)data, (
int)len);
130evaluate_evp_for_aes(
int force_val)
133 log_info(
LD_CRYPTO,
"This version of OpenSSL has a known-good EVP "
134 "counter-mode implementation. Using it.");
138evaluate_ctr_for_aes(
void)
148struct aes_cnt_cipher_t {
155#if !defined(WORDS_BIGENDIAN)
156#define USING_COUNTER_VARS
185static int should_use_EVP = 0;
191evaluate_evp_for_aes(
int force_val)
195 if (force_val >= 0) {
196 should_use_EVP = force_val;
199#ifdef DISABLE_ENGINES
202 e = ENGINE_get_cipher_engine(NID_aes_128_ecb);
205 log_info(
LD_CRYPTO,
"AES engine \"%s\" found; using EVP_* functions.",
209 log_info(
LD_CRYPTO,
"No AES engine found; using AES_* functions.");
225evaluate_ctr_for_aes(
void)
231 static const unsigned char encrypt_zero[] =
232 "\x66\xe9\x4b\xd4\xef\x8a\x2c\x3b\x88\x4c\xfa\x59\xca\x34\x2b\x2e";
233 unsigned char zero[16];
234 unsigned char output[16];
235 unsigned char ivec[16];
236 unsigned char ivec_tmp[16];
239 memset(zero, 0,
sizeof(zero));
240 memset(ivec, 0,
sizeof(ivec));
241 AES_set_encrypt_key(zero, 128, &key);
247 AES_ctr128_encrypt(&zero[i], &output[i], 1, &key, ivec, ivec_tmp, &pos);
252 log_err(
LD_CRYPTO,
"This OpenSSL has a buggy version of counter mode; "
260#if !defined(USING_COUNTER_VARS)
261#define COUNTER(c, n) ((c)->ctr_buf.buf32[3-(n)])
263#define COUNTER(c, n) ((c)->counter ## n)
266static void aes_set_key(aes_cnt_cipher_t *cipher,
const uint8_t *key,
268static void aes_set_iv(aes_cnt_cipher_t *cipher,
const uint8_t *iv);
275aes_new_cipher(
const uint8_t *key,
const uint8_t *iv,
int bits)
277 aes_cnt_cipher_t* result = tor_malloc_zero(
sizeof(aes_cnt_cipher_t));
279 aes_set_key(result, key, bits);
280 aes_set_iv(result, iv);
290aes_set_key(aes_cnt_cipher_t *cipher,
const uint8_t *key,
int key_bits)
292 if (should_use_EVP) {
293 const EVP_CIPHER *c = 0;
295 case 128: c = EVP_aes_128_ecb();
break;
296 case 192: c = EVP_aes_192_ecb();
break;
297 case 256: c = EVP_aes_256_ecb();
break;
300 EVP_EncryptInit(&cipher->key.evp, c, key, NULL);
301 cipher->using_evp = 1;
303 AES_set_encrypt_key(key, key_bits,&cipher->key.aes);
304 cipher->using_evp = 0;
307#ifdef USING_COUNTER_VARS
308 cipher->counter0 = 0;
309 cipher->counter1 = 0;
310 cipher->counter2 = 0;
311 cipher->counter3 = 0;
314 memset(cipher->ctr_buf.buf, 0,
sizeof(cipher->ctr_buf.buf));
318 memset(cipher->buf, 0,
sizeof(cipher->buf));
324aes_cipher_free_(aes_cnt_cipher_t *cipher)
328 if (cipher->using_evp) {
329 EVP_CIPHER_CTX_cleanup(&cipher->key.evp);
331 memwipe(cipher, 0,
sizeof(aes_cnt_cipher_t));
335#if defined(USING_COUNTER_VARS)
336#define UPDATE_CTR_BUF(c, n) STMT_BEGIN \
337 (c)->ctr_buf.buf32[3-(n)] = htonl((c)->counter ## n); \
340#define UPDATE_CTR_BUF(c, n)
345evp_block128_fn(
const uint8_t in[16],
349 EVP_CIPHER_CTX *ctx = (
void*)key;
351 EVP_EncryptUpdate(ctx, out, &outl, in, inl);
359aes_crypt_inplace(aes_cnt_cipher_t *cipher,
char *data,
size_t len)
363 if (cipher->using_evp) {
367 CRYPTO_ctr128_encrypt((
const unsigned char *)data,
368 (
unsigned char *)data,
376 AES_ctr128_encrypt((
const unsigned char *)data,
377 (
unsigned char *)data,
389aes_set_iv(aes_cnt_cipher_t *cipher,
const uint8_t *iv)
391#ifdef USING_COUNTER_VARS
398 memcpy(cipher->ctr_buf.buf, iv, 16);
Inline functions for reading and writing multibyte values from the middle of strings,...
static uint32_t tor_ntohl(uint32_t a)
static uint32_t get_uint32(const void *cp)
Headers for crypto_openssl_mgt.c.
void memwipe(void *mem, uint8_t byte, size_t sz)
Common functions for cryptographic routines.
#define fast_memneq(a, b, c)
Macros to manage assertions, fatal and non-fatal.