X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccrypt%2Ftwofish.c;h=87d443c7fc91f67e4b8fc1140aa82b6e7040e0d4;hb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;hp=53caed419f151b0d57e1931343b1579c40b7644d;hpb=3ed0f4669135b422c1dd094992ec0fe4cb318bca;p=silc.git diff --git a/lib/silccrypt/twofish.c b/lib/silccrypt/twofish.c index 53caed41..87d443c7 100644 --- a/lib/silccrypt/twofish.c +++ b/lib/silccrypt/twofish.c @@ -63,11 +63,22 @@ SILC_CIPHER_API_SET_KEY(twofish) SILC_CIPHER_API_SET_IV(twofish) { - if (cipher->mode == SILC_CIPHER_MODE_CTR) { - TwofishContext *twofish = context; + 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; } } @@ -90,62 +101,18 @@ SILC_CIPHER_API_ENCRYPT(twofish) switch (cipher->mode) { case SILC_CIPHER_MODE_CBC: - SILC_ASSERT((len & (16 - 1)) == 0); - if (len & (16 - 1)) - return FALSE; - SILC_CBC_GET_IV(tmp, iv); - - SILC_CBC_ENC_PRE(tmp, src); - twofish_encrypt(twofish, tmp, tmp); - SILC_CBC_ENC_POST(tmp, dst, src); - - for (i = 16; i < len; i += 16) { - SILC_CBC_ENC_PRE(tmp, src); - twofish_encrypt(twofish, tmp, tmp); - SILC_CBC_ENC_POST(tmp, dst, src); - } - - SILC_CBC_PUT_IV(tmp, iv); + SILC_CBC_ENC_LSB_128_32(len, iv, tmp, src, dst, i, + twofish_encrypt(twofish, tmp, tmp)); break; case SILC_CIPHER_MODE_CTR: - SILC_GET32_MSB(ctr[0], iv); - SILC_GET32_MSB(ctr[1], iv + 4); - SILC_GET32_MSB(ctr[2], iv + 8); - SILC_GET32_MSB(ctr[3], iv + 12); - - i = twofish->padlen; - if (!i) - i = 16; - - while (len-- > 0) { - if (i == 16) { - if (++ctr[3] == 0) - if (++ctr[2] == 0) - if (++ctr[1] == 0) - ++ctr[0]; - - tmp[0] = SILC_SWAB_32(ctr[0]); - tmp[1] = SILC_SWAB_32(ctr[1]); - tmp[2] = SILC_SWAB_32(ctr[2]); - tmp[3] = SILC_SWAB_32(ctr[3]); - - twofish_encrypt(twofish, tmp, tmp); - - SILC_PUT32_LSB(tmp[0], iv); - SILC_PUT32_LSB(tmp[1], iv + 4); - SILC_PUT32_LSB(tmp[2], iv + 8); - SILC_PUT32_LSB(tmp[3], iv + 12); - i = 0; - } - *dst++ = *src++ ^ iv[i++]; - } - twofish->padlen = i; + SILC_CTR_LSB_128_32(iv, ctr, tmp, twofish->padlen, src, dst, + twofish_encrypt(twofish, tmp, tmp)); + break; - SILC_PUT32_MSB(ctr[0], iv); - SILC_PUT32_MSB(ctr[1], iv + 4); - SILC_PUT32_MSB(ctr[2], iv + 8); - SILC_PUT32_MSB(ctr[3], iv + 12); + case SILC_CIPHER_MODE_CFB: + SILC_CFB_ENC_LSB_128_32(iv, tmp, twofish->padlen, src, dst, + twofish_encrypt(twofish, tmp, tmp)); break; default: @@ -160,33 +127,25 @@ SILC_CIPHER_API_ENCRYPT(twofish) SILC_CIPHER_API_DECRYPT(twofish) { + TwofishContext *twofish = context; SilcUInt32 tmp[4], tmp2[4], tiv[4]; int i; switch (cipher->mode) { case SILC_CIPHER_MODE_CBC: - if (len & (16 - 1)) - return FALSE; - - SILC_CBC_GET_IV(tiv, iv); - - SILC_CBC_DEC_PRE(tmp, src); - twofish_decrypt((TwofishContext *)context, tmp, tmp2); - SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv); - - 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); - } - - SILC_CBC_PUT_IV(tiv, iv); + SILC_CBC_DEC_LSB_128_32(len, iv, tiv, tmp, tmp2, src, dst, i, + twofish_decrypt(twofish, tmp, tmp2)); case SILC_CIPHER_MODE_CTR: return silc_twofish_encrypt(cipher, context, src, dst, len, iv); break; + case SILC_CIPHER_MODE_CFB: + SILC_CFB_DEC_LSB_128_32(iv, tmp, twofish->padlen, src, dst, + twofish_encrypt(twofish, tmp, tmp)); + break; + default: return FALSE; }