Major restructuring of the internals of SILC Cipher API
[crypto.git] / lib / silccrypt / rc5.c
index c0db8e950cbc57218ce3a888f5852fefa6d1908c..3e93da32c49c1b95aa5f5d27372043853f377d82 100644 (file)
  */
 
 /*
- * Based on RC5 reference code and on description of Bruce Schneier's 
+ * Based on RC5 reference code and on description of Bruce Schneier's
  * Applied Cryptography.
  *
- * This implementation has a word size of 32 bits, a rounds of 16 and 
+ * This implementation has a word size of 32 bits, a rounds of 16 and
  * variable key length from 128 and 192 up to 256 bits.
  *
  */
 
-#include "silcincludes.h"
+#include "silccrypto.h"
+#include "rc5_internal.h"
 #include "rc5.h"
 
+/*
+ * SILC Crypto API for RC5
+ */
+
+/* Sets the key for the cipher. */
+
+SILC_CIPHER_API_SET_KEY(rc5_cbc)
+{
+  SilcUInt32 k[8];
+
+  SILC_GET_WORD_KEY(key, k, keylen);
+  rc5_set_key((RC5Context *)context, k, keylen);
+
+  return TRUE;
+}
+
+/* Sets IV for the cipher. */
+
+SILC_CIPHER_API_SET_IV(rc5_cbc)
+{
+
+}
+
+/* Initialize */
+
+SILC_CIPHER_API_INIT(rc5_cbc)
+{
+  return silc_calloc(1, sizeof(RC5Context));
+}
+
+/* Initialize */
+
+SILC_CIPHER_API_UNINIT(rc5_cbc)
+{
+  RC5Context *rc5 = context;
+  memset(rc5, 0, sizeof(*rc5));
+  silc_free(rc5);
+}
+
+/* Encrypts with the cipher in CBC mode. Source and destination buffers
+   maybe one and same. */
+
+SILC_CIPHER_API_ENCRYPT(rc5_cbc)
+{
+  SilcUInt32 tiv[4];
+  int i;
+
+  SILC_CBC_GET_IV(tiv, iv);
+
+  SILC_CBC_ENC_PRE(tiv, src);
+  rc5_encrypt((RC5Context *)context, tiv, tiv);
+  SILC_CBC_ENC_POST(tiv, dst, src);
+
+  for (i = 16; i < len; i += 16) {
+    SILC_CBC_ENC_PRE(tiv, src);
+    rc5_encrypt((RC5Context *)context, tiv, tiv);
+    SILC_CBC_ENC_POST(tiv, dst, src);
+  }
+
+  SILC_CBC_PUT_IV(tiv, iv);
+
+  return TRUE;
+}
+
+/* Decrypts with the cipher in CBC mode. Source and destination buffers
+   maybe one and same. */
+
+SILC_CIPHER_API_DECRYPT(rc5_cbc)
+{
+  SilcUInt32 tmp[4], tmp2[4], tiv[4];
+  int i;
+
+  SILC_CBC_GET_IV(tiv, iv);
+
+  SILC_CBC_DEC_PRE(tmp, src);
+  rc5_decrypt((RC5Context *)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);
+    rc5_decrypt((RC5Context *)context, tmp, tmp2);
+    SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv);
+  }
+
+  SILC_CBC_PUT_IV(tiv, iv);
+
+  return TRUE;
+}
+
 /* RC5 encryption */
 #define RC5E(i, A, B)                          \
                A = A ^ B;                      \
 
 /* Sets RC5 key */
 
-int rc5_set_key(RC5Context *ctx, char *key, int key_len)
+int rc5_set_key(RC5Context *ctx, const SilcUInt32 in_key[], int key_len)
 {
-       u32 *in_key = (u32 *)key;
        u32 i, j, k, A, B, L[c];
        u32 *out_key = ctx->out_key;
 
        if (key_len < b || key_len > (2 * b))
                return -1;
 
-       //      key_len *= 8;
-
        /* init L */
        for (i = 0; i < key_len / w; i++)
                L[i] = in_key[i];
@@ -127,9 +214,9 @@ int rc5_decrypt(RC5Context *ctx, u32 *in, u32 *out)
        A = in[0];
        B = in[1];
 
-       RC5D(32, A, B); RC5D(30, A, B); 
-       RC5D(28, A, B); RC5D(26, A, B); 
-       RC5D(24, A, B); RC5D(22, A, B); 
+       RC5D(32, A, B); RC5D(30, A, B);
+       RC5D(28, A, B); RC5D(26, A, B);
+       RC5D(24, A, B); RC5D(22, A, B);
        RC5D(20, A, B); RC5D(18, A, B);
        RC5D(16, A, B); RC5D(14, A, B);
        RC5D(12, A, B); RC5D(10, A, B);
@@ -140,4 +227,4 @@ int rc5_decrypt(RC5Context *ctx, u32 *in, u32 *out)
        out[1] = B - S[1];
 
        return 0;
-}   
+}