#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 }
};