multof moved from descriptor to object
[rofl0r-kripto.git] / lib / stream / cbc.c
bloba026ca9b24b74b58d30d206d9a929c79d4a76b6b
1 /*
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.
15 #include <stdint.h>
16 #include <string.h>
17 #include <stdlib.h>
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>
28 struct kripto_stream
30 struct kripto_stream_object obj;
31 kripto_block *block;
32 unsigned int blocksize;
33 uint8_t *iv;
34 uint8_t *buf;
37 static void cbc_encrypt
39 kripto_stream *s,
40 const void *pt,
41 void *ct,
42 size_t len
45 size_t i;
46 unsigned int n;
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++)
56 s->iv[n] = U8(ct)[n];
58 pt = CU8(pt) + n;
59 ct = U8(ct) + n;
63 static void cbc_decrypt
65 kripto_stream *s,
66 const void *ct,
67 void *pt,
68 size_t len
71 size_t i;
72 unsigned int n;
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];
84 s->iv[n] = s->buf[n];
87 ct = CU8(ct) + n;
88 pt = U8(pt) + 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));
96 free(s);
99 struct ext
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,
110 unsigned int rounds,
111 const void *key,
112 unsigned int key_len,
113 const void *iv,
114 unsigned int iv_len
117 kripto_stream *s;
119 s = malloc(sizeof(kripto_stream) + (desc->maxiv << 1));
120 if(!s) return 0;
122 s->obj.desc = desc;
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;
130 /* block cipher */
131 s->block = kripto_block_create(EXT(desc)->block, rounds, key, key_len);
132 if(!s->block)
134 kripto_memwipe(s, sizeof(kripto_stream) + (s->blocksize << 1));
135 free(s);
136 return 0;
139 /* IV */
140 if(iv_len) memcpy(s->iv, iv, iv_len);
141 memset(s->iv + iv_len, 0, s->blocksize - iv_len);
143 return s;
146 static kripto_stream *cbc_recreate
148 kripto_stream *s,
149 unsigned int rounds,
150 const void *key,
151 unsigned int key_len,
152 const void *iv,
153 unsigned int iv_len
156 /* block cipher */
157 s->block = kripto_block_recreate(s->block, rounds, key, key_len);
158 if(!s->block)
160 kripto_memwipe(s, sizeof(kripto_stream) + (s->blocksize << 1));
161 free(s);
162 return 0;
165 /* IV */
166 if(iv_len) memcpy(s->iv, iv, iv_len);
167 memset(s->iv + iv_len, 0, s->blocksize - iv_len);
169 return s;
172 kripto_stream_desc *kripto_stream_cbc(const kripto_block_desc *block)
174 struct ext *s;
176 s = malloc(sizeof(struct ext));
177 if(!s) return 0;
179 s->block = block;
181 s->desc.create = &cbc_create;
182 s->desc.recreate = &cbc_recreate;
183 s->desc.encrypt = &cbc_encrypt;
184 s->desc.decrypt = &cbc_decrypt;
185 s->desc.prng = 0;
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;