/*
+ * 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,
const void *sch) {
int blocksize= alg->blocksize;
memcpy(chain,iv,blocksize);
- if (alg->byteswap) alg->byteswap(chain);
while (blocks > 0) {
- if (alg->byteswap) alg->byteswap(data);
-
memxor(data, chain, blocksize);
alg->encrypt.crypt(sch, data, data);
memcpy(chain, data, blocksize);
- if (alg->byteswap) alg->byteswap(data);
blocks--; data += blocksize;
}
return 0;
int cchain= 0;
memcpy(chain,iv,blocksize);
- if (alg->byteswap) alg->byteswap(chain);
while (blocks > 0) {
- 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;
- if (alg->byteswap) alg->byteswap(data);
blocks--; data += blocksize;
}
return 0;
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);
const BlockCipherAlgInfo *alg,
const void *sch) {
cbcmac_core(data,blocks,iv,buf,alg,sch);
- if (alg->byteswap) alg->byteswap(buf);
return 0;
}
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;
}
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[]= {
+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 }
};