X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=blobdiff_plain;f=crypto%2Fbcmode.c;h=9545af39b6644d2ab533c3e068379b8c13b0e574;hp=f6a2a4bddcedc3f41086476145a3058d3d9f4bfc;hb=1306d8ad8b0597fd67d933a363d0be2ac891dd8a;hpb=ac8c0b3b18075ae4273779544eda01c09cfb5145 diff --git a/crypto/bcmode.c b/crypto/bcmode.c index f6a2a4b..9545af3 100644 --- a/crypto/bcmode.c +++ b/crypto/bcmode.c @@ -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 . */ + -#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 } };