1 /***********************************************************************
3 ** Implementation of the Skein hash function.
5 ** Source code author: Doug Whiting, 2008.
7 ** This algorithm and source code is released to the public domain.
9 ************************************************************************/
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"
17 /*****************************************************************/
19 /*****************************************************************/
21 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
22 /* init the context for a straight hashing operation */
23 int skein_256_init(struct skein_256_ctx *ctx, size_t hash_bit_len)
26 u8 b[SKEIN_256_STATE_BYTES];
27 u64 w[SKEIN_256_STATE_WORDS];
28 } cfg; /* config block */
30 skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
31 ctx->h.hash_bit_len = hash_bit_len; /* output hash bit count */
33 switch (hash_bit_len) { /* use pre-computed values, where available */
35 memcpy(ctx->x, SKEIN_256_IV_256, sizeof(ctx->x));
38 memcpy(ctx->x, SKEIN_256_IV_224, sizeof(ctx->x));
41 memcpy(ctx->x, SKEIN_256_IV_160, sizeof(ctx->x));
44 memcpy(ctx->x, SKEIN_256_IV_128, sizeof(ctx->x));
47 /* here if there is no precomputed IV value available */
49 * build/process the config block, type == CONFIG (could be
52 /* set tweaks: T0=0; T1=CFG | FINAL */
53 skein_start_new_type(ctx, CFG_FINAL);
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]));
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);
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 */
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] */
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)
84 u8 b[SKEIN_256_STATE_BYTES];
85 u64 w[SKEIN_256_STATE_WORDS];
86 } cfg; /* config block */
88 skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
89 skein_assert_ret(key_bytes == 0 || key != NULL, SKEIN_FAIL);
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));
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));
112 * build/process the config block, type == CONFIG (could be
113 * precomputed for each key)
115 /* output hash bit count */
116 ctx->h.hash_bit_len = hash_bit_len;
117 skein_start_new_type(ctx, CFG_FINAL);
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);
127 /* compute the initial chaining values from config block */
128 skein_256_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
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);
134 return SKEIN_SUCCESS;
137 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
138 /* process the input bytes */
139 int skein_256_update(struct skein_256_ctx *ctx, const u8 *msg,
144 /* catch uninitialized context */
145 skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
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 */
151 /* # bytes free in buffer b[] */
152 n = SKEIN_256_BLOCK_BYTES - ctx->h.b_cnt;
154 /* check on our logic here */
155 skein_assert(n < msg_byte_cnt);
156 memcpy(&ctx->b[ctx->h.b_cnt], msg, n);
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);
167 * now process any remaining full blocks, directly from input
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;
178 skein_assert(ctx->h.b_cnt == 0);
181 /* copy any remaining source message data bytes into b[] */
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;
189 return SKEIN_SUCCESS;
192 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
193 /* finalize the hash computation and output the result */
194 int skein_256_final(struct skein_256_ctx *ctx, u8 *hash_val)
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);
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);
208 /* process the final block */
209 skein_256_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
211 /* now output the result */
212 /* total number of output bytes */
213 byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
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,
233 /* restore the counter mode key for next time */
234 memcpy(ctx->x, x, sizeof(x));
236 return SKEIN_SUCCESS;
239 /*****************************************************************/
241 /*****************************************************************/
243 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
244 /* init the context for a straight hashing operation */
245 int skein_512_init(struct skein_512_ctx *ctx, size_t hash_bit_len)
248 u8 b[SKEIN_512_STATE_BYTES];
249 u64 w[SKEIN_512_STATE_WORDS];
250 } cfg; /* config block */
252 skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
253 ctx->h.hash_bit_len = hash_bit_len; /* output hash bit count */
255 switch (hash_bit_len) { /* use pre-computed values, where available */
257 memcpy(ctx->x, SKEIN_512_IV_512, sizeof(ctx->x));
260 memcpy(ctx->x, SKEIN_512_IV_384, sizeof(ctx->x));
263 memcpy(ctx->x, SKEIN_512_IV_256, sizeof(ctx->x));
266 memcpy(ctx->x, SKEIN_512_IV_224, sizeof(ctx->x));
269 /* here if there is no precomputed IV value available */
271 * build/process the config block, type == CONFIG (could be
274 /* set tweaks: T0=0; T1=CFG | FINAL */
275 skein_start_new_type(ctx, CFG_FINAL);
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]));
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);
293 * The chaining vars ctx->x are now initialized for the given
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 */
299 return SKEIN_SUCCESS;
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] */
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)
310 u8 b[SKEIN_512_STATE_BYTES];
311 u64 w[SKEIN_512_STATE_WORDS];
312 } cfg; /* config block */
314 skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
315 skein_assert_ret(key_bytes == 0 || key != NULL, SKEIN_FAIL);
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));
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));
338 * build/process the config block, type == CONFIG (could be
339 * precomputed for each key)
341 ctx->h.hash_bit_len = hash_bit_len; /* output hash bit count */
342 skein_start_new_type(ctx, CFG_FINAL);
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);
352 /* compute the initial chaining values from config block */
353 skein_512_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
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);
359 return SKEIN_SUCCESS;
362 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
363 /* process the input bytes */
364 int skein_512_update(struct skein_512_ctx *ctx, const u8 *msg,
369 /* catch uninitialized context */
370 skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
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 */
376 /* # bytes free in buffer b[] */
377 n = SKEIN_512_BLOCK_BYTES - ctx->h.b_cnt;
379 /* check on our logic here */
380 skein_assert(n < msg_byte_cnt);
381 memcpy(&ctx->b[ctx->h.b_cnt], msg, n);
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);
392 * now process any remaining full blocks, directly from input
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;
403 skein_assert(ctx->h.b_cnt == 0);
406 /* copy any remaining source message data bytes into b[] */
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;
414 return SKEIN_SUCCESS;
417 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
418 /* finalize the hash computation and output the result */
419 int skein_512_final(struct skein_512_ctx *ctx, u8 *hash_val)
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);
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);
433 /* process the final block */
434 skein_512_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
436 /* now output the result */
437 /* total number of output bytes */
438 byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
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,
458 /* restore the counter mode key for next time */
459 memcpy(ctx->x, x, sizeof(x));
461 return SKEIN_SUCCESS;
464 /*****************************************************************/
466 /*****************************************************************/
468 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
469 /* init the context for a straight hashing operation */
470 int skein_1024_init(struct skein_1024_ctx *ctx, size_t hash_bit_len)
473 u8 b[SKEIN_1024_STATE_BYTES];
474 u64 w[SKEIN_1024_STATE_WORDS];
475 } cfg; /* config block */
477 skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
478 ctx->h.hash_bit_len = hash_bit_len; /* output hash bit count */
480 switch (hash_bit_len) { /* use pre-computed values, where available */
482 memcpy(ctx->x, SKEIN_1024_IV_512, sizeof(ctx->x));
485 memcpy(ctx->x, SKEIN_1024_IV_384, sizeof(ctx->x));
488 memcpy(ctx->x, SKEIN_1024_IV_1024, sizeof(ctx->x));
491 /* here if there is no precomputed IV value available */
493 * build/process the config block, type == CONFIG
494 * (could be precomputed)
496 /* set tweaks: T0=0; T1=CFG | FINAL */
497 skein_start_new_type(ctx, CFG_FINAL);
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]));
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);
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 */
518 return SKEIN_SUCCESS;
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] */
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)
529 u8 b[SKEIN_1024_STATE_BYTES];
530 u64 w[SKEIN_1024_STATE_WORDS];
531 } cfg; /* config block */
533 skein_assert_ret(hash_bit_len > 0, SKEIN_BAD_HASHLEN);
534 skein_assert_ret(key_bytes == 0 || key != NULL, SKEIN_FAIL);
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));
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));
557 * build/process the config block, type == CONFIG (could be
558 * precomputed for each key)
560 /* output hash bit count */
561 ctx->h.hash_bit_len = hash_bit_len;
562 skein_start_new_type(ctx, CFG_FINAL);
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);
572 /* compute the initial chaining values from config block */
573 skein_1024_process_block(ctx, cfg.b, 1, SKEIN_CFG_STR_LEN);
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);
579 return SKEIN_SUCCESS;
582 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
583 /* process the input bytes */
584 int skein_1024_update(struct skein_1024_ctx *ctx, const u8 *msg,
589 /* catch uninitialized context */
590 skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
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 */
596 /* # bytes free in buffer b[] */
597 n = SKEIN_1024_BLOCK_BYTES - ctx->h.b_cnt;
599 /* check on our logic here */
600 skein_assert(n < msg_byte_cnt);
601 memcpy(&ctx->b[ctx->h.b_cnt], msg, n);
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);
612 * now process any remaining full blocks, directly from input
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;
623 skein_assert(ctx->h.b_cnt == 0);
626 /* copy any remaining source message data bytes into b[] */
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;
634 return SKEIN_SUCCESS;
637 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
638 /* finalize the hash computation and output the result */
639 int skein_1024_final(struct skein_1024_ctx *ctx, u8 *hash_val)
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);
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);
653 /* process the final block */
654 skein_1024_process_block(ctx, ctx->b, 1, ctx->h.b_cnt);
656 /* now output the result */
657 /* total number of output bytes */
658 byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
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,
678 /* restore the counter mode key for next time */
679 memcpy(ctx->x, x, sizeof(x));
681 return SKEIN_SUCCESS;
684 /**************** Functions to support MAC/tree hashing ***************/
685 /* (this code is identical for Optimized and Reference versions) */
687 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
688 /* finalize the hash computation and output the block, no OUTPUT stage */
689 int skein_256_final_pad(struct skein_256_ctx *ctx, u8 *hash_val)
691 /* catch uninitialized context */
692 skein_assert_ret(ctx->h.b_cnt <= SKEIN_256_BLOCK_BYTES, SKEIN_FAIL);
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);
703 /* "output" the state bytes */
704 skein_put64_lsb_first(hash_val, ctx->x, SKEIN_256_BLOCK_BYTES);
706 return SKEIN_SUCCESS;
709 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
710 /* finalize the hash computation and output the block, no OUTPUT stage */
711 int skein_512_final_pad(struct skein_512_ctx *ctx, u8 *hash_val)
713 /* catch uninitialized context */
714 skein_assert_ret(ctx->h.b_cnt <= SKEIN_512_BLOCK_BYTES, SKEIN_FAIL);
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);
725 /* "output" the state bytes */
726 skein_put64_lsb_first(hash_val, ctx->x, SKEIN_512_BLOCK_BYTES);
728 return SKEIN_SUCCESS;
731 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
732 /* finalize the hash computation and output the block, no OUTPUT stage */
733 int skein_1024_final_pad(struct skein_1024_ctx *ctx, u8 *hash_val)
735 /* catch uninitialized context */
736 skein_assert_ret(ctx->h.b_cnt <= SKEIN_1024_BLOCK_BYTES, SKEIN_FAIL);
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);
747 /* "output" the state bytes */
748 skein_put64_lsb_first(hash_val, ctx->x, SKEIN_1024_BLOCK_BYTES);
750 return SKEIN_SUCCESS;
754 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
755 /* just do the OUTPUT stage */
756 int skein_256_output(struct skein_256_ctx *ctx, u8 *hash_val)
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);
763 /* now output the result */
764 /* total number of output bytes */
765 byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
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,
785 /* restore the counter mode key for next time */
786 memcpy(ctx->x, x, sizeof(x));
788 return SKEIN_SUCCESS;
791 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
792 /* just do the OUTPUT stage */
793 int skein_512_output(struct skein_512_ctx *ctx, u8 *hash_val)
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);
800 /* now output the result */
801 /* total number of output bytes */
802 byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
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,
822 /* restore the counter mode key for next time */
823 memcpy(ctx->x, x, sizeof(x));
825 return SKEIN_SUCCESS;
828 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
829 /* just do the OUTPUT stage */
830 int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val)
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);
837 /* now output the result */
838 /* total number of output bytes */
839 byte_cnt = (ctx->h.hash_bit_len + 7) >> 3;
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,
859 /* restore the counter mode key for next time */
860 memcpy(ctx->x, x, sizeof(x));
862 return SKEIN_SUCCESS;