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/blake2sp.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 <stdlib.h>
   15 #include <string.h>
   16 #include <stdio.h>
   17 
   18 #if defined(_OPENMP)
   19 #include <omp.h>
   20 #endif
   21 
   22 #include "blake2.h"
   23 #include "blake2-impl.h"
   24 
   25 #define PARALLELISM_DEGREE 8
   26 
   27 static int blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )
   28 {
   29   blake2s_param P[1];
   30   P->digest_length = outlen;
   31   P->key_length = keylen;
   32   P->fanout = PARALLELISM_DEGREE;
   33   P->depth = 2;
   34   P->leaf_length = 0;
   35   store48( P->node_offset, offset );
   36   P->node_depth = 0;
   37   P->inner_length = BLAKE2S_OUTBYTES;
   38   memset( P->salt, 0, sizeof( P->salt ) );
   39   memset( P->personal, 0, sizeof( P->personal ) );
   40   blake2s_init_param( S, P );
   41   S->outlen = P->inner_length;
   42   return 0;
   43 }
   44 
   45 static int blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen )
   46 {
   47   blake2s_param P[1];
   48   P->digest_length = outlen;
   49   P->key_length = keylen;
   50   P->fanout = PARALLELISM_DEGREE;
   51   P->depth = 2;
   52   P->leaf_length = 0;
   53   store48( P->node_offset, 0ULL );
   54   P->node_depth = 1;
   55   P->inner_length = BLAKE2S_OUTBYTES;
   56   memset( P->salt, 0, sizeof( P->salt ) );
   57   memset( P->personal, 0, sizeof( P->personal ) );
   58   blake2s_init_param( S, P );
   59   S->outlen = P->digest_length;
   60   return 0;
   61 }
   62 
   63 
   64 int blake2sp_init( blake2sp_state *S, size_t outlen )
   65 {
   66   if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
   67 
   68   memset( S->buf, 0, sizeof( S->buf ) );
   69   S->buflen = 0;
   70 
   71   if( blake2sp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 )
   72     return -1;
   73 
   74   for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
   75     if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1;
   76 
   77   S->R->last_node = 1;
   78   S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
   79   S->outlen = ( uint8_t ) outlen;
   80   return 0;
   81 }
   82 
   83 int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen )
   84 {
   85   if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
   86 
   87   if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
   88 
   89   memset( S->buf, 0, sizeof( S->buf ) );
   90   S->buflen = 0;
   91 
   92   if( blake2sp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 )
   93     return -1;
   94 
   95   for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
   96     if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 )
   97       return -1;
   98 
   99   S->R->last_node = 1;
  100   S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
  101   S->outlen = ( uint8_t ) outlen;
  102   {
  103     uint8_t block[BLAKE2S_BLOCKBYTES];
  104     memset( block, 0, BLAKE2S_BLOCKBYTES );
  105     memcpy( block, key, keylen );
  106 
  107     for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
  108       blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES );
  109 
  110     secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
  111   }
  112   return 0;
  113 }
  114 
  115 
  116 int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen )
  117 {
  118   size_t left = S->buflen;
  119   size_t fill = sizeof( S->buf ) - left;
  120 
  121   if( left && inlen >= fill )
  122   {
  123     memcpy( S->buf + left, in, fill );
  124 
  125     for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
  126       blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );
  127 
  128     in += fill;
  129     inlen -= fill;
  130     left = 0;
  131   }
  132 
  133 #if defined(_OPENMP)
  134   omp_set_num_threads(PARALLELISM_DEGREE);
  135   #pragma omp parallel shared(S)
  136 #else
  137   for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
  138 #endif
  139   {
  140 #if defined(_OPENMP)
  141     size_t      id__ = ( size_t ) omp_get_thread_num();
  142 #endif
  143     size_t inlen__ = inlen;
  144     const uint8_t *in__ = ( const uint8_t * )in;
  145     in__ += id__ * BLAKE2S_BLOCKBYTES;
  146 
  147     while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
  148     {
  149       blake2s_update( S->S[id__], in__, BLAKE2S_BLOCKBYTES );
  150       in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
  151       inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
  152     }
  153   }
  154 
  155   in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );
  156   inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
  157 
  158   if( inlen > 0 )
  159     memcpy( S->buf + left, in, inlen );
  160 
  161   S->buflen = ( uint32_t ) left + ( uint32_t ) inlen;
  162   return 0;
  163 }
  164 
  165 
  166 int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen )
  167 {
  168   uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
  169 
  170   if(S->outlen != outlen) return -1;
  171 
  172   for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
  173   {
  174     if( S->buflen > i * BLAKE2S_BLOCKBYTES )
  175     {
  176       size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;
  177 
  178       if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;
  179 
  180       blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );
  181     }
  182 
  183     blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES );
  184   }
  185 
  186   for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
  187     blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );
  188 
  189   blake2s_final( S->R, out, outlen );
  190   return 0;
  191 }
  192 
  193 
  194 int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
  195 {
  196   uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
  197   blake2s_state S[PARALLELISM_DEGREE][1];
  198   blake2s_state FS[1];
  199 
  200   /* Verify parameters */
  201   if ( NULL == in && inlen > 0 ) return -1;
  202 
  203   if ( NULL == out ) return -1;
  204 
  205   if ( NULL == key && keylen > 0 ) return -1;
  206 
  207   if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
  208 
  209   if( keylen > BLAKE2S_KEYBYTES ) return -1;
  210 
  211   for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
  212     if( blake2sp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 )
  213       return -1;
  214 
  215   S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node
  216 
  217   if( keylen > 0 )
  218   {
  219     uint8_t block[BLAKE2S_BLOCKBYTES];
  220     memset( block, 0, BLAKE2S_BLOCKBYTES );
  221     memcpy( block, key, keylen );
  222 
  223     for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
  224       blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );
  225 
  226     secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
  227   }
  228 
  229 #if defined(_OPENMP)
  230   omp_set_num_threads(PARALLELISM_DEGREE);
  231   #pragma omp parallel shared(S,hash)
  232 #else
  233 
  234   for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
  235 #endif
  236   {
  237 #if defined(_OPENMP)
  238     size_t      id__ = ( size_t ) omp_get_thread_num();
  239 #endif
  240     size_t inlen__ = inlen;
  241     const uint8_t *in__ = ( const uint8_t * )in;
  242     in__ += id__ * BLAKE2S_BLOCKBYTES;
  243 
  244     while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
  245     {
  246       blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES );
  247       in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
  248       inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
  249     }
  250 
  251     if( inlen__ > id__ * BLAKE2S_BLOCKBYTES )
  252     {
  253       const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES;
  254       const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;
  255       blake2s_update( S[id__], in__, len );
  256     }
  257 
  258     blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES );
  259   }
  260 
  261   if( blake2sp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 )
  262     return -1;
  263 
  264   FS->last_node = 1;
  265 
  266   for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
  267     blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );
  268 
  269   return blake2s_final( FS, out, outlen );
  270 }
  271 
  272 
  273 
  274 

Cache object: 1c38cbb394ed8e992faa9c243af8a235


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