Merge pull request #60 from emanuele-f/enable_aes

Add AES CBC psk encryption
This commit is contained in:
Luca Deri 2019-01-28 21:52:04 +01:00 committed by GitHub
commit d275965e00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 193 additions and 120 deletions

View File

@ -76,7 +76,7 @@ supernode: sn.c $(N2N_LIB) n2n.h Makefile
$(CC) $(CFLAGS) sn.c $(N2N_LIB) $(LIBS_SN) -o supernode $(CC) $(CFLAGS) sn.c $(N2N_LIB) $(LIBS_SN) -o supernode
benchmark: benchmark.c $(N2N_LIB) n2n_wire.h n2n.h Makefile benchmark: benchmark.c $(N2N_LIB) n2n_wire.h n2n.h Makefile
$(CC) $(CFLAGS) benchmark.c $(N2N_LIB) $(LIBS_SN) -o benchmark $(CC) $(CFLAGS) benchmark.c $(N2N_LIB) $(LIBS_EDGE) -o benchmark
example_edge_embed: example_edge_embed.c $(N2N_LIB) n2n.h example_edge_embed: example_edge_embed.c $(N2N_LIB) n2n.h
$(CC) $(CFLAGS) example_edge_embed.c $(N2N_LIB) $(LIBS_EDGE) -o example_edge_embed $(CC) $(CFLAGS) example_edge_embed.c $(N2N_LIB) $(LIBS_EDGE) -o example_edge_embed

View File

@ -70,14 +70,38 @@ uint8_t PKT_CONTENT[]={
/* Prototypes */ /* Prototypes */
static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c ); static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c );
static void run_transop_benchmark(const char *op_name, n2n_trans_op_t *op_fn, uint8_t *pktbuf, n2n_community_t c);
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
uint8_t pktbuf[N2N_PKT_BUF_SIZE]; uint8_t pktbuf[N2N_PKT_BUF_SIZE];
n2n_trans_op_t transop_null; n2n_community_t c;
n2n_trans_op_t transop_null, transop_twofish, transop_aes_cbc;
u_char encrypt_pwd[] = "SoMEVer!S$cUREPassWORD";
memset(c,0,sizeof(N2N_COMMUNITY_SIZE));
memcpy(c, "abc123def456", 12);
/* Init transopts */
memset(&transop_null, 0, sizeof(transop_null));
transop_null_init(&transop_null);
memset(&transop_twofish, 0, sizeof(transop_twofish));
transop_twofish_init(&transop_twofish);
transop_twofish_setup_psk(&transop_twofish, 0, encrypt_pwd, sizeof(encrypt_pwd)-1);
memset(&transop_aes_cbc, 0, sizeof(transop_aes_cbc));
transop_aes_init(&transop_aes_cbc);
transop_aes_setup_psk(&transop_aes_cbc, 0, encrypt_pwd, sizeof(encrypt_pwd)-1);
/* Run the tests */
run_transop_benchmark("transop_null", &transop_null, pktbuf, c);
run_transop_benchmark("transop_twofish", &transop_twofish, pktbuf, c);
run_transop_benchmark("transop_aes", &transop_aes_cbc, pktbuf, c);
return 0;
}
static void run_transop_benchmark(const char *op_name, n2n_trans_op_t *op_fn, uint8_t *pktbuf, n2n_community_t c) {
n2n_common_t cmn; n2n_common_t cmn;
n2n_PACKET_t pkt; n2n_PACKET_t pkt;
n2n_community_t c;
struct timeval t1; struct timeval t1;
struct timeval t2; struct timeval t2;
@ -89,18 +113,14 @@ int main(int argc, char * argv[]) {
ssize_t nw; ssize_t nw;
ssize_t tdiff; ssize_t tdiff;
transop_null_init( &transop_null );
memset(c,0,sizeof(N2N_COMMUNITY_SIZE));
n=10000; n=10000;
memcpy( c, "abc123def456", 12 );
gettimeofday( &t1, NULL ); gettimeofday( &t1, NULL );
for(i=0; i<n; ++i) for(i=0; i<n; ++i)
{ {
nw = do_encode_packet( pktbuf, N2N_PKT_BUF_SIZE, c); nw = do_encode_packet( pktbuf, N2N_PKT_BUF_SIZE, c);
nw += transop_null.fwd( &transop_null, nw += op_fn->fwd( op_fn,
pktbuf+nw, N2N_PKT_BUF_SIZE-nw, pktbuf+nw, N2N_PKT_BUF_SIZE-nw,
PKT_CONTENT, sizeof(PKT_CONTENT) ); PKT_CONTENT, sizeof(PKT_CONTENT) );
@ -110,7 +130,7 @@ int main(int argc, char * argv[]) {
decode_common( &cmn, pktbuf, &rem, &idx); decode_common( &cmn, pktbuf, &rem, &idx);
decode_PACKET( &pkt, &cmn, pktbuf, &rem, &idx ); decode_PACKET( &pkt, &cmn, pktbuf, &rem, &idx );
if ( 0 == (i%1000) ) if ( 0 == (i%(n/10)) )
{ {
fprintf(stderr,"."); fprintf(stderr,".");
} }
@ -119,13 +139,12 @@ int main(int argc, char * argv[]) {
tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec); tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec);
fprintf( stderr, "\nrun %u times. (%u -> %u nsec each) %u.%06u -> %u.%06u.\n", fprintf( stderr, "\n[%s] %u times: (%u -> %u nsec each) %u.%06u -> %u.%06u.\n",
op_name,
(unsigned int)i, (unsigned int)tdiff, (unsigned int)i, (unsigned int)tdiff,
(unsigned int)((tdiff *1000)/i), (unsigned int)((tdiff *1000)/i),
(uint32_t)t1.tv_sec, (uint32_t)t1.tv_usec, (uint32_t)t1.tv_sec, (uint32_t)t1.tv_usec,
(uint32_t)t2.tv_sec, (uint32_t)t2.tv_usec ); (uint32_t)t2.tv_sec, (uint32_t)t2.tv_usec );
return 0;
} }
static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c ) static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c )
@ -154,3 +173,4 @@ static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_com
return idx; return idx;
} }

19
edge.c
View File

@ -136,7 +136,7 @@ static void help() {
"-l <supernode host:port>\n" "-l <supernode host:port>\n"
" " " "
"[-p <local port>] [-M <mtu>] " "[-p <local port>] [-M <mtu>] "
"[-r] [-E] [-v] [-t <mgmt port>] [-b] [-h]\n\n"); "[-r] [-E] [-v] [-t <mgmt port>] [-b] [-A] [-h]\n\n");
#ifdef __linux__ #ifdef __linux__
printf("-d <tun device> | tun device name\n"); printf("-d <tun device> | tun device name\n");
@ -162,6 +162,7 @@ static void help() {
" | eg. -m 01:02:03:04:05:06\n"); " | eg. -m 01:02:03:04:05:06\n");
printf("-M <mtu> | Specify n2n MTU of edge interface (default %d).\n", DEFAULT_MTU); printf("-M <mtu> | Specify n2n MTU of edge interface (default %d).\n", DEFAULT_MTU);
printf("-r | Enable packet forwarding through n2n community.\n"); printf("-r | Enable packet forwarding through n2n community.\n");
printf("-A | Set AES CBC as the preferred encryption mode.\n");
printf("-E | Accept multicast MAC addresses (default=drop).\n"); printf("-E | Accept multicast MAC addresses (default=drop).\n");
printf("-v | Make more verbose. Repeat as required.\n"); printf("-v | Make more verbose. Repeat as required.\n");
printf("-t <port> | Management UDP Port (for multiple edges on a machine).\n"); printf("-t <port> | Management UDP Port (for multiple edges on a machine).\n");
@ -268,6 +269,12 @@ static int setOption(int optkey, char *optargument, edge_conf_t *ec, n2n_edge_t
break; break;
} }
case 'A':
{
eee->preferred_aes = 1;
break;
}
case 'l': /* supernode-list */ case 'l': /* supernode-list */
if(optargument) { if(optargument) {
if(eee->sn_num < N2N_EDGE_NUM_SUPERNODES) { if(eee->sn_num < N2N_EDGE_NUM_SUPERNODES) {
@ -357,7 +364,7 @@ static int loadFromCLI(int argc, char *argv[], edge_conf_t *ec, n2n_edge_t *eee)
u_char c; u_char c;
while((c = getopt_long(argc, argv, while((c = getopt_long(argc, argv,
"K:k:a:bc:Eu:g:m:M:s:d:l:p:fvhrt:", "K:k:a:bc:Eu:g:m:M:s:d:l:p:fvhrAt:",
long_options, NULL)) != '?') { long_options, NULL)) != '?') {
if(c == 255) break; if(c == 255) break;
setOption(c, optarg, ec, eee); setOption(c, optarg, ec, eee);
@ -665,8 +672,12 @@ int main(int argc, char* argv[]) {
traceEvent(TRACE_NORMAL, "Binding to local port %d", (signed int)ec.local_port); traceEvent(TRACE_NORMAL, "Binding to local port %d", (signed int)ec.local_port);
if(ec.encrypt_key) { if(ec.encrypt_key) {
if(edge_init_twofish(&eee, (uint8_t *)(ec.encrypt_key), strlen(ec.encrypt_key)) < 0) { if(edge_init_aes_psk(&eee, (uint8_t *)(ec.encrypt_key), strlen(ec.encrypt_key)) < 0) {
fprintf(stderr, "Error: twofish setup failed.\n"); fprintf(stderr, "Error: AES PSK setup failed.\n");
return(-1);
}
if(edge_init_twofish_psk(&eee, (uint8_t *)(ec.encrypt_key), strlen(ec.encrypt_key)) < 0) {
fprintf(stderr, "Error: twofish PSK setup failed.\n");
return(-1); return(-1);
} }
} else if(strlen(eee.keyschedule) > 0) { } else if(strlen(eee.keyschedule) > 0) {

View File

@ -75,6 +75,7 @@ int edge_init(n2n_edge_t * eee) {
eee->tx_transop_idx = N2N_TRANSOP_NULL_IDX; /* No guarantee the others have been setup */ eee->tx_transop_idx = N2N_TRANSOP_NULL_IDX; /* No guarantee the others have been setup */
eee->daemon = 1; /* By default run in daemon mode. */ eee->daemon = 1; /* By default run in daemon mode. */
eee->preferred_aes = 0; /* Disable AES by default (for compatibility) */
eee->re_resolve_supernode_ip = 0; eee->re_resolve_supernode_ip = 0;
/* keyschedule set to NULLs by memset */ /* keyschedule set to NULLs by memset */
/* community_name set to NULLs by memset */ /* community_name set to NULLs by memset */
@ -644,37 +645,65 @@ const char * supernode_ip(const n2n_edge_t * eee) {
/* ************************************** */ /* ************************************** */
int edge_init_twofish(n2n_edge_t * eee, uint8_t *encrypt_pwd, int edge_init_twofish_psk(n2n_edge_t * eee, uint8_t *encrypt_pwd,
uint32_t encrypt_pwd_len) { uint32_t encrypt_pwd_len) {
return transop_twofish_setup(&(eee->transop[N2N_TRANSOP_TF_IDX]), return transop_twofish_setup_psk(&(eee->transop[N2N_TRANSOP_TF_IDX]),
0, encrypt_pwd, encrypt_pwd_len); 0, encrypt_pwd, encrypt_pwd_len);
} }
/* ************************************** */ /* ************************************** */
int edge_init_aes_psk(n2n_edge_t * eee, uint8_t *encrypt_pwd,
uint32_t encrypt_pwd_len) {
return transop_aes_setup_psk(&(eee->transop[N2N_TRANSOP_AESCBC_IDX]),
0, encrypt_pwd, encrypt_pwd_len);
}
/* ************************************** */
static n2n_tostat_t n2n_tick_aes(n2n_edge_t * eee, time_t now, size_t *trop) {
n2n_tostat_t tst = (eee->transop[N2N_TRANSOP_AESCBC_IDX].tick)(&(eee->transop[N2N_TRANSOP_AESCBC_IDX]), now);
if(tst.can_tx)
{
traceEvent(TRACE_DEBUG, "can_tx AESCBC (idx=%u)", (unsigned int)N2N_TRANSOP_AESCBC_IDX);
*trop = N2N_TRANSOP_AESCBC_IDX;
}
return tst;
}
/* ************************************** */
static n2n_tostat_t n2n_tick_twofish(n2n_edge_t * eee, time_t now, size_t *trop) {
n2n_tostat_t tst = (eee->transop[N2N_TRANSOP_TF_IDX].tick)(&(eee->transop[N2N_TRANSOP_TF_IDX]), now);
if(tst.can_tx)
{
traceEvent(TRACE_DEBUG, "can_tx TF (idx=%u)", (unsigned int)N2N_TRANSOP_TF_IDX);
*trop = N2N_TRANSOP_TF_IDX;
}
return tst;
}
/* ************************************** */
/** Called periodically to roll keys and do any periodic maintenance in the /** Called periodically to roll keys and do any periodic maintenance in the
* tranform operations state machines. */ * tranform operations state machines. */
static int n2n_tick_transop(n2n_edge_t * eee, time_t now) static int n2n_tick_transop(n2n_edge_t * eee, time_t now)
{ {
n2n_tostat_t tst;
size_t trop = eee->tx_transop_idx; size_t trop = eee->tx_transop_idx;
/* Tests are done in order that most preferred transform is last and causes /* Tests are done in order that most preferred transform is last and causes
* tx_transop_idx to be left at most preferred valid transform. */ * tx_transop_idx to be left at most preferred valid transform. */
tst = (eee->transop[N2N_TRANSOP_NULL_IDX].tick)(&(eee->transop[N2N_TRANSOP_NULL_IDX]), now); (eee->transop[N2N_TRANSOP_NULL_IDX].tick)(&(eee->transop[N2N_TRANSOP_NULL_IDX]), now);
tst = (eee->transop[N2N_TRANSOP_AESCBC_IDX].tick)(&(eee->transop[N2N_TRANSOP_AESCBC_IDX]), now);
if(tst.can_tx)
{
traceEvent(TRACE_DEBUG, "can_tx AESCBC (idx=%u)", (unsigned int)N2N_TRANSOP_AESCBC_IDX);
trop = N2N_TRANSOP_AESCBC_IDX;
}
tst = (eee->transop[N2N_TRANSOP_TF_IDX].tick)(&(eee->transop[N2N_TRANSOP_TF_IDX]), now); if(eee->preferred_aes) {
if(tst.can_tx) n2n_tick_twofish(eee, now, &trop);
{ n2n_tick_aes(eee, now, &trop);
traceEvent(TRACE_DEBUG, "can_tx TF (idx=%u)", (unsigned int)N2N_TRANSOP_TF_IDX); } else {
trop = N2N_TRANSOP_TF_IDX; n2n_tick_aes(eee, now, &trop);
} n2n_tick_twofish(eee, now, &trop);
}
if(trop != eee->tx_transop_idx) if(trop != eee->tx_transop_idx)
{ {
@ -1688,8 +1717,10 @@ int quick_edge_init(char *device_name, char *community_name,
device_mac, DEFAULT_MTU) < 0) device_mac, DEFAULT_MTU) < 0)
return(-1); return(-1);
if(edge_init_twofish(&eee, (uint8_t *)encrypt_key, strlen(encrypt_key)) < 0) if(edge_init_aes_psk(&eee, (uint8_t *)encrypt_key, strlen(encrypt_key)) < 0)
return(-2); return(-2);
if(edge_init_twofish_psk(&eee, (uint8_t *)encrypt_key, strlen(encrypt_key)) < 0)
return(-2);
snprintf((char*)eee.community_name, sizeof(eee.community_name), "%s", community_name); snprintf((char*)eee.community_name, sizeof(eee.community_name), "%s", community_name);
supernode2addr(&(eee.supernode), supernode_ip_address_port); supernode2addr(&(eee.supernode), supernode_ip_address_port);

5
n2n.h
View File

@ -186,6 +186,7 @@ typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE];
struct n2n_edge { struct n2n_edge {
int daemon; /**< Non-zero if edge should detach and run in the background. */ int daemon; /**< Non-zero if edge should detach and run in the background. */
int preferred_aes; /**< Non-zero if AES is the preferred encryption meothd. */
uint8_t re_resolve_supernode_ip; uint8_t re_resolve_supernode_ip;
n2n_sock_t supernode; n2n_sock_t supernode;
@ -337,7 +338,9 @@ void set_peer_operational(n2n_edge_t * eee,
const n2n_mac_t mac, const n2n_mac_t mac,
const n2n_sock_t * peer); const n2n_sock_t * peer);
const char * supernode_ip(const n2n_edge_t * eee); const char * supernode_ip(const n2n_edge_t * eee);
int edge_init_twofish(n2n_edge_t * eee, uint8_t *encrypt_pwd, int edge_init_twofish_psk(n2n_edge_t * eee, uint8_t *encrypt_pwd,
uint32_t encrypt_pwd_len);
int edge_init_aes_psk(n2n_edge_t * eee, uint8_t *encrypt_pwd,
uint32_t encrypt_pwd_len); uint32_t encrypt_pwd_len);
int run_edge_loop(n2n_edge_t * eee, int *keep_running); int run_edge_loop(n2n_edge_t * eee, int *keep_running);
void edge_term(n2n_edge_t * eee); void edge_term(n2n_edge_t * eee);

View File

@ -78,7 +78,12 @@ struct n2n_trans_op {
}; };
/* Setup a single twofish SA for single-key operation. */ /* Setup a single twofish SA for single-key operation. */
int transop_twofish_setup( n2n_trans_op_t * ttt, int transop_twofish_setup_psk( n2n_trans_op_t * ttt,
n2n_sa_t sa_num,
uint8_t * encrypt_pwd,
uint32_t encrypt_pwd_len );
/* Setup a single AES SA for single-key operation. */
int transop_aes_setup_psk( n2n_trans_op_t * ttt,
n2n_sa_t sa_num, n2n_sa_t sa_num,
uint8_t * encrypt_pwd, uint8_t * encrypt_pwd,
uint32_t encrypt_pwd_len ); uint32_t encrypt_pwd_len );

View File

@ -339,6 +339,41 @@ static int transop_decode_aes( n2n_trans_op_t * arg,
return len; return len;
} }
/*
* priv: pointer to transform state
* keybuf: buffer holding the key
* pstat: length of keybuf
*/
static void add_aes_key(transop_aes_t *priv, uint8_t *keybuf, ssize_t pstat) {
/* pstat is number of bytes read into keybuf. */
sa_aes_t * sa = &(priv->sa[priv->num_sa]);
size_t aes_keysize_bytes;
size_t aes_keysize_bits;
/* Clear out any old possibly longer key matter. */
memset( &(sa->enc_key), 0, sizeof(AES_KEY) );
memset( &(sa->dec_key), 0, sizeof(AES_KEY) );
memset( &(sa->enc_ivec), 0, sizeof(N2N_AES_IVEC_SIZE) );
memset( &(sa->dec_ivec), 0, sizeof(N2N_AES_IVEC_SIZE) );
aes_keysize_bytes = aes_best_keysize(pstat);
aes_keysize_bits = 8 * aes_keysize_bytes;
/* Use N2N_MAX_KEYSIZE because the AES key needs to be of fixed
* size. If fewer bits specified then the rest will be
* zeroes. AES acceptable key sizes are 128, 192 and 256
* bits. */
AES_set_encrypt_key( keybuf, aes_keysize_bits, &(sa->enc_key));
AES_set_decrypt_key( keybuf, aes_keysize_bits, &(sa->dec_key));
/* Leave ivecs set to all zeroes */
traceEvent( TRACE_DEBUG, "transop_addspec_aes sa_id=%u, %u bits data=%s.\n",
priv->sa[priv->num_sa].sa_id, aes_keysize_bits, keybuf);
++(priv->num_sa);
}
static int transop_addspec_aes( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) static int transop_addspec_aes( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec )
{ {
int retval = 1; int retval = 1;
@ -369,33 +404,7 @@ static int transop_addspec_aes( n2n_trans_op_t * arg, const n2n_cipherspec_t * c
pstat = n2n_parse_hex( keybuf, N2N_MAX_KEYSIZE, sep+1, s ); pstat = n2n_parse_hex( keybuf, N2N_MAX_KEYSIZE, sep+1, s );
if ( pstat > 0 ) if ( pstat > 0 )
{ {
/* pstat is number of bytes read into keybuf. */ add_aes_key(priv, keybuf, pstat);
sa_aes_t * sa = &(priv->sa[priv->num_sa]);
size_t aes_keysize_bytes;
size_t aes_keysize_bits;
/* Clear out any old possibly longer key matter. */
memset( &(sa->enc_key), 0, sizeof(AES_KEY) );
memset( &(sa->dec_key), 0, sizeof(AES_KEY) );
memset( &(sa->enc_ivec), 0, sizeof(N2N_AES_IVEC_SIZE) );
memset( &(sa->dec_ivec), 0, sizeof(N2N_AES_IVEC_SIZE) );
aes_keysize_bytes = aes_best_keysize(pstat);
aes_keysize_bits = 8 * aes_keysize_bytes;
/* Use N2N_MAX_KEYSIZE because the AES key needs to be of fixed
* size. If fewer bits specified then the rest will be
* zeroes. AES acceptable key sizes are 128, 192 and 256
* bits. */
AES_set_encrypt_key( keybuf, aes_keysize_bits, &(sa->enc_key));
AES_set_decrypt_key( keybuf, aes_keysize_bits, &(sa->dec_key));
/* Leave ivecs set to all zeroes */
traceEvent( TRACE_DEBUG, "transop_addspec_aes sa_id=%u, %u bits data=%s.\n",
priv->sa[priv->num_sa].sa_id, aes_keysize_bits, sep+1);
++(priv->num_sa);
retval = 0; retval = 0;
} }
} }
@ -510,6 +519,31 @@ int transop_aes_init( n2n_trans_op_t * ttt )
return retval; return retval;
} }
/* Setup AES in pre-shared key mode */
int transop_aes_setup_psk(n2n_trans_op_t *ttt,
n2n_sa_t sa_num,
uint8_t *encrypt_pwd,
uint32_t encrypt_pwd_len) {
int retval = 1;
transop_aes_t *priv = (transop_aes_t *)ttt->priv;
if(ttt->priv) {
sa_aes_t *sa;
priv->num_sa=0;
priv->tx_sa=0;
sa = &(priv->sa[priv->tx_sa]);
sa->sa_id=sa_num;
sa->spec.valid_until = 0x7fffffff;
/* This is a preshared key setup. Both Tx and Rx are using the same security association. */
add_aes_key(priv, encrypt_pwd, encrypt_pwd_len);
retval = 0;
} else
traceEvent(TRACE_ERROR, "AES priv is not allocated");
return retval;
}
#else /* #if defined(N2N_HAVE_AES) */ #else /* #if defined(N2N_HAVE_AES) */
struct transop_aes struct transop_aes
@ -606,5 +640,13 @@ int transop_aes_init( n2n_trans_op_t * ttt )
return retval; return retval;
} }
int transop_aes_setup_psk(n2n_trans_op_t *ttt,
n2n_sa_t sa_num,
uint8_t *encrypt_pwd,
uint32_t encrypt_pwd_len) {
return 0;
}
#endif /* #if defined(N2N_HAVE_AES) */ #endif /* #if defined(N2N_HAVE_AES) */

View File

@ -384,73 +384,34 @@ static n2n_tostat_t transop_tick_twofish( n2n_trans_op_t * arg, time_t now )
return r; return r;
} }
int transop_twofish_setup_psk( n2n_trans_op_t * ttt,
int transop_twofish_setup( n2n_trans_op_t * ttt,
n2n_sa_t sa_num, n2n_sa_t sa_num,
uint8_t * encrypt_pwd, uint8_t * encrypt_pwd,
uint32_t encrypt_pwd_len ) uint32_t encrypt_pwd_len )
{ {
int retval = 1; int retval = 1;
transop_tf_t * priv = NULL; transop_tf_t * priv = (transop_tf_t *)ttt->priv;
if ( ttt->priv ) if(priv) {
{ sa_twofish_t *sa;
transop_deinit_twofish( ttt );
}
memset( ttt, 0, sizeof( n2n_trans_op_t ) ); priv->num_sa=1; /* There is one SA in the array. */
priv->tx_sa=0;
sa = &(priv->sa[priv->tx_sa]);
sa->sa_id=sa_num;
sa->spec.valid_until = 0x7fffffff;
priv = (transop_tf_t *) malloc( sizeof(transop_tf_t) ); /* This is a preshared key setup. Both Tx and Rx are using the same security association. */
if ( NULL != priv ) sa->enc_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len);
{ sa->dec_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len);
size_t i;
sa_twofish_t * sa=NULL;
/* install the private structure. */ if ( (sa->enc_tf) && (sa->dec_tf) )
ttt->priv = priv; retval = 0;
else
for(i=0; i<N2N_TWOFISH_NUM_SA; ++i) traceEvent( TRACE_ERROR, "transop_twofish_setup_psk" );
{ } else
sa = &(priv->sa[i]); traceEvent( TRACE_ERROR, "twofish priv is not allocated" );
sa->sa_id=0;
memset( &(sa->spec), 0, sizeof(n2n_cipherspec_t) );
sa->enc_tf=NULL;
sa->dec_tf=NULL;
}
priv->num_sa=1; /* There is one SA in the array. */
priv->tx_sa=0;
sa = &(priv->sa[priv->tx_sa]);
sa->sa_id=sa_num;
sa->spec.valid_until = 0x7fffffff;
/* This is a preshared key setup. Both Tx and Rx are using the same security association. */
sa->enc_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len);
sa->dec_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len);
if ( (sa->enc_tf) && (sa->dec_tf) )
{
ttt->transform_id = N2N_TRANSFORM_ID_TWOFISH;
ttt->deinit = transop_deinit_twofish;
ttt->addspec = transop_addspec_twofish;
ttt->tick = transop_tick_twofish; /* chooses a new tx_sa */
ttt->fwd = transop_encode_twofish;
ttt->rev = transop_decode_twofish;
retval = 0;
}
else
{
traceEvent( TRACE_ERROR, "TwoFishInit failed" );
}
}
else
{
memset( ttt, 0, sizeof(n2n_trans_op_t) );
traceEvent( TRACE_ERROR, "Failed to allocate priv for twofish" );
}
return retval; return retval;
} }