Port to libsodium, switch to AES256-GCM, revamp authentication
This commit is contained in:
parent
9aac84a0ce
commit
ed49289d7b
91
auth.c
91
auth.c
@ -27,6 +27,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -56,67 +57,45 @@
|
||||
#include "auth.h"
|
||||
|
||||
/* Encryption and Decryption of the challenge key */
|
||||
#ifdef HAVE_SSL
|
||||
#include <sodium.h>
|
||||
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/blowfish.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
static void gen_chal(char *buf)
|
||||
static int derive_key(struct vtun_host *host)
|
||||
{
|
||||
RAND_bytes(buf, VTUN_CHAL_SIZE);
|
||||
unsigned char salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
|
||||
int ret = -1;
|
||||
|
||||
if (host->key != NULL) {
|
||||
return 0;
|
||||
}
|
||||
if ((host->key = sodium_malloc(HOST_KEYBYTES)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memset(salt, 0xd1, sizeof salt);
|
||||
if (crypto_pwhash_scryptsalsa208sha256
|
||||
(host->key, HOST_KEYBYTES, host->passwd, strlen(host->passwd), salt,
|
||||
crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE,
|
||||
crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) == 0) {
|
||||
ret = 0;
|
||||
}
|
||||
sodium_memzero(host->passwd, strlen(host->passwd));
|
||||
free(host->passwd);
|
||||
host->passwd = NULL;
|
||||
vtun_syslog(LOG_DEBUG,"Key ready for host %s.", host->host);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void encrypt_chal(char *chal, char *pwd)
|
||||
static void gen_chal(char *chal)
|
||||
{
|
||||
register int i;
|
||||
BF_KEY key;
|
||||
|
||||
BF_set_key(&key, 16, MD5(pwd,strlen(pwd),NULL));
|
||||
|
||||
for(i=0; i < VTUN_CHAL_SIZE; i += 8 )
|
||||
BF_ecb_encrypt(chal + i, chal + i, &key, BF_ENCRYPT);
|
||||
randombytes_buf((unsigned char *) chal, VTUN_CHAL_SIZE);
|
||||
}
|
||||
|
||||
static void decrypt_chal(char *chal, char *pwd)
|
||||
static void auth_chal(char *chal, const struct vtun_host *host)
|
||||
{
|
||||
register int i;
|
||||
BF_KEY key;
|
||||
|
||||
BF_set_key(&key, 16, MD5(pwd,strlen(pwd),NULL));
|
||||
|
||||
for(i=0; i < VTUN_CHAL_SIZE; i += 8 )
|
||||
BF_ecb_encrypt(chal + i, chal + i, &key, BF_DECRYPT);
|
||||
crypto_generichash(chal, VTUN_CHAL_SIZE, chal, VTUN_CHAL_SIZE,
|
||||
host->key, HOST_KEYBYTES);
|
||||
}
|
||||
|
||||
#else /* HAVE_SSL */
|
||||
|
||||
static void encrypt_chal(char *chal, char *pwd)
|
||||
{
|
||||
char * xor_msk = pwd;
|
||||
register int i, xor_len = strlen(xor_msk);
|
||||
|
||||
for(i=0; i < VTUN_CHAL_SIZE; i++)
|
||||
chal[i] ^= xor_msk[i%xor_len];
|
||||
}
|
||||
|
||||
static void inline decrypt_chal(char *chal, char *pwd)
|
||||
{
|
||||
encrypt_chal(chal, pwd);
|
||||
}
|
||||
|
||||
/* Generate PSEUDO random challenge key. */
|
||||
static void gen_chal(char *buf)
|
||||
{
|
||||
register int i;
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
for(i=0; i < VTUN_CHAL_SIZE; i++)
|
||||
buf[i] = (unsigned int)(255.0 * rand()/RAND_MAX);
|
||||
}
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
/*
|
||||
* Functions to convert binary flags to character string.
|
||||
* string format: <CS64>
|
||||
@ -348,10 +327,10 @@ struct vtun_host * auth_server(int fd)
|
||||
|
||||
if( !(h = find_host(host)) )
|
||||
break;
|
||||
derive_key(h);
|
||||
auth_chal(chal_req, h);
|
||||
|
||||
decrypt_chal(chal_res, h->passwd);
|
||||
|
||||
if( !memcmp(chal_req, chal_res, VTUN_CHAL_SIZE) ){
|
||||
if( !sodium_memcmp(chal_req, chal_res, VTUN_CHAL_SIZE) ){
|
||||
/* Auth successeful. */
|
||||
|
||||
/* Lock host */
|
||||
@ -400,8 +379,8 @@ int auth_client(int fd, struct vtun_host *host)
|
||||
case ST_HOST:
|
||||
if( !strncmp(buf,"OK",2) && cs2cl(buf,chal)){
|
||||
stage = ST_CHAL;
|
||||
|
||||
encrypt_chal(chal,host->passwd);
|
||||
derive_key(host);
|
||||
auth_chal(chal, host);
|
||||
print_p(fd,"CHAL: %s\n", cl2cs(chal));
|
||||
|
||||
continue;
|
||||
|
@ -107,6 +107,7 @@ statement: '\n'
|
||||
memcpy(parse_host, &default_host, sizeof(struct vtun_host));
|
||||
parse_host->host = strdup($1);
|
||||
parse_host->passwd = NULL;
|
||||
parse_host->key = NULL;
|
||||
parse_host->sopt.host = strdup($1);
|
||||
|
||||
/* Copy local address */
|
||||
|
13
cfg_kwords.h
13
cfg_kwords.h
@ -86,17 +86,6 @@ struct kword cfg_param[] = {
|
||||
{ "inetd", VTUN_INETD },
|
||||
{ "stand", VTUN_STAND_ALONE },
|
||||
{ "keep", VTUN_PERSIST_KEEPIF },
|
||||
{ "blowfish128cbc", VTUN_ENC_BF128CBC },
|
||||
{ "blowfish128cfb", VTUN_ENC_BF128CFB },
|
||||
{ "blowfish128ofb", VTUN_ENC_BF128OFB },
|
||||
{ "blowfish256cbc", VTUN_ENC_BF256CBC },
|
||||
{ "blowfish256cfb", VTUN_ENC_BF256CFB },
|
||||
{ "blowfish256ofb", VTUN_ENC_BF256OFB },
|
||||
{ "aes128cbc", VTUN_ENC_AES128CBC },
|
||||
{ "aes128cfb", VTUN_ENC_AES128CFB },
|
||||
{ "aes128ofb", VTUN_ENC_AES128OFB },
|
||||
{ "aes256cbc", VTUN_ENC_AES256CBC },
|
||||
{ "aes256cfb", VTUN_ENC_AES256CFB },
|
||||
{ "aes256ofb", VTUN_ENC_AES256OFB },
|
||||
{ "aes256gcm",VTUN_ENC_AES256GCM },
|
||||
{ NULL , 0 }
|
||||
};
|
||||
|
78
configure.ac
78
configure.ac
@ -17,10 +17,10 @@ AC_ARG_ENABLE(shaper,
|
||||
SHAPER=yes
|
||||
)
|
||||
dnl Encryption support
|
||||
AC_ARG_ENABLE(ssl,
|
||||
--disable-ssl Don not compile encryption module,
|
||||
SSL=$enableval,
|
||||
SSL=yes
|
||||
AC_ARG_ENABLE(sodium,
|
||||
--disable-sodium Don not compile encryption module,
|
||||
SODIUM=$enableval,
|
||||
SODIUM=yes
|
||||
)
|
||||
dnl ZLIB support
|
||||
AC_ARG_ENABLE(zlib,
|
||||
@ -48,13 +48,13 @@ AC_ARG_ENABLE(nathack,
|
||||
NATHACK=yes
|
||||
)
|
||||
|
||||
AC_ARG_WITH(ssl-headers,
|
||||
--with-ssl-headers=DIR Crypto Include files location,
|
||||
SSL_HDR_DIR="$withval"
|
||||
AC_ARG_WITH(sodium-headers,
|
||||
--with-sodium-headers=DIR Crypto Include files location,
|
||||
SODIUM_HDR_DIR="$withval"
|
||||
CPPFLAGS="$CPPFLAGS -I$withval"
|
||||
)
|
||||
AC_ARG_WITH(ssl-lib,
|
||||
--with-ssl-lib=DIR Crypto Library location,
|
||||
AC_ARG_WITH(sodium-lib,
|
||||
--with-sodium-lib=DIR Crypto Library location,
|
||||
LIBS="$LIBS -L$withval"
|
||||
)
|
||||
|
||||
@ -165,60 +165,16 @@ if test "$LZO" = "yes"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$SSL" = "yes"; then
|
||||
if test "$SODIUM" = "yes"; then
|
||||
AC_MSG_RESULT()
|
||||
AC_CHECKING( for md5 Library and Header files ... )
|
||||
AC_SEARCH_HEADERS(md5.h,
|
||||
$SSL_HDR_DIR /usr/include/openssl "" /usr/include /usr/include/ssl /usr/local/include /usr/local/ssl/include /usr/include/sys,
|
||||
AC_CHECKING( for Sodium Library and Header files ... )
|
||||
AC_SEARCH_LIBS(crypto_aead_aes256gcm_aesni_encrypt, [sodium],
|
||||
[AC_DEFINE(HAVE_SODIUM, [1], [Define to 1 if you have Sodium])],
|
||||
AC_ERROR([libsodium with crypto_aead_aes256gcm_aesni_encrypt not found]))
|
||||
AC_SEARCH_HEADERS(sodium.h,
|
||||
$SSL_HDR_DIR /usr/include /usr/local/include /opt/include,
|
||||
,
|
||||
AC_MSG_ERROR( SSL headers not found. )
|
||||
)
|
||||
fi
|
||||
|
||||
if test "$SSL" = "yes"; then
|
||||
AC_MSG_RESULT()
|
||||
AC_CHECKING( for blowfish Library and Header files ... )
|
||||
AC_SEARCH_HEADERS(blowfish.h,
|
||||
$BLOWFISH_HDR_DIR /usr/include/ssl /usr/include/openssl /usr/include /usr/local/include /usr/local/ssl/include /usr/include/crypto,
|
||||
AC_CHECK_LIB(crypto, BF_set_key,
|
||||
[
|
||||
LIBS="$LIBS -lcrypto"
|
||||
AC_DEFINE(HAVE_SSL, [1], [Define to 1 if you have openssl])
|
||||
AC_DEFINE(HAVE_SSL_BLOWFISH, [1], [Define to 1 if you have blowfish in openssl])
|
||||
],
|
||||
AC_MSG_ERROR( SSL library not found. )
|
||||
),
|
||||
AC_MSG_ERROR( SSL headers not found. )
|
||||
)
|
||||
fi
|
||||
|
||||
if test "$SSL" = "yes"; then
|
||||
AC_MSG_RESULT()
|
||||
AC_CHECKING( for AES Library and Header files ... )
|
||||
AC_SEARCH_HEADERS(aes.h,
|
||||
$SSL_HDR_DIR /usr/include/ssl /usr/include/openssl /usr/include /usr/local/include /usr/local/ssl/include /usr/include/crypto,
|
||||
AC_CHECK_LIB(crypto, AES_set_encrypt_key,
|
||||
[
|
||||
AC_DEFINE(HAVE_SSL_AES, [1], [Define to 1 if you have AES in openssl])
|
||||
],
|
||||
AC_MSG_ERROR( AES library not found. )
|
||||
),
|
||||
AC_MSG_ERROR( AES headers not found. )
|
||||
)
|
||||
fi
|
||||
|
||||
if test "$SSL" = "yes"; then
|
||||
AC_MSG_RESULT()
|
||||
AC_CHECKING( for EVP Library and Header files ... )
|
||||
AC_SEARCH_HEADERS(evp.h,
|
||||
$SSL_HDR_DIR /usr/include/ssl /usr/include/openssl /usr/include /usr/local/include /usr/local/ssl/include /usr/include/crypto,
|
||||
AC_CHECK_LIB(crypto, EVP_EncryptInit,
|
||||
[
|
||||
AC_DEFINE(HAVE_SSL_EVP, [1], [Define to 1 if you have EVP in openssl])
|
||||
],
|
||||
AC_MSG_ERROR( EVP library not found. )
|
||||
),
|
||||
AC_MSG_ERROR( EVP headers not found. )
|
||||
AC_MSG_ERROR( Sodium headers not found. )
|
||||
)
|
||||
fi
|
||||
|
||||
|
796
lfd_encrypt.c
796
lfd_encrypt.c
@ -1,707 +1,172 @@
|
||||
/*
|
||||
VTun - Virtual Tunnel over TCP/IP network.
|
||||
|
||||
Copyright (C) 1998-2008 Maxim Krasnyansky <max_mk@yahoo.com>
|
||||
|
||||
VTun has been derived from VPPP package by Maxim Krasnyansky.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
Encryption module uses software developed by the OpenSSL Project
|
||||
for use in the OpenSSL Toolkit. (http://www.openssl.org/)
|
||||
Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This lfd_encrypt module uses MD5 to create 128 bits encryption
|
||||
* keys and BlowFish for actual data encryption.
|
||||
* It is based on code written by Chris Todd<christ@insynq.com> with
|
||||
* several improvements and modifications by me.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The current lfd_encrypt module is based on code attributed above and
|
||||
* uses new code written by Dale Fountain <dpf-vtun@fountainbay.com> to
|
||||
* allow multiple ciphers, modes, and key sizes. Feb 2004.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "vtun.h"
|
||||
#include "linkfd.h"
|
||||
#include "lib.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_SODIUM
|
||||
#include <sodium.h>
|
||||
|
||||
/* OpenSSL includes */
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/blowfish.h>
|
||||
#include <openssl/rand.h>
|
||||
#define crypto_aead_NPUBBYTES crypto_aead_aes256gcm_NPUBBYTES
|
||||
#define crypto_aead_ABYTES crypto_aead_aes256gcm_ABYTES
|
||||
#define crypto_aead_KEYBYTES crypto_aead_aes256gcm_KEYBYTES
|
||||
|
||||
/*
|
||||
* #define LFD_ENCRYPT_DEBUG
|
||||
*/
|
||||
#define MESSAGE_MAX_SIZE VTUN_FRAME_SIZE
|
||||
#define CIPHERTEXT_ABYTES (crypto_aead_ABYTES + crypto_aead_NPUBBYTES)
|
||||
#define CIPHERTEXT_MAX_SIZE MESSAGE_MAX_SIZE
|
||||
#define CIPHERTEXT_MAX_TOTAL_SIZE (CIPHERTEXT_MAX_SIZE + CIPHERTEXT_ABYTES)
|
||||
|
||||
#define ENC_BUF_SIZE VTUN_FRAME_SIZE + 128
|
||||
#define ENC_KEY_SIZE 16
|
||||
#define MINIMUM_DATE 1444341043UL
|
||||
#define SLEEP_WHEN_CLOCK_IS_OFF 10
|
||||
|
||||
static BF_KEY key;
|
||||
static char * enc_buf;
|
||||
static char * dec_buf;
|
||||
typedef struct CryptoCtx {
|
||||
crypto_aead_aes256gcm_aesni_state *state;
|
||||
unsigned char *ciphertext;
|
||||
unsigned char *key;
|
||||
unsigned char *message;
|
||||
unsigned char *nonce;
|
||||
unsigned char *previous_decrypted_nonce;
|
||||
} CryptoCtx;
|
||||
|
||||
#define CIPHER_INIT 0
|
||||
#define CIPHER_CODE 1
|
||||
#define CIPHER_SEQUENCE 2
|
||||
#define CIPHER_REQ_INIT 3
|
||||
static CryptoCtx ctx;
|
||||
|
||||
static struct vtun_host *phost;
|
||||
|
||||
extern int send_a_packet;
|
||||
|
||||
/* out of sync packet threshold before forcing a re-init */
|
||||
#define MAX_GIBBERISH 10
|
||||
#define MIN_GIBBERISH 1
|
||||
#define MAX_GIBBERISH_TIME 2
|
||||
static int gibberish;
|
||||
static time_t gib_time_start;
|
||||
|
||||
static int cipher_enc_state;
|
||||
static int cipher_dec_state;
|
||||
static int cipher;
|
||||
static int blocksize;
|
||||
static int keysize;
|
||||
static int enc_init_first_time;
|
||||
static int dec_init_first_time;
|
||||
static unsigned long sequence_num;
|
||||
static char * pkey;
|
||||
static char * iv_buf;
|
||||
|
||||
static EVP_CIPHER_CTX ctx_enc; /* encrypt */
|
||||
static EVP_CIPHER_CTX ctx_dec; /* decrypt */
|
||||
|
||||
static EVP_CIPHER_CTX ctx_enc_ecb; /* sideband ecb encrypt */
|
||||
static EVP_CIPHER_CTX ctx_dec_ecb; /* sideband ecb decrypt */
|
||||
|
||||
static int send_msg(int len, char *in, char **out);
|
||||
static int recv_msg(int len, char *in, char **out);
|
||||
static int send_ib_mesg(int *len, char **in);
|
||||
static int recv_ib_mesg(int *len, char **in);
|
||||
|
||||
static int prep_key(char **key, int size, struct vtun_host *host)
|
||||
static int
|
||||
derive_key(unsigned char *key, size_t key_size, struct vtun_host *host)
|
||||
{
|
||||
int tmplen, halflen;
|
||||
char *hashkey;
|
||||
|
||||
if ( !(hashkey = malloc(size)) )
|
||||
{
|
||||
vtun_syslog(LOG_ERR,"Can't allocate buffer for key hash");
|
||||
return -1;
|
||||
}
|
||||
memset(hashkey,0,size);
|
||||
|
||||
if (size == 32)
|
||||
{
|
||||
tmplen = strlen(host->passwd);
|
||||
if (tmplen != 0) halflen = tmplen>>1;
|
||||
else halflen = 0;
|
||||
MD5(host->passwd, halflen, hashkey);
|
||||
MD5((host->passwd)+halflen, tmplen-halflen, hashkey+16);
|
||||
}
|
||||
else if (size == 16)
|
||||
{
|
||||
MD5(host->passwd,strlen(host->passwd), hashkey);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* don't know what to do */
|
||||
free(hashkey);
|
||||
*key = NULL;
|
||||
return -1;
|
||||
}
|
||||
*key = hashkey;
|
||||
return 0;
|
||||
crypto_generichash(key, key_size, host->key, HOST_KEYBYTES, NULL, 0U);
|
||||
sodium_free(host->key);
|
||||
host->key = NULL;
|
||||
}
|
||||
|
||||
static void free_key (char *key)
|
||||
static int
|
||||
init_nonce(unsigned char *nonce, size_t nonce_size)
|
||||
{
|
||||
free(key);
|
||||
time_t now;
|
||||
|
||||
if (nonce_size < 5) {
|
||||
return -1;
|
||||
}
|
||||
time(&now);
|
||||
if (now < MINIMUM_DATE) {
|
||||
sleep(SLEEP_WHEN_CLOCK_IS_OFF);
|
||||
randombytes_buf(nonce, nonce_size);
|
||||
} else {
|
||||
randombytes_buf(nonce + 4, nonce_size - 4);
|
||||
now <<= 2;
|
||||
memcpy(nonce, &now, 3);
|
||||
nonce[3] = (nonce[3] & 0x3) ^ *(((unsigned char *) &now) + 3);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alloc_encrypt(struct vtun_host *host)
|
||||
static int
|
||||
alloc_encrypt(struct vtun_host *host)
|
||||
{
|
||||
int sb_init = 0;
|
||||
int var_key = 0;
|
||||
const EVP_CIPHER *cipher_type;
|
||||
char tmpstr[64];
|
||||
char cipher_name[32];
|
||||
EVP_CIPHER_CTX *pctx_enc;
|
||||
EVP_CIPHER_CTX *pctx_dec;
|
||||
|
||||
enc_init_first_time = 1;
|
||||
dec_init_first_time = 1;
|
||||
|
||||
if( !(enc_buf = lfd_alloc(ENC_BUF_SIZE)) ){
|
||||
vtun_syslog(LOG_ERR,"Can't allocate buffer for encryptor");
|
||||
return -1;
|
||||
}
|
||||
if( !(dec_buf = lfd_alloc(ENC_BUF_SIZE)) ){
|
||||
vtun_syslog(LOG_ERR,"Can't allocate buffer for decryptor");
|
||||
return -1;
|
||||
}
|
||||
|
||||
RAND_bytes((char *)&sequence_num, 4);
|
||||
gibberish = 0;
|
||||
gib_time_start = 0;
|
||||
phost = host;
|
||||
cipher = host->cipher;
|
||||
switch(cipher)
|
||||
{
|
||||
case VTUN_ENC_AES128OFB:
|
||||
case VTUN_ENC_AES128CFB:
|
||||
case VTUN_ENC_AES128CBC:
|
||||
blocksize = 16;
|
||||
keysize = 16;
|
||||
sb_init=1;
|
||||
cipher_type = EVP_aes_128_ecb();
|
||||
pctx_enc = &ctx_enc_ecb;
|
||||
pctx_dec = &ctx_dec_ecb;
|
||||
break;
|
||||
|
||||
case VTUN_ENC_BF256OFB:
|
||||
case VTUN_ENC_BF256CFB:
|
||||
case VTUN_ENC_BF256CBC:
|
||||
blocksize = 8;
|
||||
keysize = 32;
|
||||
var_key = 1;
|
||||
sb_init = 1;
|
||||
cipher_type = EVP_bf_ecb();
|
||||
pctx_enc = &ctx_enc_ecb;
|
||||
pctx_dec = &ctx_dec_ecb;
|
||||
break;
|
||||
|
||||
case VTUN_ENC_BF128OFB:
|
||||
case VTUN_ENC_BF128CFB:
|
||||
case VTUN_ENC_BF128CBC:
|
||||
blocksize = 8;
|
||||
keysize = 16;
|
||||
var_key = 1;
|
||||
sb_init = 1;
|
||||
cipher_type = EVP_bf_ecb();
|
||||
pctx_enc = &ctx_enc_ecb;
|
||||
pctx_dec = &ctx_dec_ecb;
|
||||
break;
|
||||
case VTUN_ENC_AES256OFB:
|
||||
case VTUN_ENC_AES256CFB:
|
||||
case VTUN_ENC_AES256CBC:
|
||||
default:
|
||||
blocksize = 16;
|
||||
keysize = 32;
|
||||
sb_init = 1;
|
||||
cipher_type = EVP_aes_256_ecb();
|
||||
pctx_enc = &ctx_enc_ecb;
|
||||
pctx_dec = &ctx_dec_ecb;
|
||||
strcpy(cipher_name,"AES-256-CBC");
|
||||
} /* switch(host->cipher) */
|
||||
|
||||
if (prep_key(&pkey, keysize, host) != 0) return -1;
|
||||
EVP_CIPHER_CTX_init(pctx_enc);
|
||||
EVP_CIPHER_CTX_init(pctx_dec);
|
||||
EVP_EncryptInit_ex(pctx_enc, cipher_type, NULL, NULL, NULL);
|
||||
EVP_DecryptInit_ex(pctx_dec, cipher_type, NULL, NULL, NULL);
|
||||
if (var_key)
|
||||
{
|
||||
EVP_CIPHER_CTX_set_key_length(pctx_enc, keysize);
|
||||
EVP_CIPHER_CTX_set_key_length(pctx_dec, keysize);
|
||||
}
|
||||
EVP_EncryptInit_ex(pctx_enc, NULL, NULL, pkey, NULL);
|
||||
EVP_DecryptInit_ex(pctx_dec, NULL, NULL, pkey, NULL);
|
||||
EVP_CIPHER_CTX_set_padding(pctx_enc, 0);
|
||||
EVP_CIPHER_CTX_set_padding(pctx_dec, 0);
|
||||
if (sb_init)
|
||||
{
|
||||
cipher_enc_state=CIPHER_INIT;
|
||||
cipher_dec_state=CIPHER_INIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
cipher_enc_state=CIPHER_CODE;
|
||||
cipher_dec_state=CIPHER_CODE;
|
||||
sprintf(tmpstr,"%s encryption initialized", cipher_name);
|
||||
vtun_syslog(LOG_INFO, tmpstr);
|
||||
}
|
||||
return 0;
|
||||
if (sodium_init() < 0) {
|
||||
return -1;
|
||||
}
|
||||
ctx.state = sodium_malloc(sizeof *ctx.state);
|
||||
ctx.key = sodium_malloc(crypto_aead_KEYBYTES);
|
||||
ctx.message = sodium_malloc(MESSAGE_MAX_SIZE);
|
||||
ctx.ciphertext = sodium_malloc(CIPHERTEXT_MAX_TOTAL_SIZE);
|
||||
ctx.nonce = sodium_malloc(crypto_aead_NPUBBYTES);
|
||||
ctx.previous_decrypted_nonce = sodium_malloc(crypto_aead_NPUBBYTES);
|
||||
if (ctx.state == NULL || ctx.key == NULL || ctx.message == NULL ||
|
||||
ctx.ciphertext == NULL || ctx.ciphertext == NULL || ctx.nonce == NULL ||
|
||||
ctx.previous_decrypted_nonce == NULL) {
|
||||
abort();
|
||||
}
|
||||
if (init_nonce(ctx.nonce, crypto_aead_NPUBBYTES) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (derive_key(ctx.key, crypto_aead_KEYBYTES, host) != 0) {
|
||||
return -1;
|
||||
}
|
||||
crypto_aead_aes256gcm_aesni_beforenm(ctx.state, ctx.key);
|
||||
sodium_free(ctx.key);
|
||||
ctx.key = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int free_encrypt()
|
||||
static int
|
||||
free_encrypt(void)
|
||||
{
|
||||
free_key(pkey); pkey = NULL;
|
||||
sodium_free(ctx.key);
|
||||
sodium_free(ctx.message);
|
||||
sodium_free(ctx.ciphertext);
|
||||
sodium_free(ctx.nonce);
|
||||
sodium_free(ctx.previous_decrypted_nonce);
|
||||
|
||||
lfd_free(enc_buf); enc_buf = NULL;
|
||||
lfd_free(dec_buf); dec_buf = NULL;
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&ctx_enc);
|
||||
EVP_CIPHER_CTX_cleanup(&ctx_dec);
|
||||
EVP_CIPHER_CTX_cleanup(&ctx_enc_ecb);
|
||||
EVP_CIPHER_CTX_cleanup(&ctx_dec_ecb);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encrypt_buf(int len, char *in, char **out)
|
||||
static int
|
||||
is_lower_or_equal(const unsigned char *a, const unsigned char *b, size_t size)
|
||||
{
|
||||
register int pad, p, msg_len;
|
||||
int outlen;
|
||||
char *in_ptr, *out_ptr = enc_buf;
|
||||
size_t i;
|
||||
|
||||
msg_len = send_msg(len, in, out);
|
||||
in = *out;
|
||||
in_ptr = in+msg_len;
|
||||
memcpy(out_ptr,in,msg_len);
|
||||
out_ptr += msg_len;
|
||||
|
||||
send_ib_mesg(&len, &in_ptr);
|
||||
if (!len) return 0;
|
||||
/* ( len % blocksize ) */
|
||||
p = (len & (blocksize-1)); pad = blocksize - p;
|
||||
|
||||
memset(in_ptr+len, pad, pad);
|
||||
outlen=len+pad;
|
||||
if (pad == blocksize)
|
||||
RAND_bytes(in_ptr+len, blocksize-1);
|
||||
EVP_EncryptUpdate(&ctx_enc, out_ptr, &outlen, in_ptr, len+pad);
|
||||
*out = enc_buf;
|
||||
|
||||
sequence_num++;
|
||||
|
||||
return outlen+msg_len;
|
||||
for (i = 0U; i < size; i++) {
|
||||
if (a[i] > b[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int decrypt_buf(int len, char *in, char **out)
|
||||
static int
|
||||
encrypt_buf(int message_len_, char *message_, char ** const ciphertext_p)
|
||||
{
|
||||
register int pad;
|
||||
char *tmp_ptr, *in_ptr, *out_ptr = dec_buf;
|
||||
int outlen;
|
||||
const unsigned char *message = (const unsigned char *) message_;
|
||||
const size_t message_len = (size_t) message_len_;
|
||||
unsigned long long ciphertext_len;
|
||||
|
||||
len = recv_msg(len, in, out);
|
||||
in = *out;
|
||||
in_ptr = in;
|
||||
if (message_len_ < 0 || message_len > MESSAGE_MAX_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
crypto_aead_aes256gcm_aesni_encrypt_afternm(ctx.ciphertext, &ciphertext_len,
|
||||
message, message_len,
|
||||
NULL, 0ULL,
|
||||
NULL, ctx.nonce, ctx.state);
|
||||
memcpy(ctx.ciphertext + message_len + crypto_aead_ABYTES,
|
||||
ctx.nonce, crypto_aead_NPUBBYTES);
|
||||
sodium_increment(ctx.nonce, crypto_aead_NPUBBYTES);
|
||||
*ciphertext_p = ctx.ciphertext;
|
||||
|
||||
outlen=len;
|
||||
if (!len) return 0;
|
||||
EVP_DecryptUpdate(&ctx_dec, out_ptr, &outlen, in_ptr, len);
|
||||
recv_ib_mesg(&outlen, &out_ptr);
|
||||
if (!outlen) return 0;
|
||||
tmp_ptr = out_ptr + outlen; tmp_ptr--;
|
||||
pad = *tmp_ptr;
|
||||
if (pad < 1 || pad > blocksize) {
|
||||
vtun_syslog(LOG_INFO, "decrypt_buf: bad pad length");
|
||||
return 0;
|
||||
}
|
||||
*out = out_ptr;
|
||||
return outlen - pad;
|
||||
return (int) ciphertext_len + crypto_aead_NPUBBYTES;
|
||||
}
|
||||
|
||||
static int cipher_enc_init(char * iv)
|
||||
static int
|
||||
decrypt_buf(int ciphertext_len_, char *ciphertext_, char ** const message_p)
|
||||
{
|
||||
int var_key = 0;
|
||||
const EVP_CIPHER *cipher_type;
|
||||
char tmpstr[64];
|
||||
char cipher_name[32];
|
||||
const unsigned char *ciphertext = (const unsigned char *) ciphertext_;
|
||||
const unsigned char *nonce;
|
||||
size_t ciphertext_len = (size_t) ciphertext_len_;
|
||||
unsigned long long message_len;
|
||||
|
||||
switch(cipher)
|
||||
{
|
||||
case VTUN_ENC_AES256OFB:
|
||||
cipher_type = EVP_aes_256_ofb();
|
||||
strcpy(cipher_name, "AES-256-OFB");
|
||||
break;
|
||||
if (ciphertext_len_ < CIPHERTEXT_ABYTES ||
|
||||
ciphertext_len > CIPHERTEXT_MAX_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
ciphertext_len -= crypto_aead_NPUBBYTES;
|
||||
nonce = ciphertext + ciphertext_len;
|
||||
if (is_lower_or_equal(nonce, ctx.previous_decrypted_nonce, crypto_aead_NPUBBYTES) ||
|
||||
crypto_aead_aes256gcm_aesni_decrypt_afternm(ctx.message, &message_len, NULL,
|
||||
ciphertext, ciphertext_len,
|
||||
NULL, 0ULL, nonce, ctx.state) != 0) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(ctx.previous_decrypted_nonce, nonce, crypto_aead_NPUBBYTES);
|
||||
*message_p = ctx.message;
|
||||
|
||||
case VTUN_ENC_AES256CFB:
|
||||
cipher_type = EVP_aes_256_cfb();
|
||||
strcpy(cipher_name, "AES-256-CFB");
|
||||
break;
|
||||
|
||||
case VTUN_ENC_AES256CBC:
|
||||
cipher_type = EVP_aes_256_cbc();
|
||||
strcpy(cipher_name, "AES-256-CBC");
|
||||
break;
|
||||
|
||||
case VTUN_ENC_AES128OFB:
|
||||
cipher_type = EVP_aes_128_ofb();
|
||||
strcpy(cipher_name, "AES-128-OFB");
|
||||
break;
|
||||
case VTUN_ENC_AES128CFB:
|
||||
cipher_type = EVP_aes_128_cfb();
|
||||
strcpy(cipher_name, "AES-128-CFB");
|
||||
break;
|
||||
case VTUN_ENC_AES128CBC:
|
||||
cipher_type = EVP_aes_128_cbc();
|
||||
strcpy(cipher_name, "AES-128-CBC");
|
||||
break;
|
||||
|
||||
case VTUN_ENC_BF256OFB:
|
||||
var_key = 1;
|
||||
cipher_type = EVP_bf_ofb();
|
||||
strcpy(cipher_name, "Blowfish-256-OFB");
|
||||
break;
|
||||
case VTUN_ENC_BF256CFB:
|
||||
var_key = 1;
|
||||
cipher_type = EVP_bf_cfb();
|
||||
strcpy(cipher_name, "Blowfish-256-CFB");
|
||||
break;
|
||||
|
||||
case VTUN_ENC_BF256CBC:
|
||||
var_key = 1;
|
||||
cipher_type = EVP_bf_cbc();
|
||||
strcpy(cipher_name, "Blowfish-256-CBC");
|
||||
break;
|
||||
|
||||
case VTUN_ENC_BF128OFB:
|
||||
var_key = 1;
|
||||
cipher_type = EVP_bf_ofb();
|
||||
strcpy(cipher_name, "Blowfish-128-OFB");
|
||||
break;
|
||||
case VTUN_ENC_BF128CFB:
|
||||
var_key = 1;
|
||||
cipher_type = EVP_bf_cfb();
|
||||
strcpy(cipher_name, "Blowfish-128-CFB");
|
||||
break;
|
||||
case VTUN_ENC_BF128CBC:
|
||||
var_key = 1;
|
||||
cipher_type = EVP_bf_cbc();
|
||||
strcpy(cipher_name, "Blowfish-128-CBC");
|
||||
break;
|
||||
default:
|
||||
/* if we're here, something weird's going on */
|
||||
return -1;
|
||||
break;
|
||||
} /* switch(cipher) */
|
||||
|
||||
EVP_CIPHER_CTX_init(&ctx_enc);
|
||||
EVP_EncryptInit_ex(&ctx_enc, cipher_type, NULL, NULL, NULL);
|
||||
if (var_key)
|
||||
EVP_CIPHER_CTX_set_key_length(&ctx_enc, keysize);
|
||||
EVP_EncryptInit_ex(&ctx_enc, NULL, NULL, pkey, NULL);
|
||||
EVP_EncryptInit_ex(&ctx_enc, NULL, NULL, NULL, iv);
|
||||
EVP_CIPHER_CTX_set_padding(&ctx_enc, 0);
|
||||
if (enc_init_first_time)
|
||||
{
|
||||
sprintf(tmpstr,"%s encryption initialized", cipher_name);
|
||||
vtun_syslog(LOG_INFO, tmpstr);
|
||||
enc_init_first_time = 0;
|
||||
}
|
||||
return 0;
|
||||
return (int) message_len;
|
||||
}
|
||||
|
||||
static int cipher_dec_init(char * iv)
|
||||
{
|
||||
int var_key = 0;
|
||||
const EVP_CIPHER *cipher_type;
|
||||
char tmpstr[64];
|
||||
char cipher_name[32];
|
||||
|
||||
switch(cipher)
|
||||
{
|
||||
case VTUN_ENC_AES256OFB:
|
||||
cipher_type = EVP_aes_256_ofb();
|
||||
strcpy(cipher_name, "AES-256-OFB");
|
||||
break;
|
||||
|
||||
case VTUN_ENC_AES256CFB:
|
||||
cipher_type = EVP_aes_256_cfb();
|
||||
strcpy(cipher_name, "AES-256-CFB");
|
||||
break;
|
||||
|
||||
case VTUN_ENC_AES256CBC:
|
||||
cipher_type = EVP_aes_256_cbc();
|
||||
strcpy(cipher_name, "AES-256-CBC");
|
||||
break;
|
||||
|
||||
case VTUN_ENC_AES128OFB:
|
||||
cipher_type = EVP_aes_128_ofb();
|
||||
strcpy(cipher_name, "AES-128-OFB");
|
||||
break;
|
||||
case VTUN_ENC_AES128CFB:
|
||||
cipher_type = EVP_aes_128_cfb();
|
||||
strcpy(cipher_name, "AES-128-CFB");
|
||||
break;
|
||||
case VTUN_ENC_AES128CBC:
|
||||
cipher_type = EVP_aes_128_cbc();
|
||||
strcpy(cipher_name, "AES-128-CBC");
|
||||
break;
|
||||
|
||||
case VTUN_ENC_BF256OFB:
|
||||
var_key = 1;
|
||||
cipher_type = EVP_bf_ofb();
|
||||
strcpy(cipher_name, "Blowfish-256-OFB");
|
||||
break;
|
||||
case VTUN_ENC_BF256CFB:
|
||||
var_key = 1;
|
||||
cipher_type = EVP_bf_cfb();
|
||||
strcpy(cipher_name, "Blowfish-256-CFB");
|
||||
break;
|
||||
case VTUN_ENC_BF256CBC:
|
||||
var_key = 1;
|
||||
cipher_type = EVP_bf_cbc();
|
||||
strcpy(cipher_name, "Blowfish-256-CBC");
|
||||
break;
|
||||
|
||||
case VTUN_ENC_BF128OFB:
|
||||
var_key = 1;
|
||||
cipher_type = EVP_bf_ofb();
|
||||
strcpy(cipher_name, "Blowfish-128-OFB");
|
||||
break;
|
||||
case VTUN_ENC_BF128CFB:
|
||||
var_key = 1;
|
||||
cipher_type = EVP_bf_cfb();
|
||||
strcpy(cipher_name, "Blowfish-128-CFB");
|
||||
break;
|
||||
case VTUN_ENC_BF128CBC:
|
||||
var_key = 1;
|
||||
cipher_type = EVP_bf_cbc();
|
||||
strcpy(cipher_name, "Blowfish-128-CBC");
|
||||
break;
|
||||
default:
|
||||
/* if we're here, something weird's going on */
|
||||
return -1;
|
||||
break;
|
||||
} /* switch(cipher) */
|
||||
|
||||
EVP_CIPHER_CTX_init(&ctx_dec);
|
||||
EVP_DecryptInit_ex(&ctx_dec, cipher_type, NULL, NULL, NULL);
|
||||
if (var_key)
|
||||
EVP_CIPHER_CTX_set_key_length(&ctx_dec, keysize);
|
||||
EVP_DecryptInit_ex(&ctx_dec, NULL, NULL, pkey, NULL);
|
||||
EVP_DecryptInit_ex(&ctx_dec, NULL, NULL, NULL, iv);
|
||||
EVP_CIPHER_CTX_set_padding(&ctx_dec, 0);
|
||||
if (dec_init_first_time)
|
||||
{
|
||||
sprintf(tmpstr,"%s decryption initialized", cipher_name);
|
||||
vtun_syslog(LOG_INFO, tmpstr);
|
||||
dec_init_first_time = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int send_msg(int len, char *in, char **out)
|
||||
{
|
||||
char * iv; char * in_ptr;
|
||||
int outlen;
|
||||
|
||||
switch(cipher_enc_state)
|
||||
{
|
||||
case CIPHER_INIT:
|
||||
in_ptr = in - blocksize*2;
|
||||
iv = malloc(blocksize);
|
||||
RAND_bytes(iv, blocksize);
|
||||
strncpy(in_ptr,"ivec",4);
|
||||
in_ptr += 4;
|
||||
memcpy(in_ptr,iv,blocksize);
|
||||
in_ptr += blocksize;
|
||||
cipher_enc_init(iv);
|
||||
|
||||
memset(iv,0,blocksize); free(iv); iv = NULL;
|
||||
RAND_bytes(in_ptr, in - in_ptr);
|
||||
|
||||
in_ptr = in - blocksize*2;
|
||||
outlen = blocksize*2;
|
||||
EVP_EncryptUpdate(&ctx_enc_ecb, in_ptr,
|
||||
&outlen, in_ptr, blocksize*2);
|
||||
*out = in_ptr;
|
||||
len = outlen;
|
||||
cipher_enc_state = CIPHER_SEQUENCE;
|
||||
break;
|
||||
|
||||
case CIPHER_CODE:
|
||||
default:
|
||||
*out = in;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static int recv_msg(int len, char *in, char **out)
|
||||
{
|
||||
char * iv; char * in_ptr;
|
||||
int outlen;
|
||||
|
||||
switch(cipher_dec_state)
|
||||
{
|
||||
case CIPHER_INIT:
|
||||
in_ptr = in;
|
||||
iv = malloc(blocksize);
|
||||
outlen = blocksize*2;
|
||||
EVP_DecryptUpdate(&ctx_dec_ecb, in_ptr, &outlen, in_ptr, blocksize*2);
|
||||
|
||||
if ( !strncmp(in_ptr, "ivec", 4) )
|
||||
{
|
||||
memcpy(iv, in_ptr+4, blocksize);
|
||||
cipher_dec_init(iv);
|
||||
|
||||
*out = in_ptr + blocksize*2;
|
||||
len -= blocksize*2;
|
||||
cipher_dec_state = CIPHER_SEQUENCE;
|
||||
gibberish = 0;
|
||||
gib_time_start = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
*out = in;
|
||||
gibberish++;
|
||||
if (gibberish == 1) gib_time_start = time(NULL);
|
||||
|
||||
if (gibberish == MIN_GIBBERISH)
|
||||
{
|
||||
cipher_enc_state = CIPHER_REQ_INIT;
|
||||
send_a_packet = 1;
|
||||
#ifdef LFD_ENCRYPT_DEBUG
|
||||
vtun_syslog(LOG_INFO,
|
||||
"Min. gibberish threshold reached");
|
||||
#endif
|
||||
}
|
||||
if (gibberish >= MAX_GIBBERISH ||
|
||||
difftime(time(NULL), gib_time_start) >= MAX_GIBBERISH_TIME)
|
||||
{
|
||||
gibberish = 0;
|
||||
gib_time_start = 0;
|
||||
send_a_packet = 1;
|
||||
|
||||
#ifdef LFD_ENCRYPT_DEBUG
|
||||
vtun_syslog(LOG_INFO,
|
||||
"Max. gibberish threshold reached");
|
||||
#endif
|
||||
if (cipher_enc_state != CIPHER_INIT)
|
||||
{
|
||||
cipher_enc_state = CIPHER_INIT;
|
||||
EVP_CIPHER_CTX_cleanup(&ctx_enc);
|
||||
#ifdef LFD_ENCRYPT_DEBUG
|
||||
vtun_syslog(LOG_INFO,
|
||||
"Forcing local encryptor re-init");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
memset(iv,0,blocksize); free(iv); iv = NULL;
|
||||
memset(in_ptr,0,blocksize*2);
|
||||
break;
|
||||
|
||||
case CIPHER_CODE:
|
||||
default:
|
||||
*out = in;
|
||||
break;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Send In-Band Message */
|
||||
static int send_ib_mesg(int *len, char **in)
|
||||
{
|
||||
char *in_ptr = *in;
|
||||
|
||||
/* To simplify matters, I assume that blocksize
|
||||
will not be less than 8 bytes */
|
||||
if (cipher_enc_state == CIPHER_SEQUENCE)
|
||||
{
|
||||
in_ptr -= blocksize;
|
||||
memset(in_ptr,0,blocksize);
|
||||
strncpy(in_ptr,"seq#",4);
|
||||
in_ptr+=4;
|
||||
*((unsigned long *)in_ptr) = htonl(sequence_num);
|
||||
in_ptr-=4;
|
||||
|
||||
*in = in_ptr;
|
||||
*len += blocksize;
|
||||
}
|
||||
else if (cipher_enc_state == CIPHER_REQ_INIT)
|
||||
{
|
||||
in_ptr -= blocksize;
|
||||
memset(in_ptr,0,blocksize);
|
||||
strncpy(in_ptr,"rsyn",4);
|
||||
in_ptr+=4;
|
||||
*((unsigned long *)in_ptr) = htonl(sequence_num);
|
||||
in_ptr-=4;
|
||||
|
||||
*in = in_ptr;
|
||||
*len += blocksize;
|
||||
#ifdef LFD_ENCRYPT_DEBUG
|
||||
vtun_syslog(LOG_INFO, "Requesting remote encryptor re-init");
|
||||
#endif
|
||||
cipher_enc_state = CIPHER_SEQUENCE;
|
||||
send_a_packet = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Receive In-Band Message */
|
||||
static int recv_ib_mesg(int *len, char **in)
|
||||
{
|
||||
char *in_ptr = *in;
|
||||
|
||||
if (cipher_dec_state == CIPHER_SEQUENCE)
|
||||
{
|
||||
/* To simplify matters, I assume that blocksize
|
||||
will not be less than 8 bytes */
|
||||
if ( !strncmp(in_ptr, "seq#", 4) )
|
||||
{
|
||||
*in += blocksize;
|
||||
*len -= blocksize;
|
||||
}
|
||||
else if ( !strncmp(in_ptr, "rsyn", 4) )
|
||||
{
|
||||
*in += blocksize;
|
||||
*len -= blocksize;
|
||||
|
||||
if (cipher_enc_state != CIPHER_INIT)
|
||||
{
|
||||
cipher_enc_state = CIPHER_INIT;
|
||||
EVP_CIPHER_CTX_cleanup(&ctx_enc);
|
||||
}
|
||||
#ifdef LFD_ENCRYPT_DEBUG
|
||||
vtun_syslog(LOG_INFO, "Remote requests encryptor re-init");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = 0;
|
||||
|
||||
if (cipher_dec_state != CIPHER_INIT &&
|
||||
cipher_enc_state != CIPHER_REQ_INIT &&
|
||||
cipher_enc_state != CIPHER_INIT)
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup (&ctx_dec);
|
||||
cipher_dec_state = CIPHER_INIT;
|
||||
cipher_enc_state = CIPHER_REQ_INIT;
|
||||
}
|
||||
#ifdef LFD_ENCRYPT_DEBUG
|
||||
vtun_syslog(LOG_INFO, "Local decryptor out of sync");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Module structure.
|
||||
*/
|
||||
struct lfd_mod lfd_encrypt = {
|
||||
"Encryptor",
|
||||
alloc_encrypt,
|
||||
@ -714,9 +179,10 @@ struct lfd_mod lfd_encrypt = {
|
||||
NULL
|
||||
};
|
||||
|
||||
#else /* HAVE_SSL */
|
||||
#else /* HAVE_SODIUM */
|
||||
|
||||
static int no_encrypt(struct vtun_host *host)
|
||||
static int
|
||||
no_encrypt(struct vtun_host *host)
|
||||
{
|
||||
vtun_syslog(LOG_INFO, "Encryption is not supported");
|
||||
return -1;
|
||||
@ -727,4 +193,4 @@ struct lfd_mod lfd_encrypt = {
|
||||
no_encrypt, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
#endif /* HAVE_SSL */
|
||||
#endif
|
||||
|
10
main.c
10
main.c
@ -35,6 +35,10 @@
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SODIUM
|
||||
#include <sodium.h>
|
||||
#endif
|
||||
|
||||
#include "vtun.h"
|
||||
#include "lib.h"
|
||||
#include "compat.h"
|
||||
@ -194,6 +198,12 @@ int main(int argc, char *argv[], char *env[])
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SODIUM
|
||||
if (sodium_init() != 0) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
if( daemon ){
|
||||
#ifdef HAVE_WORKING_FORK
|
||||
if( dofork && fork() )
|
||||
|
17
vtun.h
17
vtun.h
@ -82,9 +82,12 @@ struct vtun_addr {
|
||||
#define VTUN_ADDR_IFACE 0x01
|
||||
#define VTUN_ADDR_NAME 0x02
|
||||
|
||||
#define HOST_KEYBYTES 32
|
||||
|
||||
struct vtun_host {
|
||||
char *host;
|
||||
char *passwd;
|
||||
unsigned char *key;
|
||||
char *dev;
|
||||
|
||||
llist up;
|
||||
@ -138,19 +141,7 @@ extern llist host_list;
|
||||
#define VTUN_ENCRYPT 0x0008
|
||||
|
||||
/* Cipher options */
|
||||
#define VTUN_ENC_BF128CBC 2
|
||||
#define VTUN_ENC_BF128CFB 3
|
||||
#define VTUN_ENC_BF128OFB 4
|
||||
#define VTUN_ENC_BF256CBC 6
|
||||
#define VTUN_ENC_BF256CFB 7
|
||||
#define VTUN_ENC_BF256OFB 8
|
||||
|
||||
#define VTUN_ENC_AES128CBC 10
|
||||
#define VTUN_ENC_AES128CFB 11
|
||||
#define VTUN_ENC_AES128OFB 12
|
||||
#define VTUN_ENC_AES256CBC 14
|
||||
#define VTUN_ENC_AES256CFB 15
|
||||
#define VTUN_ENC_AES256OFB 16
|
||||
#define VTUN_ENC_AES256GCM 17
|
||||
|
||||
/* Mask to drop the flags which will be supplied by the server */
|
||||
#define VTUN_CLNT_MASK 0xf000
|
||||
|
13
vtund.conf
13
vtund.conf
@ -150,18 +150,7 @@
|
||||
# -----------
|
||||
# encrypt - Enable 'yes' or disable 'no' encryption.
|
||||
# It is also possible to specify a method:
|
||||
# 'blowfish128cbc' - Blowfish cipher, 128 bit key, mode CBC
|
||||
# 'blowfish128cfb' - Blowfish cipher, 128 bit key, mode CFB
|
||||
# 'blowfish128ofb' - Blowfish cipher, 128 bit key, mode OFB
|
||||
# 'blowfish256cbc' - Blowfish cipher, 256 bit key, mode CBC
|
||||
# 'blowfish256cfb' - Blowfish cipher, 256 bit key, mode CFB
|
||||
# 'blowfish256ofb' - Blowfish cipher, 256 bit key, mode OFB
|
||||
# 'aes128cbc' - AES cipher, 128 bit key, mode CBC
|
||||
# 'aes128cfb' - AES cipher, 128 bit key, mode CFB
|
||||
# 'aes128ofb' - AES cipher, 128 bit key, mode OFB
|
||||
# 'aes256cbc' - AES cipher, 256 bit key, mode CBC
|
||||
# 'aes256cfb' - AES cipher, 256 bit key, mode CFB
|
||||
# 'aes256ofb' - AES cipher, 256 bit key, mode OFB
|
||||
# 'aes256gcm' - AES cipher, 256 bit key, mode GCM
|
||||
#
|
||||
# Ignored by the client.
|
||||
#
|
||||
|
26
vtund.conf.5
26
vtund.conf.5
@ -199,30 +199,8 @@ specifies encryption method to use. Encryption \fImethod\fRs include:
|
||||
no encryption
|
||||
.IP \fByes\fR
|
||||
default encryption method
|
||||
.IP \fBblowfish128cbc\fR
|
||||
Blowfish cipher, 128 bit key, mode CBC
|
||||
.IP \fBblowfish128cfb\fR
|
||||
Blowfish cipher, 128 bit key, mode CFB
|
||||
.IP \fBblowfish128ofb\fR
|
||||
Blowfish cipher, 128 bit key, mode OFB
|
||||
.IP \fBblowfish256cbc\fR
|
||||
Blowfish cipher, 256 bit key, mode CBC
|
||||
.IP \fBblowfish256cfb\fR
|
||||
Blowfish cipher, 256 bit key, mode CFB
|
||||
.IP \fBblowfish256ofb\fR
|
||||
Blowfish cipher, 256 bit key, mode OFB
|
||||
.IP \fBaes128cbc\fR
|
||||
AES cipher, 128 bit key, mode CBC
|
||||
.IP \fBaes128cfb\fR
|
||||
AES cipher, 128 bit key, mode CFB
|
||||
.IP \fBaes128ofb\fR
|
||||
AES cipher, 128 bit key, mode OFB
|
||||
.IP \fBaes256cbc\fR
|
||||
AES cipher, 256 bit key, mode CBC
|
||||
.IP \fBaes256cfb\fR
|
||||
AES cipher, 256 bit key, mode CFB
|
||||
.IP \fBaes256ofb\fR
|
||||
AES cipher, 256 bit key, mode OFB
|
||||
.IP \fBaes256gcm\fR
|
||||
AES cipher, 256 bit key, mode GCM
|
||||
.RE
|
||||
.IP
|
||||
This option is ignored by the client.
|
||||
|
Loading…
Reference in New Issue
Block a user