Blame cbits/blake2/ref/blake2s-ref.c

Packit 141393
/*
Packit 141393
   BLAKE2 reference source code package - reference C implementations
Packit 141393
Packit 141393
   Copyright 2012, Samuel Neves <sneves@dei.uc.pt>.  You may use this under the
Packit 141393
   terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
Packit 141393
   your option.  The terms of these licenses can be found at:
Packit 141393
Packit 141393
   - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
Packit 141393
   - OpenSSL license   : https://www.openssl.org/source/license.html
Packit 141393
   - Apache 2.0        : http://www.apache.org/licenses/LICENSE-2.0
Packit 141393
Packit 141393
   More information about the BLAKE2 hash function can be found at
Packit 141393
   https://blake2.net.
Packit 141393
*/
Packit 141393
Packit 141393
#include <stdint.h>
Packit 141393
#include <string.h>
Packit 141393
#include <stdio.h>
Packit 141393
Packit 141393
#include "blake2.h"
Packit 141393
#include "blake2-impl.h"
Packit 141393
Packit 141393
static const uint32_t blake2s_IV[8] =
Packit 141393
{
Packit 141393
  0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
Packit 141393
  0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
Packit 141393
};
Packit 141393
Packit 141393
static const uint8_t blake2s_sigma[10][16] =
Packit 141393
{
Packit 141393
  {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
Packit 141393
  { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
Packit 141393
  { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
Packit 141393
  {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
Packit 141393
  {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
Packit 141393
  {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
Packit 141393
  { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
Packit 141393
  { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
Packit 141393
  {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
Packit 141393
  { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
Packit 141393
};
Packit 141393
Packit 141393
static void blake2s_set_lastnode( blake2s_state *S )
Packit 141393
{
Packit 141393
  S->f[1] = (uint32_t)-1;
Packit 141393
}
Packit 141393
Packit 141393
/* Some helper functions, not necessarily useful */
Packit 141393
static int blake2s_is_lastblock( const blake2s_state *S )
Packit 141393
{
Packit 141393
  return S->f[0] != 0;
Packit 141393
}
Packit 141393
Packit 141393
static void blake2s_set_lastblock( blake2s_state *S )
Packit 141393
{
Packit 141393
  if( S->last_node ) blake2s_set_lastnode( S );
Packit 141393
Packit 141393
  S->f[0] = (uint32_t)-1;
Packit 141393
}
Packit 141393
Packit 141393
static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
Packit 141393
{
Packit 141393
  S->t[0] += inc;
Packit 141393
  S->t[1] += ( S->t[0] < inc );
Packit 141393
}
Packit 141393
Packit 141393
static void blake2s_init0( blake2s_state *S )
Packit 141393
{
Packit 141393
  size_t i;
Packit 141393
  memset( S, 0, sizeof( blake2s_state ) );
Packit 141393
Packit 141393
  for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
Packit 141393
}
Packit 141393
Packit 141393
/* init2 xors IV with input parameter block */
Packit 141393
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
Packit 141393
{
Packit 141393
  const unsigned char *p = ( const unsigned char * )( P );
Packit 141393
  size_t i;
Packit 141393
Packit 141393
  blake2s_init0( S );
Packit 141393
Packit 141393
  /* IV XOR ParamBlock */
Packit 141393
  for( i = 0; i < 8; ++i )
Packit 141393
    S->h[i] ^= load32( &p[i * 4] );
Packit 141393
Packit 141393
  S->outlen = P->digest_length;
Packit 141393
  return 0;
Packit 141393
}
Packit 141393
Packit 141393
Packit 141393
/* Sequential blake2s initialization */
Packit 141393
int blake2s_init( blake2s_state *S, size_t outlen )
Packit 141393
{
Packit 141393
  blake2s_param P[1];
Packit 141393
Packit 141393
  /* Move interval verification here? */
Packit 141393
  if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
Packit 141393
Packit 141393
  P->digest_length = (uint8_t)outlen;
Packit 141393
  P->key_length    = 0;
Packit 141393
  P->fanout        = 1;
Packit 141393
  P->depth         = 1;
Packit 141393
  store32( &P->leaf_length, 0 );
Packit 141393
  store32( &P->node_offset, 0 );
Packit 141393
  store16( &P->xof_length, 0 );
Packit 141393
  P->node_depth    = 0;
Packit 141393
  P->inner_length  = 0;
Packit 141393
  /* memset(P->reserved, 0, sizeof(P->reserved) ); */
Packit 141393
  memset( P->salt,     0, sizeof( P->salt ) );
Packit 141393
  memset( P->personal, 0, sizeof( P->personal ) );
Packit 141393
  return blake2s_init_param( S, P );
Packit 141393
}
Packit 141393
Packit 141393
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
Packit 141393
{
Packit 141393
  blake2s_param P[1];
Packit 141393
Packit 141393
  if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
Packit 141393
Packit 141393
  if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
Packit 141393
Packit 141393
  P->digest_length = (uint8_t)outlen;
Packit 141393
  P->key_length    = (uint8_t)keylen;
Packit 141393
  P->fanout        = 1;
Packit 141393
  P->depth         = 1;
Packit 141393
  store32( &P->leaf_length, 0 );
Packit 141393
  store32( &P->node_offset, 0 );
Packit 141393
  store16( &P->xof_length, 0 );
Packit 141393
  P->node_depth    = 0;
Packit 141393
  P->inner_length  = 0;
Packit 141393
  /* memset(P->reserved, 0, sizeof(P->reserved) ); */
Packit 141393
  memset( P->salt,     0, sizeof( P->salt ) );
Packit 141393
  memset( P->personal, 0, sizeof( P->personal ) );
Packit 141393
Packit 141393
  if( blake2s_init_param( S, P ) < 0 ) return -1;
Packit 141393
Packit 141393
  {
Packit 141393
    uint8_t block[BLAKE2S_BLOCKBYTES];
Packit 141393
    memset( block, 0, BLAKE2S_BLOCKBYTES );
Packit 141393
    memcpy( block, key, keylen );
Packit 141393
    blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
Packit 141393
    secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
Packit 141393
  }
Packit 141393
  return 0;
Packit 141393
}
Packit 141393
Packit 141393
#define G(r,i,a,b,c,d)                      \
Packit 141393
  do {                                      \
Packit 141393
    a = a + b + m[blake2s_sigma[r][2*i+0]]; \
Packit 141393
    d = rotr32(d ^ a, 16);                  \
Packit 141393
    c = c + d;                              \
Packit 141393
    b = rotr32(b ^ c, 12);                  \
Packit 141393
    a = a + b + m[blake2s_sigma[r][2*i+1]]; \
Packit 141393
    d = rotr32(d ^ a, 8);                   \
Packit 141393
    c = c + d;                              \
Packit 141393
    b = rotr32(b ^ c, 7);                   \
Packit 141393
  } while(0)
Packit 141393
Packit 141393
#define ROUND(r)                    \
Packit 141393
  do {                              \
Packit 141393
    G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
Packit 141393
    G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
Packit 141393
    G(r,2,v[ 2],v[ 6],v[10],v[14]); \
Packit 141393
    G(r,3,v[ 3],v[ 7],v[11],v[15]); \
Packit 141393
    G(r,4,v[ 0],v[ 5],v[10],v[15]); \
Packit 141393
    G(r,5,v[ 1],v[ 6],v[11],v[12]); \
Packit 141393
    G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
Packit 141393
    G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
Packit 141393
  } while(0)
Packit 141393
Packit 141393
static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] )
Packit 141393
{
Packit 141393
  uint32_t m[16];
Packit 141393
  uint32_t v[16];
Packit 141393
  size_t i;
Packit 141393
Packit 141393
  for( i = 0; i < 16; ++i ) {
Packit 141393
    m[i] = load32( in + i * sizeof( m[i] ) );
Packit 141393
  }
Packit 141393
Packit 141393
  for( i = 0; i < 8; ++i ) {
Packit 141393
    v[i] = S->h[i];
Packit 141393
  }
Packit 141393
Packit 141393
  v[ 8] = blake2s_IV[0];
Packit 141393
  v[ 9] = blake2s_IV[1];
Packit 141393
  v[10] = blake2s_IV[2];
Packit 141393
  v[11] = blake2s_IV[3];
Packit 141393
  v[12] = S->t[0] ^ blake2s_IV[4];
Packit 141393
  v[13] = S->t[1] ^ blake2s_IV[5];
Packit 141393
  v[14] = S->f[0] ^ blake2s_IV[6];
Packit 141393
  v[15] = S->f[1] ^ blake2s_IV[7];
Packit 141393
Packit 141393
  ROUND( 0 );
Packit 141393
  ROUND( 1 );
Packit 141393
  ROUND( 2 );
Packit 141393
  ROUND( 3 );
Packit 141393
  ROUND( 4 );
Packit 141393
  ROUND( 5 );
Packit 141393
  ROUND( 6 );
Packit 141393
  ROUND( 7 );
Packit 141393
  ROUND( 8 );
Packit 141393
  ROUND( 9 );
Packit 141393
Packit 141393
  for( i = 0; i < 8; ++i ) {
Packit 141393
    S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
Packit 141393
  }
Packit 141393
}
Packit 141393
Packit 141393
#undef G
Packit 141393
#undef ROUND
Packit 141393
Packit 141393
int blake2s_update( blake2s_state *S, const void *pin, size_t inlen )
Packit 141393
{
Packit 141393
  const unsigned char * in = (const unsigned char *)pin;
Packit 141393
  if( inlen > 0 )
Packit 141393
  {
Packit 141393
    size_t left = S->buflen;
Packit 141393
    size_t fill = BLAKE2S_BLOCKBYTES - left;
Packit 141393
    if( inlen > fill )
Packit 141393
    {
Packit 141393
      S->buflen = 0;
Packit 141393
      memcpy( S->buf + left, in, fill ); /* Fill buffer */
Packit 141393
      blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
Packit 141393
      blake2s_compress( S, S->buf ); /* Compress */
Packit 141393
      in += fill; inlen -= fill;
Packit 141393
      while(inlen > BLAKE2S_BLOCKBYTES) {
Packit 141393
        blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
Packit 141393
        blake2s_compress( S, in );
Packit 141393
        in += BLAKE2S_BLOCKBYTES;
Packit 141393
        inlen -= BLAKE2S_BLOCKBYTES;
Packit 141393
      }
Packit 141393
    }
Packit 141393
    memcpy( S->buf + S->buflen, in, inlen );
Packit 141393
    S->buflen += inlen;
Packit 141393
  }
Packit 141393
  return 0;
Packit 141393
}
Packit 141393
Packit 141393
int blake2s_final( blake2s_state *S, void *out, size_t outlen )
Packit 141393
{
Packit 141393
  uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
Packit 141393
  size_t i;
Packit 141393
Packit 141393
  if( out == NULL || outlen < S->outlen )
Packit 141393
    return -1;
Packit 141393
Packit 141393
  if( blake2s_is_lastblock( S ) )
Packit 141393
    return -1;
Packit 141393
Packit 141393
  blake2s_increment_counter( S, ( uint32_t )S->buflen );
Packit 141393
  blake2s_set_lastblock( S );
Packit 141393
  memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
Packit 141393
  blake2s_compress( S, S->buf );
Packit 141393
Packit 141393
  for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
Packit 141393
    store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
Packit 141393
Packit 141393
  memcpy( out, buffer, outlen );
Packit 141393
  secure_zero_memory(buffer, sizeof(buffer));
Packit 141393
  return 0;
Packit 141393
}
Packit 141393
Packit 141393
int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
Packit 141393
{
Packit 141393
  blake2s_state S[1];
Packit 141393
Packit 141393
  /* Verify parameters */
Packit 141393
  if ( NULL == in && inlen > 0 ) return -1;
Packit 141393
Packit 141393
  if ( NULL == out ) return -1;
Packit 141393
Packit 141393
  if ( NULL == key && keylen > 0) return -1;
Packit 141393
Packit 141393
  if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
Packit 141393
Packit 141393
  if( keylen > BLAKE2S_KEYBYTES ) return -1;
Packit 141393
Packit 141393
  if( keylen > 0 )
Packit 141393
  {
Packit 141393
    if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
Packit 141393
  }
Packit 141393
  else
Packit 141393
  {
Packit 141393
    if( blake2s_init( S, outlen ) < 0 ) return -1;
Packit 141393
  }
Packit 141393
Packit 141393
  blake2s_update( S, ( const uint8_t * )in, inlen );
Packit 141393
  blake2s_final( S, out, outlen );
Packit 141393
  return 0;
Packit 141393
}
Packit 141393
Packit 141393
#if defined(SUPERCOP)
Packit 141393
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
Packit 141393
{
Packit 141393
  return blake2s( out, BLAKE2S_OUTBYTES in, inlen, NULL, 0 );
Packit 141393
}
Packit 141393
#endif
Packit 141393
Packit 141393
#if defined(BLAKE2S_SELFTEST)
Packit 141393
#include <string.h>
Packit 141393
#include "blake2-kat.h"
Packit 141393
int main( void )
Packit 141393
{
Packit 141393
  uint8_t key[BLAKE2S_KEYBYTES];
Packit 141393
  uint8_t buf[BLAKE2_KAT_LENGTH];
Packit 141393
  size_t i, step;
Packit 141393
Packit 141393
  for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
Packit 141393
    key[i] = ( uint8_t )i;
Packit 141393
Packit 141393
  for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
Packit 141393
    buf[i] = ( uint8_t )i;
Packit 141393
Packit 141393
  /* Test simple API */
Packit 141393
  for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
Packit 141393
  {
Packit 141393
    uint8_t hash[BLAKE2S_OUTBYTES];
Packit 141393
    blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES );
Packit 141393
Packit 141393
    if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
Packit 141393
    {
Packit 141393
      goto fail;
Packit 141393
    }
Packit 141393
  }
Packit 141393
Packit 141393
  /* Test streaming API */
Packit 141393
  for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) {
Packit 141393
    for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
Packit 141393
      uint8_t hash[BLAKE2S_OUTBYTES];
Packit 141393
      blake2s_state S;
Packit 141393
      uint8_t * p = buf;
Packit 141393
      size_t mlen = i;
Packit 141393
      int err = 0;
Packit 141393
Packit 141393
      if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) {
Packit 141393
        goto fail;
Packit 141393
      }
Packit 141393
Packit 141393
      while (mlen >= step) {
Packit 141393
        if ( (err = blake2s_update(&S, p, step)) < 0 ) {
Packit 141393
          goto fail;
Packit 141393
        }
Packit 141393
        mlen -= step;
Packit 141393
        p += step;
Packit 141393
      }
Packit 141393
      if ( (err = blake2s_update(&S, p, mlen)) < 0) {
Packit 141393
        goto fail;
Packit 141393
      }
Packit 141393
      if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) {
Packit 141393
        goto fail;
Packit 141393
      }
Packit 141393
Packit 141393
      if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) {
Packit 141393
        goto fail;
Packit 141393
      }
Packit 141393
    }
Packit 141393
  }
Packit 141393
Packit 141393
  puts( "ok" );
Packit 141393
  return 0;
Packit 141393
fail:
Packit 141393
  puts("error");
Packit 141393
  return -1;
Packit 141393
}
Packit 141393
#endif