Major restructuring of the internals of SILC Cipher API
[crypto.git] / lib / silccrypt / aes.c
index 27a47cc95b43731f69c3f5fd33697fcf9811f8d3..f60f395226978acba8f984369b174b2ca916a121 100644 (file)
@@ -34,7 +34,7 @@
 */
 
 #include "silccrypto.h"
-#include "rijndael_internal.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:
-  case SILC_CIPHER_MODE_CFB:
-    aes_encrypt_key(key, keylen, &((AesContext *)context)->u.enc);
-    break;
-
   default:
     return FALSE;
   }
@@ -70,13 +71,9 @@ SILC_CIPHER_API_SET_IV(aes)
 {
   AesContext *aes = context;
 
-  switch (cipher->mode) {
+  switch (ops->mode) {
 
   case SILC_CIPHER_MODE_CTR:
-    /* Starts new block. */
-    aes->u.enc.inf.b[2] = 0;
-    break;
-
   case SILC_CIPHER_MODE_CFB:
     /* Starts new block. */
     aes->u.enc.inf.b[2] = 16;
@@ -87,11 +84,22 @@ SILC_CIPHER_API_SET_IV(aes)
   }
 }
 
-/* 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
@@ -100,12 +108,29 @@ SILC_CIPHER_API_CONTEXT_LEN(aes)
 SILC_CIPHER_API_ENCRYPT(aes)
 {
   AesContext *aes = context;
-  SilcUInt32 ctr[4];
+  int i;
+
+  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;
 
-  switch (cipher->mode) {
   case SILC_CIPHER_MODE_CBC:
     {
-      int nb = len >> 4;
+      SilcUInt32 nb = len >> 4;
 
       SILC_ASSERT((len & (16 - 1)) == 0);
       if (len & (16 - 1))
@@ -124,11 +149,6 @@ SILC_CIPHER_API_ENCRYPT(aes)
     }
     break;
 
-  case SILC_CIPHER_MODE_CTR:
-    SILC_CTR_MSB_128_8(iv, ctr, iv, aes->u.enc.inf.b[2], src, dst,
-                      aes_encrypt(iv, iv, &aes->u.enc));
-    break;
-
   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));
@@ -148,11 +168,27 @@ SILC_CIPHER_API_DECRYPT(aes)
 {
   AesContext *aes = context;
 
-  switch (cipher->mode) {
+  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;
@@ -171,10 +207,6 @@ SILC_CIPHER_API_DECRYPT(aes)
     }
     break;
 
-  case SILC_CIPHER_MODE_CTR:
-    return silc_aes_encrypt(cipher, context, src, dst, len, iv);
-    break;
-
   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));