Added SILC Server library.
[silc.git] / lib / silccrypt / twofish.c
index 08d3d510aaab371ed459a214cb75add7d4eda4ef..ebfc19a4749cf05137d61ab59112174cb3991db0 100644 (file)
@@ -39,7 +39,8 @@ Mean:          378 cycles =    67.8 mbits/sec
 
 */
 
-#include "silcincludes.h"
+#include "silc.h"
+#include "twofish_internal.h"
 #include "twofish.h"
 
 /* 
@@ -50,8 +51,12 @@ 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
@@ -59,15 +64,7 @@ SILC_CIPHER_API_SET_KEY(twofish)
 
 SILC_CIPHER_API_SET_KEY_WITH_STRING(twofish)
 {
-  /*  unsigned char key[md5_hash_len];
-  SilcMarsContext *ctx = (SilcMarsContext *)context;
-
-  make_md5_hash(string, &key);
-  memcpy(&ctx->key, mars_set_key(&key, keylen), keylen);
-  memset(&key, 'F', sizeoof(key));
-  */
-
-  return 1;
+  return FALSE;
 }
 
 /* Returns the size of the cipher context. */
@@ -82,36 +79,22 @@ SILC_CIPHER_API_CONTEXT_LEN(twofish)
 
 SILC_CIPHER_API_ENCRYPT_CBC(twofish)
 {
-  unsigned int *in, *out, *tiv;
-  unsigned int tmp[4];
+  SilcUInt32 tiv[4];
   int i;
 
-  in = (unsigned int *)src;
-  out = (unsigned int *)dst;
-  tiv = (unsigned int *)iv;
+  SILC_CBC_GET_IV(tiv, 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;
+  SILC_CBC_ENC_PRE(tiv, src);
+  twofish_encrypt((TwofishContext *)context, tiv, tiv);
+  SILC_CBC_ENC_POST(tiv, dst, src);
 
   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;
+    SILC_CBC_ENC_PRE(tiv, src);
+    twofish_encrypt((TwofishContext *)context, tiv, tiv);
+    SILC_CBC_ENC_POST(tiv, dst, src);
   }
 
-  tiv[0] = out[0 - 4];
-  tiv[1] = out[1 - 4];
-  tiv[2] = out[2 - 4];
-  tiv[3] = out[3 - 4];
+  SILC_CBC_PUT_IV(tiv, iv);
 
   return TRUE;
 }
@@ -121,49 +104,23 @@ SILC_CIPHER_API_ENCRYPT_CBC(twofish)
 
 SILC_CIPHER_API_DECRYPT_CBC(twofish)
 {
-  unsigned int *tiv, *in, *out;
-  unsigned int tmp[4], tmp2[4];
+  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;
+  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) {
-    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;
+    SILC_CBC_DEC_PRE(tmp, src);
+    twofish_decrypt((TwofishContext *)context, tmp, tmp2);
+    SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv);
   }
-
-  tiv[0] = tmp[0];
-  tiv[1] = tmp[1];
-  tiv[2] = tmp[2];
-  tiv[3] = tmp[3];
-
+  
+  SILC_CBC_PUT_IV(tiv, iv);
+  
   return TRUE;
 }
 
@@ -464,27 +421,27 @@ u4byte mds_rem(u4byte p0, u4byte p1)
 
     for(i = 0; i < 8; ++i)
     {
-        t = p1 >> 24;   // get most significant coefficient
+        t = p1 >> 24;   /* get most significant coefficient */
         
-        p1 = (p1 << 8) | (p0 >> 24); p0 <<= 8;  // shift others up
+        p1 = (p1 << 8) | (p0 >> 24); p0 <<= 8;  /* shift others up */
             
-        // multiply t by a (the primitive element - i.e. left shift)
+        /* multiply t by a (the primitive element - i.e. left shift) */
 
         u = (t << 1); 
         
-        if(t & 0x80)            // subtract modular polynomial on overflow
+        if(t & 0x80)            /* subtract modular polynomial on overflow */
         
             u ^= G_MOD; 
 
-        p1 ^= t ^ (u << 16);    // remove t * (a * x^2 + 1)  
+        p1 ^= t ^ (u << 16);    /* remove t * (a * x^2 + 1) */
 
-        u ^= (t >> 1);          // form u = a * t + t / a = t * (a + 1 / a); 
+        u ^= (t >> 1);          /* form u = a * t + t / a = t * (a + 1 / a); */
         
-        if(t & 0x01)            // add the modular polynomial on underflow
+        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;