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