/src/trezor-firmware/crypto/blake256.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | BLAKE reference C implementation |
3 | | |
4 | | Copyright (c) 2012 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com> |
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 | | #include "blake256.h" |
14 | | |
15 | | #include <string.h> |
16 | | |
17 | | #define U8TO32_BIG(p) \ |
18 | 0 | (((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) | \ |
19 | 0 | ((uint32_t)((p)[2]) << 8) | ((uint32_t)((p)[3]) )) |
20 | | |
21 | | #define U32TO8_BIG(p, v) \ |
22 | 0 | (p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \ |
23 | 0 | (p)[2] = (uint8_t)((v) >> 8); (p)[3] = (uint8_t)((v) ); |
24 | | |
25 | | static const uint8_t sigma[][16] = |
26 | | { |
27 | | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, |
28 | | {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, |
29 | | {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, |
30 | | { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, |
31 | | { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, |
32 | | { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, |
33 | | {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, |
34 | | {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, |
35 | | { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, |
36 | | {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 }, |
37 | | { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, |
38 | | {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, |
39 | | {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, |
40 | | { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, |
41 | | { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, |
42 | | { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } |
43 | | }; |
44 | | |
45 | | static const uint32_t u256[16] = |
46 | | { |
47 | | 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, |
48 | | 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, |
49 | | 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, |
50 | | 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917 |
51 | | }; |
52 | | |
53 | | static const uint8_t padding[129] = |
54 | | { |
55 | | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
56 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
57 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
58 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
59 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
60 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
61 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
62 | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
63 | | }; |
64 | | |
65 | | static void blake256_compress( BLAKE256_CTX *S, const uint8_t *block ) |
66 | 0 | { |
67 | 0 | uint32_t v[16] = {0}, m[16] = {0}, i = 0; |
68 | 0 | #define ROT(x,n) (((x)<<(32-n))|( (x)>>(n))) |
69 | 0 | #define G(a,b,c,d,e) \ |
70 | 0 | v[a] += (m[sigma[i][e]] ^ u256[sigma[i][e+1]]) + v[b]; \ |
71 | 0 | v[d] = ROT( v[d] ^ v[a],16); \ |
72 | 0 | v[c] += v[d]; \ |
73 | 0 | v[b] = ROT( v[b] ^ v[c],12); \ |
74 | 0 | v[a] += (m[sigma[i][e+1]] ^ u256[sigma[i][e]])+v[b]; \ |
75 | 0 | v[d] = ROT( v[d] ^ v[a], 8); \ |
76 | 0 | v[c] += v[d]; \ |
77 | 0 | v[b] = ROT( v[b] ^ v[c], 7); |
78 | |
|
79 | 0 | for( i = 0; i < 16; ++i ) m[i] = U8TO32_BIG( block + i * 4 ); |
80 | |
|
81 | 0 | for( i = 0; i < 8; ++i ) v[i] = S->h[i]; |
82 | |
|
83 | 0 | v[ 8] = S->s[0] ^ u256[0]; |
84 | 0 | v[ 9] = S->s[1] ^ u256[1]; |
85 | 0 | v[10] = S->s[2] ^ u256[2]; |
86 | 0 | v[11] = S->s[3] ^ u256[3]; |
87 | 0 | v[12] = u256[4]; |
88 | 0 | v[13] = u256[5]; |
89 | 0 | v[14] = u256[6]; |
90 | 0 | v[15] = u256[7]; |
91 | | |
92 | | /* don't xor t when the block is only padding */ |
93 | 0 | if ( !S->nullt ) |
94 | 0 | { |
95 | 0 | v[12] ^= S->t[0]; |
96 | 0 | v[13] ^= S->t[0]; |
97 | 0 | v[14] ^= S->t[1]; |
98 | 0 | v[15] ^= S->t[1]; |
99 | 0 | } |
100 | |
|
101 | 0 | for( i = 0; i < 14; ++i ) |
102 | 0 | { |
103 | | /* column step */ |
104 | 0 | G( 0, 4, 8, 12, 0 ); |
105 | 0 | G( 1, 5, 9, 13, 2 ); |
106 | 0 | G( 2, 6, 10, 14, 4 ); |
107 | 0 | G( 3, 7, 11, 15, 6 ); |
108 | | /* diagonal step */ |
109 | 0 | G( 0, 5, 10, 15, 8 ); |
110 | 0 | G( 1, 6, 11, 12, 10 ); |
111 | 0 | G( 2, 7, 8, 13, 12 ); |
112 | 0 | G( 3, 4, 9, 14, 14 ); |
113 | 0 | } |
114 | |
|
115 | 0 | for( i = 0; i < 16; ++i ) S->h[i % 8] ^= v[i]; |
116 | |
|
117 | 0 | for( i = 0; i < 8 ; ++i ) S->h[i] ^= S->s[i % 4]; |
118 | 0 | } |
119 | | |
120 | | |
121 | | void blake256_Init( BLAKE256_CTX *S ) |
122 | 0 | { |
123 | 0 | S->h[0] = 0x6a09e667; |
124 | 0 | S->h[1] = 0xbb67ae85; |
125 | 0 | S->h[2] = 0x3c6ef372; |
126 | 0 | S->h[3] = 0xa54ff53a; |
127 | 0 | S->h[4] = 0x510e527f; |
128 | 0 | S->h[5] = 0x9b05688c; |
129 | 0 | S->h[6] = 0x1f83d9ab; |
130 | 0 | S->h[7] = 0x5be0cd19; |
131 | 0 | S->t[0] = S->t[1] = S->buflen = S->nullt = 0; |
132 | 0 | S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0; |
133 | 0 | } |
134 | | |
135 | | |
136 | | void blake256_Update( BLAKE256_CTX *S, const uint8_t *in, size_t inlen ) |
137 | 0 | { |
138 | 0 | size_t left = S->buflen; |
139 | 0 | size_t fill = 64 - left; |
140 | | |
141 | | /* data left and data received fill a block */ |
142 | 0 | if( left && ( inlen >= fill ) ) |
143 | 0 | { |
144 | 0 | memcpy( ( void * ) ( S->buf + left ), ( void * ) in, fill ); |
145 | 0 | S->t[0] += 512; |
146 | |
|
147 | 0 | if ( S->t[0] == 0 ) S->t[1]++; |
148 | |
|
149 | 0 | blake256_compress( S, S->buf ); |
150 | 0 | in += fill; |
151 | 0 | inlen -= fill; |
152 | 0 | left = 0; |
153 | 0 | } |
154 | | |
155 | | /* compress blocks of data received */ |
156 | 0 | while( inlen >= 64 ) |
157 | 0 | { |
158 | 0 | S->t[0] += 512; |
159 | |
|
160 | 0 | if ( S->t[0] == 0 ) S->t[1]++; |
161 | |
|
162 | 0 | blake256_compress( S, in ); |
163 | 0 | in += 64; |
164 | 0 | inlen -= 64; |
165 | 0 | } |
166 | | |
167 | | /* store any data left */ |
168 | 0 | if( inlen > 0 ) |
169 | 0 | { |
170 | 0 | memcpy( ( void * ) ( S->buf + left ), \ |
171 | 0 | ( void * ) in, ( size_t ) inlen ); |
172 | 0 | } |
173 | 0 | S->buflen = left + inlen; |
174 | 0 | } |
175 | | |
176 | | |
177 | | void blake256_Final( BLAKE256_CTX *S, uint8_t *out ) |
178 | 0 | { |
179 | 0 | uint8_t msglen[8] = {0}, zo = 0x01, oo = 0x81; |
180 | 0 | uint32_t lo = S->t[0] + ( S->buflen << 3 ), hi = S->t[1]; |
181 | | |
182 | | /* support for hashing more than 2^32 bits */ |
183 | 0 | if ( lo < ( S->buflen << 3 ) ) hi++; |
184 | |
|
185 | 0 | U32TO8_BIG( msglen + 0, hi ); |
186 | 0 | U32TO8_BIG( msglen + 4, lo ); |
187 | |
|
188 | 0 | if ( S->buflen == 55 ) /* one padding byte */ |
189 | 0 | { |
190 | 0 | S->t[0] -= 8; |
191 | 0 | blake256_Update( S, &oo, 1 ); |
192 | 0 | } |
193 | 0 | else |
194 | 0 | { |
195 | 0 | if ( S->buflen < 55 ) /* enough space to fill the block */ |
196 | 0 | { |
197 | 0 | if ( !S->buflen ) S->nullt = 1; |
198 | |
|
199 | 0 | S->t[0] -= 440 - ( S->buflen << 3 ); |
200 | 0 | blake256_Update( S, padding, 55 - S->buflen ); |
201 | 0 | } |
202 | 0 | else /* need 2 compressions */ |
203 | 0 | { |
204 | 0 | S->t[0] -= 512 - ( S->buflen << 3 ); |
205 | 0 | blake256_Update( S, padding, 64 - S->buflen ); |
206 | 0 | S->t[0] -= 440; |
207 | 0 | blake256_Update( S, padding + 1, 55 ); |
208 | 0 | S->nullt = 1; |
209 | 0 | } |
210 | |
|
211 | 0 | blake256_Update( S, &zo, 1 ); |
212 | 0 | S->t[0] -= 8; |
213 | 0 | } |
214 | |
|
215 | 0 | S->t[0] -= 64; |
216 | 0 | blake256_Update( S, msglen, 8 ); |
217 | 0 | U32TO8_BIG( out + 0, S->h[0] ); |
218 | 0 | U32TO8_BIG( out + 4, S->h[1] ); |
219 | 0 | U32TO8_BIG( out + 8, S->h[2] ); |
220 | 0 | U32TO8_BIG( out + 12, S->h[3] ); |
221 | 0 | U32TO8_BIG( out + 16, S->h[4] ); |
222 | 0 | U32TO8_BIG( out + 20, S->h[5] ); |
223 | 0 | U32TO8_BIG( out + 24, S->h[6] ); |
224 | 0 | U32TO8_BIG( out + 28, S->h[7] ); |
225 | 0 | } |
226 | | |
227 | | |
228 | | void blake256( const uint8_t *in, size_t inlen, uint8_t *out ) |
229 | 0 | { |
230 | 0 | BLAKE256_CTX S = {0}; |
231 | 0 | blake256_Init( &S ); |
232 | 0 | blake256_Update( &S, in, inlen ); |
233 | 0 | blake256_Final( &S, out ); |
234 | 0 | } |