Added SILC Thread Queue API
[silc.git] / lib / silccrypt / twofish.c
index 08d3d510aaab371ed459a214cb75add7d4eda4ef..87d443c7fc91f67e4b8fc1140aa82b6e7040e0d4 100644 (file)
@@ -39,10 +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
  */
 
@@ -50,24 +51,35 @@ Mean:          378 cycles =    67.8 mbits/sec
 
 SILC_CIPHER_API_SET_KEY(twofish)
 {
-  twofish_set_key((TwofishContext *)context, (unsigned int *)key, keylen);
-  return 1;
+  SilcUInt32 k[8];
+
+  SILC_GET_WORD_KEY(key, k, keylen);
+  twofish_set_key((TwofishContext *)context, k, keylen);
+
+  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)
 {
-  /*  unsigned char key[md5_hash_len];
-  SilcMarsContext *ctx = (SilcMarsContext *)context;
+  TwofishContext *twofish = context;
+
+  switch (cipher->mode) {
 
-  make_md5_hash(string, &key);
-  memcpy(&ctx->key, mars_set_key(&key, keylen), keylen);
-  memset(&key, 'F', sizeoof(key));
-  */
+  case SILC_CIPHER_MODE_CTR:
+    /* Starts new block. */
+    twofish->padlen = 0;
+    break;
 
-  return 1;
+  case SILC_CIPHER_MODE_CFB:
+    /* Starts new block. */
+    twofish->padlen = 16;
+    break;
+
+  default:
+    break;
+  }
 }
 
 /* Returns the size of the cipher context. */
@@ -77,92 +89,66 @@ 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)
 {
-  unsigned int *in, *out, *tiv;
-  unsigned int tmp[4];
+  TwofishContext *twofish = context;
+  SilcUInt32 tmp[4], ctr[4];
   int i;
 
-  in = (unsigned int *)src;
-  out = (unsigned int *)dst;
-  tiv = (unsigned int *)iv;
-
-  tmp[0] = in[0] ^ tiv[0];
-  tmp[1] = in[1] ^ tiv[1];
-  tmp[2] = in[2] ^ tiv[2];
-  tmp[3] = in[3] ^ tiv[3];
-  twofish_encrypt((TwofishContext *)context, tmp, out);
-  in += 4;
-  out += 4;
-
-  for (i = 16; i < len; i += 16) {
-    tmp[0] = in[0] ^ out[0 - 4];
-    tmp[1] = in[1] ^ out[1 - 4];
-    tmp[2] = in[2] ^ out[2 - 4];
-    tmp[3] = in[3] ^ out[3 - 4];
-    twofish_encrypt((TwofishContext *)context, tmp, out);
-    in += 4;
-    out += 4;
-  }
+  switch (cipher->mode) {
 
-  tiv[0] = out[0 - 4];
-  tiv[1] = out[1 - 4];
-  tiv[2] = out[2 - 4];
-  tiv[3] = out[3 - 4];
+  case SILC_CIPHER_MODE_CBC:
+    SILC_CBC_ENC_LSB_128_32(len, iv, tmp, src, dst, i,
+                           twofish_encrypt(twofish, tmp, tmp));
+    break;
+
+  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;
+
+  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)
 {
-  unsigned int *tiv, *in, *out;
-  unsigned int tmp[4], tmp2[4];
+  TwofishContext *twofish = context;
+  SilcUInt32 tmp[4], tmp2[4], tiv[4];
   int i;
 
-  in = (unsigned int *)src;
-  out = (unsigned int *)dst;
-  tiv = (unsigned int *)iv;
-
-  tmp[0] = in[0];
-  tmp[1] = in[1];
-  tmp[2] = in[2];
-  tmp[3] = in[3];
-  twofish_decrypt((TwofishContext *)context, in, out);
-  out[0] ^= tiv[0];
-  out[1] ^= tiv[1];
-  out[2] ^= tiv[2];
-  out[3] ^= tiv[3];
-  in += 4;
-  out += 4;
-
-  for (i = 16; i < len; i += 16) {
-    tmp2[0] = tmp[0];
-    tmp2[1] = tmp[1];
-    tmp2[2] = tmp[2];
-    tmp2[3] = tmp[3];
-    tmp[0] = in[0];
-    tmp[1] = in[1];
-    tmp[2] = in[2];
-    tmp[3] = in[3];
-    twofish_decrypt((TwofishContext *)context, in, out);
-    out[0] ^= tmp2[0];
-    out[1] ^= tmp2[1];
-    out[2] ^= tmp2[2];
-    out[3] ^= tmp2[3];
-    in += 4;
-    out += 4;
-  }
+  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));
+
+  case SILC_CIPHER_MODE_CTR:
+    return silc_twofish_encrypt(cipher, context, src, dst, len, iv);
+    break;
 
-  tiv[0] = tmp[0];
-  tiv[1] = tmp[1];
-  tiv[2] = tmp[2];
-  tiv[3] = tmp[3];
+  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;
+  }
 
   return TRUE;
 }
@@ -189,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;
 
@@ -218,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
 
@@ -231,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
 
@@ -250,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);
@@ -261,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]
 
@@ -340,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
 
@@ -378,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;
@@ -391,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;
@@ -404,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)] \
@@ -437,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.
 
 */
@@ -464,41 +450,41 @@ 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); 
-        
-        if(t & 0x80)            // subtract modular polynomial on overflow
-        
-            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
-        
+        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);
+
+        if(t & 0x80)            /* subtract modular polynomial on overflow */
+
+            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)
+        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)
     {
@@ -536,7 +522,7 @@ u4byte *twofish_set_key(TwofishContext *ctx,
 #endif
 
     return l_key;
-};
+}
 
 /* encrypt a block of text  */
 
@@ -550,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;
@@ -566,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  */
 
@@ -581,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;
@@ -597,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];
+}