Major restructuring of the internals of SILC Cipher API
[crypto.git] / lib / silccrypt / aes.c
index fc67504d91b362fcfc6962fd2803c62241899c5a..f60f395226978acba8f984369b174b2ca916a121 100644 (file)
@@ -33,8 +33,8 @@
  Issue 09/09/2006
 */
 
-#include "silc.h"
-#include "rijndael_internal.h"
+#include "silccrypto.h"
+#include "aes_internal.h"
 #include "aes.h"
 
 /*
 
 SILC_CIPHER_API_SET_KEY(aes)
 {
-  switch (cipher->mode) {
+  switch (ops->mode) {
+  case SILC_CIPHER_MODE_CTR:
+  case SILC_CIPHER_MODE_CFB:
+    aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
+    break;
+
   case SILC_CIPHER_MODE_CBC:
+  case SILC_CIPHER_MODE_ECB:
     if (encryption)
       aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
     else
       aes_decrypt_key(key, keylen, &((AesContext *)context)->u.dec);
     break;
 
-  case SILC_CIPHER_MODE_CTR:
-    aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
-    break;
-
   default:
     return FALSE;
   }
@@ -67,19 +69,37 @@ SILC_CIPHER_API_SET_KEY(aes)
 
 SILC_CIPHER_API_SET_IV(aes)
 {
-  if (cipher->mode == SILC_CIPHER_MODE_CTR) {
-    AesContext *aes = context;
+  AesContext *aes = context;
+
+  switch (ops->mode) {
 
+  case SILC_CIPHER_MODE_CTR:
+  case SILC_CIPHER_MODE_CFB:
     /* Starts new block. */
-    aes->u.enc.inf.b[2] = 0;
+    aes->u.enc.inf.b[2] = 16;
+    break;
+
+  default:
+    break;
   }
 }
 
-/* Returns the size of the cipher context. */
+/* Initialize */
+
+SILC_CIPHER_API_INIT(aes)
+{
+  AesContext *aes = silc_calloc(1, sizeof(AesContext));
+  if (aes)
+    aes->u.enc.inf.b[2] = 16;
+}
+
+/* Unnitialize */
 
-SILC_CIPHER_API_CONTEXT_LEN(aes)
+SILC_CIPHER_API_UNINIT(aes)
 {
-  return sizeof(AesContext);
+  AesContext *aes = context;
+  memset(aes, 0, sizeof(*aes));
+  silc_free(aes);
 }
 
 /* Encrypts with the cipher. Source and destination buffers maybe one and
@@ -90,10 +110,27 @@ SILC_CIPHER_API_ENCRYPT(aes)
   AesContext *aes = context;
   int i;
 
-  switch (cipher->mode) {
+  switch (ops->mode) {
+  case SILC_CIPHER_MODE_CTR:
+    SILC_CTR_MSB_128_8(iv, cipher->block, aes->u.enc.inf.b[2], src, dst,
+                      aes_encrypt(iv, cipher->block, &aes->u.enc));
+    break;
+
+  case SILC_CIPHER_MODE_ECB:
+    {
+      SilcUInt32 nb = len >> 4;
+
+      while (nb--) {
+       aes_encrypt(src, dst, &aes->u.enc);
+       src += 16;
+       dst += 16;
+      }
+    }
+    break;
+
   case SILC_CIPHER_MODE_CBC:
     {
-      int nb = len >> 4;
+      SilcUInt32 nb = len >> 4;
 
       SILC_ASSERT((len & (16 - 1)) == 0);
       if (len & (16 - 1))
@@ -112,43 +149,9 @@ SILC_CIPHER_API_ENCRYPT(aes)
     }
     break;
 
-  case SILC_CIPHER_MODE_CTR:
-    {
-      SilcUInt32 ctr[4];
-
-      SILC_GET32_MSB(ctr[0], iv);
-      SILC_GET32_MSB(ctr[1], iv + 4);
-      SILC_GET32_MSB(ctr[2], iv + 8);
-      SILC_GET32_MSB(ctr[3], iv + 12);
-
-      i = aes->u.enc.inf.b[2];
-      if (!i)
-       i = 16;
-
-      while (len-- > 0) {
-       if (i == 16) {
-         if (++ctr[3] == 0)
-           if (++ctr[2] == 0)
-             if (++ctr[1] == 0)
-               ++ctr[0];
-
-         SILC_PUT32_MSB(ctr[0], iv);
-         SILC_PUT32_MSB(ctr[1], iv + 4);
-         SILC_PUT32_MSB(ctr[2], iv + 8);
-         SILC_PUT32_MSB(ctr[3], iv + 12);
-
-         aes_encrypt(iv, iv, &aes->u.enc);
-         i = 0;
-       }
-       *dst++ = *src++ ^ iv[i++];
-      }
-      aes->u.enc.inf.b[2] = i;
-
-      SILC_PUT32_MSB(ctr[0], iv);
-      SILC_PUT32_MSB(ctr[1], iv + 4);
-      SILC_PUT32_MSB(ctr[2], iv + 8);
-      SILC_PUT32_MSB(ctr[3], iv + 12);
-    }
+  case SILC_CIPHER_MODE_CFB:
+    SILC_CFB_ENC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
+                          aes_encrypt(iv, iv, &aes->u.enc));
     break;
 
   default:
@@ -163,18 +166,36 @@ SILC_CIPHER_API_ENCRYPT(aes)
 
 SILC_CIPHER_API_DECRYPT(aes)
 {
-  switch (cipher->mode) {
+  AesContext *aes = context;
+
+  switch (ops->mode) {
+  case SILC_CIPHER_MODE_CTR:
+    return silc_aes_encrypt(cipher, ops, context, src, dst, len, iv);
+    break;
+
+  case SILC_CIPHER_MODE_ECB:
+    {
+      SilcUInt32 nb = len >> 4;
+
+      while (nb--) {
+       aes_decrypt(src, dst, &aes->u.dec);
+       src += 16;
+       dst += 16;
+      }
+    }
+    break;
+
   case SILC_CIPHER_MODE_CBC:
     {
       unsigned char tmp[16];
-      int nb = len >> 4;
+      SilcUInt32 nb = len >> 4;
 
       if (len & (16 - 1))
        return FALSE;
 
       while(nb--) {
        memcpy(tmp, src, 16);
-       aes_decrypt(src, dst, &((AesContext *)context)->u.dec);
+       aes_decrypt(src, dst, &aes->u.dec);
        lp32(dst)[0] ^= lp32(iv)[0];
        lp32(dst)[1] ^= lp32(iv)[1];
        lp32(dst)[2] ^= lp32(iv)[2];
@@ -186,8 +207,9 @@ SILC_CIPHER_API_DECRYPT(aes)
     }
     break;
 
-  case SILC_CIPHER_MODE_CTR:
-    return silc_aes_encrypt(cipher, context, src, dst, len, iv);
+  case SILC_CIPHER_MODE_CFB:
+    SILC_CFB_DEC_MSB_128_8(iv, aes->u.enc.inf.b[2], src, dst,
+                          aes_encrypt(iv, iv, &aes->u.enc));
     break;
 
   default:
@@ -244,7 +266,6 @@ AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
     ke4(cx->ks, 6);  ke4(cx->ks, 7);
     ke4(cx->ks, 8);
     ke4(cx->ks, 9);
-    cx->inf.l = 0;
     cx->inf.b[0] = 10 * 16;
 }
 
@@ -276,7 +297,6 @@ AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
     ke6(cx->ks, 4);  ke6(cx->ks, 5);
     ke6(cx->ks, 6);
     kef6(cx->ks, 7);
-    cx->inf.l = 0;
     cx->inf.b[0] = 12 * 16;
 }
 
@@ -311,7 +331,6 @@ AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
     ke8(cx->ks, 2); ke8(cx->ks, 3);
     ke8(cx->ks, 4); ke8(cx->ks, 5);
     kef8(cx->ks, 6);
-    cx->inf.l = 0;
     cx->inf.b[0] = 14 * 16;
 }
 
@@ -377,7 +396,6 @@ AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
      kd4(cx->ks, 4);  kd4(cx->ks, 5);
      kd4(cx->ks, 6);  kd4(cx->ks, 7);
      kd4(cx->ks, 8); kdl4(cx->ks, 9);
-    cx->inf.l = 0;
     cx->inf.b[0] = 10 * 16;
 }
 
@@ -436,7 +454,6 @@ AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
     kd6(cx->ks, 2);  kd6(cx->ks, 3);
     kd6(cx->ks, 4);  kd6(cx->ks, 5);
     kd6(cx->ks, 6); kdl6(cx->ks, 7);
-    cx->inf.l = 0;
     cx->inf.b[0] = 12 * 16;
 }
 
@@ -504,7 +521,6 @@ AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
     kd8(cx->ks, 2);  kd8(cx->ks, 3);
     kd8(cx->ks, 4);  kd8(cx->ks, 5);
     kdl8(cx->ks, 6);
-    cx->inf.l = 0;
     cx->inf.b[0] = 14 * 16;
 }