diff options
Diffstat (limited to 'libbb/yescrypt/alg-sha256.c')
-rw-r--r-- | libbb/yescrypt/alg-sha256.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/libbb/yescrypt/alg-sha256.c b/libbb/yescrypt/alg-sha256.c new file mode 100644 index 000000000..20e8d1ee4 --- /dev/null +++ b/libbb/yescrypt/alg-sha256.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /*- | ||
2 | * Copyright 2005-2016 Colin Percival | ||
3 | * Copyright 2016-2018,2021 Alexander Peslyak | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
19 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
21 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
25 | * SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | /** | ||
29 | * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): | ||
30 | * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and | ||
31 | * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). | ||
32 | */ | ||
33 | static void | ||
34 | PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, | ||
35 | const uint8_t *salt, size_t saltlen, | ||
36 | uint64_t c, uint8_t *buf, size_t dkLen) | ||
37 | { | ||
38 | hmac_ctx_t Phctx, PShctx; | ||
39 | uint32_t i; | ||
40 | |||
41 | /* Compute HMAC state after processing P. */ | ||
42 | hmac_begin(&Phctx, passwd, passwdlen, sha256_begin); | ||
43 | |||
44 | /* Compute HMAC state after processing P and S. */ | ||
45 | PShctx = Phctx; | ||
46 | hmac_hash(&PShctx, salt, saltlen); | ||
47 | |||
48 | /* Iterate through the blocks. */ | ||
49 | for (i = 0; dkLen != 0; ) { | ||
50 | uint64_t U[32 / 8]; | ||
51 | uint64_t T[32 / 8]; | ||
52 | uint64_t j; | ||
53 | uint32_t ivec; | ||
54 | size_t clen; | ||
55 | int k; | ||
56 | |||
57 | /* Generate INT(i). */ | ||
58 | i++; | ||
59 | ivec = SWAP_BE32(i); | ||
60 | |||
61 | /* Compute U_1 = PRF(P, S || INT(i)). */ | ||
62 | hmac_peek_hash(&PShctx, (void*)T, &ivec, 4, NULL); | ||
63 | //TODO: the above is a vararg function, might incur some ABI pain | ||
64 | //does libbb need a non-vararg version with just one (buf,len)? | ||
65 | |||
66 | if (c > 1) { | ||
67 | /* T_i = U_1 ... */ | ||
68 | memcpy(U, T, 32); | ||
69 | for (j = 2; j <= c; j++) { | ||
70 | /* Compute U_j. */ | ||
71 | hmac_peek_hash(&Phctx, (void*)U, U, 32, NULL); | ||
72 | /* ... xor U_j ... */ | ||
73 | for (k = 0; k < 32 / 8; k++) | ||
74 | T[k] ^= U[k]; | ||
75 | //TODO: xorbuf32_aligned_long(T, U); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | /* Copy as many bytes as necessary into buf. */ | ||
80 | clen = dkLen; | ||
81 | if (clen > 32) | ||
82 | clen = 32; | ||
83 | buf = mempcpy(buf, T, clen); | ||
84 | dkLen -= clen; | ||
85 | } | ||
86 | } | ||