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