2 * Written in 2011 by Gregor Pintar <grpintar@gmail.com>
4 * To the extent possible under law, the author(s) have dedicated
5 * all copyright and related and neighboring rights to this software
6 * to the public domain worldwide.
8 * This software is distributed without any warranty.
10 * You should have received a copy of the CC0 Public Domain Dedication.
11 * If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
18 #include <kripto/cast.h>
19 #include <kripto/memwipe.h>
20 #include <kripto/block.h>
21 #include <kripto/stream.h>
22 #include <kripto/desc/stream.h>
23 #include <kripto/object/stream.h>
25 #include <kripto/stream/ctr.h>
29 struct kripto_stream_object obj
;
33 unsigned int blocksize
;
48 for(i
= 0; i
< len
; i
++)
50 if(s
->used
== s
->blocksize
)
52 kripto_block_encrypt(s
->block
, s
->x
, s
->buf
);
55 for(n
= s
->blocksize
- 1; n
; n
--)
59 U8(out
)[i
] = CU8(in
)[i
] ^ s
->buf
[s
->used
++];
73 for(i
= 0; i
< len
; i
++)
75 if(s
->used
== s
->blocksize
)
77 kripto_block_encrypt(s
->block
, s
->x
, s
->buf
);
80 for(n
= s
->blocksize
- 1; n
; n
--)
84 U8(out
)[i
] = s
->buf
[s
->used
++];
88 static void ctr_destroy(kripto_stream
*s
)
90 kripto_block_destroy(s
->block
);
91 kripto_memwipe(s
, sizeof(kripto_stream
) + (s
->blocksize
<< 1));
97 kripto_stream_desc desc
;
98 const kripto_block_desc
*block
;
101 #define EXT(X) ((const struct ext *)(X))
103 static kripto_stream
*ctr_create
105 const kripto_stream_desc
*desc
,
108 unsigned int key_len
,
115 s
= malloc(sizeof(kripto_stream
) + (desc
->maxiv
<< 1));
121 s
->used
= s
->blocksize
= desc
->maxiv
;
123 s
->x
= (uint8_t *)s
+ sizeof(kripto_stream
);
124 s
->buf
= s
->x
+ s
->blocksize
;
127 s
->block
= kripto_block_create(EXT(desc
)->block
, rounds
, key
, key_len
);
130 kripto_memwipe(s
, sizeof(kripto_stream
) + (s
->blocksize
<< 1));
136 if(iv_len
) memcpy(s
->x
, iv
, iv_len
);
137 memset(s
->x
+ iv_len
, 0, s
->blocksize
- iv_len
);
142 static kripto_stream
*ctr_recreate
147 unsigned int key_len
,
153 s
->block
= kripto_block_recreate(s
->block
, rounds
, key
, key_len
);
156 kripto_memwipe(s
, sizeof(kripto_stream
) + (s
->blocksize
<< 1));
162 if(iv_len
) memcpy(s
->x
, iv
, iv_len
);
163 memset(s
->x
+ iv_len
, 0, s
->blocksize
- iv_len
);
165 s
->used
= s
->blocksize
;
170 kripto_stream_desc
*kripto_stream_ctr(const kripto_block_desc
*block
)
174 s
= malloc(sizeof(struct ext
));
179 s
->desc
.create
= &ctr_create
;
180 s
->desc
.recreate
= &ctr_recreate
;
181 s
->desc
.encrypt
= &ctr_crypt
;
182 s
->desc
.decrypt
= &ctr_crypt
;
183 s
->desc
.prng
= &ctr_prng
;
184 s
->desc
.destroy
= &ctr_destroy
;
185 s
->desc
.maxkey
= kripto_block_maxkey(block
);
186 s
->desc
.maxiv
= kripto_block_size(block
);
188 return (kripto_stream_desc
*)s
;