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