"Fossies" - the Fresh Open Source Software Archive 
Member "cryptsetup-2.4.3/lib/crypto_backend/argon2/blake2/blake2b.c" (13 Jan 2022, 12560 Bytes) of package /linux/misc/cryptsetup-2.4.3.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "blake2b.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 * Argon2 reference source code package - reference C implementations
3 *
4 * Copyright 2015
5 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
6 *
7 * You may use this work under the terms of a Creative Commons CC0 1.0
8 * License/Waiver or the Apache Public License 2.0, at your option. The terms of
9 * these licenses can be found at:
10 *
11 * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
12 * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
13 *
14 * You should have received a copy of both of these licenses along with this
15 * software. If not, they may be obtained at the above URLs.
16 */
17
18 #include <stdint.h>
19 #include <string.h>
20 #include <stdio.h>
21
22 #include "blake2.h"
23 #include "blake2-impl.h"
24
25 void clear_internal_memory(void *v, size_t n);
26
27 static const uint64_t blake2b_IV[8] = {
28 UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b),
29 UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1),
30 UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f),
31 UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)};
32
33 static const unsigned int blake2b_sigma[12][16] = {
34 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
35 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
36 {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
37 {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
38 {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
39 {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
40 {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
41 {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
42 {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
43 {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
44 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
45 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
46 };
47
48 static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *S) {
49 S->f[1] = (uint64_t)-1;
50 }
51
52 static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *S) {
53 if (S->last_node) {
54 blake2b_set_lastnode(S);
55 }
56 S->f[0] = (uint64_t)-1;
57 }
58
59 static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S,
60 uint64_t inc) {
61 S->t[0] += inc;
62 S->t[1] += (S->t[0] < inc);
63 }
64
65 static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) {
66 clear_internal_memory(S, sizeof(*S)); /* wipe */
67 blake2b_set_lastblock(S); /* invalidate for further use */
68 }
69
70 static BLAKE2_INLINE void blake2b_init0(blake2b_state *S) {
71 memset(S, 0, sizeof(*S));
72 memcpy(S->h, blake2b_IV, sizeof(S->h));
73 }
74
75 int blake2b_init_param(blake2b_state *S, const blake2b_param *P) {
76 const unsigned char *p = (const unsigned char *)P;
77 unsigned int i;
78
79 if (NULL == P || NULL == S) {
80 return -1;
81 }
82
83 blake2b_init0(S);
84 /* IV XOR Parameter Block */
85 for (i = 0; i < 8; ++i) {
86 S->h[i] ^= load64(&p[i * sizeof(S->h[i])]);
87 }
88 S->outlen = P->digest_length;
89 return 0;
90 }
91
92 /* Sequential blake2b initialization */
93 int blake2b_init(blake2b_state *S, size_t outlen) {
94 blake2b_param P;
95
96 if (S == NULL) {
97 return -1;
98 }
99
100 if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
101 blake2b_invalidate_state(S);
102 return -1;
103 }
104
105 /* Setup Parameter Block for unkeyed BLAKE2 */
106 P.digest_length = (uint8_t)outlen;
107 P.key_length = 0;
108 P.fanout = 1;
109 P.depth = 1;
110 P.leaf_length = 0;
111 P.node_offset = 0;
112 P.node_depth = 0;
113 P.inner_length = 0;
114 memset(P.reserved, 0, sizeof(P.reserved));
115 memset(P.salt, 0, sizeof(P.salt));
116 memset(P.personal, 0, sizeof(P.personal));
117
118 return blake2b_init_param(S, &P);
119 }
120
121 int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
122 size_t keylen) {
123 blake2b_param P;
124
125 if (S == NULL) {
126 return -1;
127 }
128
129 if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
130 blake2b_invalidate_state(S);
131 return -1;
132 }
133
134 if ((key == 0) || (keylen == 0) || (keylen > BLAKE2B_KEYBYTES)) {
135 blake2b_invalidate_state(S);
136 return -1;
137 }
138
139 /* Setup Parameter Block for keyed BLAKE2 */
140 P.digest_length = (uint8_t)outlen;
141 P.key_length = (uint8_t)keylen;
142 P.fanout = 1;
143 P.depth = 1;
144 P.leaf_length = 0;
145 P.node_offset = 0;
146 P.node_depth = 0;
147 P.inner_length = 0;
148 memset(P.reserved, 0, sizeof(P.reserved));
149 memset(P.salt, 0, sizeof(P.salt));
150 memset(P.personal, 0, sizeof(P.personal));
151
152 if (blake2b_init_param(S, &P) < 0) {
153 blake2b_invalidate_state(S);
154 return -1;
155 }
156
157 {
158 uint8_t block[BLAKE2B_BLOCKBYTES];
159 memset(block, 0, BLAKE2B_BLOCKBYTES);
160 memcpy(block, key, keylen);
161 blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
162 /* Burn the key from stack */
163 clear_internal_memory(block, BLAKE2B_BLOCKBYTES);
164 }
165 return 0;
166 }
167
168 static void blake2b_compress(blake2b_state *S, const uint8_t *block) {
169 uint64_t m[16];
170 uint64_t v[16];
171 unsigned int i, r;
172
173 for (i = 0; i < 16; ++i) {
174 m[i] = load64(block + i * sizeof(m[i]));
175 }
176
177 for (i = 0; i < 8; ++i) {
178 v[i] = S->h[i];
179 }
180
181 v[8] = blake2b_IV[0];
182 v[9] = blake2b_IV[1];
183 v[10] = blake2b_IV[2];
184 v[11] = blake2b_IV[3];
185 v[12] = blake2b_IV[4] ^ S->t[0];
186 v[13] = blake2b_IV[5] ^ S->t[1];
187 v[14] = blake2b_IV[6] ^ S->f[0];
188 v[15] = blake2b_IV[7] ^ S->f[1];
189
190 #define G(r, i, a, b, c, d) \
191 do { \
192 a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
193 d = rotr64(d ^ a, 32); \
194 c = c + d; \
195 b = rotr64(b ^ c, 24); \
196 a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
197 d = rotr64(d ^ a, 16); \
198 c = c + d; \
199 b = rotr64(b ^ c, 63); \
200 } while ((void)0, 0)
201
202 #define ROUND(r) \
203 do { \
204 G(r, 0, v[0], v[4], v[8], v[12]); \
205 G(r, 1, v[1], v[5], v[9], v[13]); \
206 G(r, 2, v[2], v[6], v[10], v[14]); \
207 G(r, 3, v[3], v[7], v[11], v[15]); \
208 G(r, 4, v[0], v[5], v[10], v[15]); \
209 G(r, 5, v[1], v[6], v[11], v[12]); \
210 G(r, 6, v[2], v[7], v[8], v[13]); \
211 G(r, 7, v[3], v[4], v[9], v[14]); \
212 } while ((void)0, 0)
213
214 for (r = 0; r < 12; ++r) {
215 ROUND(r);
216 }
217
218 for (i = 0; i < 8; ++i) {
219 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
220 }
221
222 #undef G
223 #undef ROUND
224 }
225
226 int blake2b_update(blake2b_state *S, const void *in, size_t inlen) {
227 const uint8_t *pin = (const uint8_t *)in;
228
229 if (inlen == 0) {
230 return 0;
231 }
232
233 /* Sanity check */
234 if (S == NULL || in == NULL) {
235 return -1;
236 }
237
238 /* Is this a reused state? */
239 if (S->f[0] != 0) {
240 return -1;
241 }
242
243 if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) {
244 /* Complete current block */
245 size_t left = S->buflen;
246 size_t fill = BLAKE2B_BLOCKBYTES - left;
247 memcpy(&S->buf[left], pin, fill);
248 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
249 blake2b_compress(S, S->buf);
250 S->buflen = 0;
251 inlen -= fill;
252 pin += fill;
253 /* Avoid buffer copies when possible */
254 while (inlen > BLAKE2B_BLOCKBYTES) {
255 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
256 blake2b_compress(S, pin);
257 inlen -= BLAKE2B_BLOCKBYTES;
258 pin += BLAKE2B_BLOCKBYTES;
259 }
260 }
261 memcpy(&S->buf[S->buflen], pin, inlen);
262 S->buflen += (unsigned int)inlen;
263 return 0;
264 }
265
266 int blake2b_final(blake2b_state *S, void *out, size_t outlen) {
267 uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
268 unsigned int i;
269
270 /* Sanity checks */
271 if (S == NULL || out == NULL || outlen < S->outlen) {
272 return -1;
273 }
274
275 /* Is this a reused state? */
276 if (S->f[0] != 0) {
277 return -1;
278 }
279
280 blake2b_increment_counter(S, S->buflen);
281 blake2b_set_lastblock(S);
282 memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
283 blake2b_compress(S, S->buf);
284
285 for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */
286 store64(buffer + sizeof(S->h[i]) * i, S->h[i]);
287 }
288
289 memcpy(out, buffer, S->outlen);
290 clear_internal_memory(buffer, sizeof(buffer));
291 clear_internal_memory(S->buf, sizeof(S->buf));
292 clear_internal_memory(S->h, sizeof(S->h));
293 return 0;
294 }
295
296 int blake2b(void *out, size_t outlen, const void *in, size_t inlen,
297 const void *key, size_t keylen) {
298 blake2b_state S;
299 int ret = -1;
300
301 /* Verify parameters */
302 if (NULL == in && inlen > 0) {
303 goto fail;
304 }
305
306 if (NULL == out || outlen == 0 || outlen > BLAKE2B_OUTBYTES) {
307 goto fail;
308 }
309
310 if ((NULL == key && keylen > 0) || keylen > BLAKE2B_KEYBYTES) {
311 goto fail;
312 }
313
314 if (keylen > 0) {
315 if (blake2b_init_key(&S, outlen, key, keylen) < 0) {
316 goto fail;
317 }
318 } else {
319 if (blake2b_init(&S, outlen) < 0) {
320 goto fail;
321 }
322 }
323
324 if (blake2b_update(&S, in, inlen) < 0) {
325 goto fail;
326 }
327 ret = blake2b_final(&S, out, outlen);
328
329 fail:
330 clear_internal_memory(&S, sizeof(S));
331 return ret;
332 }
333
334 /* Argon2 Team - Begin Code */
335 int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) {
336 uint8_t *out = (uint8_t *)pout;
337 blake2b_state blake_state;
338 uint8_t outlen_bytes[sizeof(uint32_t)] = {0};
339 int ret = -1;
340
341 if (outlen > UINT32_MAX) {
342 goto fail;
343 }
344
345 /* Ensure little-endian byte order! */
346 store32(outlen_bytes, (uint32_t)outlen);
347
348 #define TRY(statement) \
349 do { \
350 ret = statement; \
351 if (ret < 0) { \
352 goto fail; \
353 } \
354 } while ((void)0, 0)
355
356 if (outlen <= BLAKE2B_OUTBYTES) {
357 TRY(blake2b_init(&blake_state, outlen));
358 TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
359 TRY(blake2b_update(&blake_state, in, inlen));
360 TRY(blake2b_final(&blake_state, out, outlen));
361 } else {
362 uint32_t toproduce;
363 uint8_t out_buffer[BLAKE2B_OUTBYTES];
364 uint8_t in_buffer[BLAKE2B_OUTBYTES];
365 TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES));
366 TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
367 TRY(blake2b_update(&blake_state, in, inlen));
368 TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES));
369 memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
370 out += BLAKE2B_OUTBYTES / 2;
371 toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2;
372
373 while (toproduce > BLAKE2B_OUTBYTES) {
374 memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
375 TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer,
376 BLAKE2B_OUTBYTES, NULL, 0));
377 memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
378 out += BLAKE2B_OUTBYTES / 2;
379 toproduce -= BLAKE2B_OUTBYTES / 2;
380 }
381
382 memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
383 TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL,
384 0));
385 memcpy(out, out_buffer, toproduce);
386 }
387 fail:
388 clear_internal_memory(&blake_state, sizeof(blake_state));
389 return ret;
390 #undef TRY
391 }
392 /* Argon2 Team - End Code */