X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccrypt%2Ftwofish.c;h=e8f3bd44d88dc0fc961dea93b21b029b3ebed6f2;hb=e9374395ec9747bddd3ea0bfd3e5a17717e97b31;hp=b9036b4ef7e742baad81a0b9c2d17ffa6bc61bc8;hpb=642a33a4fca84f3dcf9624bd05b3dc6aa1c0dd29;p=silc.git diff --git a/lib/silccrypt/twofish.c b/lib/silccrypt/twofish.c index b9036b4e..e8f3bd44 100644 --- a/lib/silccrypt/twofish.c +++ b/lib/silccrypt/twofish.c @@ -39,18 +39,19 @@ Mean: 378 cycles = 67.8 mbits/sec */ -#include "silcincludes.h" +#include "silc.h" +#include "twofish_internal.h" #include "twofish.h" -/* +/* * SILC Crypto API for Twofish */ /* Sets the key for the cipher. */ -SILC_CIPHER_API_SET_KEY(twofish) +SILC_CIPHER_API_SET_KEY(twofish_cbc) { - uint32 k[8]; + SilcUInt32 k[8]; SILC_GET_WORD_KEY(key, k, keylen); twofish_set_key((TwofishContext *)context, k, keylen); @@ -58,17 +59,16 @@ SILC_CIPHER_API_SET_KEY(twofish) return TRUE; } -/* Sets the string as a new key for the cipher. The string is first - hashed and then used as a new key. */ +/* Sets IV for the cipher. */ -SILC_CIPHER_API_SET_KEY_WITH_STRING(twofish) +SILC_CIPHER_API_SET_IV(twofish_cbc) { - return FALSE; + } /* Returns the size of the cipher context. */ -SILC_CIPHER_API_CONTEXT_LEN(twofish) +SILC_CIPHER_API_CONTEXT_LEN(twofish_cbc) { return sizeof(TwofishContext); } @@ -76,11 +76,14 @@ SILC_CIPHER_API_CONTEXT_LEN(twofish) /* Encrypts with the cipher in CBC mode. Source and destination buffers maybe one and same. */ -SILC_CIPHER_API_ENCRYPT_CBC(twofish) +SILC_CIPHER_API_ENCRYPT(twofish_cbc) { - uint32 tiv[4]; + SilcUInt32 tiv[4]; int i; + SILC_ASSERT((len & (16 - 1)) == 0); + if (len & (16 - 1)) + return FALSE; SILC_CBC_GET_IV(tiv, iv); SILC_CBC_ENC_PRE(tiv, src); @@ -101,11 +104,14 @@ SILC_CIPHER_API_ENCRYPT_CBC(twofish) /* Decrypts with the cipher in CBC mode. Source and destination buffers maybe one and same. */ -SILC_CIPHER_API_DECRYPT_CBC(twofish) +SILC_CIPHER_API_DECRYPT(twofish_cbc) { - uint32 tmp[4], tmp2[4], tiv[4]; + SilcUInt32 tmp[4], tmp2[4], tiv[4]; int i; + if (len & (16 - 1)) + return FALSE; + SILC_CBC_GET_IV(tiv, iv); SILC_CBC_DEC_PRE(tmp, src); @@ -117,9 +123,9 @@ SILC_CIPHER_API_DECRYPT_CBC(twofish) twofish_decrypt((TwofishContext *)context, tmp, tmp2); SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv); } - + SILC_CBC_PUT_IV(tiv, iv); - + return TRUE; } @@ -145,26 +151,26 @@ u1byte tab_ef[4] = { 0, (G_M >> 1) ^ (G_M >> 2), G_M >> 1, G_M >> 2 }; u1byte ror4[16] = { 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 }; u1byte ashx[16] = { 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7 }; -u1byte qt0[2][16] = +u1byte qt0[2][16] = { { 8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4 }, { 2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5 } }; u1byte qt1[2][16] = -{ { 14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13 }, +{ { 14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13 }, { 1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8 } }; -u1byte qt2[2][16] = +u1byte qt2[2][16] = { { 11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1 }, { 4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15 } }; -u1byte qt3[2][16] = +u1byte qt3[2][16] = { { 13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10 }, { 11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10 } }; - + u1byte qp(const u4byte n, const u1byte x) { u1byte a0, a1, a2, a3, a4, b0, b1, b2, b3, b4; @@ -174,7 +180,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 @@ -187,11 +193,11 @@ void gen_qtab(void) { u4byte i; for(i = 0; i < 256; ++i) - { + { q(0,i) = qp(0, (u1byte)i); q(1,i) = qp(1, (u1byte)i); } -}; +} #else @@ -206,7 +212,7 @@ u4byte m_tab[4][256]; void gen_mtab(void) { u4byte i, f01, f5b, fef; - + for(i = 0; i < 256; ++i) { f01 = q(1,i); f5b = ffm_5b(f01); fef = ffm_ef(f01); @@ -217,7 +223,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] @@ -296,7 +302,7 @@ u4byte h_fun(TwofishContext *ctx, const u4byte x, const u4byte key[]) return b0 | (b3 << 8) | (b2 << 16) | (b1 << 24); #endif -}; +} #ifdef MK_TABLE @@ -334,12 +340,12 @@ void gen_mk_tab(TwofishContext *ctx, u4byte key[]) mk_tab[0][i] = mds(0, q20(by)); mk_tab[1][i] = mds(1, q21(by)); mk_tab[2][i] = mds(2, q22(by)); mk_tab[3][i] = mds(3, q23(by)); #else - sb[0][i] = q20(by); sb[1][i] = q21(by); + sb[0][i] = q20(by); sb[1][i] = q21(by); sb[2][i] = q22(by); sb[3][i] = q23(by); #endif } break; - + case 3: for(i = 0; i < 256; ++i) { by = (u1byte)i; @@ -347,12 +353,12 @@ void gen_mk_tab(TwofishContext *ctx, u4byte key[]) mk_tab[0][i] = mds(0, q30(by)); mk_tab[1][i] = mds(1, q31(by)); mk_tab[2][i] = mds(2, q32(by)); mk_tab[3][i] = mds(3, q33(by)); #else - sb[0][i] = q30(by); sb[1][i] = q31(by); + sb[0][i] = q30(by); sb[1][i] = q31(by); sb[2][i] = q32(by); sb[3][i] = q33(by); #endif } break; - + case 4: for(i = 0; i < 256; ++i) { by = (u1byte)i; @@ -360,12 +366,12 @@ void gen_mk_tab(TwofishContext *ctx, u4byte key[]) mk_tab[0][i] = mds(0, q40(by)); mk_tab[1][i] = mds(1, q41(by)); mk_tab[2][i] = mds(2, q42(by)); mk_tab[3][i] = mds(3, q43(by)); #else - sb[0][i] = q40(by); sb[1][i] = q41(by); + sb[0][i] = q40(by); sb[1][i] = q41(by); sb[2][i] = q42(by); sb[3][i] = q43(by); #endif } } -}; +} # ifdef ONE_STEP # define g0_fun(x) ( mk_tab[0][byte(x,0)] ^ mk_tab[1][byte(x,1)] \ @@ -393,22 +399,22 @@ void gen_mk_tab(TwofishContext *ctx, u4byte key[]) where the coefficients are in the finite field GF(2^8) with a modular polynomial a^8 + a^6 + a^3 + a^2 + 1. To generate the remainder we have to start with a 12th order polynomial with our -eight input bytes as the coefficients of the 4th to 11th terms. +eight input bytes as the coefficients of the 4th to 11th terms. That is: m[7] * x^11 + m[6] * x^10 ... + m[0] * x^4 + 0 * x^3 +... + 0 - + We then multiply the generator polynomial by m[7] * x^7 and subtract -it - xor in GF(2^8) - from the above to eliminate the x^7 term (the -artihmetic on the coefficients is done in GF(2^8). We then multiply +it - xor in GF(2^8) - from the above to eliminate the x^7 term (the +artihmetic on the coefficients is done in GF(2^8). We then multiply the generator polynomial by x^6 * coeff(x^10) and use this to remove the x^10 term. We carry on in this way until the x^4 term is removed so that we are left with: r[3] * x^3 + r[2] * x^2 + r[1] 8 x^1 + r[0] -which give the resulting 4 bytes of the remainder. This is equivalent -to the matrix multiplication in the Twofish description but much faster +which give the resulting 4 bytes of the remainder. This is equivalent +to the matrix multiplication in the Twofish description but much faster to implement. */ @@ -421,40 +427,40 @@ u4byte mds_rem(u4byte p0, u4byte p1) for(i = 0; i < 8; ++i) { t = p1 >> 24; /* get most significant coefficient */ - + p1 = (p1 << 8) | (p0 >> 24); p0 <<= 8; /* shift others up */ - + /* multiply t by a (the primitive element - i.e. left shift) */ - u = (t << 1); - + u = (t << 1); + if(t & 0x80) /* subtract modular polynomial on overflow */ - - u ^= G_MOD; + + u ^= G_MOD; p1 ^= t ^ (u << 16); /* remove t * (a * x^2 + 1) */ u ^= (t >> 1); /* form u = a * t + t / a = t * (a + 1 / a); */ - + if(t & 0x01) /* add the modular polynomial on underflow */ - + u ^= G_MOD >> 1; p1 ^= (u << 24) | (u << 8); /* remove t * (a + 1/a) * (x^3 + x) */ } return p1; -}; +} /* initialise the key schedule from the user supplied key */ u4byte *twofish_set_key(TwofishContext *ctx, const u4byte in_key[], const u4byte key_len) -{ +{ u4byte i, a, b, me_key[4], mo_key[4]; u4byte *l_key = ctx->l_key; u4byte *s_key = ctx->s_key; - + #ifdef Q_TABLES if(!qt_gen) { @@ -492,7 +498,7 @@ u4byte *twofish_set_key(TwofishContext *ctx, #endif return l_key; -}; +} /* encrypt a block of text */ @@ -506,7 +512,7 @@ u4byte *twofish_set_key(TwofishContext *ctx, void twofish_encrypt(TwofishContext *ctx, const u4byte in_blk[4], u4byte out_blk[]) -{ +{ u4byte t0, t1, blk[4]; u4byte *l_key = ctx->l_key; u4byte *s_key = ctx->s_key; @@ -522,8 +528,8 @@ void twofish_encrypt(TwofishContext *ctx, out_blk[0] = blk[2] ^ l_key[4]; out_blk[1] = blk[3] ^ l_key[5]; out_blk[2] = blk[0] ^ l_key[6]; - out_blk[3] = blk[1] ^ l_key[7]; -}; + out_blk[3] = blk[1] ^ l_key[7]; +} /* decrypt a block of text */ @@ -537,7 +543,7 @@ void twofish_encrypt(TwofishContext *ctx, void twofish_decrypt(TwofishContext *ctx, const u4byte in_blk[4], u4byte out_blk[4]) -{ +{ u4byte t0, t1, blk[4]; u4byte *l_key = ctx->l_key; u4byte *s_key = ctx->s_key; @@ -553,5 +559,5 @@ void twofish_decrypt(TwofishContext *ctx, out_blk[0] = blk[2] ^ l_key[0]; out_blk[1] = blk[3] ^ l_key[1]; out_blk[2] = blk[0] ^ l_key[2]; - out_blk[3] = blk[1] ^ l_key[3]; -}; + out_blk[3] = blk[1] ^ l_key[3]; +}