multof moved from descriptor to object
[rofl0r-kripto.git] / lib / stream / ctr.c
blob4ed7b652a51940010c0d9729f80e8e15cd2c4d40
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/ctr.h>
28 struct kripto_stream
30 struct kripto_stream_object obj;
31 kripto_block *block;
32 uint8_t *x;
33 uint8_t *buf;
34 unsigned int blocksize;
35 unsigned int used;
38 static void ctr_crypt
40 kripto_stream *s,
41 const void *in,
42 void *out,
43 size_t len
46 size_t i;
47 unsigned int n;
49 for(i = 0; i < len; i++)
51 if(s->used == s->blocksize)
53 kripto_block_encrypt(s->block, s->x, s->buf);
54 s->used = 0;
56 for(n = s->blocksize - 1; n; n--)
57 if(++s->x[n]) break;
60 U8(out)[i] = CU8(in)[i] ^ s->buf[s->used++];
64 static void ctr_prng
66 kripto_stream *s,
67 void *out,
68 size_t len
71 size_t i;
72 unsigned int n;
74 for(i = 0; i < len; i++)
76 if(s->used == s->blocksize)
78 kripto_block_encrypt(s->block, s->x, s->buf);
79 s->used = 0;
81 for(n = s->blocksize - 1; n; n--)
82 if(++s->x[n]) break;
85 U8(out)[i] = s->buf[s->used++];
89 static void ctr_destroy(kripto_stream *s)
91 kripto_block_destroy(s->block);
92 kripto_memwipe(s, sizeof(kripto_stream) + (s->blocksize << 1));
93 free(s);
96 struct ext
98 kripto_stream_desc desc;
99 const kripto_block_desc *block;
102 #define EXT(X) ((const struct ext *)(X))
104 static kripto_stream *ctr_create
106 const kripto_stream_desc *desc,
107 unsigned int rounds,
108 const void *key,
109 unsigned int key_len,
110 const void *iv,
111 unsigned int iv_len
114 kripto_stream *s;
116 s = malloc(sizeof(kripto_stream) + (desc->maxiv << 1));
117 if(!s) return 0;
119 s->obj.desc = desc;
120 s->obj.multof = 1;
122 s->used = s->blocksize = desc->maxiv;
124 s->x = (uint8_t *)s + sizeof(kripto_stream);
125 s->buf = s->x + s->blocksize;
127 /* block cipher */
128 s->block = kripto_block_create(EXT(desc)->block, rounds, key, key_len);
129 if(!s->block)
131 kripto_memwipe(s, sizeof(kripto_stream) + (s->blocksize << 1));
132 free(s);
133 return 0;
136 /* IV (nonce) */
137 if(iv_len) memcpy(s->x, iv, iv_len);
138 memset(s->x + iv_len, 0, s->blocksize - iv_len);
140 return s;
143 static kripto_stream *ctr_recreate
145 kripto_stream *s,
146 unsigned int rounds,
147 const void *key,
148 unsigned int key_len,
149 const void *iv,
150 unsigned int iv_len
153 /* block cipher */
154 s->block = kripto_block_recreate(s->block, rounds, key, key_len);
155 if(!s->block)
157 kripto_memwipe(s, sizeof(kripto_stream) + (s->blocksize << 1));
158 free(s);
159 return 0;
162 /* IV (nonce) */
163 if(iv_len) memcpy(s->x, iv, iv_len);
164 memset(s->x + iv_len, 0, s->blocksize - iv_len);
166 s->used = s->blocksize;
168 return s;
171 kripto_stream_desc *kripto_stream_ctr(const kripto_block_desc *block)
173 struct ext *s;
175 s = malloc(sizeof(struct ext));
176 if(!s) return 0;
178 s->block = block;
180 s->desc.create = &ctr_create;
181 s->desc.recreate = &ctr_recreate;
182 s->desc.encrypt = &ctr_crypt;
183 s->desc.decrypt = &ctr_crypt;
184 s->desc.prng = &ctr_prng;
185 s->desc.destroy = &ctr_destroy;
186 s->desc.maxkey = kripto_block_maxkey(block);
187 s->desc.maxiv = kripto_block_size(block);
189 return (kripto_stream_desc *)s;