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