chiark / gitweb /
provide errorCode for invalid reverse addrs
[chiark-tcl.git] / crypto / bcmode.c
1 /*
2  */
3   
4 #include "chiark_tcl_crypto.h"
5
6 static const char *mode_cbc_encrypt(Byte *data, int blocks,
7                                     const Byte *iv, Byte *chain,
8                                     const BlockCipherAlgInfo *alg, int encr,
9                                     const void *sch) {
10   int blocksize= alg->blocksize;
11   memcpy(chain,iv,blocksize);
12   
13   while (blocks > 0) {
14     memxor(data, chain, blocksize);
15     alg->encrypt.crypt(sch, data, data);
16     memcpy(chain, data, blocksize);
17
18     blocks--; data += blocksize;
19   }
20   return 0;
21 }
22
23 static const char *mode_cbc_decrypt(Byte *data, int blocks,
24                                     const Byte *iv, Byte *chain,
25                                     const BlockCipherAlgInfo *alg, int encr,
26                                     const void *sch) {
27   int blocksize= alg->blocksize;
28   int cchain= 0;
29
30   memcpy(chain,iv,blocksize);
31   
32   while (blocks > 0) {
33     memcpy(chain + (cchain^blocksize), data, blocksize);
34     alg->decrypt.crypt(sch, data, data);
35     memxor(data, chain + cchain, blocksize);
36     cchain ^= blocksize;
37
38     blocks--; data += blocksize;
39   }
40   return 0;
41 }
42
43 static void cbcmac_core(const Byte *data, int blocks,
44                         const Byte *iv, Byte *buf,
45                         const BlockCipherAlgInfo *alg,
46                         const void *sch) {
47   int blocksize= alg->blocksize;
48
49   memcpy(buf,iv,blocksize);
50   
51   while (blocks > 0) {
52     memcpy(buf + blocksize, data, blocksize);
53     memxor(buf, buf + blocksize, blocksize);
54     
55     alg->encrypt.crypt(sch, buf, buf);
56
57     blocks--; data += blocksize;
58   }
59 }  
60
61 static const char *mode_cbc_mac(const Byte *data, int blocks,
62                                 const Byte *iv, Byte *buf,
63                                 const BlockCipherAlgInfo *alg,
64                                 const void *sch) {
65   cbcmac_core(data,blocks,iv,buf,alg,sch);
66   return 0;
67 }
68
69 static const char *mode_cbc_mac2(const Byte *data, int blocks,
70                                  const Byte *iv, Byte *buf,
71                                  const BlockCipherAlgInfo *alg,
72                                  const void *sch) {
73   cbcmac_core(data,blocks,iv,buf,alg,sch);
74   alg->encrypt.crypt(sch, buf, buf);
75   return 0;
76 }
77
78 static const char *mode_ecb(Byte *data, int blocks,
79                             const Byte *iv, Byte *chain,
80                             const BlockCipherAlgInfo *alg, int encr,
81                             const void *sch) {
82   int blocksize= alg->blocksize;
83   
84   while (blocks > 0) {
85     (encr ? &alg->encrypt : &alg->decrypt)->crypt(sch, data, data);
86     blocks--; data += blocksize;
87   }
88   return 0;
89 }
90
91 static const char *mode_ctr(Byte *data, int blocks,
92                             const Byte *iv, Byte *counter,
93                             const BlockCipherAlgInfo *alg, int encr,
94                             const void *sch) {
95   int blocksize= alg->blocksize;
96   Byte *cipher= counter + blocksize;
97   int byte;
98
99   memcpy(counter, iv, blocksize);
100   while (blocks > 0) {
101     alg->encrypt.crypt(sch, counter, cipher);
102     memxor(data, cipher, blocksize);
103     for (byte=blocksize-1; byte>=0; byte--) {
104       if (++counter[byte]) break;
105       /* new value of zero implies carry, so increment next byte */
106     }
107     blocks--;
108     data += blocksize;
109   }
110   return 0;
111 }
112
113 const BlockCipherModeInfo cht_blockciphermodeinfo_entries[]= {
114   { "cbc",      1, 2, 1, mode_cbc_encrypt, mode_cbc_decrypt, mode_cbc_mac  },
115   { "cbc-mac2", 1, 2, 1, 0,                0,                mode_cbc_mac2 },
116   { "ecb",      0, 0, 0, mode_ecb,         mode_ecb,         0             },
117   { "ctr-sif",  1, 2, 0, mode_ctr,         mode_ctr,         0             },
118   { 0 }
119 };