keccak stream ciphers added
[rofl0r-kripto.git] / lib / stream / skein1024.c
blob6debde5e25dedd7d2eaaf1519988ad2f58a612dd
1 /*
2 * Copyright (C) 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>
18 #include <limits.h>
19 #include <assert.h>
21 #include <kripto/cast.h>
22 #include <kripto/loadstore.h>
23 #include <kripto/memwipe.h>
24 #include <kripto/block.h>
25 #include <kripto/block/threefish1024.h>
26 #include <kripto/stream.h>
27 #include <kripto/desc/stream.h>
29 #include <kripto/stream/skein1024.h>
31 struct kripto_stream
33 const kripto_stream_desc *stream;
34 kripto_block *block;
35 unsigned int r;
36 unsigned int i;
37 uint8_t ctr[128];
38 uint8_t buf[128];
41 #define POS_ADD(TWEAK, ADD) \
42 { \
43 TWEAK[0] += ADD; \
44 if(!TWEAK[0]) \
45 if(!++TWEAK[1]) \
46 if(!++TWEAK[2]) \
47 if(!++TWEAK[3]) \
48 if(!++TWEAK[4]) \
49 if(!++TWEAK[5]) \
50 if(!++TWEAK[6]) \
51 if(!++TWEAK[7]) \
52 if(!++TWEAK[8]) \
53 if(!++TWEAK[9]) \
54 if(!++TWEAK[10]) \
55 { \
56 TWEAK[11]++; \
57 assert(TWEAK[11]); \
58 } \
61 static kripto_stream *skein1024_recreate
63 kripto_stream *s,
64 unsigned int r,
65 const void *key,
66 unsigned int key_len,
67 const void *iv,
68 unsigned int iv_len
71 uint8_t tweak[16];
72 uint8_t k[128];
73 unsigned int block;
74 unsigned int i;
76 s->r = r;
77 s->i = 0;
78 memset(k, 0, 128);
79 memset(s->ctr, 0, 128);
81 /* KEY */
82 memset(tweak, 0, 16);
83 tweak[15] = 0x40; /* type KEY, first */
85 while(key_len)
87 if(key_len > 128) block = 128;
88 else block = key_len;
90 memcpy(s->buf, key, block);
91 memset(s->buf, 0, 128 - block);
93 POS_ADD(tweak, block);
95 key_len -= block;
97 if(!key_len) tweak[15] |= 0x80; /* add final */
99 /* process */
100 (void)kripto_block_recreate(s->block, s->r, k, 128);
101 kripto_block_tweak(s->block, tweak, 16);
102 kripto_block_encrypt(s->block, s->buf, k);
103 for(i = 0; i < 128; i++) k[i] ^= s->buf[i];
105 tweak[15] &= 0xBF; /* remove first */
108 /* CFG */
109 s->buf[0] = 'S';
110 s->buf[1] = 'H';
111 s->buf[2] = 'A';
112 s->buf[3] = '3';
113 s->buf[4] = 1;
114 s->buf[5] = 0;
115 s->buf[6] = 0;
116 s->buf[7] = 0;
117 memset(s->buf + 8, 0xFF, 8); /* output UINT64_MAX */
118 memset(s->buf + 16, 0, 112);
119 memset(tweak, 0, 12);
120 tweak[0] = 32;
121 tweak[15] = 0xC4; /* type CFG, first, final */
123 /* process */
124 (void)kripto_block_recreate(s->block, s->r, k, 128);
125 kripto_block_tweak(s->block, tweak, 16);
126 kripto_block_encrypt(s->block, s->buf, k);
127 for(i = 0; i < 128; i++) k[i] ^= s->buf[i];
129 /* NONCE */
130 memset(tweak, 0, 12);
131 tweak[15] = 0x54; /* type NONCE, first */
133 while(iv_len)
135 if(iv_len > 128) block = 128;
136 else block = iv_len;
138 memcpy(s->buf, iv, block);
139 memset(s->buf, 0, 128 - block);
141 POS_ADD(tweak, block);
143 iv_len -= block;
145 if(!iv_len) tweak[15] |= 0x80; /* add final */
147 /* process */
148 (void)kripto_block_recreate(s->block, s->r, k, 128);
149 kripto_block_tweak(s->block, tweak, 16);
150 kripto_block_encrypt(s->block, s->buf, k);
151 for(i = 0; i < 128; i++) k[i] ^= s->buf[i];
153 tweak[15] &= 0xBF; /* remove first */
156 /* final setup */
157 (void)kripto_block_recreate(s->block, s->r, k, 128);
158 memset(tweak, 0, 12);
159 tweak[0] = 8; /* 8 byte counter */
160 tweak[15] = 0xFF; /* type OUTPUT, first, final */
161 kripto_block_tweak(s->block, tweak, 16);
163 kripto_memwipe(k, 128);
165 return s;
168 static void skein1024_crypt
170 kripto_stream *s,
171 const void *in,
172 void *out,
173 size_t len
176 size_t i;
178 for(i = 0; i < len; i++)
180 if(s->i == 128)
182 kripto_block_encrypt(s->block, s->ctr, s->buf);
183 for(s->i = 0; s->i < 128; s->i++)
184 s->buf[s->i] ^= s->ctr[s->i];
186 if(!++s->ctr[0])
187 if(!++s->ctr[1])
188 if(!++s->ctr[2])
189 if(!++s->ctr[3])
190 if(!++s->ctr[4])
191 if(!++s->ctr[5])
192 if(!++s->ctr[6])
194 s->ctr[7]++;
195 assert(s->ctr[7]);
198 s->i = 0;
201 U8(out)[i] = CU8(in)[i] ^ s->buf[s->i++];
205 static void skein1024_prng(kripto_stream *s, void *out, size_t len)
207 size_t i;
209 for(i = 0; i < len; i++)
211 if(s->i == 128)
213 kripto_block_encrypt(s->block, s->ctr, s->buf);
214 for(s->i = 0; s->i < 128; s->i++)
215 s->buf[s->i] ^= s->ctr[s->i];
217 if(!++s->ctr[0])
218 if(!++s->ctr[1])
219 if(!++s->ctr[2])
220 if(!++s->ctr[3])
221 if(!++s->ctr[4])
222 if(!++s->ctr[5])
223 if(!++s->ctr[6])
225 s->ctr[7]++;
226 assert(s->ctr[7]);
229 s->i = 0;
232 U8(out)[i] = s->buf[s->i++];
236 static kripto_stream *skein1024_create
238 const kripto_stream_desc *desc,
239 unsigned int r,
240 const void *key,
241 unsigned int key_len,
242 const void *iv,
243 unsigned int iv_len
246 kripto_stream *s;
248 (void)desc;
250 s = malloc(sizeof(kripto_stream));
251 if(!s) return 0;
253 s->stream = kripto_stream_skein1024;
255 s->block = kripto_block_create(kripto_block_threefish1024, r, "", 1);
256 if(!s->block)
258 free(s);
259 return 0;
262 (void)skein1024_recreate(s, r, key, key_len, iv, iv_len);
264 return s;
267 static void skein1024_destroy(kripto_stream *s)
269 kripto_block_destroy(s->block);
270 kripto_memwipe(s, sizeof(kripto_stream));
271 free(s);
274 static const kripto_stream_desc skein1024 =
276 &skein1024_create,
277 &skein1024_recreate,
278 &skein1024_crypt,
279 &skein1024_crypt,
280 &skein1024_prng,
281 &skein1024_destroy,
283 UINT_MAX, /* max key */
284 UINT_MAX /* max iv */
287 const kripto_stream_desc *const kripto_stream_skein1024 = &skein1024;