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