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/contrib/libb2/blake2s.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    BLAKE2 reference source code package - optimized C implementations
    3 
    4    Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
    5 
    6    To the extent possible under law, the author(s) have dedicated all copyright
    7    and related and neighboring rights to this software to the public domain
    8    worldwide. This software is distributed without any warranty.
    9 
   10    You should have received a copy of the CC0 Public Domain Dedication along with
   11    this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
   12 */
   13 
   14 #include <stdint.h>
   15 #include <string.h>
   16 #include <stdio.h>
   17 
   18 #include "blake2.h"
   19 #include "blake2-impl.h"
   20 
   21 #include "blake2-config.h"
   22 
   23 #if defined(_MSC_VER)
   24 #include <intrin.h>
   25 #endif
   26 
   27 #if defined(HAVE_SSE2)
   28 #include <emmintrin.h>
   29 // MSVC only defines  _mm_set_epi64x for x86_64...
   30 #if defined(_MSC_VER) && !defined(_M_X64)
   31 static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 )
   32 {
   33   return _mm_set_epi32( u1 >> 32, u1, u0 >> 32, u0 );
   34 }
   35 #endif
   36 #endif
   37 
   38 
   39 #if defined(HAVE_SSSE3)
   40 #include <tmmintrin.h>
   41 #endif
   42 #if defined(HAVE_SSE4_1)
   43 #include <smmintrin.h>
   44 #endif
   45 #if defined(HAVE_AVX)
   46 #include <immintrin.h>
   47 #endif
   48 #if defined(HAVE_XOP) && !defined(_MSC_VER)
   49 #include <x86intrin.h>
   50 #endif
   51 
   52 #include "blake2s-round.h"
   53 
   54 static const uint32_t blake2s_IV[8] =
   55 {
   56   0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
   57   0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
   58 };
   59 
   60 static const uint8_t blake2s_sigma[10][16] =
   61 {
   62   {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
   63   { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
   64   { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
   65   {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
   66   {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
   67   {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
   68   { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
   69   { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
   70   {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
   71   { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
   72 };
   73 
   74 
   75 /* Some helper functions, not necessarily useful */
   76 static inline int blake2s_set_lastnode( blake2s_state *S )
   77 {
   78   S->f[1] = ~0U;
   79   return 0;
   80 }
   81 
   82 static inline int blake2s_clear_lastnode( blake2s_state *S )
   83 {
   84   S->f[1] = 0U;
   85   return 0;
   86 }
   87 
   88 static inline int blake2s_set_lastblock( blake2s_state *S )
   89 {
   90   if( S->last_node ) blake2s_set_lastnode( S );
   91 
   92   S->f[0] = ~0U;
   93   return 0;
   94 }
   95 
   96 static inline int blake2s_clear_lastblock( blake2s_state *S )
   97 {
   98   if( S->last_node ) blake2s_clear_lastnode( S );
   99 
  100   S->f[0] = 0U;
  101   return 0;
  102 }
  103 
  104 static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
  105 {
  106   uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0];
  107   t += inc;
  108   S->t[0] = ( uint32_t )( t >>  0 );
  109   S->t[1] = ( uint32_t )( t >> 32 );
  110   return 0;
  111 }
  112 
  113 
  114 // Parameter-related functions
  115 static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
  116 {
  117   P->digest_length = digest_length;
  118   return 0;
  119 }
  120 
  121 static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
  122 {
  123   P->fanout = fanout;
  124   return 0;
  125 }
  126 
  127 static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
  128 {
  129   P->depth = depth;
  130   return 0;
  131 }
  132 
  133 static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
  134 {
  135   P->leaf_length = leaf_length;
  136   return 0;
  137 }
  138 
  139 static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
  140 {
  141   store48( P->node_offset, node_offset );
  142   return 0;
  143 }
  144 
  145 static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
  146 {
  147   P->node_depth = node_depth;
  148   return 0;
  149 }
  150 
  151 static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
  152 {
  153   P->inner_length = inner_length;
  154   return 0;
  155 }
  156 
  157 static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
  158 {
  159   memcpy( P->salt, salt, BLAKE2S_SALTBYTES );
  160   return 0;
  161 }
  162 
  163 static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
  164 {
  165   memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );
  166   return 0;
  167 }
  168 
  169 static inline int blake2s_init0( blake2s_state *S )
  170 {
  171   memset( S, 0, sizeof( blake2s_state ) );
  172 
  173   for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
  174 
  175   return 0;
  176 }
  177 
  178 #define blake2s_init BLAKE2_IMPL_NAME(blake2s_init)
  179 #define blake2s_init_param BLAKE2_IMPL_NAME(blake2s_init_param)
  180 #define blake2s_init_key BLAKE2_IMPL_NAME(blake2s_init_key)
  181 #define blake2s_update BLAKE2_IMPL_NAME(blake2s_update)
  182 #define blake2s_final BLAKE2_IMPL_NAME(blake2s_final)
  183 #define blake2s BLAKE2_IMPL_NAME(blake2s)
  184 
  185 #if defined(__cplusplus)
  186 extern "C" {
  187 #endif
  188   int blake2s_init( blake2s_state *S, size_t outlen );
  189   int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
  190   int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
  191   int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen );
  192   int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen );
  193   int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
  194 #if defined(__cplusplus)
  195 }
  196 #endif
  197 
  198 
  199 /* init2 xors IV with input parameter block */
  200 int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
  201 {
  202   uint8_t *p, *h, *v;
  203   //blake2s_init0( S );
  204   v = ( uint8_t * )( blake2s_IV );
  205   h = ( uint8_t * )( S->h );
  206   p = ( uint8_t * )( P );
  207   /* IV XOR ParamBlock */
  208   memset( S, 0, sizeof( blake2s_state ) );
  209 
  210   for( int i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
  211 
  212   S->outlen = P->digest_length;
  213   return 0;
  214 }
  215 
  216 
  217 /* Some sort of default parameter block initialization, for sequential blake2s */
  218 int blake2s_init( blake2s_state *S, size_t outlen )
  219 {
  220   if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
  221 
  222   const blake2s_param P =
  223   {
  224     outlen,
  225     0,
  226     1,
  227     1,
  228     0,
  229     {0},
  230     0,
  231     0,
  232     {0},
  233     {0}
  234   };
  235   return blake2s_init_param( S, &P );
  236 }
  237 
  238 
  239 int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
  240 {
  241   if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
  242 
  243   if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1;
  244 
  245   const blake2s_param P =
  246   {
  247     outlen,
  248     keylen,
  249     1,
  250     1,
  251     0,
  252     {0},
  253     0,
  254     0,
  255     {0},
  256     {0}
  257   };
  258 
  259   if( blake2s_init_param( S, &P ) < 0 )
  260     return -1;
  261 
  262   {
  263     uint8_t block[BLAKE2S_BLOCKBYTES];
  264     memset( block, 0, BLAKE2S_BLOCKBYTES );
  265     memcpy( block, key, keylen );
  266     blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
  267     secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
  268   }
  269   return 0;
  270 }
  271 
  272 
  273 static inline int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )
  274 {
  275   __m128i row1, row2, row3, row4;
  276   __m128i buf1, buf2, buf3, buf4;
  277 #if defined(HAVE_SSE4_1)
  278   __m128i t0, t1;
  279 #if !defined(HAVE_XOP)
  280   __m128i t2;
  281 #endif
  282 #endif
  283   __m128i ff0, ff1;
  284 #if defined(HAVE_SSSE3) && !defined(HAVE_XOP)
  285   const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 );
  286   const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 );
  287 #endif
  288 #if defined(HAVE_SSE4_1)
  289   const __m128i m0 = LOADU( block +  00 );
  290   const __m128i m1 = LOADU( block +  16 );
  291   const __m128i m2 = LOADU( block +  32 );
  292   const __m128i m3 = LOADU( block +  48 );
  293 #else
  294   const uint32_t  m0 = ( ( uint32_t * )block )[ 0];
  295   const uint32_t  m1 = ( ( uint32_t * )block )[ 1];
  296   const uint32_t  m2 = ( ( uint32_t * )block )[ 2];
  297   const uint32_t  m3 = ( ( uint32_t * )block )[ 3];
  298   const uint32_t  m4 = ( ( uint32_t * )block )[ 4];
  299   const uint32_t  m5 = ( ( uint32_t * )block )[ 5];
  300   const uint32_t  m6 = ( ( uint32_t * )block )[ 6];
  301   const uint32_t  m7 = ( ( uint32_t * )block )[ 7];
  302   const uint32_t  m8 = ( ( uint32_t * )block )[ 8];
  303   const uint32_t  m9 = ( ( uint32_t * )block )[ 9];
  304   const uint32_t m10 = ( ( uint32_t * )block )[10];
  305   const uint32_t m11 = ( ( uint32_t * )block )[11];
  306   const uint32_t m12 = ( ( uint32_t * )block )[12];
  307   const uint32_t m13 = ( ( uint32_t * )block )[13];
  308   const uint32_t m14 = ( ( uint32_t * )block )[14];
  309   const uint32_t m15 = ( ( uint32_t * )block )[15];
  310 #endif
  311   row1 = ff0 = LOADU( &S->h[0] );
  312   row2 = ff1 = LOADU( &S->h[4] );
  313   row3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A );
  314   row4 = _mm_xor_si128( _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ), LOADU( &S->t[0] ) );
  315   ROUND( 0 );
  316   ROUND( 1 );
  317   ROUND( 2 );
  318   ROUND( 3 );
  319   ROUND( 4 );
  320   ROUND( 5 );
  321   ROUND( 6 );
  322   ROUND( 7 );
  323   ROUND( 8 );
  324   ROUND( 9 );
  325   STOREU( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row1, row3 ) ) );
  326   STOREU( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row2, row4 ) ) );
  327   return 0;
  328 }
  329 
  330 
  331 int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen )
  332 {
  333   while( inlen > 0 )
  334   {
  335     size_t left = S->buflen;
  336     size_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
  337 
  338     if( inlen > fill )
  339     {
  340       memcpy( S->buf + left, in, fill ); // Fill buffer
  341       S->buflen += fill;
  342       blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
  343       blake2s_compress( S, S->buf ); // Compress
  344       memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left
  345       S->buflen -= BLAKE2S_BLOCKBYTES;
  346       in += fill;
  347       inlen -= fill;
  348     }
  349     else /* inlen <= fill */
  350     {
  351       memcpy( S->buf + left, in, inlen );
  352       S->buflen += inlen; // Be lazy, do not compress
  353       in += inlen;
  354       inlen -= inlen;
  355     }
  356   }
  357 
  358   return 0;
  359 }
  360 
  361 
  362 int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen )
  363 {
  364   uint8_t buffer[BLAKE2S_OUTBYTES];
  365 
  366   if(outlen != S->outlen ) return -1;
  367 
  368   if( S->buflen > BLAKE2S_BLOCKBYTES )
  369   {
  370     blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
  371     blake2s_compress( S, S->buf );
  372     S->buflen -= BLAKE2S_BLOCKBYTES;
  373     memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
  374   }
  375 
  376   blake2s_increment_counter( S, ( uint32_t )S->buflen );
  377   blake2s_set_lastblock( S );
  378   memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
  379   blake2s_compress( S, S->buf );
  380 
  381   for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
  382     store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
  383 
  384   memcpy( out, buffer, outlen );
  385   return 0;
  386 }
  387 
  388 int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
  389 {
  390   blake2s_state S[1];
  391 
  392   /* Verify parameters */
  393   if ( NULL == in && inlen > 0 ) return -1;
  394 
  395   if ( NULL == out ) return -1;
  396 
  397   if ( NULL == key && keylen > 0) return -1;
  398 
  399   if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
  400 
  401   if( keylen > BLAKE2S_KEYBYTES ) return -1;
  402 
  403   if( keylen > 0 )
  404   {
  405     if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
  406   }
  407   else
  408   {
  409     if( blake2s_init( S, outlen ) < 0 ) return -1;
  410   }
  411 
  412   if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1;
  413   return blake2s_final( S, out, outlen );
  414 }
  415 
  416 #if defined(SUPERCOP)
  417 int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
  418 {
  419   return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, (size_t)inlen, 0 );
  420 }
  421 #endif
  422 

Cache object: 0cfe401a7f2a827f77036f2b67037d71


[ 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.