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