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>
28 #include <kripto/object/stream.h>
30 #include <kripto/stream/skein1024.h>
34 struct kripto_stream_object obj
;
42 #define POS_ADD(TWEAK, ADD) \
62 static kripto_stream
*skein1024_recreate
80 memset(s
->ctr
, 0, 128);
84 tweak
[15] = 0x40; /* type KEY, first */
88 if(key_len
> 128) block
= 128;
91 memcpy(s
->buf
, key
, block
);
92 memset(s
->buf
, 0, 128 - block
);
94 POS_ADD(tweak
, block
);
98 if(!key_len
) tweak
[15] |= 0x80; /* add final */
101 (void)kripto_block_recreate(s
->block
, s
->r
, k
, 128);
102 kripto_block_tweak(s
->block
, tweak
, 16);
103 kripto_block_encrypt(s
->block
, s
->buf
, k
);
104 for(i
= 0; i
< 128; i
++) k
[i
] ^= s
->buf
[i
];
106 tweak
[15] &= 0xBF; /* remove first */
118 memset(s
->buf
+ 8, 0xFF, 8); /* output UINT64_MAX */
119 memset(s
->buf
+ 16, 0, 112);
120 memset(tweak
, 0, 12);
122 tweak
[15] = 0xC4; /* type CFG, first, final */
125 (void)kripto_block_recreate(s
->block
, s
->r
, k
, 128);
126 kripto_block_tweak(s
->block
, tweak
, 16);
127 kripto_block_encrypt(s
->block
, s
->buf
, k
);
128 for(i
= 0; i
< 128; i
++) k
[i
] ^= s
->buf
[i
];
131 memset(tweak
, 0, 12);
132 tweak
[15] = 0x54; /* type NONCE, first */
136 if(iv_len
> 128) block
= 128;
139 memcpy(s
->buf
, iv
, block
);
140 memset(s
->buf
, 0, 128 - block
);
142 POS_ADD(tweak
, block
);
146 if(!iv_len
) tweak
[15] |= 0x80; /* add final */
149 (void)kripto_block_recreate(s
->block
, s
->r
, k
, 128);
150 kripto_block_tweak(s
->block
, tweak
, 16);
151 kripto_block_encrypt(s
->block
, s
->buf
, k
);
152 for(i
= 0; i
< 128; i
++) k
[i
] ^= s
->buf
[i
];
154 tweak
[15] &= 0xBF; /* remove first */
158 (void)kripto_block_recreate(s
->block
, s
->r
, k
, 128);
159 memset(tweak
, 0, 12);
160 tweak
[0] = 8; /* 8 byte counter */
161 tweak
[15] = 0xFF; /* type OUTPUT, first, final */
162 kripto_block_tweak(s
->block
, tweak
, 16);
164 kripto_memwipe(k
, 128);
169 static void skein1024_crypt
179 for(i
= 0; i
< len
; i
++)
183 kripto_block_encrypt(s
->block
, s
->ctr
, s
->buf
);
184 for(s
->i
= 0; s
->i
< 128; s
->i
++)
185 s
->buf
[s
->i
] ^= s
->ctr
[s
->i
];
202 U8(out
)[i
] = CU8(in
)[i
] ^ s
->buf
[s
->i
++];
206 static void skein1024_prng(kripto_stream
*s
, void *out
, size_t len
)
210 for(i
= 0; i
< len
; i
++)
214 kripto_block_encrypt(s
->block
, s
->ctr
, s
->buf
);
215 for(s
->i
= 0; s
->i
< 128; s
->i
++)
216 s
->buf
[s
->i
] ^= s
->ctr
[s
->i
];
233 U8(out
)[i
] = s
->buf
[s
->i
++];
237 static kripto_stream
*skein1024_create
239 const kripto_stream_desc
*desc
,
242 unsigned int key_len
,
251 s
= malloc(sizeof(kripto_stream
));
254 s
->obj
.desc
= kripto_stream_skein1024
;
256 s
->block
= kripto_block_create(kripto_block_threefish1024
, r
, "", 1);
263 (void)skein1024_recreate(s
, r
, key
, key_len
, iv
, iv_len
);
268 static void skein1024_destroy(kripto_stream
*s
)
270 kripto_block_destroy(s
->block
);
271 kripto_memwipe(s
, sizeof(kripto_stream
));
275 static const kripto_stream_desc skein1024
=
284 UINT_MAX
, /* max key */
285 UINT_MAX
/* max iv */
288 const kripto_stream_desc
*const kripto_stream_skein1024
= &skein1024
;