Browse Source

Added comparibility with OpenSSL 1.0

pull/232/head
Luca Deri 5 years ago
parent
commit
1cc4996ef3
  1. 3
      autogen.sh
  2. 10
      configure.seed
  3. 90
      transform_aes.c

3
autogen.sh

@ -18,5 +18,4 @@ rm -f config.h config.h.in *~ Makefile configure #*
echo "Wait please..." echo "Wait please..."
autoreconf -if autoreconf -if
echo "" ./configure
echo "Now run ./configure"

10
configure.seed

@ -23,13 +23,17 @@ else
N2N_LIBS=-lcrypto N2N_LIBS=-lcrypto
fi fi
OLD_CFLAGS="${CFLAGS}"
OLD_LDFLAGS="${LDFLAGS}"
CFLAGS="${CFLAGS} -I/usr/local/opt/openssl@1.1/include" CFLAGS="${CFLAGS} -I/usr/local/opt/openssl@1.1/include"
LDFLAGS="${LDFLAGS} -L/usr/local/opt/openssl@1.1/lib/" LDFLAGS="${LDFLAGS} -L/usr/local/opt/openssl@1.1/lib/"
AC_CHECK_LIB([crypto], [EVP_CIPHER_CTX_reset]) AC_CHECK_LIB([crypto], [EVP_CIPHER_CTX_reset])
if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_reset" != xyes; then if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_reset" != xyes; then
echo "" CFLAGS="${OLD_CFLAGS}"
echo "You do not seem to use OpenSSL 1.1 or better. Please upgrade" LDFLAGS="${OLD_LDFLAGS}"
echo "" else
AC_DEFINE([HAVE_OPENSSL_1_1], [], [OpenSSL 1.1 is present])
fi fi
AC_CHECK_LIB([pcap], [pcap_open_live], pcap=true) AC_CHECK_LIB([pcap], [pcap_open_live], pcap=true)

90
transform_aes.c

@ -43,19 +43,28 @@
typedef unsigned char n2n_aes_ivec_t[N2N_AES_IVEC_SIZE]; typedef unsigned char n2n_aes_ivec_t[N2N_AES_IVEC_SIZE];
typedef struct transop_aes { typedef struct transop_aes {
#ifdef OPENSSL_1_1
EVP_CIPHER_CTX *enc_ctx; /* openssl's reusable evp_* encryption context */ EVP_CIPHER_CTX *enc_ctx; /* openssl's reusable evp_* encryption context */
EVP_CIPHER_CTX *dec_ctx; /* openssl's reusable evp_* decryption context */ EVP_CIPHER_CTX *dec_ctx; /* openssl's reusable evp_* decryption context */
const EVP_CIPHER *cipher; /* cipher to use: e.g. EVP_aes_128_cbc */ const EVP_CIPHER *cipher; /* cipher to use: e.g. EVP_aes_128_cbc */
uint8_t key[32]; /* the pure key data for payload encryption & decryption */ uint8_t key[32]; /* the pure key data for payload encryption & decryption */
#else
AES_KEY enc_key; /* tx key */
AES_KEY dec_key; /* tx key */
#endif
AES_KEY iv_enc_key; /* key used to encrypt the IV */ AES_KEY iv_enc_key; /* key used to encrypt the IV */
uint8_t iv_pad_val[TRANSOP_AES_IV_PADDING_SIZE]; /* key used to pad the random IV seed to full block size */ uint8_t iv_pad_val[TRANSOP_AES_IV_PADDING_SIZE]; /* key used to pad the random IV seed to full block size */
} transop_aes_t; } transop_aes_t;
/* ****************************************************** */
static int transop_deinit_aes(n2n_trans_op_t *arg) { static int transop_deinit_aes(n2n_trans_op_t *arg) {
transop_aes_t *priv = (transop_aes_t *)arg->priv; transop_aes_t *priv = (transop_aes_t *)arg->priv;
#ifdef OPENSSL_1_1
EVP_CIPHER_CTX_free(priv->enc_ctx); EVP_CIPHER_CTX_free(priv->enc_ctx);
EVP_CIPHER_CTX_free(priv->dec_ctx); EVP_CIPHER_CTX_free(priv->dec_ctx);
#endif
if(priv) if(priv)
free(priv); free(priv);
@ -63,6 +72,9 @@ static int transop_deinit_aes(n2n_trans_op_t *arg) {
return 0; return 0;
} }
/* ****************************************************** */
#ifdef OPENSSL_1_1
/* get any erorr message out of openssl /* get any erorr message out of openssl
taken from https://en.wikibooks.org/wiki/OpenSSL/Error_handling */ taken from https://en.wikibooks.org/wiki/OpenSSL/Error_handling */
char *openssl_err_as_string (void) { char *openssl_err_as_string (void) {
@ -76,6 +88,9 @@ char *openssl_err_as_string (void) {
BIO_free (bio); BIO_free (bio);
return ret; return ret;
} }
#endif
/* ****************************************************** */
static void set_aes_cbc_iv(transop_aes_t *priv, n2n_aes_ivec_t ivec, uint64_t iv_seed) { static void set_aes_cbc_iv(transop_aes_t *priv, n2n_aes_ivec_t ivec, uint64_t iv_seed) {
uint8_t iv_full[N2N_AES_IVEC_SIZE]; uint8_t iv_full[N2N_AES_IVEC_SIZE];
@ -93,6 +108,8 @@ static void set_aes_cbc_iv(transop_aes_t *priv, n2n_aes_ivec_t ivec, uint64_t iv
AES_ecb_encrypt(iv_full, ivec, &priv->iv_enc_key, AES_ENCRYPT); AES_ecb_encrypt(iv_full, ivec, &priv->iv_enc_key, AES_ENCRYPT);
} }
/* ****************************************************** */
/** The aes packet format consists of: /** The aes packet format consists of:
* *
* - a 8-bit aes encoding version in clear text * - a 8-bit aes encoding version in clear text
@ -107,8 +124,7 @@ static int transop_encode_aes( n2n_trans_op_t * arg,
size_t out_len, size_t out_len,
const uint8_t * inbuf, const uint8_t * inbuf,
size_t in_len, size_t in_len,
const uint8_t * peer_mac) const uint8_t * peer_mac) {
{
int len2=-1; int len2=-1;
transop_aes_t * priv = (transop_aes_t *)arg->priv; transop_aes_t * priv = (transop_aes_t *)arg->priv;
uint8_t assembly[N2N_PKT_BUF_SIZE] = {0}; uint8_t assembly[N2N_PKT_BUF_SIZE] = {0};
@ -150,15 +166,18 @@ static int transop_encode_aes( n2n_trans_op_t * arg,
set_aes_cbc_iv(priv, enc_ivec, iv_seed); set_aes_cbc_iv(priv, enc_ivec, iv_seed);
#ifdef OPENSSL_1_1
EVP_CIPHER_CTX *ctx = priv->enc_ctx; EVP_CIPHER_CTX *ctx = priv->enc_ctx;
int evp_len; int evp_len;
int evp_ciphertext_len; int evp_ciphertext_len;
if(1 == EVP_EncryptInit_ex(ctx, priv->cipher, NULL, priv->key, enc_ivec)) { if(1 == EVP_EncryptInit_ex(ctx, priv->cipher, NULL, priv->key, enc_ivec)) {
if(1 == EVP_CIPHER_CTX_set_padding(ctx, 0)) { if(1 == EVP_CIPHER_CTX_set_padding(ctx, 0)) {
if(1 == EVP_EncryptUpdate(ctx, outbuf + TRANSOP_AES_PREAMBLE_SIZE, &evp_len, assembly, len2)) { if(1 == EVP_EncryptUpdate(ctx, outbuf + TRANSOP_AES_PREAMBLE_SIZE, &evp_len, assembly, len2)) {
evp_ciphertext_len = evp_len; evp_ciphertext_len = evp_len;
if(1 == EVP_EncryptFinal_ex(ctx, outbuf + TRANSOP_AES_PREAMBLE_SIZE + evp_len, &evp_len)) { if(1 == EVP_EncryptFinal_ex(ctx, outbuf + TRANSOP_AES_PREAMBLE_SIZE + evp_len, &evp_len)) {
evp_ciphertext_len += evp_len; evp_ciphertext_len += evp_len;
if(evp_ciphertext_len != len2) if(evp_ciphertext_len != len2)
traceEvent(TRACE_ERROR, "encode_aes openssl encryption: encrypted %u bytes where %u were expected.\n", traceEvent(TRACE_ERROR, "encode_aes openssl encryption: encrypted %u bytes where %u were expected.\n",
evp_ciphertext_len, len2); evp_ciphertext_len, len2);
@ -170,7 +189,14 @@ static int transop_encode_aes( n2n_trans_op_t * arg,
traceEvent(TRACE_ERROR, "encode_aes openssl padding setup: %s\n", openssl_err_as_string()); traceEvent(TRACE_ERROR, "encode_aes openssl padding setup: %s\n", openssl_err_as_string());
} else } else
traceEvent(TRACE_ERROR, "encode_aes openssl init: %s\n", openssl_err_as_string()); traceEvent(TRACE_ERROR, "encode_aes openssl init: %s\n", openssl_err_as_string());
EVP_CIPHER_CTX_reset(ctx); EVP_CIPHER_CTX_reset(ctx);
#else
AES_cbc_encrypt( assembly, /* source */
outbuf + TRANSOP_AES_PREAMBLE_SIZE, /* dest */
len2, /* enc size */
&(priv->enc_key), enc_ivec, AES_ENCRYPT);
#endif
len2 += TRANSOP_AES_PREAMBLE_SIZE; /* size of data carried in UDP. */ len2 += TRANSOP_AES_PREAMBLE_SIZE; /* size of data carried in UDP. */
} else } else
@ -181,6 +207,8 @@ static int transop_encode_aes( n2n_trans_op_t * arg,
return len2; return len2;
} }
/* ****************************************************** */
/* See transop_encode_aes for packet format */ /* See transop_encode_aes for packet format */
static int transop_decode_aes( n2n_trans_op_t * arg, static int transop_decode_aes( n2n_trans_op_t * arg,
uint8_t * outbuf, uint8_t * outbuf,
@ -218,15 +246,18 @@ static int transop_decode_aes( n2n_trans_op_t * arg,
set_aes_cbc_iv(priv, dec_ivec, iv_seed); set_aes_cbc_iv(priv, dec_ivec, iv_seed);
#ifdef OPENSSL_1_1
EVP_CIPHER_CTX *ctx = priv->dec_ctx; EVP_CIPHER_CTX *ctx = priv->dec_ctx;
int evp_len; int evp_len;
int evp_plaintext_len; int evp_plaintext_len;
if(1 == EVP_DecryptInit_ex(ctx, priv->cipher, NULL, priv->key, dec_ivec)) { if(1 == EVP_DecryptInit_ex(ctx, priv->cipher, NULL, priv->key, dec_ivec)) {
if(1 == EVP_CIPHER_CTX_set_padding(ctx, 0)) { if(1 == EVP_CIPHER_CTX_set_padding(ctx, 0)) {
if(1 == EVP_DecryptUpdate(ctx, assembly, &evp_len, inbuf + TRANSOP_AES_PREAMBLE_SIZE, len)) { if(1 == EVP_DecryptUpdate(ctx, assembly, &evp_len, inbuf + TRANSOP_AES_PREAMBLE_SIZE, len)) {
evp_plaintext_len = evp_len; evp_plaintext_len = evp_len;
if(1 == EVP_DecryptFinal_ex(ctx, assembly + evp_len, &evp_len)) { if(1 == EVP_DecryptFinal_ex(ctx, assembly + evp_len, &evp_len)) {
evp_plaintext_len += evp_len; evp_plaintext_len += evp_len;
if(evp_plaintext_len != len) if(evp_plaintext_len != len)
traceEvent(TRACE_ERROR, "decode_aes openssl decryption: decrypted %u bytes where %u were expected.\n", traceEvent(TRACE_ERROR, "decode_aes openssl decryption: decrypted %u bytes where %u were expected.\n",
evp_plaintext_len, len); evp_plaintext_len, len);
@ -236,16 +267,23 @@ static int transop_decode_aes( n2n_trans_op_t * arg,
traceEvent(TRACE_ERROR, "decode_aes openssl decrpytion: %s\n", openssl_err_as_string()); traceEvent(TRACE_ERROR, "decode_aes openssl decrpytion: %s\n", openssl_err_as_string());
} else } else
traceEvent(TRACE_ERROR, "decode_aes openssl padding setup: %s\n", openssl_err_as_string()); traceEvent(TRACE_ERROR, "decode_aes openssl padding setup: %s\n", openssl_err_as_string());
} else } else
traceEvent(TRACE_ERROR, "decode_aes openssl init: %s\n", openssl_err_as_string()); traceEvent(TRACE_ERROR, "decode_aes openssl init: %s\n", openssl_err_as_string());
EVP_CIPHER_CTX_reset(ctx);
EVP_CIPHER_CTX_reset(ctx);
#else
AES_cbc_encrypt( (inbuf + TRANSOP_AES_PREAMBLE_SIZE),
assembly, /* destination */
len,
&(priv->dec_key),
dec_ivec, AES_DECRYPT);
#endif
/* last byte is how much was padding: max value should be /* last byte is how much was padding: max value should be
* AES_BLOCKSIZE-1 */ * AES_BLOCKSIZE-1 */
padding = assembly[ len-1 ] & 0xff; padding = assembly[ len-1 ] & 0xff;
if ( len >= padding) if(len >= padding) {
{
/* strictly speaking for this to be an ethernet packet /* strictly speaking for this to be an ethernet packet
* it is going to need to be even bigger; but this is * it is going to need to be even bigger; but this is
* enough to prevent segfaults. */ * enough to prevent segfaults. */
@ -269,6 +307,8 @@ static int transop_decode_aes( n2n_trans_op_t * arg,
return len; return len;
} }
/* ****************************************************** */
static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_size) { static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_size) {
size_t aes_key_size_bytes; size_t aes_key_size_bytes;
size_t aes_key_size_bits; size_t aes_key_size_bits;
@ -277,7 +317,12 @@ static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_si
size_t key_mat_buf_length; size_t key_mat_buf_length;
/* Clear out any old possibly longer key matter. */ /* Clear out any old possibly longer key matter. */
#ifdef OPENSSL_1_1
memset( &(priv->key), 0, sizeof(priv->key) ); memset( &(priv->key), 0, sizeof(priv->key) );
#else
memset( &(priv->enc_key), 0, sizeof(priv->enc_key) );
memset( &(priv->dec_key), 0, sizeof(priv->dec_key) );
#endif
memset( &(priv->iv_enc_key), 0, sizeof(priv->iv_enc_key) ); memset( &(priv->iv_enc_key), 0, sizeof(priv->iv_enc_key) );
memset( &(priv->iv_pad_val), 0, sizeof(priv->iv_pad_val) ); memset( &(priv->iv_pad_val), 0, sizeof(priv->iv_pad_val) );
@ -296,25 +341,26 @@ static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_si
* actual "filling level" of the buffer * actual "filling level" of the buffer
*/ */
if (key_size >= 65) if(key_size >= 65) {
{ #ifdef OPENSSL_1_1
priv->cipher = EVP_aes_256_cbc(); priv->cipher = EVP_aes_256_cbc();
#endif
aes_key_size_bytes = AES256_KEY_BYTES; aes_key_size_bytes = AES256_KEY_BYTES;
SHA512(key, key_size, key_mat_buf); SHA512(key, key_size, key_mat_buf);
key_mat_buf_length = SHA512_DIGEST_LENGTH; key_mat_buf_length = SHA512_DIGEST_LENGTH;
} } else if(key_size >= 44) {
else if (key_size >= 44) #ifdef OPENSSL_1_1
{
priv->cipher = EVP_aes_192_cbc(); priv->cipher = EVP_aes_192_cbc();
#endif
aes_key_size_bytes = AES192_KEY_BYTES; aes_key_size_bytes = AES192_KEY_BYTES;
SHA384(key, key_size, key_mat_buf); SHA384(key, key_size, key_mat_buf);
/* append a hash of the first hash to create enough material for IV padding */ /* append a hash of the first hash to create enough material for IV padding */
SHA256(key_mat_buf, SHA384_DIGEST_LENGTH, key_mat_buf + SHA384_DIGEST_LENGTH); SHA256(key_mat_buf, SHA384_DIGEST_LENGTH, key_mat_buf + SHA384_DIGEST_LENGTH);
key_mat_buf_length = SHA384_DIGEST_LENGTH + SHA256_DIGEST_LENGTH; key_mat_buf_length = SHA384_DIGEST_LENGTH + SHA256_DIGEST_LENGTH;
} } else {
else #ifdef OPENSSL_1_1
{
priv->cipher = EVP_aes_128_cbc(); priv->cipher = EVP_aes_128_cbc();
#endif
aes_key_size_bytes = AES128_KEY_BYTES; aes_key_size_bytes = AES128_KEY_BYTES;
SHA256(key, key_size, key_mat_buf); SHA256(key, key_size, key_mat_buf);
/* append a hash of the first hash to create enough material for IV padding */ /* append a hash of the first hash to create enough material for IV padding */
@ -323,8 +369,7 @@ static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_si
} }
/* is there enough material available? */ /* is there enough material available? */
if (key_mat_buf_length < (aes_key_size_bytes + TRANSOP_AES_IV_KEY_BYTES + TRANSOP_AES_IV_PADDING_SIZE)) if(key_mat_buf_length < (aes_key_size_bytes + TRANSOP_AES_IV_KEY_BYTES + TRANSOP_AES_IV_PADDING_SIZE)) {
{
/* this should never happen */ /* this should never happen */
traceEvent( TRACE_ERROR, "AES missing %u bits hashed key material\n", traceEvent( TRACE_ERROR, "AES missing %u bits hashed key material\n",
(aes_key_size_bytes + TRANSOP_AES_IV_KEY_BYTES + TRANSOP_AES_IV_PADDING_SIZE - key_mat_buf_length) * 8); (aes_key_size_bytes + TRANSOP_AES_IV_KEY_BYTES + TRANSOP_AES_IV_PADDING_SIZE - key_mat_buf_length) * 8);
@ -333,7 +378,13 @@ static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_si
/* setup of key, used for the CBC encryption */ /* setup of key, used for the CBC encryption */
aes_key_size_bits = 8 * aes_key_size_bytes; aes_key_size_bits = 8 * aes_key_size_bytes;
#ifdef OPENSSL_1_1
memcpy (priv->key, key_mat_buf, aes_key_size_bytes); memcpy (priv->key, key_mat_buf, aes_key_size_bytes);
#else
AES_set_encrypt_key(key_mat_buf, aes_key_size_bits, &(priv->enc_key));
AES_set_decrypt_key(key_mat_buf, aes_key_size_bits, &(priv->dec_key));
#endif
/* setup of iv_enc_key (AES128 key) and iv_pad_val, used for generating the CBC IV */ /* setup of iv_enc_key (AES128 key) and iv_pad_val, used for generating the CBC IV */
AES_set_encrypt_key(key_mat_buf + aes_key_size_bytes, TRANSOP_AES_IV_KEY_BYTES * 8, &(priv->iv_enc_key)); AES_set_encrypt_key(key_mat_buf + aes_key_size_bytes, TRANSOP_AES_IV_KEY_BYTES * 8, &(priv->iv_enc_key));
@ -345,7 +396,11 @@ static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_si
return(0); return(0);
} }
static void transop_tick_aes(n2n_trans_op_t * arg, time_t now) {} /* ****************************************************** */
static void transop_tick_aes(n2n_trans_op_t * arg, time_t now) { ; }
/* ****************************************************** */
/* AES initialization function */ /* AES initialization function */
int n2n_transop_aes_cbc_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { int n2n_transop_aes_cbc_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
@ -368,15 +423,18 @@ int n2n_transop_aes_cbc_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
} }
ttt->priv = priv; ttt->priv = priv;
#ifdef OPENSSL_1_1
/* Setup openssl's reusable evp_* contexts for encryption and decryption*/ /* Setup openssl's reusable evp_* contexts for encryption and decryption*/
if(!(priv->enc_ctx = EVP_CIPHER_CTX_new())) { if(!(priv->enc_ctx = EVP_CIPHER_CTX_new())) {
traceEvent(TRACE_ERROR, "openssl's evp_* encryption context creation: %s\n", openssl_err_as_string()); traceEvent(TRACE_ERROR, "openssl's evp_* encryption context creation: %s\n", openssl_err_as_string());
return(-1); return(-1);
} }
if(!(priv->dec_ctx = EVP_CIPHER_CTX_new())) { if(!(priv->dec_ctx = EVP_CIPHER_CTX_new())) {
traceEvent(TRACE_ERROR, "openssl's evp_* decryption context creation: %s\n", openssl_err_as_string()); traceEvent(TRACE_ERROR, "openssl's evp_* decryption context creation: %s\n", openssl_err_as_string());
return(-1); return(-1);
} }
#endif
/* Setup the cipher and key */ /* Setup the cipher and key */
return(setup_aes_key(priv, encrypt_key, encrypt_key_len)); return(setup_aes_key(priv, encrypt_key, encrypt_key_len));

Loading…
Cancel
Save