17db96d56Sopenharmony_ci/* 27db96d56Sopenharmony_ci BLAKE2 reference source code package - reference C implementations 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci Written in 2012 by Samuel Neves <sneves@dei.uc.pt> 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ci To the extent possible under law, the author(s) have dedicated all copyright 77db96d56Sopenharmony_ci and related and neighboring rights to this software to the public domain 87db96d56Sopenharmony_ci worldwide. This software is distributed without any warranty. 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci You should have received a copy of the CC0 Public Domain Dedication along with 117db96d56Sopenharmony_ci this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. 127db96d56Sopenharmony_ci*/ 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ci#include <stdint.h> 157db96d56Sopenharmony_ci#include <string.h> 167db96d56Sopenharmony_ci#include <stdio.h> 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_ci#include "blake2.h" 197db96d56Sopenharmony_ci#include "blake2-impl.h" 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_cistatic const uint32_t blake2s_IV[8] = 227db96d56Sopenharmony_ci{ 237db96d56Sopenharmony_ci 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, 247db96d56Sopenharmony_ci 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL 257db96d56Sopenharmony_ci}; 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_cistatic const uint8_t blake2s_sigma[10][16] = 287db96d56Sopenharmony_ci{ 297db96d56Sopenharmony_ci { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , 307db96d56Sopenharmony_ci { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , 317db96d56Sopenharmony_ci { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , 327db96d56Sopenharmony_ci { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , 337db96d56Sopenharmony_ci { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , 347db96d56Sopenharmony_ci { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , 357db96d56Sopenharmony_ci { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , 367db96d56Sopenharmony_ci { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , 377db96d56Sopenharmony_ci { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , 387db96d56Sopenharmony_ci { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , 397db96d56Sopenharmony_ci}; 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_cistatic inline int blake2s_set_lastnode( blake2s_state *S ) 427db96d56Sopenharmony_ci{ 437db96d56Sopenharmony_ci S->f[1] = ~0U; 447db96d56Sopenharmony_ci return 0; 457db96d56Sopenharmony_ci} 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_cistatic inline int blake2s_clear_lastnode( blake2s_state *S ) 487db96d56Sopenharmony_ci{ 497db96d56Sopenharmony_ci S->f[1] = 0U; 507db96d56Sopenharmony_ci return 0; 517db96d56Sopenharmony_ci} 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci/* Some helper functions, not necessarily useful */ 547db96d56Sopenharmony_cistatic inline int blake2s_set_lastblock( blake2s_state *S ) 557db96d56Sopenharmony_ci{ 567db96d56Sopenharmony_ci if( S->last_node ) blake2s_set_lastnode( S ); 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci S->f[0] = ~0U; 597db96d56Sopenharmony_ci return 0; 607db96d56Sopenharmony_ci} 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_cistatic inline int blake2s_clear_lastblock( blake2s_state *S ) 637db96d56Sopenharmony_ci{ 647db96d56Sopenharmony_ci if( S->last_node ) blake2s_clear_lastnode( S ); 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ci S->f[0] = 0U; 677db96d56Sopenharmony_ci return 0; 687db96d56Sopenharmony_ci} 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_cistatic inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) 717db96d56Sopenharmony_ci{ 727db96d56Sopenharmony_ci S->t[0] += inc; 737db96d56Sopenharmony_ci S->t[1] += ( S->t[0] < inc ); 747db96d56Sopenharmony_ci return 0; 757db96d56Sopenharmony_ci} 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci// Parameter-related functions 787db96d56Sopenharmony_cistatic inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length ) 797db96d56Sopenharmony_ci{ 807db96d56Sopenharmony_ci P->digest_length = digest_length; 817db96d56Sopenharmony_ci return 0; 827db96d56Sopenharmony_ci} 837db96d56Sopenharmony_ci 847db96d56Sopenharmony_cistatic inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) 857db96d56Sopenharmony_ci{ 867db96d56Sopenharmony_ci P->fanout = fanout; 877db96d56Sopenharmony_ci return 0; 887db96d56Sopenharmony_ci} 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_cistatic inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth ) 917db96d56Sopenharmony_ci{ 927db96d56Sopenharmony_ci P->depth = depth; 937db96d56Sopenharmony_ci return 0; 947db96d56Sopenharmony_ci} 957db96d56Sopenharmony_ci 967db96d56Sopenharmony_cistatic inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) 977db96d56Sopenharmony_ci{ 987db96d56Sopenharmony_ci store32( &P->leaf_length, leaf_length ); 997db96d56Sopenharmony_ci return 0; 1007db96d56Sopenharmony_ci} 1017db96d56Sopenharmony_ci 1027db96d56Sopenharmony_cistatic inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset ) 1037db96d56Sopenharmony_ci{ 1047db96d56Sopenharmony_ci store48( P->node_offset, node_offset ); 1057db96d56Sopenharmony_ci return 0; 1067db96d56Sopenharmony_ci} 1077db96d56Sopenharmony_ci 1087db96d56Sopenharmony_cistatic inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) 1097db96d56Sopenharmony_ci{ 1107db96d56Sopenharmony_ci P->node_depth = node_depth; 1117db96d56Sopenharmony_ci return 0; 1127db96d56Sopenharmony_ci} 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_cistatic inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length ) 1157db96d56Sopenharmony_ci{ 1167db96d56Sopenharmony_ci P->inner_length = inner_length; 1177db96d56Sopenharmony_ci return 0; 1187db96d56Sopenharmony_ci} 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_cistatic inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) 1217db96d56Sopenharmony_ci{ 1227db96d56Sopenharmony_ci memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); 1237db96d56Sopenharmony_ci return 0; 1247db96d56Sopenharmony_ci} 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_cistatic inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] ) 1277db96d56Sopenharmony_ci{ 1287db96d56Sopenharmony_ci memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); 1297db96d56Sopenharmony_ci return 0; 1307db96d56Sopenharmony_ci} 1317db96d56Sopenharmony_ci 1327db96d56Sopenharmony_cistatic inline int blake2s_init0( blake2s_state *S ) 1337db96d56Sopenharmony_ci{ 1347db96d56Sopenharmony_ci memset( S, 0, sizeof( blake2s_state ) ); 1357db96d56Sopenharmony_ci 1367db96d56Sopenharmony_ci for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; 1377db96d56Sopenharmony_ci 1387db96d56Sopenharmony_ci return 0; 1397db96d56Sopenharmony_ci} 1407db96d56Sopenharmony_ci 1417db96d56Sopenharmony_ci#if defined(__cplusplus) 1427db96d56Sopenharmony_ciextern "C" { 1437db96d56Sopenharmony_ci#endif 1447db96d56Sopenharmony_ci int blake2s_init( blake2s_state *S, size_t outlen ); 1457db96d56Sopenharmony_ci int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); 1467db96d56Sopenharmony_ci int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); 1477db96d56Sopenharmony_ci int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ); 1487db96d56Sopenharmony_ci int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ); 1497db96d56Sopenharmony_ci int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); 1507db96d56Sopenharmony_ci#if defined(__cplusplus) 1517db96d56Sopenharmony_ci} 1527db96d56Sopenharmony_ci#endif 1537db96d56Sopenharmony_ci 1547db96d56Sopenharmony_ci/* init2 xors IV with input parameter block */ 1557db96d56Sopenharmony_ciint blake2s_init_param( blake2s_state *S, const blake2s_param *P ) 1567db96d56Sopenharmony_ci{ 1577db96d56Sopenharmony_ci blake2s_init0( S ); 1587db96d56Sopenharmony_ci uint32_t *p = ( uint32_t * )( P ); 1597db96d56Sopenharmony_ci 1607db96d56Sopenharmony_ci /* IV XOR ParamBlock */ 1617db96d56Sopenharmony_ci for( size_t i = 0; i < 8; ++i ) 1627db96d56Sopenharmony_ci S->h[i] ^= load32( &p[i] ); 1637db96d56Sopenharmony_ci 1647db96d56Sopenharmony_ci S->outlen = P->digest_length; 1657db96d56Sopenharmony_ci return 0; 1667db96d56Sopenharmony_ci} 1677db96d56Sopenharmony_ci 1687db96d56Sopenharmony_ci 1697db96d56Sopenharmony_ci// Sequential blake2s initialization 1707db96d56Sopenharmony_ciint blake2s_init( blake2s_state *S, size_t outlen ) 1717db96d56Sopenharmony_ci{ 1727db96d56Sopenharmony_ci blake2s_param P[1]; 1737db96d56Sopenharmony_ci 1747db96d56Sopenharmony_ci /* Move interval verification here? */ 1757db96d56Sopenharmony_ci if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; 1767db96d56Sopenharmony_ci 1777db96d56Sopenharmony_ci P->digest_length = ( uint8_t) outlen; 1787db96d56Sopenharmony_ci P->key_length = 0; 1797db96d56Sopenharmony_ci P->fanout = 1; 1807db96d56Sopenharmony_ci P->depth = 1; 1817db96d56Sopenharmony_ci store32( &P->leaf_length, 0 ); 1827db96d56Sopenharmony_ci store48( &P->node_offset, 0 ); 1837db96d56Sopenharmony_ci P->node_depth = 0; 1847db96d56Sopenharmony_ci P->inner_length = 0; 1857db96d56Sopenharmony_ci // memset(P->reserved, 0, sizeof(P->reserved) ); 1867db96d56Sopenharmony_ci memset( P->salt, 0, sizeof( P->salt ) ); 1877db96d56Sopenharmony_ci memset( P->personal, 0, sizeof( P->personal ) ); 1887db96d56Sopenharmony_ci return blake2s_init_param( S, P ); 1897db96d56Sopenharmony_ci} 1907db96d56Sopenharmony_ci 1917db96d56Sopenharmony_ciint blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) 1927db96d56Sopenharmony_ci{ 1937db96d56Sopenharmony_ci blake2s_param P[1]; 1947db96d56Sopenharmony_ci 1957db96d56Sopenharmony_ci if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; 1967db96d56Sopenharmony_ci 1977db96d56Sopenharmony_ci if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; 1987db96d56Sopenharmony_ci 1997db96d56Sopenharmony_ci P->digest_length = ( uint8_t ) outlen; 2007db96d56Sopenharmony_ci P->key_length = ( uint8_t ) keylen; 2017db96d56Sopenharmony_ci P->fanout = 1; 2027db96d56Sopenharmony_ci P->depth = 1; 2037db96d56Sopenharmony_ci store32( &P->leaf_length, 0 ); 2047db96d56Sopenharmony_ci store48( &P->node_offset, 0 ); 2057db96d56Sopenharmony_ci P->node_depth = 0; 2067db96d56Sopenharmony_ci P->inner_length = 0; 2077db96d56Sopenharmony_ci // memset(P->reserved, 0, sizeof(P->reserved) ); 2087db96d56Sopenharmony_ci memset( P->salt, 0, sizeof( P->salt ) ); 2097db96d56Sopenharmony_ci memset( P->personal, 0, sizeof( P->personal ) ); 2107db96d56Sopenharmony_ci 2117db96d56Sopenharmony_ci if( blake2s_init_param( S, P ) < 0 ) return -1; 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ci { 2147db96d56Sopenharmony_ci uint8_t block[BLAKE2S_BLOCKBYTES]; 2157db96d56Sopenharmony_ci memset( block, 0, BLAKE2S_BLOCKBYTES ); 2167db96d56Sopenharmony_ci memcpy( block, key, keylen ); 2177db96d56Sopenharmony_ci blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); 2187db96d56Sopenharmony_ci secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ 2197db96d56Sopenharmony_ci } 2207db96d56Sopenharmony_ci return 0; 2217db96d56Sopenharmony_ci} 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_cistatic int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) 2247db96d56Sopenharmony_ci{ 2257db96d56Sopenharmony_ci uint32_t m[16]; 2267db96d56Sopenharmony_ci uint32_t v[16]; 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ci for( size_t i = 0; i < 16; ++i ) 2297db96d56Sopenharmony_ci m[i] = load32( block + i * sizeof( m[i] ) ); 2307db96d56Sopenharmony_ci 2317db96d56Sopenharmony_ci for( size_t i = 0; i < 8; ++i ) 2327db96d56Sopenharmony_ci v[i] = S->h[i]; 2337db96d56Sopenharmony_ci 2347db96d56Sopenharmony_ci v[ 8] = blake2s_IV[0]; 2357db96d56Sopenharmony_ci v[ 9] = blake2s_IV[1]; 2367db96d56Sopenharmony_ci v[10] = blake2s_IV[2]; 2377db96d56Sopenharmony_ci v[11] = blake2s_IV[3]; 2387db96d56Sopenharmony_ci v[12] = S->t[0] ^ blake2s_IV[4]; 2397db96d56Sopenharmony_ci v[13] = S->t[1] ^ blake2s_IV[5]; 2407db96d56Sopenharmony_ci v[14] = S->f[0] ^ blake2s_IV[6]; 2417db96d56Sopenharmony_ci v[15] = S->f[1] ^ blake2s_IV[7]; 2427db96d56Sopenharmony_ci#define G(r,i,a,b,c,d) \ 2437db96d56Sopenharmony_ci do { \ 2447db96d56Sopenharmony_ci a = a + b + m[blake2s_sigma[r][2*i+0]]; \ 2457db96d56Sopenharmony_ci d = rotr32(d ^ a, 16); \ 2467db96d56Sopenharmony_ci c = c + d; \ 2477db96d56Sopenharmony_ci b = rotr32(b ^ c, 12); \ 2487db96d56Sopenharmony_ci a = a + b + m[blake2s_sigma[r][2*i+1]]; \ 2497db96d56Sopenharmony_ci d = rotr32(d ^ a, 8); \ 2507db96d56Sopenharmony_ci c = c + d; \ 2517db96d56Sopenharmony_ci b = rotr32(b ^ c, 7); \ 2527db96d56Sopenharmony_ci } while(0) 2537db96d56Sopenharmony_ci#define ROUND(r) \ 2547db96d56Sopenharmony_ci do { \ 2557db96d56Sopenharmony_ci G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ 2567db96d56Sopenharmony_ci G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ 2577db96d56Sopenharmony_ci G(r,2,v[ 2],v[ 6],v[10],v[14]); \ 2587db96d56Sopenharmony_ci G(r,3,v[ 3],v[ 7],v[11],v[15]); \ 2597db96d56Sopenharmony_ci G(r,4,v[ 0],v[ 5],v[10],v[15]); \ 2607db96d56Sopenharmony_ci G(r,5,v[ 1],v[ 6],v[11],v[12]); \ 2617db96d56Sopenharmony_ci G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ 2627db96d56Sopenharmony_ci G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ 2637db96d56Sopenharmony_ci } while(0) 2647db96d56Sopenharmony_ci ROUND( 0 ); 2657db96d56Sopenharmony_ci ROUND( 1 ); 2667db96d56Sopenharmony_ci ROUND( 2 ); 2677db96d56Sopenharmony_ci ROUND( 3 ); 2687db96d56Sopenharmony_ci ROUND( 4 ); 2697db96d56Sopenharmony_ci ROUND( 5 ); 2707db96d56Sopenharmony_ci ROUND( 6 ); 2717db96d56Sopenharmony_ci ROUND( 7 ); 2727db96d56Sopenharmony_ci ROUND( 8 ); 2737db96d56Sopenharmony_ci ROUND( 9 ); 2747db96d56Sopenharmony_ci 2757db96d56Sopenharmony_ci for( size_t i = 0; i < 8; ++i ) 2767db96d56Sopenharmony_ci S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; 2777db96d56Sopenharmony_ci 2787db96d56Sopenharmony_ci#undef G 2797db96d56Sopenharmony_ci#undef ROUND 2807db96d56Sopenharmony_ci return 0; 2817db96d56Sopenharmony_ci} 2827db96d56Sopenharmony_ci 2837db96d56Sopenharmony_ci 2847db96d56Sopenharmony_ciint blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ) 2857db96d56Sopenharmony_ci{ 2867db96d56Sopenharmony_ci while( inlen > 0 ) 2877db96d56Sopenharmony_ci { 2887db96d56Sopenharmony_ci uint32_t left = S->buflen; 2897db96d56Sopenharmony_ci uint32_t fill = 2 * BLAKE2S_BLOCKBYTES - left; 2907db96d56Sopenharmony_ci 2917db96d56Sopenharmony_ci if( inlen > fill ) 2927db96d56Sopenharmony_ci { 2937db96d56Sopenharmony_ci memcpy( S->buf + left, in, fill ); // Fill buffer 2947db96d56Sopenharmony_ci S->buflen += fill; 2957db96d56Sopenharmony_ci blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); 2967db96d56Sopenharmony_ci blake2s_compress( S, S->buf ); // Compress 2977db96d56Sopenharmony_ci memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left 2987db96d56Sopenharmony_ci S->buflen -= BLAKE2S_BLOCKBYTES; 2997db96d56Sopenharmony_ci in += fill; 3007db96d56Sopenharmony_ci inlen -= fill; 3017db96d56Sopenharmony_ci } 3027db96d56Sopenharmony_ci else // inlen <= fill 3037db96d56Sopenharmony_ci { 3047db96d56Sopenharmony_ci memcpy( S->buf + left, in, inlen ); 3057db96d56Sopenharmony_ci S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress 3067db96d56Sopenharmony_ci in += inlen; 3077db96d56Sopenharmony_ci inlen -= inlen; 3087db96d56Sopenharmony_ci } 3097db96d56Sopenharmony_ci } 3107db96d56Sopenharmony_ci 3117db96d56Sopenharmony_ci return 0; 3127db96d56Sopenharmony_ci} 3137db96d56Sopenharmony_ci 3147db96d56Sopenharmony_ciint blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ) 3157db96d56Sopenharmony_ci{ 3167db96d56Sopenharmony_ci uint8_t buffer[BLAKE2S_OUTBYTES]; 3177db96d56Sopenharmony_ci size_t i; 3187db96d56Sopenharmony_ci 3197db96d56Sopenharmony_ci if(S->outlen != outlen) return -1; 3207db96d56Sopenharmony_ci 3217db96d56Sopenharmony_ci if( S->buflen > BLAKE2S_BLOCKBYTES ) 3227db96d56Sopenharmony_ci { 3237db96d56Sopenharmony_ci blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); 3247db96d56Sopenharmony_ci blake2s_compress( S, S->buf ); 3257db96d56Sopenharmony_ci S->buflen -= BLAKE2S_BLOCKBYTES; 3267db96d56Sopenharmony_ci memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen ); 3277db96d56Sopenharmony_ci } 3287db96d56Sopenharmony_ci 3297db96d56Sopenharmony_ci blake2s_increment_counter( S, ( uint32_t )S->buflen ); 3307db96d56Sopenharmony_ci blake2s_set_lastblock( S ); 3317db96d56Sopenharmony_ci memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ 3327db96d56Sopenharmony_ci blake2s_compress( S, S->buf ); 3337db96d56Sopenharmony_ci 3347db96d56Sopenharmony_ci for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ 3357db96d56Sopenharmony_ci store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); 3367db96d56Sopenharmony_ci 3377db96d56Sopenharmony_ci memcpy( out, buffer, outlen ); 3387db96d56Sopenharmony_ci return 0; 3397db96d56Sopenharmony_ci} 3407db96d56Sopenharmony_ci 3417db96d56Sopenharmony_ciint blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) 3427db96d56Sopenharmony_ci{ 3437db96d56Sopenharmony_ci blake2s_state S[1]; 3447db96d56Sopenharmony_ci 3457db96d56Sopenharmony_ci /* Verify parameters */ 3467db96d56Sopenharmony_ci if ( NULL == in && inlen > 0 ) return -1; 3477db96d56Sopenharmony_ci 3487db96d56Sopenharmony_ci if ( NULL == out ) return -1; 3497db96d56Sopenharmony_ci 3507db96d56Sopenharmony_ci if ( NULL == key && keylen > 0 ) return -1; 3517db96d56Sopenharmony_ci 3527db96d56Sopenharmony_ci if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; 3537db96d56Sopenharmony_ci 3547db96d56Sopenharmony_ci if( keylen > BLAKE2S_KEYBYTES ) return -1; 3557db96d56Sopenharmony_ci 3567db96d56Sopenharmony_ci if( keylen > 0 ) 3577db96d56Sopenharmony_ci { 3587db96d56Sopenharmony_ci if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; 3597db96d56Sopenharmony_ci } 3607db96d56Sopenharmony_ci else 3617db96d56Sopenharmony_ci { 3627db96d56Sopenharmony_ci if( blake2s_init( S, outlen ) < 0 ) return -1; 3637db96d56Sopenharmony_ci } 3647db96d56Sopenharmony_ci 3657db96d56Sopenharmony_ci if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1; 3667db96d56Sopenharmony_ci return blake2s_final( S, out, outlen ); 3677db96d56Sopenharmony_ci} 3687db96d56Sopenharmony_ci 369