13#define TOR_AES_PRIVATE
26#include "lib/crypt_ops/compat_openssl.h"
27#include <openssl/opensslv.h>
30DISABLE_GCC_WARNING(
"-Wredundant-decls")
34#include <openssl/aes.h>
35#include <openssl/evp.h>
36#include <openssl/engine.h>
37#include <openssl/modes.h>
39ENABLE_GCC_WARNING(
"-Wredundant-decls")
41#include "lib/log/log.h"
48static const EVP_CIPHER *aes128ctr = NULL;
49static const EVP_CIPHER *aes192ctr = NULL;
50static const EVP_CIPHER *aes256ctr = NULL;
51static const EVP_CIPHER *aes128ecb = NULL;
52static const EVP_CIPHER *aes192ecb = NULL;
53static const EVP_CIPHER *aes256ecb = NULL;
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)), "")
60#define RESOLVE_CIPHER(c) (c)
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());
76#define INIT_CIPHERS() STMT_BEGIN { \
77 if (PREDICT_UNLIKELY(NULL == aes128ctr)) { \
104aes_new_cipher(
const uint8_t *key,
const uint8_t *iv,
int key_bits)
107 EVP_CIPHER_CTX *cipher = EVP_CIPHER_CTX_new();
108 const EVP_CIPHER *c = NULL;
110 case 128: c = aes128ctr;
break;
111 case 192: c = aes192ctr;
break;
112 case 256: c = aes256ctr;
break;
113 default: tor_assert_unreached();
115 EVP_EncryptInit(cipher, c, key, iv);
123 EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
124 EVP_CIPHER_CTX_reset(cipher);
125 EVP_CIPHER_CTX_free(cipher);
134 EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
135 uint8_t iv[16] = {0};
136 const EVP_CIPHER *c = NULL;
138 case 128: c = aes128ctr;
break;
139 case 192: c = aes192ctr;
break;
140 case 256: c = aes256ctr;
break;
141 default: tor_assert_unreached();
146 EVP_EncryptInit(cipher, c, key, iv);
155 EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
156#ifdef LIBRESSL_VERSION_NUMBER
157 EVP_CIPHER_CTX_set_iv(cipher, iv, 16);
162 memcpy(EVP_CIPHER_CTX_iv_noconst(cipher), iv, 16);
169 EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
173 EVP_EncryptUpdate(cipher, (
unsigned char*)data,
174 &outl, (
unsigned char*)data, (
int)len);
196 EVP_CIPHER_CTX *cipher = EVP_CIPHER_CTX_new();
198 const EVP_CIPHER *c = NULL;
200 case 128: c = aes128ecb;
break;
201 case 192: c = aes192ecb;
break;
202 case 256: c = aes256ecb;
break;
203 default: tor_assert_unreached();
208 int r = EVP_CipherInit(cipher, c, key, NULL, encrypt);
210 EVP_CIPHER_CTX_set_padding(cipher, 0);
211 return (aes_raw_t *)cipher;
220 int key_bits,
bool encrypt)
222 const EVP_CIPHER *c = *(EVP_CIPHER**) cipher_;
224 case 128: c = aes128ecb;
break;
225 case 192: c = aes192ecb;
break;
226 case 256: c = aes256ecb;
break;
227 default: tor_assert_unreached();
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);
233 EVP_CIPHER_CTX_set_padding(cipher, 0);
244 EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *)cipher_;
245#ifdef OPENSSL_1_1_API
246 EVP_CIPHER_CTX_reset(cipher);
248 EVP_CIPHER_CTX_cleanup(cipher);
250 EVP_CIPHER_CTX_free(cipher);
252#define aes_raw_free(cipher) \
253 FREE_AND_NULL(aes_raw_t, aes_raw_free_, (cipher))
262 int r = EVP_EncryptUpdate((EVP_CIPHER_CTX *)cipher, block, &outl, block, 16);
274 int r = EVP_DecryptUpdate((EVP_CIPHER_CTX *)cipher, block, &outl, block, 16);
void aes_cipher_set_key(aes_cnt_cipher_t *cipher_, const uint8_t *key, int key_bits)
void aes_cipher_set_iv_aligned(aes_cnt_cipher_t *cipher_, const uint8_t *iv)
void aes_raw_set_key(aes_raw_t **cipher_, const uint8_t *key, int key_bits, bool encrypt)
void aes_raw_encrypt(const aes_raw_t *cipher, uint8_t *block)
void aes_raw_decrypt(const aes_raw_t *cipher, uint8_t *block)
static void init_ciphers(void)
void aes_raw_free_(aes_raw_t *cipher_)
aes_raw_t * aes_raw_new(const uint8_t *key, int key_bits, bool encrypt)
Inline functions for reading and writing multibyte values from the middle of strings,...
Headers for crypto_openssl_mgt.c.
Common functions for cryptographic routines.
Macros to manage assertions, fatal and non-fatal.