X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccrypt%2Ftwofish.c;h=87d443c7fc91f67e4b8fc1140aa82b6e7040e0d4;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hp=c52438125f83fc1cfd7719c5971491fffd7d7933;hpb=22df1889422ee8031d08d1d6f08117c79dbade96;p=silc.git diff --git a/lib/silccrypt/twofish.c b/lib/silccrypt/twofish.c index c5243812..87d443c7 100644 --- a/lib/silccrypt/twofish.c +++ b/lib/silccrypt/twofish.c @@ -49,7 +49,7 @@ Mean: 378 cycles = 67.8 mbits/sec /* Sets the key for the cipher. */ -SILC_CIPHER_API_SET_KEY(twofish_cbc) +SILC_CIPHER_API_SET_KEY(twofish) { SilcUInt32 k[8]; @@ -59,65 +59,96 @@ SILC_CIPHER_API_SET_KEY(twofish_cbc) return TRUE; } +/* Sets IV for the cipher. */ + +SILC_CIPHER_API_SET_IV(twofish) +{ + TwofishContext *twofish = context; + + switch (cipher->mode) { + + case SILC_CIPHER_MODE_CTR: + /* Starts new block. */ + twofish->padlen = 0; + break; + + case SILC_CIPHER_MODE_CFB: + /* Starts new block. */ + twofish->padlen = 16; + break; + + default: + break; + } +} + /* Returns the size of the cipher context. */ -SILC_CIPHER_API_CONTEXT_LEN(twofish_cbc) +SILC_CIPHER_API_CONTEXT_LEN(twofish) { return sizeof(TwofishContext); } -/* Encrypts with the cipher in CBC mode. Source and destination buffers - maybe one and same. */ +/* Encrypts with the cipher. Source and destination buffers maybe one + and same. */ -SILC_CIPHER_API_ENCRYPT(twofish_cbc) +SILC_CIPHER_API_ENCRYPT(twofish) { - SilcUInt32 tiv[4]; + TwofishContext *twofish = context; + SilcUInt32 tmp[4], ctr[4]; int i; - SILC_ASSERT((len & (16 - 1)) == 0); - if (len & (16 - 1)) - return FALSE; - SILC_CBC_GET_IV(tiv, iv); + switch (cipher->mode) { - SILC_CBC_ENC_PRE(tiv, src); - twofish_encrypt((TwofishContext *)context, tiv, tiv); - SILC_CBC_ENC_POST(tiv, dst, src); + case SILC_CIPHER_MODE_CBC: + SILC_CBC_ENC_LSB_128_32(len, iv, tmp, src, dst, i, + twofish_encrypt(twofish, tmp, tmp)); + break; - for (i = 16; i < len; i += 16) { - SILC_CBC_ENC_PRE(tiv, src); - twofish_encrypt((TwofishContext *)context, tiv, tiv); - SILC_CBC_ENC_POST(tiv, dst, src); - } + case SILC_CIPHER_MODE_CTR: + SILC_CTR_LSB_128_32(iv, ctr, tmp, twofish->padlen, src, dst, + twofish_encrypt(twofish, tmp, tmp)); + break; + + case SILC_CIPHER_MODE_CFB: + SILC_CFB_ENC_LSB_128_32(iv, tmp, twofish->padlen, src, dst, + twofish_encrypt(twofish, tmp, tmp)); + break; - SILC_CBC_PUT_IV(tiv, iv); + default: + return FALSE; + } return TRUE; } -/* Decrypts with the cipher in CBC mode. Source and destination buffers - maybe one and same. */ +/* Decrypts with the cipher. Source and destination buffers maybe one + and same. */ -SILC_CIPHER_API_DECRYPT(twofish_cbc) +SILC_CIPHER_API_DECRYPT(twofish) { + TwofishContext *twofish = context; SilcUInt32 tmp[4], tmp2[4], tiv[4]; int i; - if (len & (16 - 1)) - return FALSE; + switch (cipher->mode) { - SILC_CBC_GET_IV(tiv, iv); + case SILC_CIPHER_MODE_CBC: + SILC_CBC_DEC_LSB_128_32(len, iv, tiv, tmp, tmp2, src, dst, i, + twofish_decrypt(twofish, tmp, tmp2)); - SILC_CBC_DEC_PRE(tmp, src); - twofish_decrypt((TwofishContext *)context, tmp, tmp2); - SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv); + case SILC_CIPHER_MODE_CTR: + return silc_twofish_encrypt(cipher, context, src, dst, len, iv); + break; - for (i = 16; i < len; i += 16) { - SILC_CBC_DEC_PRE(tmp, src); - twofish_decrypt((TwofishContext *)context, tmp, tmp2); - SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv); - } + case SILC_CIPHER_MODE_CFB: + SILC_CFB_DEC_LSB_128_32(iv, tmp, twofish->padlen, src, dst, + twofish_encrypt(twofish, tmp, tmp)); + break; - SILC_CBC_PUT_IV(tiv, iv); + default: + return FALSE; + } return TRUE; } @@ -173,7 +204,7 @@ u1byte qp(const u4byte n, const u1byte x) a3 = a2 ^ b2; b3 = ror4[b2] ^ ashx[a2]; a4 = qt2[n][a3]; b4 = qt3[n][b3]; return (b4 << 4) | a4; -}; +} #ifdef Q_TABLES @@ -190,7 +221,7 @@ void gen_qtab(void) q(0,i) = qp(0, (u1byte)i); q(1,i) = qp(1, (u1byte)i); } -}; +} #else @@ -216,7 +247,7 @@ void gen_mtab(void) m_tab[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24); m_tab[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24); } -}; +} #define mds(n,x) m_tab[n][x] @@ -295,7 +326,7 @@ u4byte h_fun(TwofishContext *ctx, const u4byte x, const u4byte key[]) return b0 | (b3 << 8) | (b2 << 16) | (b1 << 24); #endif -}; +} #ifdef MK_TABLE @@ -364,7 +395,7 @@ void gen_mk_tab(TwofishContext *ctx, u4byte key[]) #endif } } -}; +} # ifdef ONE_STEP # define g0_fun(x) ( mk_tab[0][byte(x,0)] ^ mk_tab[1][byte(x,1)] \ @@ -443,7 +474,7 @@ u4byte mds_rem(u4byte p0, u4byte p1) } return p1; -}; +} /* initialise the key schedule from the user supplied key */ @@ -491,7 +522,7 @@ u4byte *twofish_set_key(TwofishContext *ctx, #endif return l_key; -}; +} /* encrypt a block of text */ @@ -522,7 +553,7 @@ void twofish_encrypt(TwofishContext *ctx, out_blk[1] = blk[3] ^ l_key[5]; out_blk[2] = blk[0] ^ l_key[6]; out_blk[3] = blk[1] ^ l_key[7]; -}; +} /* decrypt a block of text */ @@ -553,4 +584,4 @@ void twofish_decrypt(TwofishContext *ctx, out_blk[1] = blk[3] ^ l_key[1]; out_blk[2] = blk[0] ^ l_key[2]; out_blk[3] = blk[1] ^ l_key[3]; -}; +}