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