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.
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>
33 const kripto_stream_desc
*stream
;
41 #define POS_ADD(TWEAK, ADD) \
61 static kripto_stream
*skein1024_recreate
79 memset(s
->ctr
, 0, 128);
83 tweak
[15] = 0x40; /* type KEY, first */
87 if(key_len
> 128) block
= 128;
90 memcpy(s
->buf
, key
, block
);
91 memset(s
->buf
, 0, 128 - block
);
93 POS_ADD(tweak
, block
);
97 if(!key_len
) tweak
[15] |= 0x80; /* add final */
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 */
117 memset(s
->buf
+ 8, 0xFF, 8); /* output UINT64_MAX */
118 memset(s
->buf
+ 16, 0, 112);
119 memset(tweak
, 0, 12);
121 tweak
[15] = 0xC4; /* type CFG, first, final */
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
];
130 memset(tweak
, 0, 12);
131 tweak
[15] = 0x54; /* type NONCE, first */
135 if(iv_len
> 128) block
= 128;
138 memcpy(s
->buf
, iv
, block
);
139 memset(s
->buf
, 0, 128 - block
);
141 POS_ADD(tweak
, block
);
145 if(!iv_len
) tweak
[15] |= 0x80; /* add final */
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 */
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);
168 static void skein1024_crypt
178 for(i
= 0; i
< len
; i
++)
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
];
201 U8(out
)[i
] = CU8(in
)[i
] ^ s
->buf
[s
->i
++];
205 static void skein1024_prng(kripto_stream
*s
, void *out
, size_t len
)
209 for(i
= 0; i
< len
; i
++)
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
];
232 U8(out
)[i
] = s
->buf
[s
->i
++];
236 static kripto_stream
*skein1024_create
238 const kripto_stream_desc
*desc
,
241 unsigned int key_len
,
250 s
= malloc(sizeof(kripto_stream
));
253 s
->stream
= kripto_stream_skein1024
;
255 s
->block
= kripto_block_create(kripto_block_threefish1024
, r
, "", 1);
262 (void)skein1024_recreate(s
, r
, key
, key_len
, iv
, iv_len
);
267 static void skein1024_destroy(kripto_stream
*s
)
269 kripto_block_destroy(s
->block
);
270 kripto_memwipe(s
, sizeof(kripto_stream
));
274 static const kripto_stream_desc skein1024
=
283 UINT_MAX
, /* max key */
284 UINT_MAX
/* max iv */
287 const kripto_stream_desc
*const kripto_stream_skein1024
= &skein1024
;