X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccrypt%2Ftwofish.c;h=87d443c7fc91f67e4b8fc1140aa82b6e7040e0d4;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hp=ced96d3df4f76b239551b26f33a1815beb17d17f;hpb=cf21209b9866f826f566ebd10059661446f8b702;p=silc.git diff --git a/lib/silccrypt/twofish.c b/lib/silccrypt/twofish.c index ced96d3d..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; }