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