The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/crypto/skein/skein.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: f14764bf9499d92980119953667eb56a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.