Browse Source

Added comparibility with OpenSSL 1.0

pull/232/head
Luca Deri 4 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..."
autoreconf -if
echo ""
echo "Now run ./configure"
./configure

10
configure.seed

@ -23,13 +23,17 @@ else
N2N_LIBS=-lcrypto
fi
OLD_CFLAGS="${CFLAGS}"
OLD_LDFLAGS="${LDFLAGS}"
CFLAGS="${CFLAGS} -I/usr/local/opt/openssl@1.1/include"
LDFLAGS="${LDFLAGS} -L/usr/local/opt/openssl@1.1/lib/"
AC_CHECK_LIB([crypto], [EVP_CIPHER_CTX_reset])
if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_reset" != xyes; then
echo ""
echo "You do not seem to use OpenSSL 1.1 or better. Please upgrade"
echo ""
CFLAGS="${OLD_CFLAGS}"
LDFLAGS="${OLD_LDFLAGS}"
else
AC_DEFINE([HAVE_OPENSSL_1_1], [], [OpenSSL 1.1 is present])
fi
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 struct transop_aes {
#ifdef OPENSSL_1_1
EVP_CIPHER_CTX *enc_ctx; /* openssl's reusable evp_* encryption 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 */
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 */
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;
/* ****************************************************** */
static int transop_deinit_aes(n2n_trans_op_t *arg) {
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->dec_ctx);
#endif
if(priv)
free(priv);
@ -63,6 +72,9 @@ static int transop_deinit_aes(n2n_trans_op_t *arg) {
return 0;
}
/* ****************************************************** */
#ifdef OPENSSL_1_1
/* get any erorr message out of openssl
taken from https://en.wikibooks.org/wiki/OpenSSL/Error_handling */
char *openssl_err_as_string (void) {
@ -76,6 +88,9 @@ char *openssl_err_as_string (void) {
BIO_free (bio);
return ret;
}
#endif
/* ****************************************************** */
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];
@ -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);
}
/* ****************************************************** */
/** The aes packet format consists of:
*
* - 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,
const uint8_t * inbuf,
size_t in_len,
const uint8_t * peer_mac)
{
const uint8_t * peer_mac) {
int len2=-1;
transop_aes_t * priv = (transop_aes_t *)arg->priv;
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);
#ifdef OPENSSL_1_1
EVP_CIPHER_CTX *ctx = priv->enc_ctx;
int evp_len;
int evp_ciphertext_len;
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_EncryptUpdate(ctx, outbuf + TRANSOP_AES_PREAMBLE_SIZE, &evp_len, assembly, len2)) {
evp_ciphertext_len = evp_len;
if(1 == EVP_EncryptFinal_ex(ctx, outbuf + TRANSOP_AES_PREAMBLE_SIZE + evp_len, &evp_len)) {
evp_ciphertext_len += evp_len;
if(evp_ciphertext_len != len2)
traceEvent(TRACE_ERROR, "encode_aes openssl encryption: encrypted %u bytes where %u were expected.\n",
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());
} else
traceEvent(TRACE_ERROR, "encode_aes openssl init: %s\n", openssl_err_as_string());
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. */
} else
@ -181,6 +207,8 @@ static int transop_encode_aes( n2n_trans_op_t * arg,
return len2;
}
/* ****************************************************** */
/* See transop_encode_aes for packet format */
static int transop_decode_aes( n2n_trans_op_t * arg,
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);
#ifdef OPENSSL_1_1
EVP_CIPHER_CTX *ctx = priv->dec_ctx;
int evp_len;
int evp_plaintext_len;
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_DecryptUpdate(ctx, assembly, &evp_len, inbuf + TRANSOP_AES_PREAMBLE_SIZE, len)) {
evp_plaintext_len = evp_len;
if(1 == EVP_DecryptFinal_ex(ctx, assembly + evp_len, &evp_len)) {
evp_plaintext_len += evp_len;
if(evp_plaintext_len != len)
traceEvent(TRACE_ERROR, "decode_aes openssl decryption: decrypted %u bytes where %u were expected.\n",
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());
} else
traceEvent(TRACE_ERROR, "decode_aes openssl padding setup: %s\n", openssl_err_as_string());
} else
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
* AES_BLOCKSIZE-1 */
padding = assembly[ len-1 ] & 0xff;
if ( len >= padding)
{
if(len >= padding) {
/* strictly speaking for this to be an ethernet packet
* it is going to need to be even bigger; but this is
* enough to prevent segfaults. */
@ -269,6 +307,8 @@ static int transop_decode_aes( n2n_trans_op_t * arg,
return len;
}
/* ****************************************************** */
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_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;
/* Clear out any old possibly longer key matter. */
#ifdef OPENSSL_1_1
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_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
*/
if (key_size >= 65)
{
if(key_size >= 65) {
#ifdef OPENSSL_1_1
priv->cipher = EVP_aes_256_cbc();
#endif
aes_key_size_bytes = AES256_KEY_BYTES;
SHA512(key, key_size, key_mat_buf);
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();
#endif
aes_key_size_bytes = AES192_KEY_BYTES;
SHA384(key, key_size, key_mat_buf);
/* 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);
key_mat_buf_length = SHA384_DIGEST_LENGTH + SHA256_DIGEST_LENGTH;
}
else
{
} else {
#ifdef OPENSSL_1_1
priv->cipher = EVP_aes_128_cbc();
#endif
aes_key_size_bytes = AES128_KEY_BYTES;
SHA256(key, key_size, key_mat_buf);
/* 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? */
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 */
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);
@ -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 */
aes_key_size_bits = 8 * aes_key_size_bytes;
#ifdef OPENSSL_1_1
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 */
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);
}
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 */
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;
#ifdef OPENSSL_1_1
/* Setup openssl's reusable evp_* contexts for encryption and decryption*/
if(!(priv->enc_ctx = EVP_CIPHER_CTX_new())) {
traceEvent(TRACE_ERROR, "openssl's evp_* encryption context creation: %s\n", openssl_err_as_string());
return(-1);
}
if(!(priv->dec_ctx = EVP_CIPHER_CTX_new())) {
traceEvent(TRACE_ERROR, "openssl's evp_* decryption context creation: %s\n", openssl_err_as_string());
return(-1);
}
#endif
/* Setup the cipher and key */
return(setup_aes_key(priv, encrypt_key, encrypt_key_len));

Loading…
Cancel
Save