Added SILC Thread Queue API
[silc.git] / lib / silccrypt / twofish.c
index c4cf7c8629d42b6c879f0cbb7e6bed29a095e163..87d443c7fc91f67e4b8fc1140aa82b6e7040e0d4 100644 (file)
@@ -39,11 +39,11 @@ 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
  */
 
@@ -51,7 +51,7 @@ Mean:          378 cycles =    67.8 mbits/sec
 
 SILC_CIPHER_API_SET_KEY(twofish)
 {
-  uint32 k[8];
+  SilcUInt32 k[8];
 
   SILC_GET_WORD_KEY(key, k, keylen);
   twofish_set_key((TwofishContext *)context, k, keylen);
@@ -59,12 +59,27 @@ 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)
 {
-  return FALSE;
+  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. */
@@ -74,53 +89,67 @@ 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_CBC(twofish)
+SILC_CIPHER_API_ENCRYPT(twofish)
 {
-  uint32 tiv[4];
+  TwofishContext *twofish = context;
+  SilcUInt32 tmp[4], ctr[4];
   int i;
 
-  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;
 
-  SILC_CBC_PUT_IV(tiv, iv);
+  case SILC_CIPHER_MODE_CFB:
+    SILC_CFB_ENC_LSB_128_32(iv, tmp, twofish->padlen, src, dst,
+                           twofish_encrypt(twofish, tmp, tmp));
+    break;
+
+  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_CBC(twofish)
+SILC_CIPHER_API_DECRYPT(twofish)
 {
-  uint32 tmp[4], tmp2[4], tiv[4];
+  TwofishContext *twofish = context;
+  SilcUInt32 tmp[4], tmp2[4], tiv[4];
   int i;
 
-  SILC_CBC_GET_IV(tiv, iv);
+  switch (cipher->mode) {
+
+  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;
+
+  default:
+    return FALSE;
   }
-  
-  SILC_CBC_PUT_IV(tiv, iv);
-  
+
   return TRUE;
 }
 
@@ -146,26 +175,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;
 
@@ -175,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
 
@@ -188,11 +217,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
 
@@ -207,7 +236,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);
@@ -218,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]
 
@@ -297,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
 
@@ -335,12 +364,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;
@@ -348,12 +377,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;
@@ -361,12 +390,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)] \
@@ -394,22 +423,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.
 
 */
@@ -422,40 +451,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)
     {
@@ -493,7 +522,7 @@ u4byte *twofish_set_key(TwofishContext *ctx,
 #endif
 
     return l_key;
-};
+}
 
 /* encrypt a block of text  */
 
@@ -507,7 +536,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;
@@ -523,8 +552,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  */
 
@@ -538,7 +567,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;
@@ -554,5 +583,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];
+}