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/* [identical to skein_256_init() when key_bytes == 0 && \
  79 *      tree_info == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */
  80int 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 */
 139int 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 */
 194int 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  */
 245int 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] */
 306int 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 */
 364int 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 */
 419int 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  */
 470int 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] */
 525int 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 */
 584int 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 */
 639int 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 */
 689int 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 */
 711int 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 */
 733int 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                                       */
 756int 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                                       */
 793int 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                                       */
 830int 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
 865