2 * crypto - Tcl bindings for parts of the `nettle' crypto library
3 * Copyright 2006 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, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 #include "chiark_tcl_crypto.h"
24 static const char *mode_cbc_encrypt(Byte *data, int blocks,
25 const Byte *iv, Byte *chain,
26 const BlockCipherAlgInfo *alg, int encr,
28 int blocksize= alg->blocksize;
29 memcpy(chain,iv,blocksize);
32 memxor(data, chain, blocksize);
33 alg->encrypt.crypt(sch, data, data);
34 memcpy(chain, data, blocksize);
36 blocks--; data += blocksize;
41 static const char *mode_cbc_decrypt(Byte *data, int blocks,
42 const Byte *iv, Byte *chain,
43 const BlockCipherAlgInfo *alg, int encr,
45 int blocksize= alg->blocksize;
48 memcpy(chain,iv,blocksize);
51 memcpy(chain + (cchain^blocksize), data, blocksize);
52 alg->decrypt.crypt(sch, data, data);
53 memxor(data, chain + cchain, blocksize);
56 blocks--; data += blocksize;
61 static void cbcmac_core(const Byte *data, int blocks,
62 const Byte *iv, Byte *buf,
63 const BlockCipherAlgInfo *alg,
65 int blocksize= alg->blocksize;
67 memcpy(buf,iv,blocksize);
70 memcpy(buf + blocksize, data, blocksize);
71 memxor(buf, buf + blocksize, blocksize);
73 alg->encrypt.crypt(sch, buf, buf);
75 blocks--; data += blocksize;
79 static const char *mode_cbc_mac(const Byte *data, int blocks,
80 const Byte *iv, Byte *buf,
81 const BlockCipherAlgInfo *alg,
83 cbcmac_core(data,blocks,iv,buf,alg,sch);
87 static const char *mode_cbc_mac2(const Byte *data, int blocks,
88 const Byte *iv, Byte *buf,
89 const BlockCipherAlgInfo *alg,
91 cbcmac_core(data,blocks,iv,buf,alg,sch);
92 alg->encrypt.crypt(sch, buf, buf);
96 static const char *mode_ecb(Byte *data, int blocks,
97 const Byte *iv, Byte *chain,
98 const BlockCipherAlgInfo *alg, int encr,
100 int blocksize= alg->blocksize;
103 (encr ? &alg->encrypt : &alg->decrypt)->crypt(sch, data, data);
104 blocks--; data += blocksize;
109 static const char *mode_ctr(Byte *data, int blocks,
110 const Byte *iv, Byte *counter,
111 const BlockCipherAlgInfo *alg, int encr,
113 int blocksize= alg->blocksize;
114 Byte *cipher= counter + blocksize;
117 memcpy(counter, iv, blocksize);
119 alg->encrypt.crypt(sch, counter, cipher);
120 memxor(data, cipher, blocksize);
121 for (byte=blocksize-1; byte>=0; byte--) {
122 if (++counter[byte]) break;
123 /* new value of zero implies carry, so increment next byte */
131 const BlockCipherModeInfo cht_blockciphermodeinfo_entries[]= {
132 { "cbc", 1, 2, 1, mode_cbc_encrypt, mode_cbc_decrypt, mode_cbc_mac },
133 { "cbc-mac2", 1, 2, 1, 0, 0, mode_cbc_mac2 },
134 { "ecb", 0, 0, 0, mode_ecb, mode_ecb, 0 },
135 { "ctr-sif", 1, 2, 0, mode_ctr, mode_ctr, 0 },