int transop_twofish_setup( ntvl_trans_op_t * ttt, ntvl_sa_t sa_num, uint8_t * encrypt_pwd, uint32_t encrypt_pwd_len ) { int retval = 1; transop_tf_t * priv = NULL; if ( ttt->priv ) transop_deinit_twofish( ttt ); memset( ttt, 0, sizeof( ntvl_trans_op_t ) ); priv = (transop_tf_t *) malloc( sizeof(transop_tf_t) ); if ( NULL != priv ) { size_t i; sa_twofish_t * sa=NULL; /* install the private structure. */ ttt->priv = priv; for(i=0; i<NTVL_TWOFISH_NUM_SA; ++i) { sa = &(priv->sa[i]); sa->sa_id=0; memset( &(sa->spec), 0, sizeof(ntvl_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 = NTVL_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(ntvl_trans_op_t) ); traceEvent( TRACE_ERROR, "Failed to allocate priv for twofish" ); } return retval; }
static int transop_addspec_twofish( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) { int retval = 1; ssize_t pstat=-1; transop_tf_t * priv = (transop_tf_t *)arg->priv; uint8_t keybuf[N2N_MAX_KEYSIZE]; if ( priv->num_sa < N2N_TWOFISH_NUM_SA ) { const char * op = (const char *)cspec->opaque; const char * sep = index( op, '_' ); if ( sep ) { char tmp[256]; size_t s; s = sep - op; memcpy( tmp, cspec->opaque, s ); tmp[s]=0; s = strlen(sep+1); /* sep is the _ which might be immediately followed by NULL */ priv->sa[priv->num_sa].spec = *cspec; priv->sa[priv->num_sa].sa_id = strtoul(tmp, NULL, 10); pstat = n2n_parse_hex( keybuf, N2N_MAX_KEYSIZE, sep+1, s ); if ( pstat > 0 ) { priv->sa[priv->num_sa].enc_tf = TwoFishInit( keybuf, pstat); priv->sa[priv->num_sa].dec_tf = TwoFishInit( keybuf, pstat); traceEvent( TRACE_DEBUG, "transop_addspec_twofish sa_id=%u data=%s.\n", priv->sa[priv->num_sa].sa_id, sep+1); ++(priv->num_sa); retval = 0; } } else { traceEvent( TRACE_ERROR, "transop_addspec_twofish : bad key data - missing '_'.\n"); } } else { traceEvent( TRACE_ERROR, "transop_addspec_twofish : full.\n"); } return retval; }
void testObj::test<1>(void) { TWOFISHPtr fish( TwoFishInit("$3<r37") ); ensure("initialization failed", fish.get()!=NULL ); // encrypt const char bufEnc[]="Cypher"; char *encBuf =(char*)TwoFishAlloc(sizeof(bufEnc), false, false, fish.get()); size_t lenEnc =TwoFishEncrypt(bufEnc, &encBuf, sizeof(bufEnc), false, fish.get()); ensure("encryption failed", lenEnc!=0); // decrypt char decBuf[sizeof(bufEnc)]; char *decBufPtr=decBuf; size_t lenDec =TwoFishDecrypt(encBuf, &decBufPtr, sizeof(decBuf)+TwoFish_BLOCK_SIZE, false, fish.get()); ensure("decryption failed", lenDec!=0); ensure_equals("invalid size after decryption", lenDec, sizeof(bufEnc)); for(size_t i=0; i<sizeof(bufEnc); ++i) ensure_equals("invalid char decoded", decBuf[i], bufEnc[i]); }