2 * Copyright (C) 2011, 2013 Gregor Pintar <grpintar@gmail.com>
4 * Permission is granted to deal in this work without any restriction,
5 * including unlimited rights to use, publicly perform, publish,
6 * reproduce, relicence, modify, merge, and/or distribute in any form,
7 * for any purpose, with or without fee, and by any means.
9 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind,
10 * to the utmost extent permitted by applicable law. In no event
11 * shall a licensor, author or contributor be held liable for any
12 * issues arising in any way out of dealing in the work.
19 #include <kripto/cast.h>
20 #include <kripto/memwipe.h>
21 #include <kripto/block.h>
22 #include <kripto/stream.h>
23 #include <kripto/desc/stream.h>
24 #include <kripto/object/stream.h>
26 #include <kripto/stream/cbc.h>
30 struct kripto_stream_object obj
;
32 unsigned int blocksize
;
37 static void cbc_encrypt
48 for(i
= 0; i
< len
; i
+= n
)
50 for(n
= 0; n
< s
->blocksize
; n
++)
51 U8(ct
)[n
] = CU8(pt
)[n
] ^ s
->iv
[n
];
53 kripto_block_encrypt(s
->block
, ct
, ct
);
55 for(n
= 0; n
< s
->blocksize
; n
++)
63 static void cbc_decrypt
74 for(i
= 0; i
< len
; i
+= n
)
76 for(n
= 0; n
< s
->blocksize
; n
++)
77 s
->buf
[n
] = CU8(ct
)[n
];
79 kripto_block_decrypt(s
->block
, ct
, pt
);
81 for(n
= 0; n
< s
->blocksize
; n
++)
83 U8(pt
)[n
] ^= s
->iv
[n
];
92 static void cbc_destroy(kripto_stream
*s
)
94 kripto_block_destroy(s
->block
);
95 kripto_memwipe(s
, sizeof(kripto_stream
) + (s
->blocksize
<< 1));
101 kripto_stream_desc desc
;
102 const kripto_block_desc
*block
;
105 #define EXT(X) ((const struct ext *)(X))
107 static kripto_stream
*cbc_create
109 const kripto_stream_desc
*desc
,
112 unsigned int key_len
,
119 s
= malloc(sizeof(kripto_stream
) + (desc
->maxiv
<< 1));
123 s
->obj
.multof
= s
->blocksize
;
125 s
->blocksize
= desc
->maxiv
;
127 s
->iv
= (uint8_t *)s
+ sizeof(kripto_stream
);
128 s
->buf
= s
->iv
+ s
->blocksize
;
131 s
->block
= kripto_block_create(EXT(desc
)->block
, rounds
, key
, key_len
);
134 kripto_memwipe(s
, sizeof(kripto_stream
) + (s
->blocksize
<< 1));
140 if(iv_len
) memcpy(s
->iv
, iv
, iv_len
);
141 memset(s
->iv
+ iv_len
, 0, s
->blocksize
- iv_len
);
146 static kripto_stream
*cbc_recreate
151 unsigned int key_len
,
157 s
->block
= kripto_block_recreate(s
->block
, rounds
, key
, key_len
);
160 kripto_memwipe(s
, sizeof(kripto_stream
) + (s
->blocksize
<< 1));
166 if(iv_len
) memcpy(s
->iv
, iv
, iv_len
);
167 memset(s
->iv
+ iv_len
, 0, s
->blocksize
- iv_len
);
172 kripto_stream_desc
*kripto_stream_cbc(const kripto_block_desc
*block
)
176 s
= malloc(sizeof(struct ext
));
181 s
->desc
.create
= &cbc_create
;
182 s
->desc
.recreate
= &cbc_recreate
;
183 s
->desc
.encrypt
= &cbc_encrypt
;
184 s
->desc
.decrypt
= &cbc_decrypt
;
186 s
->desc
.destroy
= &cbc_destroy
;
187 s
->desc
.maxkey
= kripto_block_maxkey(block
);
188 s
->desc
.maxiv
= kripto_block_size(block
);
190 return (kripto_stream_desc
*)s
;