1 /* 2 BLAKE2 reference source code package - reference C implementations 3 4 Copyright 2012, Samuel Neves <sneves (at) dei.uc.pt>. You may use this under the 5 terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 your option. The terms of these licenses can be found at: 7 8 - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 - OpenSSL license : https://www.openssl.org/source/license.html 10 - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 12 More information about the BLAKE2 hash function can be found at 13 https://blake2.net. 14 */ 15 16 #include <stdint.h> 17 #include <string.h> 18 #include <stdio.h> 19 20 #include "blake2.h" 21 #include "blake2-impl.h" 22 23 static const uint32_t blake2s_IV[8] = 24 { 25 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, 26 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL 27 }; 28 29 static const uint8_t blake2s_sigma[10][16] = 30 { 31 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , 32 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , 33 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , 34 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , 35 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , 36 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , 37 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , 38 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , 39 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , 40 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , 41 }; 42 43 BLAKE2_LOCAL_INLINE(int) blake2s_set_lastnode( blake2s_state *S ) 44 { 45 S->f[1] = -1; 46 return 0; 47 } 48 49 BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastnode( blake2s_state *S ) 50 { 51 S->f[1] = 0; 52 return 0; 53 } 54 55 /* Some helper functions, not necessarily useful */ 56 BLAKE2_LOCAL_INLINE(int) blake2s_is_lastblock( const blake2s_state *S ) 57 { 58 return S->f[0] != 0; 59 } 60 61 BLAKE2_LOCAL_INLINE(int) blake2s_set_lastblock( blake2s_state *S ) 62 { 63 if( S->last_node ) blake2s_set_lastnode( S ); 64 65 S->f[0] = -1; 66 return 0; 67 } 68 69 BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastblock( blake2s_state *S ) 70 { 71 if( S->last_node ) blake2s_clear_lastnode( S ); 72 73 S->f[0] = 0; 74 return 0; 75 } 76 77 BLAKE2_LOCAL_INLINE(int) blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) 78 { 79 S->t[0] += inc; 80 S->t[1] += ( S->t[0] < inc ); 81 return 0; 82 } 83 84 /* Parameter-related functions */ 85 BLAKE2_LOCAL_INLINE(int) blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length ) 86 { 87 P->digest_length = digest_length; 88 return 0; 89 } 90 91 BLAKE2_LOCAL_INLINE(int) blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) 92 { 93 P->fanout = fanout; 94 return 0; 95 } 96 97 BLAKE2_LOCAL_INLINE(int) blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth ) 98 { 99 P->depth = depth; 100 return 0; 101 } 102 103 BLAKE2_LOCAL_INLINE(int) blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) 104 { 105 store32( &P->leaf_length, leaf_length ); 106 return 0; 107 } 108 109 BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset ) 110 { 111 store48( P->node_offset, node_offset ); 112 return 0; 113 } 114 115 BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) 116 { 117 P->node_depth = node_depth; 118 return 0; 119 } 120 121 BLAKE2_LOCAL_INLINE(int) blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length ) 122 { 123 P->inner_length = inner_length; 124 return 0; 125 } 126 127 BLAKE2_LOCAL_INLINE(int) blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) 128 { 129 memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); 130 return 0; 131 } 132 133 BLAKE2_LOCAL_INLINE(int) blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] ) 134 { 135 memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); 136 return 0; 137 } 138 139 BLAKE2_LOCAL_INLINE(int) blake2s_init0( blake2s_state *S ) 140 { 141 int i; 142 memset( S, 0, sizeof( blake2s_state ) ); 143 144 for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; 145 146 return 0; 147 } 148 149 /* init2 xors IV with input parameter block */ 150 int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) 151 { 152 const uint32_t *p = ( const uint32_t * )( P ); 153 size_t i; 154 155 blake2s_init0( S ); 156 157 /* IV XOR ParamBlock */ 158 for( i = 0; i < 8; ++i ) 159 S->h[i] ^= load32( &p[i] ); 160 161 return 0; 162 } 163 164 165 /* Sequential blake2s initialization */ 166 int blake2s_init( blake2s_state *S, const uint8_t outlen ) 167 { 168 blake2s_param P[1]; 169 170 /* Move interval verification here? */ 171 if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; 172 173 P->digest_length = outlen; 174 P->key_length = 0; 175 P->fanout = 1; 176 P->depth = 1; 177 store32( &P->leaf_length, 0 ); 178 store48( &P->node_offset, 0 ); 179 P->node_depth = 0; 180 P->inner_length = 0; 181 /* memset(P->reserved, 0, sizeof(P->reserved) ); */ 182 memset( P->salt, 0, sizeof( P->salt ) ); 183 memset( P->personal, 0, sizeof( P->personal ) ); 184 return blake2s_init_param( S, P ); 185 } 186 187 int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) 188 { 189 blake2s_param P[1]; 190 191 if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; 192 193 if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; 194 195 P->digest_length = outlen; 196 P->key_length = keylen; 197 P->fanout = 1; 198 P->depth = 1; 199 store32( &P->leaf_length, 0 ); 200 store48( &P->node_offset, 0 ); 201 P->node_depth = 0; 202 P->inner_length = 0; 203 /* memset(P->reserved, 0, sizeof(P->reserved) ); */ 204 memset( P->salt, 0, sizeof( P->salt ) ); 205 memset( P->personal, 0, sizeof( P->personal ) ); 206 207 if( blake2s_init_param( S, P ) < 0 ) return -1; 208 209 { 210 uint8_t block[BLAKE2S_BLOCKBYTES]; 211 memset( block, 0, BLAKE2S_BLOCKBYTES ); 212 memcpy( block, key, keylen ); 213 blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); 214 secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ 215 } 216 return 0; 217 } 218 219 static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) 220 { 221 uint32_t m[16]; 222 uint32_t v[16]; 223 size_t i; 224 225 for( i = 0; i < 16; ++i ) 226 m[i] = load32( block + i * sizeof( m[i] ) ); 227 228 for( i = 0; i < 8; ++i ) 229 v[i] = S->h[i]; 230 231 v[ 8] = blake2s_IV[0]; 232 v[ 9] = blake2s_IV[1]; 233 v[10] = blake2s_IV[2]; 234 v[11] = blake2s_IV[3]; 235 v[12] = S->t[0] ^ blake2s_IV[4]; 236 v[13] = S->t[1] ^ blake2s_IV[5]; 237 v[14] = S->f[0] ^ blake2s_IV[6]; 238 v[15] = S->f[1] ^ blake2s_IV[7]; 239 #define G(r,i,a,b,c,d) \ 240 do { \ 241 a = a + b + m[blake2s_sigma[r][2*i+0]]; \ 242 d = rotr32(d ^ a, 16); \ 243 c = c + d; \ 244 b = rotr32(b ^ c, 12); \ 245 a = a + b + m[blake2s_sigma[r][2*i+1]]; \ 246 d = rotr32(d ^ a, 8); \ 247 c = c + d; \ 248 b = rotr32(b ^ c, 7); \ 249 } while(0) 250 #define ROUND(r) \ 251 do { \ 252 G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ 253 G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ 254 G(r,2,v[ 2],v[ 6],v[10],v[14]); \ 255 G(r,3,v[ 3],v[ 7],v[11],v[15]); \ 256 G(r,4,v[ 0],v[ 5],v[10],v[15]); \ 257 G(r,5,v[ 1],v[ 6],v[11],v[12]); \ 258 G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ 259 G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ 260 } while(0) 261 ROUND( 0 ); 262 ROUND( 1 ); 263 ROUND( 2 ); 264 ROUND( 3 ); 265 ROUND( 4 ); 266 ROUND( 5 ); 267 ROUND( 6 ); 268 ROUND( 7 ); 269 ROUND( 8 ); 270 ROUND( 9 ); 271 272 for( i = 0; i < 8; ++i ) 273 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; 274 275 #undef G 276 #undef ROUND 277 return 0; 278 } 279 280 281 int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ) 282 { 283 while( inlen > 0 ) 284 { 285 size_t left = S->buflen; 286 size_t fill = 2 * BLAKE2S_BLOCKBYTES - left; 287 288 if( inlen > fill ) 289 { 290 memcpy( S->buf + left, in, fill ); /* Fill buffer */ 291 S->buflen += fill; 292 blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); 293 blake2s_compress( S, S->buf ); /* Compress */ 294 memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); /* Shift buffer left */ 295 S->buflen -= BLAKE2S_BLOCKBYTES; 296 in += fill; 297 inlen -= fill; 298 } 299 else /* inlen <= fill */ 300 { 301 memcpy( S->buf + left, in, (size_t)inlen ); 302 S->buflen += (size_t)inlen; /* Be lazy, do not compress */ 303 in += inlen; 304 inlen -= inlen; 305 } 306 } 307 308 return 0; 309 } 310 311 int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen ) 312 { 313 uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; 314 int i; 315 316 if( out == NULL || outlen == 0 || outlen > BLAKE2S_OUTBYTES ) 317 return -1; 318 319 if( blake2s_is_lastblock( S ) ) 320 return -1; 321 322 323 if( S->buflen > BLAKE2S_BLOCKBYTES ) 324 { 325 blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); 326 blake2s_compress( S, S->buf ); 327 S->buflen -= BLAKE2S_BLOCKBYTES; 328 memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen ); 329 } 330 331 blake2s_increment_counter( S, ( uint32_t )S->buflen ); 332 blake2s_set_lastblock( S ); 333 memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ 334 blake2s_compress( S, S->buf ); 335 336 for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ 337 store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); 338 339 memcpy( out, buffer, outlen ); 340 return 0; 341 } 342 343 int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) 344 { 345 blake2s_state S[1]; 346 347 /* Verify parameters */ 348 if ( NULL == in && inlen > 0 ) return -1; 349 350 if ( NULL == out ) return -1; 351 352 if ( NULL == key && keylen > 0) return -1; 353 354 if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; 355 356 if( keylen > BLAKE2S_KEYBYTES ) return -1; 357 358 if( keylen > 0 ) 359 { 360 if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; 361 } 362 else 363 { 364 if( blake2s_init( S, outlen ) < 0 ) return -1; 365 } 366 367 blake2s_update( S, ( const uint8_t * )in, inlen ); 368 blake2s_final( S, out, outlen ); 369 return 0; 370 } 371 372 #if defined(SUPERCOP) 373 int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) 374 { 375 return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, inlen, 0 ); 376 } 377 #endif 378 379 #if defined(BLAKE2S_SELFTEST) 380 #include <string.h> 381 #include "blake2-kat.h" 382 int main( int argc, char **argv ) 383 { 384 uint8_t key[BLAKE2S_KEYBYTES]; 385 uint8_t buf[KAT_LENGTH]; 386 size_t i; 387 388 for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) 389 key[i] = ( uint8_t )i; 390 391 for( i = 0; i < KAT_LENGTH; ++i ) 392 buf[i] = ( uint8_t )i; 393 394 for( i = 0; i < KAT_LENGTH; ++i ) 395 { 396 uint8_t hash[BLAKE2S_OUTBYTES]; 397 blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ); 398 399 if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) 400 { 401 puts( "error" ); 402 return -1; 403 } 404 } 405 406 puts( "ok" ); 407 return 0; 408 } 409 #endif 410 411 412