linux/drivers/staging/skein/skein_base.c
<<
>>
Prefs
   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  */
  23int 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 */
  82int 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 */
 141int 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 */
 196int 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),
 234                                      ctx->x, 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  */
 247int 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 */
 310int 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 */
 368int 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 */
 423int 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),
 461                                      ctx->x, 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  */
 474int 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 */
 531int 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 */
 590int 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 */
 645int 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),
 683                                      ctx->x, 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 */
 695int 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 */
 717int 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 */
 739int 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                                       */
 762int 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),
 790                                      ctx->x, 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                                       */
 799int 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),
 827                                      ctx->x, 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                                       */
 836int 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),
 864                                      ctx->x, 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
 871