1 /* 2 BLAKE2 reference source code package - reference C implementations 3 4 Copyright 2012, Samuel Neves <sneves@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-impl.h" 21 22 static const uint64_t blake2b_IV[8] = 23 { 24 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 25 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 26 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 27 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL 28 }; 29 30 static const uint8_t blake2b_sigma[12][16] = 31 { 32 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , 33 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , 34 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , 35 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , 36 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , 37 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , 38 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , 39 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , 40 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , 41 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , 42 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , 43 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } 44 }; 45 46 static int blake2b_update(blake2b_state* S, const void* in, size_t inlen); 47 48 static void blake2b_set_lastnode( blake2b_state *S ) 49 { 50 S->f[1] = (uint64_t)-1; 51 } 52 53 /* Some helper functions, not necessarily useful */ 54 static int blake2b_is_lastblock( const blake2b_state *S ) 55 { 56 return S->f[0] != 0; 57 } 58 59 static void blake2b_set_lastblock( blake2b_state *S ) 60 { 61 if( S->last_node ) blake2b_set_lastnode( S ); 62 63 S->f[0] = (uint64_t)-1; 64 } 65 66 static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) 67 { 68 S->t[0] += inc; 69 S->t[1] += ( S->t[0] < inc ); 70 } 71 72 static void blake2b_init0( blake2b_state *S ) 73 { 74 size_t i; 75 memset( S, 0, sizeof( blake2b_state ) ); 76 77 for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; 78 } 79 80 /* init xors IV with input parameter block */ 81 static void blake2b_init_param( blake2b_state *S, const blake2b_param *P ) 82 { 83 const uint8_t *p = ( const uint8_t * )( P ); 84 size_t i; 85 86 blake2b_init0( S ); 87 88 /* IV XOR ParamBlock */ 89 for( i = 0; i < 8; ++i ) 90 S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); 91 92 S->outlen = P->digest_length; 93 } 94 95 96 97 static void blake2b_init( blake2b_state *S, size_t outlen ) 98 { 99 blake2b_param P[1]; 100 101 P->digest_length = (uint8_t)outlen; 102 P->key_length = 0; 103 P->fanout = 1; 104 P->depth = 1; 105 store32( &P->leaf_length, 0 ); 106 store32( &P->node_offset, 0 ); 107 store32( &P->xof_length, 0 ); 108 P->node_depth = 0; 109 P->inner_length = 0; 110 memset( P->reserved, 0, sizeof( P->reserved ) ); 111 memset( P->salt, 0, sizeof( P->salt ) ); 112 memset( P->personal, 0, sizeof( P->personal ) ); 113 114 blake2b_init_param( S, P ); 115 } 116 117 #define G(r,i,a,b,c,d) \ 118 do { \ 119 a = a + b + m[blake2b_sigma[r][2*i+0]]; \ 120 d = rotr64(d ^ a, 32); \ 121 c = c + d; \ 122 b = rotr64(b ^ c, 24); \ 123 a = a + b + m[blake2b_sigma[r][2*i+1]]; \ 124 d = rotr64(d ^ a, 16); \ 125 c = c + d; \ 126 b = rotr64(b ^ c, 63); \ 127 } while(0) 128 129 #define ROUND(r) \ 130 do { \ 131 G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ 132 G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ 133 G(r,2,v[ 2],v[ 6],v[10],v[14]); \ 134 G(r,3,v[ 3],v[ 7],v[11],v[15]); \ 135 G(r,4,v[ 0],v[ 5],v[10],v[15]); \ 136 G(r,5,v[ 1],v[ 6],v[11],v[12]); \ 137 G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ 138 G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ 139 } while(0) 140 141 static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) 142 { 143 uint64_t m[16]; 144 uint64_t v[16]; 145 size_t i; 146 147 for( i = 0; i < 16; ++i ) { 148 m[i] = load64( block + i * sizeof( m[i] ) ); 149 } 150 151 for( i = 0; i < 8; ++i ) { 152 v[i] = S->h[i]; 153 } 154 155 v[ 8] = blake2b_IV[0]; 156 v[ 9] = blake2b_IV[1]; 157 v[10] = blake2b_IV[2]; 158 v[11] = blake2b_IV[3]; 159 v[12] = blake2b_IV[4] ^ S->t[0]; 160 v[13] = blake2b_IV[5] ^ S->t[1]; 161 v[14] = blake2b_IV[6] ^ S->f[0]; 162 v[15] = blake2b_IV[7] ^ S->f[1]; 163 164 ROUND( 0 ); 165 ROUND( 1 ); 166 ROUND( 2 ); 167 ROUND( 3 ); 168 ROUND( 4 ); 169 ROUND( 5 ); 170 ROUND( 6 ); 171 ROUND( 7 ); 172 ROUND( 8 ); 173 ROUND( 9 ); 174 ROUND( 10 ); 175 ROUND( 11 ); 176 177 for( i = 0; i < 8; ++i ) { 178 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; 179 } 180 } 181 182 #undef G 183 #undef ROUND 184 185 static int blake2b_update( blake2b_state *S, const void *pin, size_t inlen ) 186 { 187 const unsigned char * in = (const unsigned char *)pin; 188 if( inlen > 0 ) 189 { 190 size_t left = S->buflen; 191 size_t fill = BLAKE2B_BLOCKBYTES - left; 192 if( inlen > fill ) 193 { 194 S->buflen = 0; 195 memcpy( S->buf + left, in, fill ); /* Fill buffer */ 196 blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); 197 blake2b_compress( S, S->buf ); /* Compress */ 198 in += fill; inlen -= fill; 199 while(inlen > BLAKE2B_BLOCKBYTES) { 200 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); 201 blake2b_compress( S, in ); 202 in += BLAKE2B_BLOCKBYTES; 203 inlen -= BLAKE2B_BLOCKBYTES; 204 } 205 } 206 memcpy( S->buf + S->buflen, in, inlen ); 207 S->buflen += inlen; 208 } 209 return 0; 210 } 211 212 static int blake2b_final( blake2b_state *S, void *out, size_t outlen ) 213 { 214 uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; 215 size_t i; 216 217 if( out == NULL || outlen < S->outlen ) 218 return -1; 219 220 if( blake2b_is_lastblock( S ) ) 221 return -1; 222 223 blake2b_increment_counter( S, S->buflen ); 224 blake2b_set_lastblock( S ); 225 memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ 226 blake2b_compress( S, S->buf ); 227 228 for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ 229 store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); 230 231 memcpy( out, buffer, S->outlen ); 232 233 return 0; 234 } 235 236 /* inlen, at least, should be uint64_t. Others can be size_t. */ 237 void blake2b( void *out, size_t outlen, const void *in, size_t inlen ) 238 { 239 blake2b_state S[1]; 240 241 blake2b_init( S, outlen ); 242 243 blake2b_update( S, ( const uint8_t * )in, inlen ); 244 blake2b_final( S, out, outlen ); 245 } 246