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

Cache object: 41c138c17ba35d7986607f7f9d8acb69


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