1 /***********************************************************************
2 **
3 ** Implementation of the Skein hash function.
4 **
5 ** Source code author: Doug Whiting, 2008.
6 **
7 ** This algorithm and source code is released to the public domain.
8 **
9 ************************************************************************/
10
11 #include <linux/string.h> /* get the memcpy/memset functions */
12 #include <linux/export.h>
13 #include "skein_base.h" /* get the Skein API definitions */
14 #include "skein_iv.h" /* get precomputed IVs */
15 #include "skein_block.h"
16
17 /*****************************************************************/
18 /* 256-bit Skein */
19 /*****************************************************************/
20
21 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
22 /* init the context for a straight hashing operation */
skein_256_init(struct skein_256_ctx * ctx,size_t hash_bit_len)23 int skein_256_init(struct skein_256_ctx *ctx, size_t hash_bit_len)
24 {
25 union {
26 u8 b[SKEIN_256_STATE_BYTES];
27 u64 w[SKEIN_256_STATE_WORDS];
28 } cfg; /* config block */
29
30 skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
31 ctx->h.hash_bit_len = hash_bit_len; /* output hash bit count */
32
33 switch (hash_bit_len) { /* use pre-computed values, where available */
34 case 256:
35 memcpy(ctx->x, SKEIN_256_IV_256, sizeof(ctx->x));
36 break;
37 case 224:
38 memcpy(ctx->x, SKEIN_256_IV_224, sizeof(ctx->x));
39 break;
40 case 160:
41 memcpy(ctx->x, SKEIN_256_IV_160, sizeof(ctx->x));
42 break;
43 case 128:
44 memcpy(ctx->x, SKEIN_256_IV_128, sizeof(ctx->x));
45 break;
46 default:
47 /* here if there is no precomputed IV value available */
48 /*
49 * build/process the config block, type == CONFIG (could be
50 * precomputed)
51 */
52 /* set tweaks: T0=0; T1=CFG | FINAL */
53 skein_start_new_type(ctx, CFG_FINAL);
54
55 /* set the schema, version */
56 cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
57 /* hash result length in bits */
58 cfg.w[1] = skein_swap64(hash_bit_len);
59 cfg.w[2] = skein_swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
60 /* zero pad config block */
61 memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
62
63 /* compute the initial chaining values from config block */
64 /* zero the chaining variables */
65 memset(ctx->x, 0, sizeof(ctx->x));
66 skein_256_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
67 break;
68 }
69 /* The chaining vars ctx->x are now initialized for hash_bit_len. */
70 /* Set up to process the data message portion of the hash (default) */
71 skein_start_new_type(ctx, MSG); /* T0=0, T1= MSG type */
72
73 return SKEIN_SUCCESS;
74 }
75
76 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
77 /* init the context for a MAC and/or tree hash operation */
78 /* [identical to skein_256_init() when key_bytes == 0 && \
79 * tree_info == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
skein_256_init_ext(struct skein_256_ctx * ctx,size_t hash_bit_len,u64 tree_info,const u8 * key,size_t key_bytes)80 int skein_256_init_ext(struct skein_256_ctx *ctx, size_t hash_bit_len,
81 u64 tree_info, const u8 *key, size_t key_bytes)
82 {
83 union {
84 u8 b[SKEIN_256_STATE_BYTES];
85 u64 w[SKEIN_256_STATE_WORDS];
86 } cfg; /* config block */
87
88 skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
89 skein_assert_ret(key_bytes == 0 || key != NULL, SKEIN_FAIL);
90
91 /* compute the initial chaining values ctx->x[], based on key */
92 if (key_bytes == 0) { /* is there a key? */
93 /* no key: use all zeroes as key for config block */
94 memset(ctx->x, 0, sizeof(ctx->x));
95 } else { /* here to pre-process a key */
96 skein_assert(sizeof(cfg.b) >= sizeof(ctx->x));
97 /* do a mini-Init right here */
98 /* set output hash bit count = state size */
99 ctx->h.hash_bit_len = 8*sizeof(ctx->x);
100 /* set tweaks: T0 = 0; T1 = KEY type */
101 skein_start_new_type(ctx, KEY);
102 /* zero the initial chaining variables */
103 memset(ctx->x, 0, sizeof(ctx->x));
104 /* hash the key */
105 skein_256_update(ctx, key, key_bytes);
106 /* put result into cfg.b[] */
107 skein_256_final_pad(ctx, cfg.b);
108 /* copy over into ctx->x[] */
109 memcpy(ctx->x, cfg.b, sizeof(cfg.b));
110 }
111 /*
112 * build/process the config block, type == CONFIG (could be
113 * precomputed for each key)
114 */
115 /* output hash bit count */
116 ctx->h.hash_bit_len = hash_bit_len;
117 skein_start_new_type(ctx, CFG_FINAL);
118
119 /* pre-pad cfg.w[] with zeroes */
120 memset(&cfg.w, 0, sizeof(cfg.w));
121 cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
122 /* hash result length in bits */
123 cfg.w[1] = skein_swap64(hash_bit_len);
124 /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
125 cfg.w[2] = skein_swap64(tree_info);
126
127 /* compute the initial chaining values from config block */
128 skein_256_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
129
130 /* The chaining vars ctx->x are now initialized */
131 /* Set up to process the data message portion of the hash (default) */
132 skein_start_new_type(ctx, MSG);
133
134 return SKEIN_SUCCESS;
135 }
136
137 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
138 /* process the input bytes */
skein_256_update(struct skein_256_ctx * ctx,const u8 * msg,size_t msg_byte_cnt)139 int skein_256_update(struct skein_256_ctx *ctx, const u8 *msg,
140 size_t msg_byte_cnt)
141 {
142 size_t n;
143
144 /* catch uninitialized context */
145 skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
146
147 /* process full blocks, if any */
148 if (msg_byte_cnt + ctx->h.b_cnt > SKEIN_256_BLOCK_BYTES) {
149 /* finish up any buffered message data */
150 if (ctx->h.b_cnt) {
151 /* # bytes free in buffer b[] */
152 n = SKEIN_256_BLOCK_BYTES - ctx->h.b_cnt;
153 if (n) {
154 /* check on our logic here */
155 skein_assert(n < msg_byte_cnt);
156 memcpy(&ctx->b[ctx->h.b_cnt], msg, n);
157 msg_byte_cnt -= n;
158 msg += n;
159 ctx->h.b_cnt += n;
160 }
161 skein_assert(ctx->h.b_cnt == SKEIN_256_BLOCK_BYTES);
162 skein_256_process_block(ctx, ctx->b, 1,
163 SKEIN_256_BLOCK_BYTES);
164 ctx->h.b_cnt = 0;
165 }
166 /*
167 * now process any remaining full blocks, directly from input
168 * message data
169 */
170 if (msg_byte_cnt > SKEIN_256_BLOCK_BYTES) {
171 /* number of full blocks to process */
172 n = (msg_byte_cnt-1) / SKEIN_256_BLOCK_BYTES;
173 skein_256_process_block(ctx, msg, n,
174 SKEIN_256_BLOCK_BYTES);
175 msg_byte_cnt -= n * SKEIN_256_BLOCK_BYTES;
176 msg += n * SKEIN_256_BLOCK_BYTES;
177 }
178 skein_assert(ctx->h.b_cnt == 0);
179 }
180
181 /* copy any remaining source message data bytes into b[] */
182 if (msg_byte_cnt) {
183 skein_assert(msg_byte_cnt + ctx->h.b_cnt <=
184 SKEIN_256_BLOCK_BYTES);
185 memcpy(&ctx->b[ctx->h.b_cnt], msg, msg_byte_cnt);
186 ctx->h.b_cnt += msg_byte_cnt;
187 }
188
189 return SKEIN_SUCCESS;
190 }
191
192 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
193 /* finalize the hash computation and output the result */
skein_256_final(struct skein_256_ctx * ctx,u8 * hash_val)194 int skein_256_final(struct skein_256_ctx *ctx, u8 *hash_val)
195 {
196 size_t i, n, byte_cnt;
197 u64 x[SKEIN_256_STATE_WORDS];
198 /* catch uninitialized context */
199 skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
200
201 /* tag as the final block */
202 ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
203 /* zero pad b[] if necessary */
204 if (ctx->h.b_cnt < SKEIN_256_BLOCK_BYTES)
205 memset(&ctx->b[ctx->h.b_cnt], 0,
206 SKEIN_256_BLOCK_BYTES - ctx->h.b_cnt);
207
208 /* process the final block */
209 skein_256_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
210
211 /* now output the result */
212 /* total number of output bytes */
213 byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
214
215 /* run Threefish in "counter mode" to generate output */
216 /* zero out b[], so it can hold the counter */
217 memset(ctx->b, 0, sizeof(ctx->b));
218 /* keep a local copy of counter mode "key" */
219 memcpy(x, ctx->x, sizeof(x));
220 for (i = 0; i*SKEIN_256_BLOCK_BYTES < byte_cnt; i++) {
221 /* build the counter block */
222 ((u64 *)ctx->b)[0] = skein_swap64((u64) i);
223 skein_start_new_type(ctx, OUT_FINAL);
224 /* run "counter mode" */
225 skein_256_process_block(ctx, ctx->b, 1, sizeof(u64));
226 /* number of output bytes left to go */
227 n = byte_cnt - i*SKEIN_256_BLOCK_BYTES;
228 if (n >= SKEIN_256_BLOCK_BYTES)
229 n = SKEIN_256_BLOCK_BYTES;
230 /* "output" the ctr mode bytes */
231 skein_put64_lsb_first(hash_val+i*SKEIN_256_BLOCK_BYTES, ctx->x,
232 n);
233 /* restore the counter mode key for next time */
234 memcpy(ctx->x, x, sizeof(x));
235 }
236 return SKEIN_SUCCESS;
237 }
238
239 /*****************************************************************/
240 /* 512-bit Skein */
241 /*****************************************************************/
242
243 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
244 /* init the context for a straight hashing operation */
skein_512_init(struct skein_512_ctx * ctx,size_t hash_bit_len)245 int skein_512_init(struct skein_512_ctx *ctx, size_t hash_bit_len)
246 {
247 union {
248 u8 b[SKEIN_512_STATE_BYTES];
249 u64 w[SKEIN_512_STATE_WORDS];
250 } cfg; /* config block */
251
252 skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
253 ctx->h.hash_bit_len = hash_bit_len; /* output hash bit count */
254
255 switch (hash_bit_len) { /* use pre-computed values, where available */
256 case 512:
257 memcpy(ctx->x, SKEIN_512_IV_512, sizeof(ctx->x));
258 break;
259 case 384:
260 memcpy(ctx->x, SKEIN_512_IV_384, sizeof(ctx->x));
261 break;
262 case 256:
263 memcpy(ctx->x, SKEIN_512_IV_256, sizeof(ctx->x));
264 break;
265 case 224:
266 memcpy(ctx->x, SKEIN_512_IV_224, sizeof(ctx->x));
267 break;
268 default:
269 /* here if there is no precomputed IV value available */
270 /*
271 * build/process the config block, type == CONFIG (could be
272 * precomputed)
273 */
274 /* set tweaks: T0=0; T1=CFG | FINAL */
275 skein_start_new_type(ctx, CFG_FINAL);
276
277 /* set the schema, version */
278 cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
279 /* hash result length in bits */
280 cfg.w[1] = skein_swap64(hash_bit_len);
281 cfg.w[2] = skein_swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
282 /* zero pad config block */
283 memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
284
285 /* compute the initial chaining values from config block */
286 /* zero the chaining variables */
287 memset(ctx->x, 0, sizeof(ctx->x));
288 skein_512_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
289 break;
290 }
291
292 /*
293 * The chaining vars ctx->x are now initialized for the given
294 * hash_bit_len.
295 */
296 /* Set up to process the data message portion of the hash (default) */
297 skein_start_new_type(ctx, MSG); /* T0=0, T1= MSG type */
298
299 return SKEIN_SUCCESS;
300 }
301
302 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
303 /* init the context for a MAC and/or tree hash operation */
304 /* [identical to skein_512_init() when key_bytes == 0 && \
305 * tree_info == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
skein_512_init_ext(struct skein_512_ctx * ctx,size_t hash_bit_len,u64 tree_info,const u8 * key,size_t key_bytes)306 int skein_512_init_ext(struct skein_512_ctx *ctx, size_t hash_bit_len,
307 u64 tree_info, const u8 *key, size_t key_bytes)
308 {
309 union {
310 u8 b[SKEIN_512_STATE_BYTES];
311 u64 w[SKEIN_512_STATE_WORDS];
312 } cfg; /* config block */
313
314 skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
315 skein_assert_ret(key_bytes == 0 || key != NULL, SKEIN_FAIL);
316
317 /* compute the initial chaining values ctx->x[], based on key */
318 if (key_bytes == 0) { /* is there a key? */
319 /* no key: use all zeroes as key for config block */
320 memset(ctx->x, 0, sizeof(ctx->x));
321 } else { /* here to pre-process a key */
322 skein_assert(sizeof(cfg.b) >= sizeof(ctx->x));
323 /* do a mini-Init right here */
324 /* set output hash bit count = state size */
325 ctx->h.hash_bit_len = 8*sizeof(ctx->x);
326 /* set tweaks: T0 = 0; T1 = KEY type */
327 skein_start_new_type(ctx, KEY);
328 /* zero the initial chaining variables */
329 memset(ctx->x, 0, sizeof(ctx->x));
330 /* hash the key */
331 skein_512_update(ctx, key, key_bytes);
332 /* put result into cfg.b[] */
333 skein_512_final_pad(ctx, cfg.b);
334 /* copy over into ctx->x[] */
335 memcpy(ctx->x, cfg.b, sizeof(cfg.b));
336 }
337 /*
338 * build/process the config block, type == CONFIG (could be
339 * precomputed for each key)
340 */
341 ctx->h.hash_bit_len = hash_bit_len; /* output hash bit count */
342 skein_start_new_type(ctx, CFG_FINAL);
343
344 /* pre-pad cfg.w[] with zeroes */
345 memset(&cfg.w, 0, sizeof(cfg.w));
346 cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
347 /* hash result length in bits */
348 cfg.w[1] = skein_swap64(hash_bit_len);
349 /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
350 cfg.w[2] = skein_swap64(tree_info);
351
352 /* compute the initial chaining values from config block */
353 skein_512_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
354
355 /* The chaining vars ctx->x are now initialized */
356 /* Set up to process the data message portion of the hash (default) */
357 skein_start_new_type(ctx, MSG);
358
359 return SKEIN_SUCCESS;
360 }
361
362 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
363 /* process the input bytes */
skein_512_update(struct skein_512_ctx * ctx,const u8 * msg,size_t msg_byte_cnt)364 int skein_512_update(struct skein_512_ctx *ctx, const u8 *msg,
365 size_t msg_byte_cnt)
366 {
367 size_t n;
368
369 /* catch uninitialized context */
370 skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
371
372 /* process full blocks, if any */
373 if (msg_byte_cnt + ctx->h.b_cnt > SKEIN_512_BLOCK_BYTES) {
374 /* finish up any buffered message data */
375 if (ctx->h.b_cnt) {
376 /* # bytes free in buffer b[] */
377 n = SKEIN_512_BLOCK_BYTES - ctx->h.b_cnt;
378 if (n) {
379 /* check on our logic here */
380 skein_assert(n < msg_byte_cnt);
381 memcpy(&ctx->b[ctx->h.b_cnt], msg, n);
382 msg_byte_cnt -= n;
383 msg += n;
384 ctx->h.b_cnt += n;
385 }
386 skein_assert(ctx->h.b_cnt == SKEIN_512_BLOCK_BYTES);
387 skein_512_process_block(ctx, ctx->b, 1,
388 SKEIN_512_BLOCK_BYTES);
389 ctx->h.b_cnt = 0;
390 }
391 /*
392 * now process any remaining full blocks, directly from input
393 * message data
394 */
395 if (msg_byte_cnt > SKEIN_512_BLOCK_BYTES) {
396 /* number of full blocks to process */
397 n = (msg_byte_cnt-1) / SKEIN_512_BLOCK_BYTES;
398 skein_512_process_block(ctx, msg, n,
399 SKEIN_512_BLOCK_BYTES);
400 msg_byte_cnt -= n * SKEIN_512_BLOCK_BYTES;
401 msg += n * SKEIN_512_BLOCK_BYTES;
402 }
403 skein_assert(ctx->h.b_cnt == 0);
404 }
405
406 /* copy any remaining source message data bytes into b[] */
407 if (msg_byte_cnt) {
408 skein_assert(msg_byte_cnt + ctx->h.b_cnt <=
409 SKEIN_512_BLOCK_BYTES);
410 memcpy(&ctx->b[ctx->h.b_cnt], msg, msg_byte_cnt);
411 ctx->h.b_cnt += msg_byte_cnt;
412 }
413
414 return SKEIN_SUCCESS;
415 }
416
417 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
418 /* finalize the hash computation and output the result */
skein_512_final(struct skein_512_ctx * ctx,u8 * hash_val)419 int skein_512_final(struct skein_512_ctx *ctx, u8 *hash_val)
420 {
421 size_t i, n, byte_cnt;
422 u64 x[SKEIN_512_STATE_WORDS];
423 /* catch uninitialized context */
424 skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
425
426 /* tag as the final block */
427 ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
428 /* zero pad b[] if necessary */
429 if (ctx->h.b_cnt < SKEIN_512_BLOCK_BYTES)
430 memset(&ctx->b[ctx->h.b_cnt], 0,
431 SKEIN_512_BLOCK_BYTES - ctx->h.b_cnt);
432
433 /* process the final block */
434 skein_512_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
435
436 /* now output the result */
437 /* total number of output bytes */
438 byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
439
440 /* run Threefish in "counter mode" to generate output */
441 /* zero out b[], so it can hold the counter */
442 memset(ctx->b, 0, sizeof(ctx->b));
443 /* keep a local copy of counter mode "key" */
444 memcpy(x, ctx->x, sizeof(x));
445 for (i = 0; i*SKEIN_512_BLOCK_BYTES < byte_cnt; i++) {
446 /* build the counter block */
447 ((u64 *)ctx->b)[0] = skein_swap64((u64) i);
448 skein_start_new_type(ctx, OUT_FINAL);
449 /* run "counter mode" */
450 skein_512_process_block(ctx, ctx->b, 1, sizeof(u64));
451 /* number of output bytes left to go */
452 n = byte_cnt - i*SKEIN_512_BLOCK_BYTES;
453 if (n >= SKEIN_512_BLOCK_BYTES)
454 n = SKEIN_512_BLOCK_BYTES;
455 /* "output" the ctr mode bytes */
456 skein_put64_lsb_first(hash_val+i*SKEIN_512_BLOCK_BYTES, ctx->x,
457 n);
458 /* restore the counter mode key for next time */
459 memcpy(ctx->x, x, sizeof(x));
460 }
461 return SKEIN_SUCCESS;
462 }
463
464 /*****************************************************************/
465 /* 1024-bit Skein */
466 /*****************************************************************/
467
468 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
469 /* init the context for a straight hashing operation */
skein_1024_init(struct skein_1024_ctx * ctx,size_t hash_bit_len)470 int skein_1024_init(struct skein_1024_ctx *ctx, size_t hash_bit_len)
471 {
472 union {
473 u8 b[SKEIN_1024_STATE_BYTES];
474 u64 w[SKEIN_1024_STATE_WORDS];
475 } cfg; /* config block */
476
477 skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
478 ctx->h.hash_bit_len = hash_bit_len; /* output hash bit count */
479
480 switch (hash_bit_len) { /* use pre-computed values, where available */
481 case 512:
482 memcpy(ctx->x, SKEIN_1024_IV_512, sizeof(ctx->x));
483 break;
484 case 384:
485 memcpy(ctx->x, SKEIN_1024_IV_384, sizeof(ctx->x));
486 break;
487 case 1024:
488 memcpy(ctx->x, SKEIN_1024_IV_1024, sizeof(ctx->x));
489 break;
490 default:
491 /* here if there is no precomputed IV value available */
492 /*
493 * build/process the config block, type == CONFIG
494 * (could be precomputed)
495 */
496 /* set tweaks: T0=0; T1=CFG | FINAL */
497 skein_start_new_type(ctx, CFG_FINAL);
498
499 /* set the schema, version */
500 cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
501 /* hash result length in bits */
502 cfg.w[1] = skein_swap64(hash_bit_len);
503 cfg.w[2] = skein_swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);
504 /* zero pad config block */
505 memset(&cfg.w[3], 0, sizeof(cfg) - 3*sizeof(cfg.w[0]));
506
507 /* compute the initial chaining values from config block */
508 /* zero the chaining variables */
509 memset(ctx->x, 0, sizeof(ctx->x));
510 skein_1024_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
511 break;
512 }
513
514 /* The chaining vars ctx->x are now initialized for the hash_bit_len. */
515 /* Set up to process the data message portion of the hash (default) */
516 skein_start_new_type(ctx, MSG); /* T0=0, T1= MSG type */
517
518 return SKEIN_SUCCESS;
519 }
520
521 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
522 /* init the context for a MAC and/or tree hash operation */
523 /* [identical to skein_1024_init() when key_bytes == 0 && \
524 * tree_info == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
skein_1024_init_ext(struct skein_1024_ctx * ctx,size_t hash_bit_len,u64 tree_info,const u8 * key,size_t key_bytes)525 int skein_1024_init_ext(struct skein_1024_ctx *ctx, size_t hash_bit_len,
526 u64 tree_info, const u8 *key, size_t key_bytes)
527 {
528 union {
529 u8 b[SKEIN_1024_STATE_BYTES];
530 u64 w[SKEIN_1024_STATE_WORDS];
531 } cfg; /* config block */
532
533 skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
534 skein_assert_ret(key_bytes == 0 || key != NULL, SKEIN_FAIL);
535
536 /* compute the initial chaining values ctx->x[], based on key */
537 if (key_bytes == 0) { /* is there a key? */
538 /* no key: use all zeroes as key for config block */
539 memset(ctx->x, 0, sizeof(ctx->x));
540 } else { /* here to pre-process a key */
541 skein_assert(sizeof(cfg.b) >= sizeof(ctx->x));
542 /* do a mini-Init right here */
543 /* set output hash bit count = state size */
544 ctx->h.hash_bit_len = 8*sizeof(ctx->x);
545 /* set tweaks: T0 = 0; T1 = KEY type */
546 skein_start_new_type(ctx, KEY);
547 /* zero the initial chaining variables */
548 memset(ctx->x, 0, sizeof(ctx->x));
549 /* hash the key */
550 skein_1024_update(ctx, key, key_bytes);
551 /* put result into cfg.b[] */
552 skein_1024_final_pad(ctx, cfg.b);
553 /* copy over into ctx->x[] */
554 memcpy(ctx->x, cfg.b, sizeof(cfg.b));
555 }
556 /*
557 * build/process the config block, type == CONFIG (could be
558 * precomputed for each key)
559 */
560 /* output hash bit count */
561 ctx->h.hash_bit_len = hash_bit_len;
562 skein_start_new_type(ctx, CFG_FINAL);
563
564 /* pre-pad cfg.w[] with zeroes */
565 memset(&cfg.w, 0, sizeof(cfg.w));
566 cfg.w[0] = skein_swap64(SKEIN_SCHEMA_VER);
567 /* hash result length in bits */
568 cfg.w[1] = skein_swap64(hash_bit_len);
569 /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */
570 cfg.w[2] = skein_swap64(tree_info);
571
572 /* compute the initial chaining values from config block */
573 skein_1024_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
574
575 /* The chaining vars ctx->x are now initialized */
576 /* Set up to process the data message portion of the hash (default) */
577 skein_start_new_type(ctx, MSG);
578
579 return SKEIN_SUCCESS;
580 }
581
582 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
583 /* process the input bytes */
skein_1024_update(struct skein_1024_ctx * ctx,const u8 * msg,size_t msg_byte_cnt)584 int skein_1024_update(struct skein_1024_ctx *ctx, const u8 *msg,
585 size_t msg_byte_cnt)
586 {
587 size_t n;
588
589 /* catch uninitialized context */
590 skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
591
592 /* process full blocks, if any */
593 if (msg_byte_cnt + ctx->h.b_cnt > SKEIN_1024_BLOCK_BYTES) {
594 /* finish up any buffered message data */
595 if (ctx->h.b_cnt) {
596 /* # bytes free in buffer b[] */
597 n = SKEIN_1024_BLOCK_BYTES - ctx->h.b_cnt;
598 if (n) {
599 /* check on our logic here */
600 skein_assert(n < msg_byte_cnt);
601 memcpy(&ctx->b[ctx->h.b_cnt], msg, n);
602 msg_byte_cnt -= n;
603 msg += n;
604 ctx->h.b_cnt += n;
605 }
606 skein_assert(ctx->h.b_cnt == SKEIN_1024_BLOCK_BYTES);
607 skein_1024_process_block(ctx, ctx->b, 1,
608 SKEIN_1024_BLOCK_BYTES);
609 ctx->h.b_cnt = 0;
610 }
611 /*
612 * now process any remaining full blocks, directly from input
613 * message data
614 */
615 if (msg_byte_cnt > SKEIN_1024_BLOCK_BYTES) {
616 /* number of full blocks to process */
617 n = (msg_byte_cnt-1) / SKEIN_1024_BLOCK_BYTES;
618 skein_1024_process_block(ctx, msg, n,
619 SKEIN_1024_BLOCK_BYTES);
620 msg_byte_cnt -= n * SKEIN_1024_BLOCK_BYTES;
621 msg += n * SKEIN_1024_BLOCK_BYTES;
622 }
623 skein_assert(ctx->h.b_cnt == 0);
624 }
625
626 /* copy any remaining source message data bytes into b[] */
627 if (msg_byte_cnt) {
628 skein_assert(msg_byte_cnt + ctx->h.b_cnt <=
629 SKEIN_1024_BLOCK_BYTES);
630 memcpy(&ctx->b[ctx->h.b_cnt], msg, msg_byte_cnt);
631 ctx->h.b_cnt += msg_byte_cnt;
632 }
633
634 return SKEIN_SUCCESS;
635 }
636
637 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
638 /* finalize the hash computation and output the result */
skein_1024_final(struct skein_1024_ctx * ctx,u8 * hash_val)639 int skein_1024_final(struct skein_1024_ctx *ctx, u8 *hash_val)
640 {
641 size_t i, n, byte_cnt;
642 u64 x[SKEIN_1024_STATE_WORDS];
643 /* catch uninitialized context */
644 skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
645
646 /* tag as the final block */
647 ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
648 /* zero pad b[] if necessary */
649 if (ctx->h.b_cnt < SKEIN_1024_BLOCK_BYTES)
650 memset(&ctx->b[ctx->h.b_cnt], 0,
651 SKEIN_1024_BLOCK_BYTES - ctx->h.b_cnt);
652
653 /* process the final block */
654 skein_1024_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
655
656 /* now output the result */
657 /* total number of output bytes */
658 byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
659
660 /* run Threefish in "counter mode" to generate output */
661 /* zero out b[], so it can hold the counter */
662 memset(ctx->b, 0, sizeof(ctx->b));
663 /* keep a local copy of counter mode "key" */
664 memcpy(x, ctx->x, sizeof(x));
665 for (i = 0; i*SKEIN_1024_BLOCK_BYTES < byte_cnt; i++) {
666 /* build the counter block */
667 ((u64 *)ctx->b)[0] = skein_swap64((u64) i);
668 skein_start_new_type(ctx, OUT_FINAL);
669 /* run "counter mode" */
670 skein_1024_process_block(ctx, ctx->b, 1, sizeof(u64));
671 /* number of output bytes left to go */
672 n = byte_cnt - i*SKEIN_1024_BLOCK_BYTES;
673 if (n >= SKEIN_1024_BLOCK_BYTES)
674 n = SKEIN_1024_BLOCK_BYTES;
675 /* "output" the ctr mode bytes */
676 skein_put64_lsb_first(hash_val+i*SKEIN_1024_BLOCK_BYTES, ctx->x,
677 n);
678 /* restore the counter mode key for next time */
679 memcpy(ctx->x, x, sizeof(x));
680 }
681 return SKEIN_SUCCESS;
682 }
683
684 /**************** Functions to support MAC/tree hashing ***************/
685 /* (this code is identical for Optimized and Reference versions) */
686
687 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
688 /* finalize the hash computation and output the block, no OUTPUT stage */
skein_256_final_pad(struct skein_256_ctx * ctx,u8 * hash_val)689 int skein_256_final_pad(struct skein_256_ctx *ctx, u8 *hash_val)
690 {
691 /* catch uninitialized context */
692 skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
693
694 /* tag as the final block */
695 ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
696 /* zero pad b[] if necessary */
697 if (ctx->h.b_cnt < SKEIN_256_BLOCK_BYTES)
698 memset(&ctx->b[ctx->h.b_cnt], 0,
699 SKEIN_256_BLOCK_BYTES - ctx->h.b_cnt);
700 /* process the final block */
701 skein_256_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
702
703 /* "output" the state bytes */
704 skein_put64_lsb_first(hash_val, ctx->x, SKEIN_256_BLOCK_BYTES);
705
706 return SKEIN_SUCCESS;
707 }
708
709 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
710 /* finalize the hash computation and output the block, no OUTPUT stage */
skein_512_final_pad(struct skein_512_ctx * ctx,u8 * hash_val)711 int skein_512_final_pad(struct skein_512_ctx *ctx, u8 *hash_val)
712 {
713 /* catch uninitialized context */
714 skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
715
716 /* tag as the final block */
717 ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
718 /* zero pad b[] if necessary */
719 if (ctx->h.b_cnt < SKEIN_512_BLOCK_BYTES)
720 memset(&ctx->b[ctx->h.b_cnt], 0,
721 SKEIN_512_BLOCK_BYTES - ctx->h.b_cnt);
722 /* process the final block */
723 skein_512_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
724
725 /* "output" the state bytes */
726 skein_put64_lsb_first(hash_val, ctx->x, SKEIN_512_BLOCK_BYTES);
727
728 return SKEIN_SUCCESS;
729 }
730
731 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
732 /* finalize the hash computation and output the block, no OUTPUT stage */
skein_1024_final_pad(struct skein_1024_ctx * ctx,u8 * hash_val)733 int skein_1024_final_pad(struct skein_1024_ctx *ctx, u8 *hash_val)
734 {
735 /* catch uninitialized context */
736 skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
737
738 /* tag as the final block */
739 ctx->h.tweak[1] |= SKEIN_T1_FLAG_FINAL;
740 /* zero pad b[] if necessary */
741 if (ctx->h.b_cnt < SKEIN_1024_BLOCK_BYTES)
742 memset(&ctx->b[ctx->h.b_cnt], 0,
743 SKEIN_1024_BLOCK_BYTES - ctx->h.b_cnt);
744 /* process the final block */
745 skein_1024_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
746
747 /* "output" the state bytes */
748 skein_put64_lsb_first(hash_val, ctx->x, SKEIN_1024_BLOCK_BYTES);
749
750 return SKEIN_SUCCESS;
751 }
752
753 #if SKEIN_TREE_HASH
754 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
755 /* just do the OUTPUT stage */
skein_256_output(struct skein_256_ctx * ctx,u8 * hash_val)756 int skein_256_output(struct skein_256_ctx *ctx, u8 *hash_val)
757 {
758 size_t i, n, byte_cnt;
759 u64 x[SKEIN_256_STATE_WORDS];
760 /* catch uninitialized context */
761 skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
762
763 /* now output the result */
764 /* total number of output bytes */
765 byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
766
767 /* run Threefish in "counter mode" to generate output */
768 /* zero out b[], so it can hold the counter */
769 memset(ctx->b, 0, sizeof(ctx->b));
770 /* keep a local copy of counter mode "key" */
771 memcpy(x, ctx->x, sizeof(x));
772 for (i = 0; i*SKEIN_256_BLOCK_BYTES < byte_cnt; i++) {
773 /* build the counter block */
774 ((u64 *)ctx->b)[0] = skein_swap64((u64) i);
775 skein_start_new_type(ctx, OUT_FINAL);
776 /* run "counter mode" */
777 skein_256_process_block(ctx, ctx->b, 1, sizeof(u64));
778 /* number of output bytes left to go */
779 n = byte_cnt - i*SKEIN_256_BLOCK_BYTES;
780 if (n >= SKEIN_256_BLOCK_BYTES)
781 n = SKEIN_256_BLOCK_BYTES;
782 /* "output" the ctr mode bytes */
783 skein_put64_lsb_first(hash_val+i*SKEIN_256_BLOCK_BYTES, ctx->x,
784 n);
785 /* restore the counter mode key for next time */
786 memcpy(ctx->x, x, sizeof(x));
787 }
788 return SKEIN_SUCCESS;
789 }
790
791 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
792 /* just do the OUTPUT stage */
skein_512_output(struct skein_512_ctx * ctx,u8 * hash_val)793 int skein_512_output(struct skein_512_ctx *ctx, u8 *hash_val)
794 {
795 size_t i, n, byte_cnt;
796 u64 x[SKEIN_512_STATE_WORDS];
797 /* catch uninitialized context */
798 skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
799
800 /* now output the result */
801 /* total number of output bytes */
802 byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
803
804 /* run Threefish in "counter mode" to generate output */
805 /* zero out b[], so it can hold the counter */
806 memset(ctx->b, 0, sizeof(ctx->b));
807 /* keep a local copy of counter mode "key" */
808 memcpy(x, ctx->x, sizeof(x));
809 for (i = 0; i*SKEIN_512_BLOCK_BYTES < byte_cnt; i++) {
810 /* build the counter block */
811 ((u64 *)ctx->b)[0] = skein_swap64((u64) i);
812 skein_start_new_type(ctx, OUT_FINAL);
813 /* run "counter mode" */
814 skein_512_process_block(ctx, ctx->b, 1, sizeof(u64));
815 /* number of output bytes left to go */
816 n = byte_cnt - i*SKEIN_512_BLOCK_BYTES;
817 if (n >= SKEIN_512_BLOCK_BYTES)
818 n = SKEIN_512_BLOCK_BYTES;
819 /* "output" the ctr mode bytes */
820 skein_put64_lsb_first(hash_val+i*SKEIN_512_BLOCK_BYTES, ctx->x,
821 n);
822 /* restore the counter mode key for next time */
823 memcpy(ctx->x, x, sizeof(x));
824 }
825 return SKEIN_SUCCESS;
826 }
827
828 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
829 /* just do the OUTPUT stage */
skein_1024_output(struct skein_1024_ctx * ctx,u8 * hash_val)830 int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val)
831 {
832 size_t i, n, byte_cnt;
833 u64 x[SKEIN_1024_STATE_WORDS];
834 /* catch uninitialized context */
835 skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
836
837 /* now output the result */
838 /* total number of output bytes */
839 byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
840
841 /* run Threefish in "counter mode" to generate output */
842 /* zero out b[], so it can hold the counter */
843 memset(ctx->b, 0, sizeof(ctx->b));
844 /* keep a local copy of counter mode "key" */
845 memcpy(x, ctx->x, sizeof(x));
846 for (i = 0; i*SKEIN_1024_BLOCK_BYTES < byte_cnt; i++) {
847 /* build the counter block */
848 ((u64 *)ctx->b)[0] = skein_swap64((u64) i);
849 skein_start_new_type(ctx, OUT_FINAL);
850 /* run "counter mode" */
851 skein_1024_process_block(ctx, ctx->b, 1, sizeof(u64));
852 /* number of output bytes left to go */
853 n = byte_cnt - i*SKEIN_1024_BLOCK_BYTES;
854 if (n >= SKEIN_1024_BLOCK_BYTES)
855 n = SKEIN_1024_BLOCK_BYTES;
856 /* "output" the ctr mode bytes */
857 skein_put64_lsb_first(hash_val+i*SKEIN_1024_BLOCK_BYTES, ctx->x,
858 n);
859 /* restore the counter mode key for next time */
860 memcpy(ctx->x, x, sizeof(x));
861 }
862 return SKEIN_SUCCESS;
863 }
864 #endif
865