chiark / gitweb /
Build-Depends: move tcl-dev to the end, so that we prefer tcl8.4-dev. This is necessa...
[chiark-tcl.git] / crypto / bcmode.c
index f6a2a4bddcedc3f41086476145a3058d3d9f4bfc..9545af39b6644d2ab533c3e068379b8c13b0e574 100644 (file)
@@ -1,7 +1,23 @@
 /*
+ * crypto - Tcl bindings for parts of the `nettle' crypto library
+ * Copyright 2006-2012 Ian Jackson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
+
   
-#include "hbytes.h"
+#include "chiark_tcl_crypto.h"
 
 static const char *mode_cbc_encrypt(Byte *data, int blocks,
                                    const Byte *iv, Byte *chain,
@@ -9,16 +25,12 @@ static const char *mode_cbc_encrypt(Byte *data, int blocks,
                                    const void *sch) {
   int blocksize= alg->blocksize;
   memcpy(chain,iv,blocksize);
-  alg->byteswap(chain);
   
   while (blocks > 0) {
-    alg->byteswap(data);
-
     memxor(data, chain, blocksize);
     alg->encrypt.crypt(sch, data, data);
     memcpy(chain, data, blocksize);
 
-    alg->byteswap(data);
     blocks--; data += blocksize;
   }
   return 0;
@@ -32,17 +44,13 @@ static const char *mode_cbc_decrypt(Byte *data, int blocks,
   int cchain= 0;
 
   memcpy(chain,iv,blocksize);
-  alg->byteswap(chain);
   
   while (blocks > 0) {
-    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);
     blocks--; data += blocksize;
   }
   return 0;
@@ -55,11 +63,9 @@ static void cbcmac_core(const Byte *data, int blocks,
   int blocksize= alg->blocksize;
 
   memcpy(buf,iv,blocksize);
-  alg->byteswap(buf);
   
   while (blocks > 0) {
     memcpy(buf + blocksize, data, blocksize);
-    alg->byteswap(buf + blocksize);
     memxor(buf, buf + blocksize, blocksize);
     
     alg->encrypt.crypt(sch, buf, buf);
@@ -73,7 +79,6 @@ static const char *mode_cbc_mac(const Byte *data, int blocks,
                                const BlockCipherAlgInfo *alg,
                                const void *sch) {
   cbcmac_core(data,blocks,iv,buf,alg,sch);
-  alg->byteswap(buf);
   return 0;
 }
 
@@ -83,7 +88,6 @@ static const char *mode_cbc_mac2(const Byte *data, int blocks,
                                 const void *sch) {
   cbcmac_core(data,blocks,iv,buf,alg,sch);
   alg->encrypt.crypt(sch, buf, buf);
-  alg->byteswap(buf);
   return 0;
 }
 
@@ -94,17 +98,38 @@ static const char *mode_ecb(Byte *data, int blocks,
   int blocksize= alg->blocksize;
   
   while (blocks > 0) {
-    alg->byteswap(data);
     (encr ? &alg->encrypt : &alg->decrypt)->crypt(sch, data, data);
-    alg->byteswap(data);
     blocks--; data += blocksize;
   }
   return 0;
 }
 
-const BlockCipherModeInfo blockciphermodeinfos[]= {
+static const char *mode_ctr(Byte *data, int blocks,
+                           const Byte *iv, Byte *counter,
+                           const BlockCipherAlgInfo *alg, int encr,
+                           const void *sch) {
+  int blocksize= alg->blocksize;
+  Byte *cipher= counter + blocksize;
+  int byte;
+
+  memcpy(counter, iv, blocksize);
+  while (blocks > 0) {
+    alg->encrypt.crypt(sch, counter, cipher);
+    memxor(data, cipher, blocksize);
+    for (byte=blocksize-1; byte>=0; byte--) {
+      if (++counter[byte]) break;
+      /* new value of zero implies carry, so increment next byte */
+    }
+    blocks--;
+    data += blocksize;
+  }
+  return 0;
+}
+
+const BlockCipherModeInfo cht_blockciphermodeinfo_entries[]= {
   { "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             },
+  { "ctr-sif",  1, 2, 0, mode_ctr,         mode_ctr,         0             },
   { 0 }
 };