"Fossies" - the Fresh Open Source Software Archive

Member "littleutils-1.2.5/littleutils/blake2b-ref.c" (29 Oct 2021, 8498 Bytes) of package /linux/privat/littleutils-1.2.5.tar.lz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "blake2b-ref.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.2.4_vs_1.2.5.

    1 /*
    2    BLAKE2 reference source code package - reference C implementations
    3 
    4    Copyright 2012, Samuel Neves <sneves@dei.uc.pt>.  You may use this under the
    5    terms of the CC0, the OpenSSL License, or the Apache Public License 2.0, at
    6    your option.  The terms of these licenses can be found at:
    7 
    8    - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
    9    - OpenSSL license   : https://www.openssl.org/source/license.html
   10    - Apache 2.0        : https://www.apache.org/licenses/LICENSE-2.0
   11 
   12    More information about the BLAKE2 hash function can be found at
   13    https://blake2.net.
   14 
   15    Modifications for portability by Brian Lindholm, 2020-2021.
   16 */
   17 
   18 #include <config.h>
   19 
   20 #ifdef HAVE_STDINT_H
   21 # include <stdint.h>
   22 #endif
   23 #ifdef HAVE_STRING_H
   24 # include <string.h>
   25 #endif
   26 
   27 #include "blake2.h"
   28 #include "blake2-impl.h"
   29 
   30 static const uint64_t blake2b_IV[8] =
   31 {
   32   0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
   33   0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
   34   0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
   35   0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
   36 };
   37 
   38 static const uint8_t blake2b_sigma[12][16] =
   39 {
   40   {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
   41   { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
   42   { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
   43   {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
   44   {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
   45   {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
   46   { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
   47   { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
   48   {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
   49   { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
   50   {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
   51   { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 }
   52 };
   53 
   54 static void blake2b_set_lastnode( blake2b_state *S )
   55 {
   56   S->f[1] = (uint64_t)-1;
   57 }
   58 
   59 /* Some helper functions, not necessarily useful */
   60 static int blake2b_is_lastblock( const blake2b_state *S )
   61 {
   62   return S->f[0] != 0;
   63 }
   64 
   65 static void blake2b_set_lastblock( blake2b_state *S )
   66 {
   67   if( S->last_node ) blake2b_set_lastnode( S );
   68 
   69   S->f[0] = (uint64_t)-1;
   70 }
   71 
   72 static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
   73 {
   74   S->t[0] += inc;
   75   S->t[1] += ( S->t[0] < inc );
   76 }
   77 
   78 static void blake2b_init0( blake2b_state *S )
   79 {
   80   size_t i;
   81   memset( S, 0, sizeof( blake2b_state ) );
   82 
   83   for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
   84 }
   85 
   86 /* init xors IV with input parameter block */
   87 int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
   88 {
   89   const uint8_t *p = ( const uint8_t * )( P );
   90   size_t i;
   91 
   92   blake2b_init0( S );
   93 
   94   /* IV XOR ParamBlock */
   95   for( i = 0; i < 8; ++i )
   96     S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
   97 
   98   S->outlen = P->digest_length;
   99   return 0;
  100 }
  101 
  102 int blake2b_init( blake2b_state *S, size_t outlen )
  103 {
  104   blake2b_param P[1];
  105 
  106   if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
  107 
  108   P->digest_length = (uint8_t)outlen;
  109   P->key_length    = 0;
  110   P->fanout        = 1;
  111   P->depth         = 1;
  112   store32( &P->leaf_length, 0 );
  113   store32( &P->node_offset, 0 );
  114   store32( &P->xof_length, 0 );
  115   P->node_depth    = 0;
  116   P->inner_length  = 0;
  117   memset( P->reserved, 0, sizeof( P->reserved ) );
  118   memset( P->salt,     0, sizeof( P->salt ) );
  119   memset( P->personal, 0, sizeof( P->personal ) );
  120   return blake2b_init_param( S, P );
  121 }
  122 
  123 int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
  124 {
  125   blake2b_param P[1];
  126 
  127   if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
  128 
  129   if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
  130 
  131   P->digest_length = (uint8_t)outlen;
  132   P->key_length    = (uint8_t)keylen;
  133   P->fanout        = 1;
  134   P->depth         = 1;
  135   store32( &P->leaf_length, 0 );
  136   store32( &P->node_offset, 0 );
  137   store32( &P->xof_length, 0 );
  138   P->node_depth    = 0;
  139   P->inner_length  = 0;
  140   memset( P->reserved, 0, sizeof( P->reserved ) );
  141   memset( P->salt,     0, sizeof( P->salt ) );
  142   memset( P->personal, 0, sizeof( P->personal ) );
  143 
  144   if( blake2b_init_param( S, P ) < 0 ) return -1;
  145 
  146   {
  147     uint8_t block[BLAKE2B_BLOCKBYTES];
  148     memset( block, 0, BLAKE2B_BLOCKBYTES );
  149     memcpy( block, key, keylen );
  150     blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
  151     secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
  152   }
  153   return 0;
  154 }
  155 
  156 #define G(r,i,a,b,c,d)                      \
  157   do {                                      \
  158     a = a + b + m[blake2b_sigma[r][2*i+0]]; \
  159     d = rotr64(d ^ a, 32);                  \
  160     c = c + d;                              \
  161     b = rotr64(b ^ c, 24);                  \
  162     a = a + b + m[blake2b_sigma[r][2*i+1]]; \
  163     d = rotr64(d ^ a, 16);                  \
  164     c = c + d;                              \
  165     b = rotr64(b ^ c, 63);                  \
  166   } while(0)
  167 
  168 #define ROUND(r)                    \
  169   do {                              \
  170     G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
  171     G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
  172     G(r,2,v[ 2],v[ 6],v[10],v[14]); \
  173     G(r,3,v[ 3],v[ 7],v[11],v[15]); \
  174     G(r,4,v[ 0],v[ 5],v[10],v[15]); \
  175     G(r,5,v[ 1],v[ 6],v[11],v[12]); \
  176     G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
  177     G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
  178   } while(0)
  179 
  180 static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
  181 {
  182   uint64_t m[16];
  183   uint64_t v[16];
  184   size_t i;
  185 
  186   for( i = 0; i < 16; ++i ) {
  187     m[i] = load64( block + i * sizeof( m[i] ) );
  188   }
  189 
  190   for( i = 0; i < 8; ++i ) {
  191     v[i] = S->h[i];
  192   }
  193 
  194   v[ 8] = blake2b_IV[0];
  195   v[ 9] = blake2b_IV[1];
  196   v[10] = blake2b_IV[2];
  197   v[11] = blake2b_IV[3];
  198   v[12] = blake2b_IV[4] ^ S->t[0];
  199   v[13] = blake2b_IV[5] ^ S->t[1];
  200   v[14] = blake2b_IV[6] ^ S->f[0];
  201   v[15] = blake2b_IV[7] ^ S->f[1];
  202 
  203   ROUND( 0 );
  204   ROUND( 1 );
  205   ROUND( 2 );
  206   ROUND( 3 );
  207   ROUND( 4 );
  208   ROUND( 5 );
  209   ROUND( 6 );
  210   ROUND( 7 );
  211   ROUND( 8 );
  212   ROUND( 9 );
  213   ROUND( 10 );
  214   ROUND( 11 );
  215 
  216   for( i = 0; i < 8; ++i ) {
  217     S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
  218   }
  219 }
  220 
  221 #undef G
  222 #undef ROUND
  223 
  224 int blake2b_update( blake2b_state *S, const void *pin, size_t inlen )
  225 {
  226   const unsigned char * in = (const unsigned char *)pin;
  227   if( inlen > 0 )
  228   {
  229     size_t left = S->buflen;
  230     size_t fill = BLAKE2B_BLOCKBYTES - left;
  231     if( inlen > fill )
  232     {
  233       S->buflen = 0;
  234       memcpy( S->buf + left, in, fill ); /* Fill buffer */
  235       blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
  236       blake2b_compress( S, S->buf ); /* Compress */
  237       in += fill; inlen -= fill;
  238       while(inlen > BLAKE2B_BLOCKBYTES) {
  239         blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
  240         blake2b_compress( S, in );
  241         in += BLAKE2B_BLOCKBYTES;
  242         inlen -= BLAKE2B_BLOCKBYTES;
  243       }
  244     }
  245     memcpy( S->buf + S->buflen, in, inlen );
  246     S->buflen += inlen;
  247   }
  248   return 0;
  249 }
  250 
  251 int blake2b_final( blake2b_state *S, void *out, size_t outlen )
  252 {
  253   uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
  254   size_t i;
  255 
  256   if( out == NULL || outlen < S->outlen )
  257     return -1;
  258 
  259   if( blake2b_is_lastblock( S ) )
  260     return -1;
  261 
  262   blake2b_increment_counter( S, S->buflen );
  263   blake2b_set_lastblock( S );
  264   memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
  265   blake2b_compress( S, S->buf );
  266 
  267   for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
  268     store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
  269 
  270   memcpy( out, buffer, S->outlen );
  271   secure_zero_memory(buffer, sizeof(buffer));
  272   return 0;
  273 }
  274 
  275 /* inlen, at least, should be uint64_t. Others can be size_t. */
  276 int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
  277 {
  278   blake2b_state S[1];
  279 
  280   /* Verify parameters */
  281   if( NULL == in && inlen > 0 ) return -1;
  282 
  283   if( NULL == out ) return -1;
  284 
  285   if( NULL == key && keylen > 0 ) return -1;
  286 
  287   if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
  288 
  289   if( keylen > BLAKE2B_KEYBYTES ) return -1;
  290 
  291   if( keylen > 0 )
  292   {
  293     if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
  294   }
  295   else
  296   {
  297     if( blake2b_init( S, outlen ) < 0 ) return -1;
  298   }
  299 
  300   blake2b_update( S, ( const uint8_t * )in, inlen );
  301   blake2b_final( S, out, outlen );
  302   return 0;
  303 }
  304 
  305 int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) {
  306   return blake2b(out, outlen, in, inlen, key, keylen);
  307 }