about summary refs log tree commit diff stats
path: root/gba/source/blake2.c
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2017-09-26 16:52:33 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2017-09-26 16:52:33 -0400
commit566d5fe1e012c0001396810bc56395597eb79c2c (patch)
tree464262d2772299b3c7b39d153395461983d17c83 /gba/source/blake2.c
parent8d9df7cc26ef86c7af1d4aa6fd4633667bb3a743 (diff)
downloadgen3uploader-566d5fe1e012c0001396810bc56395597eb79c2c.tar.gz
gen3uploader-566d5fe1e012c0001396810bc56395597eb79c2c.tar.bz2
gen3uploader-566d5fe1e012c0001396810bc56395597eb79c2c.zip
Replaced SHA-224 with BLAKE2s
Also changed the hash determiner format such that each IV, as well as
the Shedinja flag, has its own byte. This increases the size of the
determiner to 16 bytes, 33 bits of which are always unset. While this is
somewhat wasteful, it is useful for debugging purposes because it is
hard to predict the behavior of bitfields.

For testing purposes, the amount of time that the Wii waits for the GBA
to compute hashes has been increased. Given that BLAKE2s is a generally
faster algorithm than SHA-224, it will likely be safe to decrease this
delay in a future commit.

Because the hash algorithm has changed, all old hashes are now invalid.

refs #2
Diffstat (limited to 'gba/source/blake2.c')
-rw-r--r--gba/source/blake2.c322
1 files changed, 322 insertions, 0 deletions
diff --git a/gba/source/blake2.c b/gba/source/blake2.c new file mode 100644 index 0000000..4a09c71 --- /dev/null +++ b/gba/source/blake2.c
@@ -0,0 +1,322 @@
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.h"
21
22#define BLAKE2_INLINE
23
24static BLAKE2_INLINE uint32_t load32( const void *src )
25{
26 uint32_t w;
27 memcpy(&w, src, sizeof w);
28 return w;
29}
30
31static BLAKE2_INLINE void store16( void *dst, uint16_t w )
32{
33 memcpy(dst, &w, sizeof w);
34}
35
36static BLAKE2_INLINE void store32( void *dst, uint32_t w )
37{
38 memcpy(dst, &w, sizeof w);
39}
40
41static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c )
42{
43 return ( w >> c ) | ( w << ( 32 - c ) );
44}
45
46/* prevents compiler optimizing out memset() */
47static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n)
48{
49 static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
50 memset_v(v, 0, n);
51}
52
53static const uint32_t blake2s_IV[8] =
54{
55 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
56 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
57};
58
59static const uint8_t blake2s_sigma[10][16] =
60{
61 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
62 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
63 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
64 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
65 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
66 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
67 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
68 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
69 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
70 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
71};
72
73static void blake2s_set_lastnode( blake2s_state *S )
74{
75 S->f[1] = (uint32_t)-1;
76}
77
78/* Some helper functions, not necessarily useful */
79static int blake2s_is_lastblock( const blake2s_state *S )
80{
81 return S->f[0] != 0;
82}
83
84static void blake2s_set_lastblock( blake2s_state *S )
85{
86 if( S->last_node ) blake2s_set_lastnode( S );
87
88 S->f[0] = (uint32_t)-1;
89}
90
91static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
92{
93 S->t[0] += inc;
94 S->t[1] += ( S->t[0] < inc );
95}
96
97static void blake2s_init0( blake2s_state *S )
98{
99 size_t i;
100 memset( S, 0, sizeof( blake2s_state ) );
101
102 for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
103}
104
105/* init2 xors IV with input parameter block */
106int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
107{
108 const unsigned char *p = ( const unsigned char * )( P );
109 size_t i;
110
111 blake2s_init0( S );
112
113 /* IV XOR ParamBlock */
114 for( i = 0; i < 8; ++i )
115 S->h[i] ^= load32( &p[i * 4] );
116
117 S->outlen = P->digest_length;
118 return 0;
119}
120
121
122/* Sequential blake2s initialization */
123int blake2s_init( blake2s_state *S, size_t outlen )
124{
125 blake2s_param P[1];
126
127 /* Move interval verification here? */
128 if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
129
130 P->digest_length = (uint8_t)outlen;
131 P->key_length = 0;
132 P->fanout = 1;
133 P->depth = 1;
134 store32( &P->leaf_length, 0 );
135 store32( &P->node_offset, 0 );
136 store16( &P->xof_length, 0 );
137 P->node_depth = 0;
138 P->inner_length = 0;
139 /* memset(P->reserved, 0, sizeof(P->reserved) ); */
140 memset( P->salt, 0, sizeof( P->salt ) );
141 memset( P->personal, 0, sizeof( P->personal ) );
142 return blake2s_init_param( S, P );
143}
144
145int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
146{
147 blake2s_param P[1];
148
149 if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
150
151 if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
152
153 P->digest_length = (uint8_t)outlen;
154 P->key_length = (uint8_t)keylen;
155 P->fanout = 1;
156 P->depth = 1;
157 store32( &P->leaf_length, 0 );
158 store32( &P->node_offset, 0 );
159 store16( &P->xof_length, 0 );
160 P->node_depth = 0;
161 P->inner_length = 0;
162 /* memset(P->reserved, 0, sizeof(P->reserved) ); */
163 memset( P->salt, 0, sizeof( P->salt ) );
164 memset( P->personal, 0, sizeof( P->personal ) );
165
166 if( blake2s_init_param( S, P ) < 0 ) return -1;
167
168 {
169 uint8_t block[BLAKE2S_BLOCKBYTES];
170 memset( block, 0, BLAKE2S_BLOCKBYTES );
171 memcpy( block, key, keylen );
172 blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
173 secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
174 }
175 return 0;
176}
177
178#define G(r,i,a,b,c,d) \
179 do { \
180 a = a + b + m[blake2s_sigma[r][2*i+0]]; \
181 d = rotr32(d ^ a, 16); \
182 c = c + d; \
183 b = rotr32(b ^ c, 12); \
184 a = a + b + m[blake2s_sigma[r][2*i+1]]; \
185 d = rotr32(d ^ a, 8); \
186 c = c + d; \
187 b = rotr32(b ^ c, 7); \
188 } while(0)
189
190#define ROUND(r) \
191 do { \
192 G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
193 G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
194 G(r,2,v[ 2],v[ 6],v[10],v[14]); \
195 G(r,3,v[ 3],v[ 7],v[11],v[15]); \
196 G(r,4,v[ 0],v[ 5],v[10],v[15]); \
197 G(r,5,v[ 1],v[ 6],v[11],v[12]); \
198 G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
199 G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
200 } while(0)
201
202static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] )
203{
204 uint32_t m[16];
205 uint32_t v[16];
206 size_t i;
207
208 for( i = 0; i < 16; ++i ) {
209 m[i] = load32( in + i * sizeof( m[i] ) );
210 }
211
212 for( i = 0; i < 8; ++i ) {
213 v[i] = S->h[i];
214 }
215
216 v[ 8] = blake2s_IV[0];
217 v[ 9] = blake2s_IV[1];
218 v[10] = blake2s_IV[2];
219 v[11] = blake2s_IV[3];
220 v[12] = S->t[0] ^ blake2s_IV[4];
221 v[13] = S->t[1] ^ blake2s_IV[5];
222 v[14] = S->f[0] ^ blake2s_IV[6];
223 v[15] = S->f[1] ^ blake2s_IV[7];
224
225 ROUND( 0 );
226 ROUND( 1 );
227 ROUND( 2 );
228 ROUND( 3 );
229 ROUND( 4 );
230 ROUND( 5 );
231 ROUND( 6 );
232 ROUND( 7 );
233 ROUND( 8 );
234 ROUND( 9 );
235
236 for( i = 0; i < 8; ++i ) {
237 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
238 }
239}
240
241#undef G
242#undef ROUND
243
244int blake2s_update( blake2s_state *S, const void *pin, size_t inlen )
245{
246 const unsigned char * in = (const unsigned char *)pin;
247 if( inlen > 0 )
248 {
249 size_t left = S->buflen;
250 size_t fill = BLAKE2S_BLOCKBYTES - left;
251 if( inlen > fill )
252 {
253 S->buflen = 0;
254 memcpy( S->buf + left, in, fill ); /* Fill buffer */
255 blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
256 blake2s_compress( S, S->buf ); /* Compress */
257 in += fill; inlen -= fill;
258 while(inlen > BLAKE2S_BLOCKBYTES) {
259 blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES);
260 blake2s_compress( S, in );
261 in += BLAKE2S_BLOCKBYTES;
262 inlen -= BLAKE2S_BLOCKBYTES;
263 }
264 }
265 memcpy( S->buf + S->buflen, in, inlen );
266 S->buflen += inlen;
267 }
268 return 0;
269}
270
271int blake2s_final( blake2s_state *S, void *out, size_t outlen )
272{
273 uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
274 size_t i;
275
276 if( out == NULL || outlen < S->outlen )
277 return -1;
278
279 if( blake2s_is_lastblock( S ) )
280 return -1;
281
282 blake2s_increment_counter( S, ( uint32_t )S->buflen );
283 blake2s_set_lastblock( S );
284 memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
285 blake2s_compress( S, S->buf );
286
287 for( i = 0; i < 8; ++i ) // Output full hash to temp buffer
288 store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
289
290 memcpy( out, buffer, outlen );
291 //secure_zero_memory(buffer, sizeof(buffer));
292 return 0;
293}
294
295int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
296{
297 blake2s_state S[1];
298
299 /* Verify parameters */
300 if ( NULL == in && inlen > 0 ) return -1;
301
302 if ( NULL == out ) return -1;
303
304 if ( NULL == key && keylen > 0) return -1;
305
306 if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
307
308 if( keylen > BLAKE2S_KEYBYTES ) return -1;
309
310 if( keylen > 0 )
311 {
312 if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
313 }
314 else
315 {
316 if( blake2s_init( S, outlen ) < 0 ) return -1;
317 }
318
319 blake2s_update( S, ( const uint8_t * )in, inlen );
320 blake2s_final( S, out, outlen );
321 return 0;
322}