Browse Source

readability code clean-up (#543)

pull/554/head
Logan oos Even 4 years ago
committed by GitHub
parent
commit
30a1ff9313
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 344
      src/transform_aes.c
  2. 223
      src/transform_cc20.c
  3. 101
      src/transform_null.c
  4. 224
      src/transform_speck.c
  5. 309
      src/transform_tf.c

344
src/transform_aes.c

@ -27,27 +27,29 @@
// might encounter an issue with lower values here
#define AES_PREAMBLE_SIZE (AES_BLOCK_SIZE)
// cts/cbc mode is being used with random value prepended to plaintext
// instead of iv so, actual iv is aes_null_iv
const uint8_t aes_null_iv[AES_IV_SIZE] = {0};
const uint8_t aes_null_iv[AES_IV_SIZE] = { 0 };
typedef struct transop_aes {
aes_context_t *ctx;
aes_context_t *ctx;
} transop_aes_t;
/* ****************************************************** */
static int transop_deinit_aes(n2n_trans_op_t *arg) {
transop_aes_t *priv = (transop_aes_t *)arg->priv;
static int transop_deinit_aes (n2n_trans_op_t *arg) {
transop_aes_t *priv = (transop_aes_t *)arg->priv;
if(priv->ctx) aes_deinit(priv->ctx);
if(priv->ctx)
aes_deinit(priv->ctx);
if(priv) free(priv);
if(priv)
free(priv);
return 0;
return 0;
}
/* ****************************************************** */
// the aes packet format consists of
//
@ -58,187 +60,187 @@ static int transop_deinit_aes(n2n_trans_op_t *arg) {
// [VV|DDDDDDDDDDDDDDDDDDDDD]
// | <---- encrypted ----> |
//
static int transop_encode_aes(n2n_trans_op_t * arg,
uint8_t * outbuf,
size_t out_len,
const uint8_t * inbuf,
size_t in_len,
const uint8_t * peer_mac) {
transop_aes_t * priv = (transop_aes_t *)arg->priv;
// the assembly buffer is a source for encrypting data
// the whole contents of assembly are encrypted
uint8_t assembly[N2N_PKT_BUF_SIZE];
size_t idx = 0;
int padded_len;
uint8_t padding;
uint8_t buf[AES_BLOCK_SIZE];
if(in_len <= N2N_PKT_BUF_SIZE) {
if((in_len + AES_PREAMBLE_SIZE + AES_BLOCK_SIZE) <= out_len) {
traceEvent(TRACE_DEBUG, "transop_encode_aes %lu bytes plaintext", in_len);
// full block sized random value (128 bit)
encode_uint64(assembly, &idx, n2n_rand());
encode_uint64(assembly, &idx, n2n_rand());
// adjust for maybe differently chosen AES_PREAMBLE_SIZE
idx = AES_PREAMBLE_SIZE;
// the plaintext data
encode_buf(assembly, &idx, inbuf, in_len);
// round up to next whole AES block size
padded_len = (((idx - 1) / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
padding = (padded_len-idx);
// pad the following bytes with zero, fixed length (AES_BLOCK_SIZE) seems to compile
// to slightly faster code than run-time dependant 'padding'
memset (assembly + idx, 0, AES_BLOCK_SIZE);
aes_cbc_encrypt(outbuf, assembly, padded_len, aes_null_iv, priv->ctx);
if(padding) {
// exchange last two cipher blocks
memcpy (buf, outbuf+padded_len - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
memcpy (outbuf + padded_len - AES_BLOCK_SIZE, outbuf + padded_len - 2 * AES_BLOCK_SIZE, AES_BLOCK_SIZE);
memcpy (outbuf + padded_len - 2 * AES_BLOCK_SIZE, buf, AES_BLOCK_SIZE);
}
static int transop_encode_aes (n2n_trans_op_t *arg,
uint8_t *outbuf,
size_t out_len,
const uint8_t *inbuf,
size_t in_len,
const uint8_t *peer_mac) {
transop_aes_t *priv = (transop_aes_t *)arg->priv;
// the assembly buffer is a source for encrypting data
// the whole contents of assembly are encrypted
uint8_t assembly[N2N_PKT_BUF_SIZE];
size_t idx = 0;
int padded_len;
uint8_t padding;
uint8_t buf[AES_BLOCK_SIZE];
if(in_len <= N2N_PKT_BUF_SIZE) {
if((in_len + AES_PREAMBLE_SIZE + AES_BLOCK_SIZE) <= out_len) {
traceEvent(TRACE_DEBUG, "transop_encode_aes %lu bytes plaintext", in_len);
// full block sized random value (128 bit)
encode_uint64(assembly, &idx, n2n_rand());
encode_uint64(assembly, &idx, n2n_rand());
// adjust for maybe differently chosen AES_PREAMBLE_SIZE
idx = AES_PREAMBLE_SIZE;
// the plaintext data
encode_buf(assembly, &idx, inbuf, in_len);
// round up to next whole AES block size
padded_len = (((idx - 1) / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
padding = (padded_len-idx);
// pad the following bytes with zero, fixed length (AES_BLOCK_SIZE) seems to compile
// to slightly faster code than run-time dependant 'padding'
memset(assembly + idx, 0, AES_BLOCK_SIZE);
aes_cbc_encrypt(outbuf, assembly, padded_len, aes_null_iv, priv->ctx);
if(padding) {
// exchange last two cipher blocks
memcpy(buf, outbuf+padded_len - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
memcpy(outbuf + padded_len - AES_BLOCK_SIZE, outbuf + padded_len - 2 * AES_BLOCK_SIZE, AES_BLOCK_SIZE);
memcpy(outbuf + padded_len - 2 * AES_BLOCK_SIZE, buf, AES_BLOCK_SIZE);
}
} else
traceEvent(TRACE_ERROR, "transop_encode_aes outbuf too small");
} else
traceEvent(TRACE_ERROR, "transop_encode_aes outbuf too small");
} else
traceEvent(TRACE_ERROR, "transop_encode_aes inbuf too big to encrypt");
return idx;
return idx;
}
/* ****************************************************** */
// see transop_encode_aes for packet format
static int transop_decode_aes(n2n_trans_op_t * arg,
uint8_t * outbuf,
size_t out_len,
const uint8_t * inbuf,
size_t in_len,
const uint8_t * peer_mac) {
transop_aes_t * priv = (transop_aes_t *)arg->priv;
uint8_t assembly[N2N_PKT_BUF_SIZE];
uint8_t rest;
size_t penultimate_block;
uint8_t buf[AES_BLOCK_SIZE];
int len=-1;
if( ((in_len - AES_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) // cipher text fits in assembly
&& (in_len >= AES_PREAMBLE_SIZE) // has at least random number
&& (in_len >= AES_BLOCK_SIZE) // minimum size requirement for cipher text stealing
) {
traceEvent(TRACE_DEBUG, "transop_decode_aes %lu bytes ciphertext", in_len);
rest = in_len % AES_BLOCK_SIZE;
if(rest) {
// cipher text stealing
penultimate_block = ((in_len / AES_BLOCK_SIZE) - 1) * AES_BLOCK_SIZE;
// everything normal up to penultimate block
memcpy(assembly, inbuf, penultimate_block);
// prepare new penultimate block in buf
aes_ecb_decrypt(buf, inbuf + penultimate_block, priv->ctx);
memcpy(buf, inbuf + in_len - rest, rest);
// former penultimate block becomes new ultimate block
memcpy(assembly + penultimate_block + AES_BLOCK_SIZE, inbuf + penultimate_block, AES_BLOCK_SIZE);
// write new penultimate block from buf
memcpy(assembly + penultimate_block, buf, AES_BLOCK_SIZE);
// regular cbc decryption on the re-arranged ciphertext
aes_cbc_decrypt(assembly, assembly, in_len + AES_BLOCK_SIZE - rest, aes_null_iv, priv->ctx);
// check for expected zero padding and give a warning otherwise
if (memcmp(assembly + in_len, aes_null_iv, AES_BLOCK_SIZE - rest)) {
traceEvent(TRACE_WARNING, "transop_decode_aes payload decryption failed with unexpected cipher text stealing padding");
return -1;
}
static int transop_decode_aes (n2n_trans_op_t *arg,
uint8_t *outbuf,
size_t out_len,
const uint8_t *inbuf,
size_t in_len,
const uint8_t *peer_mac) {
transop_aes_t *priv = (transop_aes_t *)arg->priv;
uint8_t assembly[N2N_PKT_BUF_SIZE];
uint8_t rest;
size_t penultimate_block;
uint8_t buf[AES_BLOCK_SIZE];
int len = -1;
if(((in_len - AES_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* cipher text fits in assembly */
&& (in_len >= AES_PREAMBLE_SIZE) /* has at least random number */
&& (in_len >= AES_BLOCK_SIZE)) { /* minimum size requirement for cipher text stealing */
traceEvent(TRACE_DEBUG, "transop_decode_aes %lu bytes ciphertext", in_len);
rest = in_len % AES_BLOCK_SIZE;
if(rest) { /* cipher text stealing */
penultimate_block = ((in_len / AES_BLOCK_SIZE) - 1) * AES_BLOCK_SIZE;
// everything normal up to penultimate block
memcpy(assembly, inbuf, penultimate_block);
// prepare new penultimate block in buf
aes_ecb_decrypt(buf, inbuf + penultimate_block, priv->ctx);
memcpy(buf, inbuf + in_len - rest, rest);
// former penultimate block becomes new ultimate block
memcpy(assembly + penultimate_block + AES_BLOCK_SIZE, inbuf + penultimate_block, AES_BLOCK_SIZE);
// write new penultimate block from buf
memcpy(assembly + penultimate_block, buf, AES_BLOCK_SIZE);
// regular cbc decryption of the re-arranged ciphertext
aes_cbc_decrypt(assembly, assembly, in_len + AES_BLOCK_SIZE - rest, aes_null_iv, priv->ctx);
// check for expected zero padding and give a warning otherwise
if(memcmp(assembly + in_len, aes_null_iv, AES_BLOCK_SIZE - rest)) {
traceEvent(TRACE_WARNING, "transop_decode_aes payload decryption failed with unexpected cipher text stealing padding");
return -1;
}
} else {
// regular cbc decryption on multiple block-sized payload
aes_cbc_decrypt(assembly, inbuf, in_len, aes_null_iv, priv->ctx);
}
len = in_len - AES_PREAMBLE_SIZE;
memcpy(outbuf, assembly + AES_PREAMBLE_SIZE, len);
} else
traceEvent(TRACE_ERROR, "transop_decode_aes inbuf wrong size (%ul) to decrypt", in_len);
return len;
}
static int setup_aes_key (transop_aes_t *priv, const uint8_t *password, ssize_t password_len) {
unsigned char key_mat[32]; /* maximum aes key length, equals hash length */
unsigned char *key;
size_t key_size;
// let the user choose the degree of encryption:
// long input passwords will pick AES192 or AES256 with more robust but expensive encryption
// the input password always gets hashed to make a more unpredictable use of the key space
// just think of usually reset MSB of ASCII coded password bytes
pearson_hash_256(key_mat, password, password_len);
// the length-dependant scheme for key setup was discussed on github:
// https://github.com/ntop/n2n/issues/101 -- as no iv encryption required
// anymore, the key-size trigger values were roughly halved
if(password_len >= 33) {
key_size = AES256_KEY_BYTES; /* 256 bit */
} else if(password_len >= 23) {
key_size = AES192_KEY_BYTES; /* 192 bit */
} else {
// regular cbc decryption on multiple block-sized payload
aes_cbc_decrypt(assembly, inbuf, in_len, aes_null_iv, priv->ctx);
key_size = AES128_KEY_BYTES; /* 128 bit */
}
len = in_len - AES_PREAMBLE_SIZE;
memcpy(outbuf,
assembly + AES_PREAMBLE_SIZE,
len);
} else
traceEvent(TRACE_ERROR, "transop_decode_aes inbuf wrong size (%ul) to decrypt", in_len);
return len;
}
/* ****************************************************** */
static int setup_aes_key(transop_aes_t *priv, const uint8_t *password, ssize_t password_len) {
unsigned char key_mat[32]; // maximum aes key length, equals hash length
unsigned char *key;
size_t key_size;
// let the user choose the degree of encryption:
// long input passwords will pick AES192 or AES256 with more robust but expensive encryption
// the input password always gets hashed to make a more unpredictable use of the key space
// just think of usually reset MSB of ASCII coded password bytes
pearson_hash_256(key_mat, password, password_len);
// the length-dependant scheme for key setup was discussed on github:
// https://github.com/ntop/n2n/issues/101 -- as no iv encryption required
// anymore, the key-size trigger values were roughly halved
if(password_len >= 33) {
key_size = AES256_KEY_BYTES; // 256 bit
} else if(password_len >= 23) {
key_size = AES192_KEY_BYTES; // 192 bit
} else {
key_size = AES128_KEY_BYTES; // 128 bit
}
// and use the last key-sized part of the hash as aes key
key = key_mat + sizeof(key_mat) - key_size;
// setup the key and have corresponding context created
if (aes_init (key, key_size, &(priv->ctx))) {
traceEvent(TRACE_ERROR, "setup_aes_key %u-bit key setup unsuccessful",
key_size * 8);
return -1;
}
traceEvent(TRACE_DEBUG, "setup_aes_key %u-bit key setup completed",
key_size * 8);
return 0;
// and use the last key-sized part of the hash as aes key
key = key_mat + sizeof(key_mat) - key_size;
// setup the key and have corresponding context created
if(aes_init (key, key_size, &(priv->ctx))) {
traceEvent(TRACE_ERROR, "setup_aes_key %u-bit key setup unsuccessful", key_size * 8);
return -1;
}
traceEvent(TRACE_DEBUG, "setup_aes_key %u-bit key setup completed", key_size * 8);
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) {
// no tick action
}
/* ****************************************************** */
// AES initialization function
int n2n_transop_aes_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
int n2n_transop_aes_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
transop_aes_t *priv;
const u_char *encrypt_key = (const u_char *)conf->encrypt_key;
size_t encrypt_key_len = strlen(conf->encrypt_key);
transop_aes_t *priv;
const u_char *encrypt_key = (const u_char *)conf->encrypt_key;
size_t encrypt_key_len = strlen(conf->encrypt_key);
memset(ttt, 0, sizeof(*ttt));
ttt->transform_id = N2N_TRANSFORM_ID_AES;
memset(ttt, 0, sizeof(*ttt));
ttt->transform_id = N2N_TRANSFORM_ID_AES;
ttt->tick = transop_tick_aes;
ttt->deinit = transop_deinit_aes;
ttt->fwd = transop_encode_aes;
ttt->rev = transop_decode_aes;
ttt->tick = transop_tick_aes;
ttt->deinit = transop_deinit_aes;
ttt->fwd = transop_encode_aes;
ttt->rev = transop_decode_aes;
priv = (transop_aes_t*) calloc(1, sizeof(transop_aes_t));
if(!priv) {
traceEvent(TRACE_ERROR, "n2n_transop_aes_init cannot allocate transop_aes_t memory");
return(-1);
}
ttt->priv = priv;
priv = (transop_aes_t*)calloc(1, sizeof(transop_aes_t));
if(!priv) {
traceEvent(TRACE_ERROR, "n2n_transop_aes_init cannot allocate transop_aes_t memory");
return -1;
}
ttt->priv = priv;
// setup the cipher and key
return(setup_aes_key(priv, encrypt_key, encrypt_key_len));
// setup the cipher and key
return setup_aes_key(priv, encrypt_key, encrypt_key_len);
}

223
src/transform_cc20.c

@ -20,160 +20,155 @@
#include "n2n.h"
/* ChaCha20 plaintext preamble */
// ChaCha20 plaintext preamble
#define CC20_PREAMBLE_SIZE (CC20_IV_SIZE)
typedef struct transop_cc20 {
cc20_context_t *ctx;
cc20_context_t *ctx;
} transop_cc20_t;
/* ****************************************************** */
static int transop_deinit_cc20(n2n_trans_op_t *arg) {
static int transop_deinit_cc20 (n2n_trans_op_t *arg) {
transop_cc20_t *priv = (transop_cc20_t *)arg->priv;
transop_cc20_t *priv = (transop_cc20_t *)arg->priv;
if(priv->ctx)
cc20_deinit(priv->ctx);
if(priv->ctx)
cc20_deinit(priv->ctx);
if(priv)
free(priv);
if(priv)
free(priv);
return 0;
return 0;
}
/* ****************************************************** */
/** The ChaCha20 packet format consists of:
*
* - a 128-bit random IV
* - encrypted payload.
*
* [IIII|DDDDDDDDDDDDDDDDDDDDD]
* |<---- encrypted ---->|
*/
static int transop_encode_cc20(n2n_trans_op_t * arg,
uint8_t * outbuf,
size_t out_len,
const uint8_t * inbuf,
size_t in_len,
const uint8_t * peer_mac) {
int len=-1;
transop_cc20_t * priv = (transop_cc20_t *)arg->priv;
uint8_t assembly[N2N_PKT_BUF_SIZE] = {0};
if(in_len <= N2N_PKT_BUF_SIZE) {
if((in_len + CC20_PREAMBLE_SIZE) <= out_len) {
size_t idx=0;
traceEvent(TRACE_DEBUG, "encode_cc20 %lu bytes", in_len);
// full IV sized random value (128 bit)
encode_uint64(outbuf, &idx, n2n_rand());
encode_uint64(outbuf, &idx, n2n_rand());
len = in_len;
cc20_crypt(outbuf + CC20_PREAMBLE_SIZE,
inbuf,
in_len,
outbuf, // IV
priv->ctx);
len += CC20_PREAMBLE_SIZE; /* size of data carried in UDP. */
// the ChaCha20 packet format consists of
//
// - a 128-bit random iv
// - encrypted payload
//
// [IIII|DDDDDDDDDDDDDDDDDDDDD]
// |<---- encrypted ---->|
//
static int transop_encode_cc20 (n2n_trans_op_t *arg,
uint8_t *outbuf,
size_t out_len,
const uint8_t *inbuf,
size_t in_len,
const uint8_t *peer_mac) {
int len = -1;
transop_cc20_t *priv = (transop_cc20_t *)arg->priv;
uint8_t assembly[N2N_PKT_BUF_SIZE] = { 0 };
if(in_len <= N2N_PKT_BUF_SIZE) {
if((in_len + CC20_PREAMBLE_SIZE) <= out_len) {
size_t idx = 0;
traceEvent(TRACE_DEBUG, "encode_cc20 %lu bytes", in_len);
// full iv sized random value (128 bit)
encode_uint64(outbuf, &idx, n2n_rand());
encode_uint64(outbuf, &idx, n2n_rand());
len = in_len;
cc20_crypt(outbuf + CC20_PREAMBLE_SIZE,
inbuf,
in_len,
outbuf, /* iv */
priv->ctx);
// size of datacarried in UDP
len += CC20_PREAMBLE_SIZE;
} else
traceEvent(TRACE_ERROR, "encode_cc20 outbuf too small.");
} else
traceEvent(TRACE_ERROR, "encode_cc20 outbuf too small.");
} else
traceEvent(TRACE_ERROR, "encode_cc20 inbuf too big to encrypt.");
traceEvent(TRACE_ERROR, "encode_cc20 inbuf too big to encrypt.");
return len;
return len;
}
/* ****************************************************** */
/* See transop_encode_cc20 for packet format */
static int transop_decode_cc20(n2n_trans_op_t * arg,
uint8_t * outbuf,
size_t out_len,
const uint8_t * inbuf,
size_t in_len,
const uint8_t * peer_mac) {
int len=0;
transop_cc20_t * priv = (transop_cc20_t *)arg->priv;
uint8_t assembly[N2N_PKT_BUF_SIZE];
// see transop_encode_cc20 for packet format
static int transop_decode_cc20 (n2n_trans_op_t *arg,
uint8_t *outbuf,
size_t out_len,
const uint8_t *inbuf,
size_t in_len,
const uint8_t *peer_mac) {
if(((in_len - CC20_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* Cipher text fits in assembly */
&& (in_len >= CC20_PREAMBLE_SIZE) /* Has at least iv */
)
{
size_t rem=in_len;
size_t idx=0;
int len = 0;
transop_cc20_t *priv = (transop_cc20_t *)arg->priv;
uint8_t assembly[N2N_PKT_BUF_SIZE];
traceEvent(TRACE_DEBUG, "decode_cc20 %lu bytes", in_len);
if(((in_len - CC20_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* cipher text fits in assembly */
&& (in_len >= CC20_PREAMBLE_SIZE)) { /* has at least iv */
size_t rem = in_len;
size_t idx = 0;
len = (in_len - CC20_PREAMBLE_SIZE);
traceEvent(TRACE_DEBUG, "decode_cc20 %lu bytes", in_len);
cc20_crypt(outbuf,
inbuf + CC20_PREAMBLE_SIZE,
in_len,
inbuf, // IV
priv->ctx);
len = (in_len - CC20_PREAMBLE_SIZE);
} else
traceEvent(TRACE_ERROR, "decode_cc20 inbuf wrong size (%ul) to decrypt.", in_len);
cc20_crypt(outbuf,
inbuf + CC20_PREAMBLE_SIZE,
in_len,
inbuf, /* iv */
priv->ctx);
} else
traceEvent(TRACE_ERROR, "decode_cc20 inbuf wrong size (%ul) to decrypt.", in_len);
return len;
return len;
}
/* ****************************************************** */
static int setup_cc20_key(transop_cc20_t *priv, const uint8_t *password, ssize_t password_len) {
static int setup_cc20_key (transop_cc20_t *priv, const uint8_t *password, ssize_t password_len) {
uint8_t key_mat[CC20_KEY_BYTES];
uint8_t key_mat[CC20_KEY_BYTES];
/* The input key always gets hashed to make a more unpredictable and more complete use of the key space */
pearson_hash_256(key_mat, password, password_len);
// the input key always gets hashed to make a more unpredictable and more complete use of the key space
pearson_hash_256(key_mat, password, password_len);
if(cc20_init(key_mat, &(priv->ctx))) {
traceEvent(TRACE_ERROR, "setup_cc20_key setup unsuccessful");
return -1;
}
if(cc20_init(key_mat, &(priv->ctx))) {
traceEvent(TRACE_ERROR, "setup_cc20_key setup unsuccessful");
return -1;
}
traceEvent(TRACE_DEBUG, "setup_cc20_key completed");
traceEvent(TRACE_DEBUG, "setup_cc20_key completed");
return 0;
return 0;
}
/* ****************************************************** */
static void transop_tick_cc20(n2n_trans_op_t * arg, time_t now) { ; }
static void transop_tick_cc20 (n2n_trans_op_t *arg, time_t now) {
// no tick action
}
/* ****************************************************** */
/* ChaCha20 initialization function */
int n2n_transop_cc20_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
// ChaCha20 initialization function
int n2n_transop_cc20_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
transop_cc20_t *priv;
const u_char *encrypt_key = (const u_char *)conf->encrypt_key;
size_t encrypt_key_len = strlen(conf->encrypt_key);
transop_cc20_t *priv;
const u_char *encrypt_key = (const u_char *)conf->encrypt_key;
size_t encrypt_key_len = strlen(conf->encrypt_key);
memset(ttt, 0, sizeof(*ttt));
ttt->transform_id = N2N_TRANSFORM_ID_CHACHA20;
memset(ttt, 0, sizeof(*ttt));
ttt->transform_id = N2N_TRANSFORM_ID_CHACHA20;
ttt->tick = transop_tick_cc20;
ttt->deinit = transop_deinit_cc20;
ttt->fwd = transop_encode_cc20;
ttt->rev = transop_decode_cc20;
ttt->tick = transop_tick_cc20;
ttt->deinit = transop_deinit_cc20;
ttt->fwd = transop_encode_cc20;
ttt->rev = transop_decode_cc20;
priv = (transop_cc20_t*) calloc(1, sizeof(transop_cc20_t));
if(!priv) {
traceEvent(TRACE_ERROR, "cannot allocate transop_cc20_t memory");
return(-1);
}
ttt->priv = priv;
priv = (transop_cc20_t*)calloc(1, sizeof(transop_cc20_t));
if(!priv) {
traceEvent(TRACE_ERROR, "cannot allocate transop_cc20_t memory");
return -1;
}
ttt->priv = priv;
/* Setup the cipher and key */
return setup_cc20_key(priv, encrypt_key, encrypt_key_len);
// setup the cipher and key
return setup_cc20_key(priv, encrypt_key, encrypt_key_len);
}

101
src/transform_null.c

@ -16,71 +16,76 @@
*
*/
#include "n2n.h"
static int transop_deinit_null( n2n_trans_op_t * arg )
{
/* nothing to deallocate, nothing to release. */
return 0;
static int transop_deinit_null (n2n_trans_op_t *arg ) {
// nothing to deallocate, nothing to release
return 0;
}
static int transop_encode_null( n2n_trans_op_t * arg,
uint8_t * outbuf,
static int transop_encode_null (n2n_trans_op_t *arg,
uint8_t *outbuf,
size_t out_len,
const uint8_t * inbuf,
const uint8_t *inbuf,
size_t in_len,
const uint8_t * peer_mac)
{
int retval = -1;
traceEvent( TRACE_DEBUG, "encode_null %lu", in_len );
if ( out_len >= in_len )
{
memcpy( outbuf, inbuf, in_len );
retval = in_len;
}
else
{
traceEvent( TRACE_DEBUG, "encode_null %lu too big for packet buffer", in_len );
const uint8_t *peer_mac) {
int retval = -1;
traceEvent(TRACE_DEBUG, "encode_null %lu", in_len);
if(out_len >= in_len) {
memcpy(outbuf, inbuf, in_len);
retval = in_len;
} else {
traceEvent(TRACE_DEBUG, "encode_null %lu too big for packet buffer", in_len);
}
return retval;
return retval;
}
static int transop_decode_null( n2n_trans_op_t * arg,
uint8_t * outbuf,
static int transop_decode_null (n2n_trans_op_t *arg,
uint8_t *outbuf,
size_t out_len,
const uint8_t * inbuf,
const uint8_t *inbuf,
size_t in_len,
const uint8_t * peer_mac)
{
int retval = -1;
traceEvent( TRACE_DEBUG, "decode_null %lu", in_len );
if ( out_len >= in_len )
{
memcpy( outbuf, inbuf, in_len );
retval = in_len;
}
else
{
traceEvent( TRACE_DEBUG, "decode_null %lu too big for packet buffer", in_len );
const uint8_t *peer_mac) {
int retval = -1;
traceEvent(TRACE_DEBUG, "decode_null %lu", in_len);
if(out_len >= in_len) {
memcpy(outbuf, inbuf, in_len);
retval = in_len;
} else {
traceEvent(TRACE_DEBUG, "decode_null %lu too big for packet buffer", in_len);
}
return retval;
return retval;
}
static void transop_tick_null (n2n_trans_op_t *arg, time_t now) {
// no tick action
}
static void transop_tick_null(n2n_trans_op_t * arg, time_t now) {}
int n2n_transop_null_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
memset(ttt, 0, sizeof(n2n_trans_op_t) );
int n2n_transop_null_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
memset(ttt, 0, sizeof(n2n_trans_op_t));
ttt->transform_id = N2N_TRANSFORM_ID_NULL;
ttt->no_encryption = 1;
ttt->deinit = transop_deinit_null;
ttt->tick = transop_tick_null;
ttt->fwd = transop_encode_null;
ttt->rev = transop_decode_null;
ttt->transform_id = N2N_TRANSFORM_ID_NULL;
ttt->no_encryption = 1;
ttt->deinit = transop_deinit_null;
ttt->tick = transop_tick_null;
ttt->fwd = transop_encode_null;
ttt->rev = transop_decode_null;
return(0);
return 0;
}

224
src/transform_speck.c

@ -20,159 +20,157 @@
#include "n2n.h"
/* Speck plaintext preamble */
// Speck plaintext preamble
#define TRANSOP_SPECK_PREAMBLE_SIZE (N2N_SPECK_IVEC_SIZE)
typedef struct transop_speck {
speck_context_t *ctx; /* the round keys for payload encryption & decryption */
speck_context_t *ctx; /* the round keys for payload encryption & decryption */
} transop_speck_t;
/* ****************************************************** */
static int transop_deinit_speck(n2n_trans_op_t *arg) {
transop_speck_t *priv = (transop_speck_t *)arg->priv;
static int transop_deinit_speck (n2n_trans_op_t *arg) {
if(priv->ctx) speck_deinit(priv->ctx);
transop_speck_t *priv = (transop_speck_t *)arg->priv;
if(priv) free (priv);
if(priv->ctx)
speck_deinit(priv->ctx);
return 0;
if(priv)
free(priv);
return 0;
}
/* ****************************************************** */
/** The Speck packet format consists of:
*
* - a 128-bit random IV
* - encrypted payload.
*
* [IIII|DDDDDDDDDDDDDDDDDDDDD]
* |<---- encrypted ---->|
*/
static int transop_encode_speck(n2n_trans_op_t * arg,
uint8_t * outbuf,
size_t out_len,
const uint8_t * inbuf,
size_t in_len,
const uint8_t * peer_mac) {
int len=-1;
transop_speck_t * priv = (transop_speck_t *)arg->priv;
if(in_len <= N2N_PKT_BUF_SIZE) {
if((in_len + TRANSOP_SPECK_PREAMBLE_SIZE) <= out_len) {
size_t idx=0;
traceEvent(TRACE_DEBUG, "encode_speck %lu bytes", in_len);
/* Generate and encode the IV. */
encode_uint64(outbuf, &idx, n2n_rand());
encode_uint64(outbuf, &idx, n2n_rand());
/* Encrypt the payload and write the ciphertext after the iv. */
/* len is set to the length of the cipher plain text to be encrpyted
which is (in this case) identical to original packet lentgh */
len = in_len;
speck_ctr (outbuf + TRANSOP_SPECK_PREAMBLE_SIZE, // output starts right after the iv
inbuf, // input
in_len, // len
outbuf, // iv (already encoded in outbuf, speck does not change it)
priv->ctx); // ctx already setup with round keys
traceEvent(TRACE_DEBUG, "encode_speck: encrypted %u bytes.\n", in_len);
len += TRANSOP_SPECK_PREAMBLE_SIZE; /* size of data carried in UDP. */
// the Speck packet format consists of
//
// - a 128-bit random iv
// - encrypted payload
//
// [IIII|DDDDDDDDDDDDDDDDDDDDD]
// |<---- encrypted ---->|
//
static int transop_encode_speck (n2n_trans_op_t *arg,
uint8_t *outbuf,
size_t out_len,
const uint8_t *inbuf,
size_t in_len,
const uint8_t *peer_mac) {
int len = -1;
transop_speck_t *priv = (transop_speck_t *)arg->priv;
if(in_len <= N2N_PKT_BUF_SIZE) {
if((in_len + TRANSOP_SPECK_PREAMBLE_SIZE) <= out_len) {
size_t idx = 0;
traceEvent(TRACE_DEBUG, "encode_speck %lu bytes", in_len);
// generate and encode the iv
encode_uint64(outbuf, &idx, n2n_rand());
encode_uint64(outbuf, &idx, n2n_rand());
// encrypt the payload and write the ciphertext after the iv
// len is set to the length of the cipher plain text to be encrpyted
// which is (in this case) identical to original packet lentgh
len = in_len;
speck_ctr (outbuf + TRANSOP_SPECK_PREAMBLE_SIZE, /* output starts right after the iv */
inbuf, /* input */
in_len, /* len */
outbuf, /* iv, already encoded in outbuf, speck does not change it */
priv->ctx); /* ctx already setup with round keys */
traceEvent(TRACE_DEBUG, "encode_speck: encrypted %u bytes.\n", in_len);
// size of data carried in UDP
len += TRANSOP_SPECK_PREAMBLE_SIZE;
} else
traceEvent(TRACE_ERROR, "encode_speck outbuf too small.");
} else
traceEvent(TRACE_ERROR, "encode_speck outbuf too small.");
} else
traceEvent(TRACE_ERROR, "encode_speck inbuf too big to encrypt.");
traceEvent(TRACE_ERROR, "encode_speck inbuf too big to encrypt.");
return len;
return len;
}
/* ****************************************************** */
/* See transop_encode_speck for packet format */
static int transop_decode_speck(n2n_trans_op_t * arg,
uint8_t * outbuf,
size_t out_len,
const uint8_t * inbuf,
size_t in_len,
const uint8_t * peer_mac) {
// see transop_encode_speck for packet format
static int transop_decode_speck (n2n_trans_op_t *arg,
uint8_t *outbuf,
size_t out_len,
const uint8_t *inbuf,
size_t in_len,
const uint8_t *peer_mac) {
int len=0;
transop_speck_t * priv = (transop_speck_t *)arg->priv;
int len = 0;
transop_speck_t *priv = (transop_speck_t *)arg->priv;
if(((in_len - TRANSOP_SPECK_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* Cipher text fits in buffer */
&& (in_len >= TRANSOP_SPECK_PREAMBLE_SIZE) /* Has at least iv */
)
{
size_t rem=in_len;
size_t idx=0;
if(((in_len - TRANSOP_SPECK_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* cipher text fits in buffer */
&& (in_len >= TRANSOP_SPECK_PREAMBLE_SIZE)) { /* has at least iv */
size_t rem = in_len;
size_t idx = 0;
traceEvent(TRACE_DEBUG, "decode_speck %lu bytes", in_len);
traceEvent(TRACE_DEBUG, "decode_speck %lu bytes", in_len);
len = (in_len - TRANSOP_SPECK_PREAMBLE_SIZE);
speck_ctr (outbuf, // output
inbuf + TRANSOP_SPECK_PREAMBLE_SIZE, // encrypted data starts right after preamble (IV)
len, // len
inbuf, // IV can be found at input's beginning
priv->ctx); // ctx already setup with round keys
len = (in_len - TRANSOP_SPECK_PREAMBLE_SIZE);
speck_ctr (outbuf, /* output */
inbuf + TRANSOP_SPECK_PREAMBLE_SIZE, /* encrypted data starts right after preamble (iv) */
len, /* len */
inbuf, /* iv can be found at input's beginning */
priv->ctx); /* ctx already setup with round keys */
traceEvent(TRACE_DEBUG, "decode_speck decrypted %u bytes.\n", len);
} else
traceEvent(TRACE_ERROR, "decode_speck inbuf wrong size (%ul) to decrypt.", in_len);
traceEvent(TRACE_DEBUG, "decode_speck decrypted %u bytes.\n", len);
} else
traceEvent(TRACE_ERROR, "decode_speck inbuf wrong size (%ul) to decrypt.", in_len);
return len;
return len;
}
/* ****************************************************** */
static int setup_speck_key(transop_speck_t *priv, const uint8_t *key, ssize_t key_size) {
static int setup_speck_key (transop_speck_t *priv, const uint8_t *key, ssize_t key_size) {
uint8_t key_mat_buf[32];
uint8_t key_mat_buf[32];
/* the input key always gets hashed to make a more unpredictable and more complete use of the key space */
pearson_hash_256(key_mat_buf, key, key_size);
// the input key always gets hashed to make a more unpredictable and more complete use of the key space
pearson_hash_256(key_mat_buf, key, key_size);
/* expand the key material to the context (= round keys) */
speck_init(key_mat_buf, &(priv->ctx));
// expand the key material to the context (= round keys)
speck_init(key_mat_buf, &(priv->ctx));
traceEvent(TRACE_DEBUG, "setup_speck_key completed\n");
traceEvent(TRACE_DEBUG, "setup_speck_key completed\n");
return 0;
return 0;
}
/* ****************************************************** */
static void transop_tick_speck(n2n_trans_op_t * arg, time_t now) { ; }
static void transop_tick_speck (n2n_trans_op_t *arg, time_t now) {
// no tick action
}
/* ****************************************************** */
/* Speck initialization function */
int n2n_transop_speck_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
// Speck initialization function
int n2n_transop_speck_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
transop_speck_t *priv;
const u_char *encrypt_key = (const u_char *)conf->encrypt_key;
size_t encrypt_key_len = strlen(conf->encrypt_key);
transop_speck_t *priv;
const u_char *encrypt_key = (const u_char *)conf->encrypt_key;
size_t encrypt_key_len = strlen(conf->encrypt_key);
memset(ttt, 0, sizeof(*ttt));
ttt->transform_id = N2N_TRANSFORM_ID_SPECK;
memset(ttt, 0, sizeof(*ttt));
ttt->transform_id = N2N_TRANSFORM_ID_SPECK;
ttt->tick = transop_tick_speck;
ttt->deinit = transop_deinit_speck;
ttt->fwd = transop_encode_speck;
ttt->rev = transop_decode_speck;
ttt->tick = transop_tick_speck;
ttt->deinit = transop_deinit_speck;
ttt->fwd = transop_encode_speck;
ttt->rev = transop_decode_speck;
priv = (transop_speck_t*) calloc(1, sizeof(transop_speck_t));
if(!priv) {
traceEvent(TRACE_ERROR, "n2n_transop_speck_init cannot allocate transop_speck_t memory");
return(-1);
}
ttt->priv = priv;
priv = (transop_speck_t*)calloc(1, sizeof(transop_speck_t));
if(!priv) {
traceEvent(TRACE_ERROR, "n2n_transop_speck_init cannot allocate transop_speck_t memory");
return -1;
}
ttt->priv = priv;
/* Setup the cipher and key */
return setup_speck_key(priv, encrypt_key, encrypt_key_len);
// setup the cipher and key
return setup_speck_key(priv, encrypt_key, encrypt_key_len);
}

309
src/transform_tf.c

@ -27,27 +27,29 @@
// might encounter an issue with lower values here
#define TF_PREAMBLE_SIZE (TF_BLOCK_SIZE)
// cbc mode is being used with random value prepended to plaintext
// instead of iv so, actual iv is tf_null_iv
const uint8_t tf_null_iv[TF_IV_SIZE] = {0};
const uint8_t tf_null_iv[TF_IV_SIZE] = { 0 };
typedef struct transop_tf {
tf_context_t *ctx;
tf_context_t *ctx;
} transop_tf_t;
/* ****************************************************** */
static int transop_deinit_tf(n2n_trans_op_t *arg) {
transop_tf_t *priv = (transop_tf_t *)arg->priv;
static int transop_deinit_tf (n2n_trans_op_t *arg) {
transop_tf_t *priv = (transop_tf_t *)arg->priv;
if(priv->ctx) tf_deinit(priv->ctx);
if(priv->ctx)
tf_deinit(priv->ctx);
if(priv) free(priv);
if(priv)
free(priv);
return 0;
return 0;
}
/* ****************************************************** */
// the Twofish packet format consists of
//
@ -58,174 +60,173 @@ static int transop_deinit_tf(n2n_trans_op_t *arg) {
// [VV|DDDDDDDDDDDDDDDDDDDDD]
// | <---- encrypted ----> |
//
static int transop_encode_tf(n2n_trans_op_t * arg,
uint8_t * outbuf,
size_t out_len,
const uint8_t * inbuf,
size_t in_len,
const uint8_t * peer_mac) {
transop_tf_t * priv = (transop_tf_t *)arg->priv;
// the assembly buffer is a source for encrypting data
// the whole contents of assembly are encrypted
uint8_t assembly[N2N_PKT_BUF_SIZE];
size_t idx = 0;
int padded_len;
uint8_t padding;
uint8_t buf[TF_BLOCK_SIZE];
if(in_len <= N2N_PKT_BUF_SIZE) {
if((in_len + TF_PREAMBLE_SIZE + TF_BLOCK_SIZE) <= out_len) {
traceEvent(TRACE_DEBUG, "transop_encode_tf %lu bytes plaintext", in_len);
// full block sized random value (128 bit)
encode_uint64(assembly, &idx, n2n_rand());
encode_uint64(assembly, &idx, n2n_rand());
// adjust for maybe differently chosen TF_PREAMBLE_SIZE
idx = TF_PREAMBLE_SIZE;
// the plaintext data
encode_buf(assembly, &idx, inbuf, in_len);
// round up to next whole TF block size
padded_len = (((idx - 1) / TF_BLOCK_SIZE) + 1) * TF_BLOCK_SIZE;
padding = (padded_len-idx);
// pad the following bytes with zero, fixed length (TF_BLOCK_SIZE) seems to compile
// to slightly faster code than run-time dependant 'padding'
memset (assembly + idx, 0, TF_BLOCK_SIZE);
tf_cbc_encrypt(outbuf, assembly, padded_len, tf_null_iv, priv->ctx);
if(padding) {
// exchange last two cipher blocks
memcpy (buf, outbuf + padded_len - TF_BLOCK_SIZE, TF_BLOCK_SIZE);
memcpy (outbuf + padded_len - TF_BLOCK_SIZE, outbuf + padded_len - 2 * TF_BLOCK_SIZE, TF_BLOCK_SIZE);
memcpy (outbuf + padded_len - 2 * TF_BLOCK_SIZE, buf, TF_BLOCK_SIZE);
}
static int transop_encode_tf (n2n_trans_op_t *arg,
uint8_t *outbuf,
size_t out_len,
const uint8_t *inbuf,
size_t in_len,
const uint8_t *peer_mac) {
transop_tf_t *priv = (transop_tf_t *)arg->priv;
// the assembly buffer is a source for encrypting data
// the whole contents of assembly are encrypted
uint8_t assembly[N2N_PKT_BUF_SIZE];
size_t idx = 0;
int padded_len;
uint8_t padding;
uint8_t buf[TF_BLOCK_SIZE];
if(in_len <= N2N_PKT_BUF_SIZE) {
if((in_len + TF_PREAMBLE_SIZE + TF_BLOCK_SIZE) <= out_len) {
traceEvent(TRACE_DEBUG, "transop_encode_tf %lu bytes plaintext", in_len);
// full block sized random value (128 bit)
encode_uint64(assembly, &idx, n2n_rand());
encode_uint64(assembly, &idx, n2n_rand());
// adjust for maybe differently chosen TF_PREAMBLE_SIZE
idx = TF_PREAMBLE_SIZE;
// the plaintext data
encode_buf(assembly, &idx, inbuf, in_len);
// round up to next whole TF block size
padded_len = (((idx - 1) / TF_BLOCK_SIZE) + 1) * TF_BLOCK_SIZE;
padding = (padded_len-idx);
// pad the following bytes with zero, fixed length (TF_BLOCK_SIZE) seems to compile
// to slightly faster code than run-time dependant 'padding'
memset(assembly + idx, 0, TF_BLOCK_SIZE);
tf_cbc_encrypt(outbuf, assembly, padded_len, tf_null_iv, priv->ctx);
if(padding) {
// exchange last two cipher blocks
memcpy(buf, outbuf + padded_len - TF_BLOCK_SIZE, TF_BLOCK_SIZE);
memcpy(outbuf + padded_len - TF_BLOCK_SIZE, outbuf + padded_len - 2 * TF_BLOCK_SIZE, TF_BLOCK_SIZE);
memcpy(outbuf + padded_len - 2 * TF_BLOCK_SIZE, buf, TF_BLOCK_SIZE);
}
} else
traceEvent(TRACE_ERROR, "transop_encode_tf outbuf too small");
} else
traceEvent(TRACE_ERROR, "transop_encode_tf outbuf too small");
} else
traceEvent(TRACE_ERROR, "transop_encode_tf inbuf too big to encrypt");
traceEvent(TRACE_ERROR, "transop_encode_tf inbuf too big to encrypt");
return idx;
return idx;
}
/* ****************************************************** */
// see transop_encode_tf for packet format
static int transop_decode_tf(n2n_trans_op_t * arg,
uint8_t * outbuf,
size_t out_len,
const uint8_t * inbuf,
size_t in_len,
const uint8_t * peer_mac) {
transop_tf_t * priv = (transop_tf_t *)arg->priv;
uint8_t assembly[N2N_PKT_BUF_SIZE];
uint8_t rest;
size_t penultimate_block;
uint8_t buf[TF_BLOCK_SIZE];
int len=-1;
if( ((in_len - TF_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) // cipher text fits in assembly
&& (in_len >= TF_PREAMBLE_SIZE) // has at least random number
&& (in_len >= TF_BLOCK_SIZE) // minimum size requirement for cipher text stealing
) {
traceEvent(TRACE_DEBUG, "transop_decode_tf %lu bytes ciphertext", in_len);
rest = in_len % TF_BLOCK_SIZE;
if(rest) {
// cipher text stealing
penultimate_block = ((in_len / TF_BLOCK_SIZE) - 1) * TF_BLOCK_SIZE;
// everything normal up to penultimate block
memcpy(assembly, inbuf, penultimate_block);
// prepare new penultimate block in buf
tf_ecb_decrypt(buf, inbuf + penultimate_block, priv->ctx);
memcpy(buf, inbuf + in_len - rest, rest);
// former penultimate block becomes new ultimate block
memcpy(assembly + penultimate_block + TF_BLOCK_SIZE, inbuf + penultimate_block, TF_BLOCK_SIZE);
// write new penultimate block from buf
memcpy(assembly + penultimate_block, buf, TF_BLOCK_SIZE);
// regular cbc decryption on the re-arranged ciphertext
tf_cbc_decrypt(assembly, assembly, in_len + TF_BLOCK_SIZE - rest, tf_null_iv, priv->ctx);
// check for expected zero padding and give a warning otherwise
if(memcmp(assembly + in_len, tf_null_iv, TF_BLOCK_SIZE - rest)) {
traceEvent(TRACE_WARNING, "transop_decode_tf payload decryption failed with unexpected cipher text stealing padding");
return -1;
}
} else {
// regular cbc decryption on multiple block-sized payload
tf_cbc_decrypt(assembly, inbuf, in_len, tf_null_iv, priv->ctx);
}
len = in_len - TF_PREAMBLE_SIZE;
memcpy(outbuf,
assembly + TF_PREAMBLE_SIZE,
len);
} else
traceEvent(TRACE_ERROR, "transop_decode_tf inbuf wrong size (%ul) to decrypt", in_len);
return len;
static int transop_decode_tf (n2n_trans_op_t *arg,
uint8_t *outbuf,
size_t out_len,
const uint8_t *inbuf,
size_t in_len,
const uint8_t *peer_mac) {
transop_tf_t *priv = (transop_tf_t *)arg->priv;
uint8_t assembly[N2N_PKT_BUF_SIZE];
uint8_t rest;
size_t penultimate_block;
uint8_t buf[TF_BLOCK_SIZE];
int len = -1;
if(((in_len - TF_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* cipher text fits in assembly */
&& (in_len >= TF_PREAMBLE_SIZE) /* has at least random number */
&& (in_len >= TF_BLOCK_SIZE)) { /* minimum size requirement for cipher text stealing */
traceEvent(TRACE_DEBUG, "transop_decode_tf %lu bytes ciphertext", in_len);
rest = in_len % TF_BLOCK_SIZE;
if(rest) { /* cipher text stealing */
penultimate_block = ((in_len / TF_BLOCK_SIZE) - 1) * TF_BLOCK_SIZE;
// everything normal up to penultimate block
memcpy(assembly, inbuf, penultimate_block);
// prepare new penultimate block in buf
tf_ecb_decrypt(buf, inbuf + penultimate_block, priv->ctx);
memcpy(buf, inbuf + in_len - rest, rest);
// former penultimate block becomes new ultimate block
memcpy(assembly + penultimate_block + TF_BLOCK_SIZE, inbuf + penultimate_block, TF_BLOCK_SIZE);
// write new penultimate block from buf
memcpy(assembly + penultimate_block, buf, TF_BLOCK_SIZE);
// regular cbc decryption of the re-arranged ciphertext
tf_cbc_decrypt(assembly, assembly, in_len + TF_BLOCK_SIZE - rest, tf_null_iv, priv->ctx);
// check for expected zero padding and give a warning otherwise
if(memcmp(assembly + in_len, tf_null_iv, TF_BLOCK_SIZE - rest)) {
traceEvent(TRACE_WARNING, "transop_decode_tf payload decryption failed with unexpected cipher text stealing padding");
return -1;
}
} else {
// regular cbc decryption on multiple block-sized payload
tf_cbc_decrypt(assembly, inbuf, in_len, tf_null_iv, priv->ctx);
}
len = in_len - TF_PREAMBLE_SIZE;
memcpy(outbuf, assembly + TF_PREAMBLE_SIZE, len);
} else
traceEvent(TRACE_ERROR, "transop_decode_tf inbuf wrong size (%ul) to decrypt", in_len);
return len;
}
/* ****************************************************** */
static int setup_tf_key(transop_tf_t *priv, const uint8_t *password, ssize_t password_len) {
static int setup_tf_key (transop_tf_t *priv, const uint8_t *password, ssize_t password_len) {
unsigned char key[32]; // tf key length, equals hash length
size_t key_size;
unsigned char key[32]; /* tf key length, equals hash length */
size_t key_size;
// the input password always gets hashed to make a more unpredictable use of the key space
// just think of usually reset MSB of ASCII coded password bytes
pearson_hash_256(key, password, password_len);
// the input password always gets hashed to make a more unpredictable use of the key space
// just think of usually reset MSB of ASCII coded password bytes
pearson_hash_256(key, password, password_len);
key_size = 32; // 256 bit
key_size = 32; /* 256 bit */
// setup the key and have corresponding context created
if(tf_init(key, key_size * 8, &(priv->ctx))) {
traceEvent(TRACE_ERROR, "setup_tf_key %u-bit key setup unsuccessful",
key_size * 8);
return -1;
}
// setup the key and have corresponding context created
if(tf_init(key, key_size * 8, &(priv->ctx))) {
traceEvent(TRACE_ERROR, "setup_tf_key %u-bit key setup unsuccessful", key_size * 8);
return -1;
}
traceEvent(TRACE_DEBUG, "setup_tf_key %u-bit key setup completed", key_size * 8);
traceEvent(TRACE_DEBUG, "setup_tf_key %u-bit key setup completed",
key_size * 8);
return 0;
return 0;
}
/* ****************************************************** */
static void transop_tick_tf(n2n_trans_op_t * arg, time_t now) { ; }
static void transop_tick_tf (n2n_trans_op_t *arg, time_t now) {
// no tick action
}
/* ****************************************************** */
// Twofish initialization function
int n2n_transop_tf_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
int n2n_transop_tf_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
transop_tf_t *priv;
const u_char *encrypt_key = (const u_char *)conf->encrypt_key;
size_t encrypt_key_len = strlen(conf->encrypt_key);
transop_tf_t *priv;
const u_char *encrypt_key = (const u_char *)conf->encrypt_key;
size_t encrypt_key_len = strlen(conf->encrypt_key);
memset(ttt, 0, sizeof(*ttt));
ttt->transform_id = N2N_TRANSFORM_ID_TWOFISH;
memset(ttt, 0, sizeof(*ttt));
ttt->transform_id = N2N_TRANSFORM_ID_TWOFISH;
ttt->tick = transop_tick_tf;
ttt->deinit = transop_deinit_tf;
ttt->fwd = transop_encode_tf;
ttt->rev = transop_decode_tf;
ttt->tick = transop_tick_tf;
ttt->deinit = transop_deinit_tf;
ttt->fwd = transop_encode_tf;
ttt->rev = transop_decode_tf;
priv = (transop_tf_t*) calloc(1, sizeof(transop_tf_t));
if(!priv) {
traceEvent(TRACE_ERROR, "n2n_transop_tf_cbc_init cannot allocate transop_tf_t memory");
return -1;
}
ttt->priv = priv;
priv = (transop_tf_t*)calloc(1, sizeof(transop_tf_t));
if(!priv) {
traceEvent(TRACE_ERROR, "n2n_transop_tf_cbc_init cannot allocate transop_tf_t memory");
return -1;
}
ttt->priv = priv;
// setup the cipher and key
return setup_tf_key(priv, encrypt_key, encrypt_key_len);
// setup the cipher and key
return setup_tf_key(priv, encrypt_key, encrypt_key_len);
}

Loading…
Cancel
Save