chiark / gitweb /
better core algorithm selection and new core alg suites
[chiark-tcl.git] / crypto / bcmode.c
index 7d5a5d4..9a5ae92 100644 (file)
   
 #include "hbytes.h"
 
-const char *mode_cbc_encrypt(Byte *data, int blocks,
-                            const Byte *iv, Byte *chain,
-                            const BlockCipherAlgInfo *alg, int encr,
-                            int blocksize, const void *sch) {
+static const char *mode_cbc_encrypt(Byte *data, int blocks,
+                                   const Byte *iv, Byte *chain,
+                                   const BlockCipherAlgInfo *alg, int encr,
+                                   const void *sch) {
+  int blocksize= alg->blocksize;
   memcpy(chain,iv,blocksize);
-  alg->byteswap(chain);
+  if (alg->byteswap) alg->byteswap(chain);
   
   while (blocks > 0) {
-    alg->byteswap(data);
+    if (alg->byteswap) alg->byteswap(data);
 
     memxor(data, chain, blocksize);
     alg->encrypt.crypt(sch, data, data);
     memcpy(chain, data, blocksize);
 
-    alg->byteswap(data);
+    if (alg->byteswap) alg->byteswap(data);
     blocks--; data += blocksize;
   }
   return 0;
 }
 
-const char *mode_cbc_decrypt(Byte *data, int blocks,
-                            const Byte *iv, Byte *chain,
-                            const BlockCipherAlgInfo *alg, int encr,
-                            int blocksize, const void *sch) {
+static const char *mode_cbc_decrypt(Byte *data, int blocks,
+                                   const Byte *iv, Byte *chain,
+                                   const BlockCipherAlgInfo *alg, int encr,
+                                   const void *sch) {
+  int blocksize= alg->blocksize;
   int cchain= 0;
 
   memcpy(chain,iv,blocksize);
-  alg->byteswap(chain);
+  if (alg->byteswap) alg->byteswap(chain);
   
   while (blocks > 0) {
-    alg->byteswap(data);
+    if (alg->byteswap) alg->byteswap(data);
     
     memcpy(chain + (cchain^blocksize), data, blocksize);
     alg->decrypt.crypt(sch, data, data);
     memxor(data, chain + cchain, blocksize);
     cchain ^= blocksize;
 
-    alg->byteswap(data);
+    if (alg->byteswap) alg->byteswap(data);
+    blocks--; data += blocksize;
+  }
+  return 0;
+}
+
+static void cbcmac_core(const Byte *data, int blocks,
+                       const Byte *iv, Byte *buf,
+                       const BlockCipherAlgInfo *alg,
+                       const void *sch) {
+  int blocksize= alg->blocksize;
+
+  memcpy(buf,iv,blocksize);
+  if (alg->byteswap) alg->byteswap(buf);
+  
+  while (blocks > 0) {
+    memcpy(buf + blocksize, data, blocksize);
+    if (alg->byteswap) alg->byteswap(buf + blocksize);
+    memxor(buf, buf + blocksize, blocksize);
+    
+    alg->encrypt.crypt(sch, buf, buf);
+
+    blocks--; data += blocksize;
+  }
+}  
+
+static const char *mode_cbc_mac(const Byte *data, int blocks,
+                               const Byte *iv, Byte *buf,
+                               const BlockCipherAlgInfo *alg,
+                               const void *sch) {
+  cbcmac_core(data,blocks,iv,buf,alg,sch);
+  if (alg->byteswap) alg->byteswap(buf);
+  return 0;
+}
+
+static const char *mode_cbc_mac2(const Byte *data, int blocks,
+                                const Byte *iv, Byte *buf,
+                                const BlockCipherAlgInfo *alg,
+                                const void *sch) {
+  cbcmac_core(data,blocks,iv,buf,alg,sch);
+  alg->encrypt.crypt(sch, buf, buf);
+  if (alg->byteswap) alg->byteswap(buf);
+  return 0;
+}
+
+static const char *mode_ecb(Byte *data, int blocks,
+                           const Byte *iv, Byte *chain,
+                           const BlockCipherAlgInfo *alg, int encr,
+                           const void *sch) {
+  int blocksize= alg->blocksize;
+  
+  while (blocks > 0) {
+    if (alg->byteswap) alg->byteswap(data);
+    (encr ? &alg->encrypt : &alg->decrypt)->crypt(sch, data, data);
+    if (alg->byteswap) alg->byteswap(data);
     blocks--; data += blocksize;
   }
   return 0;
 }
 
 const BlockCipherModeInfo blockciphermodeinfos[]= {
-  { "cbc", 1, 2, mode_cbc_encrypt, mode_cbc_decrypt },
+  { "cbc",      1, 2, 1, mode_cbc_encrypt, mode_cbc_decrypt, mode_cbc_mac  },
+  { "cbc-mac2", 1, 2, 1, 0,                0,                mode_cbc_mac2 },
+  { "ecb",      0, 0, 0, mode_ecb,         mode_ecb,         0             },
   { 0 }
 };