2 * crypto - Tcl bindings for parts of the `nettle' crypto library
3 * Copyright 2006-2012 Ian Jackson
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "chiark_tcl_crypto.h"
22 static const char *mode_cbc_encrypt(Byte *data, int blocks,
23 const Byte *iv, Byte *chain,
24 const BlockCipherAlgInfo *alg, int encr,
26 int blocksize= alg->blocksize;
27 memcpy(chain,iv,blocksize);
30 memxor(data, chain, blocksize);
31 alg->encrypt.crypt(sch, data, data);
32 memcpy(chain, data, blocksize);
34 blocks--; data += blocksize;
39 static const char *mode_cbc_decrypt(Byte *data, int blocks,
40 const Byte *iv, Byte *chain,
41 const BlockCipherAlgInfo *alg, int encr,
43 int blocksize= alg->blocksize;
46 memcpy(chain,iv,blocksize);
49 memcpy(chain + (cchain^blocksize), data, blocksize);
50 alg->decrypt.crypt(sch, data, data);
51 memxor(data, chain + cchain, blocksize);
54 blocks--; data += blocksize;
59 static void cbcmac_core(const Byte *data, int blocks,
60 const Byte *iv, Byte *buf,
61 const BlockCipherAlgInfo *alg,
63 int blocksize= alg->blocksize;
65 memcpy(buf,iv,blocksize);
68 memcpy(buf + blocksize, data, blocksize);
69 memxor(buf, buf + blocksize, blocksize);
71 alg->encrypt.crypt(sch, buf, buf);
73 blocks--; data += blocksize;
77 static const char *mode_cbc_mac(const Byte *data, int blocks,
78 const Byte *iv, Byte *buf,
79 const BlockCipherAlgInfo *alg,
81 cbcmac_core(data,blocks,iv,buf,alg,sch);
85 static const char *mode_cbc_mac2(const Byte *data, int blocks,
86 const Byte *iv, Byte *buf,
87 const BlockCipherAlgInfo *alg,
89 cbcmac_core(data,blocks,iv,buf,alg,sch);
90 alg->encrypt.crypt(sch, buf, buf);
94 static const char *mode_ecb(Byte *data, int blocks,
95 const Byte *iv, Byte *chain,
96 const BlockCipherAlgInfo *alg, int encr,
98 int blocksize= alg->blocksize;
101 (encr ? &alg->encrypt : &alg->decrypt)->crypt(sch, data, data);
102 blocks--; data += blocksize;
107 static const char *mode_ctr(Byte *data, int blocks,
108 const Byte *iv, Byte *counter,
109 const BlockCipherAlgInfo *alg, int encr,
111 int blocksize= alg->blocksize;
112 Byte *cipher= counter + blocksize;
115 memcpy(counter, iv, blocksize);
117 alg->encrypt.crypt(sch, counter, cipher);
118 memxor(data, cipher, blocksize);
119 for (byte=blocksize-1; byte>=0; byte--) {
120 if (++counter[byte]) break;
121 /* new value of zero implies carry, so increment next byte */
129 const BlockCipherModeInfo cht_blockciphermodeinfo_entries[]= {
130 { "cbc", 1, 2, 1, mode_cbc_encrypt, mode_cbc_decrypt, mode_cbc_mac },
131 { "cbc-mac2", 1, 2, 1, 0, 0, mode_cbc_mac2 },
132 { "ecb", 0, 0, 0, mode_ecb, mode_ecb, 0 },
133 { "ctr-sif", 1, 2, 0, mode_ctr, mode_ctr, 0 },