Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / staging / skein / skein_base.c
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  */
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] */
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 */
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 */
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  */
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] */
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 */
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 */
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  */
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] */
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 */
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 */
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 */
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 */
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 */
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                                       */
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                                       */
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                                       */
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