1*cd192fa9SAndroid Build Coastguard Worker /*-
2*cd192fa9SAndroid Build Coastguard Worker * Copyright 2009 Colin Percival
3*cd192fa9SAndroid Build Coastguard Worker * All rights reserved.
4*cd192fa9SAndroid Build Coastguard Worker *
5*cd192fa9SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*cd192fa9SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
7*cd192fa9SAndroid Build Coastguard Worker * are met:
8*cd192fa9SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
9*cd192fa9SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
10*cd192fa9SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
11*cd192fa9SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
12*cd192fa9SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
13*cd192fa9SAndroid Build Coastguard Worker *
14*cd192fa9SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*cd192fa9SAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*cd192fa9SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*cd192fa9SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*cd192fa9SAndroid Build Coastguard Worker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*cd192fa9SAndroid Build Coastguard Worker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*cd192fa9SAndroid Build Coastguard Worker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*cd192fa9SAndroid Build Coastguard Worker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*cd192fa9SAndroid Build Coastguard Worker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*cd192fa9SAndroid Build Coastguard Worker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*cd192fa9SAndroid Build Coastguard Worker * SUCH DAMAGE.
25*cd192fa9SAndroid Build Coastguard Worker *
26*cd192fa9SAndroid Build Coastguard Worker * This file was originally written by Colin Percival as part of the Tarsnap
27*cd192fa9SAndroid Build Coastguard Worker * online backup system.
28*cd192fa9SAndroid Build Coastguard Worker */
29*cd192fa9SAndroid Build Coastguard Worker #include "scrypt_platform.h"
30*cd192fa9SAndroid Build Coastguard Worker
31*cd192fa9SAndroid Build Coastguard Worker #include <sys/types.h>
32*cd192fa9SAndroid Build Coastguard Worker #ifndef _WIN32
33*cd192fa9SAndroid Build Coastguard Worker #include <sys/mman.h>
34*cd192fa9SAndroid Build Coastguard Worker #endif
35*cd192fa9SAndroid Build Coastguard Worker
36*cd192fa9SAndroid Build Coastguard Worker #include <emmintrin.h>
37*cd192fa9SAndroid Build Coastguard Worker #include <errno.h>
38*cd192fa9SAndroid Build Coastguard Worker #include <stdint.h>
39*cd192fa9SAndroid Build Coastguard Worker #include <stdlib.h>
40*cd192fa9SAndroid Build Coastguard Worker #include <string.h>
41*cd192fa9SAndroid Build Coastguard Worker
42*cd192fa9SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_PBKDF2
43*cd192fa9SAndroid Build Coastguard Worker #include <openssl/evp.h>
44*cd192fa9SAndroid Build Coastguard Worker #else
45*cd192fa9SAndroid Build Coastguard Worker #include "sha256.h"
46*cd192fa9SAndroid Build Coastguard Worker #endif
47*cd192fa9SAndroid Build Coastguard Worker #include "sysendian.h"
48*cd192fa9SAndroid Build Coastguard Worker
49*cd192fa9SAndroid Build Coastguard Worker #include "crypto_scrypt.h"
50*cd192fa9SAndroid Build Coastguard Worker
51*cd192fa9SAndroid Build Coastguard Worker static void blkcpy(void *, void *, size_t);
52*cd192fa9SAndroid Build Coastguard Worker static void blkxor(void *, void *, size_t);
53*cd192fa9SAndroid Build Coastguard Worker static void salsa20_8(__m128i *);
54*cd192fa9SAndroid Build Coastguard Worker static void blockmix_salsa8(__m128i *, __m128i *, __m128i *, size_t);
55*cd192fa9SAndroid Build Coastguard Worker static uint64_t integerify(void *, size_t);
56*cd192fa9SAndroid Build Coastguard Worker static void smix(uint8_t *, size_t, uint64_t, void *, void *);
57*cd192fa9SAndroid Build Coastguard Worker
58*cd192fa9SAndroid Build Coastguard Worker static void
blkcpy(void * dest,void * src,size_t len)59*cd192fa9SAndroid Build Coastguard Worker blkcpy(void * dest, void * src, size_t len)
60*cd192fa9SAndroid Build Coastguard Worker {
61*cd192fa9SAndroid Build Coastguard Worker __m128i * D = dest;
62*cd192fa9SAndroid Build Coastguard Worker __m128i * S = src;
63*cd192fa9SAndroid Build Coastguard Worker size_t L = len / 16;
64*cd192fa9SAndroid Build Coastguard Worker size_t i;
65*cd192fa9SAndroid Build Coastguard Worker
66*cd192fa9SAndroid Build Coastguard Worker for (i = 0; i < L; i++)
67*cd192fa9SAndroid Build Coastguard Worker D[i] = S[i];
68*cd192fa9SAndroid Build Coastguard Worker }
69*cd192fa9SAndroid Build Coastguard Worker
70*cd192fa9SAndroid Build Coastguard Worker static void
blkxor(void * dest,void * src,size_t len)71*cd192fa9SAndroid Build Coastguard Worker blkxor(void * dest, void * src, size_t len)
72*cd192fa9SAndroid Build Coastguard Worker {
73*cd192fa9SAndroid Build Coastguard Worker __m128i * D = dest;
74*cd192fa9SAndroid Build Coastguard Worker __m128i * S = src;
75*cd192fa9SAndroid Build Coastguard Worker size_t L = len / 16;
76*cd192fa9SAndroid Build Coastguard Worker size_t i;
77*cd192fa9SAndroid Build Coastguard Worker
78*cd192fa9SAndroid Build Coastguard Worker for (i = 0; i < L; i++)
79*cd192fa9SAndroid Build Coastguard Worker D[i] = _mm_xor_si128(D[i], S[i]);
80*cd192fa9SAndroid Build Coastguard Worker }
81*cd192fa9SAndroid Build Coastguard Worker
82*cd192fa9SAndroid Build Coastguard Worker /**
83*cd192fa9SAndroid Build Coastguard Worker * salsa20_8(B):
84*cd192fa9SAndroid Build Coastguard Worker * Apply the salsa20/8 core to the provided block.
85*cd192fa9SAndroid Build Coastguard Worker */
86*cd192fa9SAndroid Build Coastguard Worker static void
salsa20_8(__m128i B[4])87*cd192fa9SAndroid Build Coastguard Worker salsa20_8(__m128i B[4])
88*cd192fa9SAndroid Build Coastguard Worker {
89*cd192fa9SAndroid Build Coastguard Worker __m128i X0, X1, X2, X3;
90*cd192fa9SAndroid Build Coastguard Worker __m128i T;
91*cd192fa9SAndroid Build Coastguard Worker size_t i;
92*cd192fa9SAndroid Build Coastguard Worker
93*cd192fa9SAndroid Build Coastguard Worker X0 = B[0];
94*cd192fa9SAndroid Build Coastguard Worker X1 = B[1];
95*cd192fa9SAndroid Build Coastguard Worker X2 = B[2];
96*cd192fa9SAndroid Build Coastguard Worker X3 = B[3];
97*cd192fa9SAndroid Build Coastguard Worker
98*cd192fa9SAndroid Build Coastguard Worker for (i = 0; i < 8; i += 2) {
99*cd192fa9SAndroid Build Coastguard Worker /* Operate on "columns". */
100*cd192fa9SAndroid Build Coastguard Worker T = _mm_add_epi32(X0, X3);
101*cd192fa9SAndroid Build Coastguard Worker X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 7));
102*cd192fa9SAndroid Build Coastguard Worker X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 25));
103*cd192fa9SAndroid Build Coastguard Worker T = _mm_add_epi32(X1, X0);
104*cd192fa9SAndroid Build Coastguard Worker X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
105*cd192fa9SAndroid Build Coastguard Worker X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
106*cd192fa9SAndroid Build Coastguard Worker T = _mm_add_epi32(X2, X1);
107*cd192fa9SAndroid Build Coastguard Worker X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 13));
108*cd192fa9SAndroid Build Coastguard Worker X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 19));
109*cd192fa9SAndroid Build Coastguard Worker T = _mm_add_epi32(X3, X2);
110*cd192fa9SAndroid Build Coastguard Worker X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
111*cd192fa9SAndroid Build Coastguard Worker X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
112*cd192fa9SAndroid Build Coastguard Worker
113*cd192fa9SAndroid Build Coastguard Worker /* Rearrange data. */
114*cd192fa9SAndroid Build Coastguard Worker X1 = _mm_shuffle_epi32(X1, 0x93);
115*cd192fa9SAndroid Build Coastguard Worker X2 = _mm_shuffle_epi32(X2, 0x4E);
116*cd192fa9SAndroid Build Coastguard Worker X3 = _mm_shuffle_epi32(X3, 0x39);
117*cd192fa9SAndroid Build Coastguard Worker
118*cd192fa9SAndroid Build Coastguard Worker /* Operate on "rows". */
119*cd192fa9SAndroid Build Coastguard Worker T = _mm_add_epi32(X0, X1);
120*cd192fa9SAndroid Build Coastguard Worker X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 7));
121*cd192fa9SAndroid Build Coastguard Worker X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 25));
122*cd192fa9SAndroid Build Coastguard Worker T = _mm_add_epi32(X3, X0);
123*cd192fa9SAndroid Build Coastguard Worker X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
124*cd192fa9SAndroid Build Coastguard Worker X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
125*cd192fa9SAndroid Build Coastguard Worker T = _mm_add_epi32(X2, X3);
126*cd192fa9SAndroid Build Coastguard Worker X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 13));
127*cd192fa9SAndroid Build Coastguard Worker X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 19));
128*cd192fa9SAndroid Build Coastguard Worker T = _mm_add_epi32(X1, X2);
129*cd192fa9SAndroid Build Coastguard Worker X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
130*cd192fa9SAndroid Build Coastguard Worker X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
131*cd192fa9SAndroid Build Coastguard Worker
132*cd192fa9SAndroid Build Coastguard Worker /* Rearrange data. */
133*cd192fa9SAndroid Build Coastguard Worker X1 = _mm_shuffle_epi32(X1, 0x39);
134*cd192fa9SAndroid Build Coastguard Worker X2 = _mm_shuffle_epi32(X2, 0x4E);
135*cd192fa9SAndroid Build Coastguard Worker X3 = _mm_shuffle_epi32(X3, 0x93);
136*cd192fa9SAndroid Build Coastguard Worker }
137*cd192fa9SAndroid Build Coastguard Worker
138*cd192fa9SAndroid Build Coastguard Worker B[0] = _mm_add_epi32(B[0], X0);
139*cd192fa9SAndroid Build Coastguard Worker B[1] = _mm_add_epi32(B[1], X1);
140*cd192fa9SAndroid Build Coastguard Worker B[2] = _mm_add_epi32(B[2], X2);
141*cd192fa9SAndroid Build Coastguard Worker B[3] = _mm_add_epi32(B[3], X3);
142*cd192fa9SAndroid Build Coastguard Worker }
143*cd192fa9SAndroid Build Coastguard Worker
144*cd192fa9SAndroid Build Coastguard Worker /**
145*cd192fa9SAndroid Build Coastguard Worker * blockmix_salsa8(Bin, Bout, X, r):
146*cd192fa9SAndroid Build Coastguard Worker * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
147*cd192fa9SAndroid Build Coastguard Worker * bytes in length; the output Bout must also be the same size. The
148*cd192fa9SAndroid Build Coastguard Worker * temporary space X must be 64 bytes.
149*cd192fa9SAndroid Build Coastguard Worker */
150*cd192fa9SAndroid Build Coastguard Worker static void
blockmix_salsa8(__m128i * Bin,__m128i * Bout,__m128i * X,size_t r)151*cd192fa9SAndroid Build Coastguard Worker blockmix_salsa8(__m128i * Bin, __m128i * Bout, __m128i * X, size_t r)
152*cd192fa9SAndroid Build Coastguard Worker {
153*cd192fa9SAndroid Build Coastguard Worker size_t i;
154*cd192fa9SAndroid Build Coastguard Worker
155*cd192fa9SAndroid Build Coastguard Worker /* 1: X <-- B_{2r - 1} */
156*cd192fa9SAndroid Build Coastguard Worker blkcpy(X, &Bin[8 * r - 4], 64);
157*cd192fa9SAndroid Build Coastguard Worker
158*cd192fa9SAndroid Build Coastguard Worker /* 2: for i = 0 to 2r - 1 do */
159*cd192fa9SAndroid Build Coastguard Worker for (i = 0; i < r; i++) {
160*cd192fa9SAndroid Build Coastguard Worker /* 3: X <-- H(X \xor B_i) */
161*cd192fa9SAndroid Build Coastguard Worker blkxor(X, &Bin[i * 8], 64);
162*cd192fa9SAndroid Build Coastguard Worker salsa20_8(X);
163*cd192fa9SAndroid Build Coastguard Worker
164*cd192fa9SAndroid Build Coastguard Worker /* 4: Y_i <-- X */
165*cd192fa9SAndroid Build Coastguard Worker /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
166*cd192fa9SAndroid Build Coastguard Worker blkcpy(&Bout[i * 4], X, 64);
167*cd192fa9SAndroid Build Coastguard Worker
168*cd192fa9SAndroid Build Coastguard Worker /* 3: X <-- H(X \xor B_i) */
169*cd192fa9SAndroid Build Coastguard Worker blkxor(X, &Bin[i * 8 + 4], 64);
170*cd192fa9SAndroid Build Coastguard Worker salsa20_8(X);
171*cd192fa9SAndroid Build Coastguard Worker
172*cd192fa9SAndroid Build Coastguard Worker /* 4: Y_i <-- X */
173*cd192fa9SAndroid Build Coastguard Worker /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
174*cd192fa9SAndroid Build Coastguard Worker blkcpy(&Bout[(r + i) * 4], X, 64);
175*cd192fa9SAndroid Build Coastguard Worker }
176*cd192fa9SAndroid Build Coastguard Worker }
177*cd192fa9SAndroid Build Coastguard Worker
178*cd192fa9SAndroid Build Coastguard Worker /**
179*cd192fa9SAndroid Build Coastguard Worker * integerify(B, r):
180*cd192fa9SAndroid Build Coastguard Worker * Return the result of parsing B_{2r-1} as a little-endian integer.
181*cd192fa9SAndroid Build Coastguard Worker */
182*cd192fa9SAndroid Build Coastguard Worker static uint64_t
integerify(void * B,size_t r)183*cd192fa9SAndroid Build Coastguard Worker integerify(void * B, size_t r)
184*cd192fa9SAndroid Build Coastguard Worker {
185*cd192fa9SAndroid Build Coastguard Worker uint32_t * X = (void *)((uintptr_t)(B) + (2 * r - 1) * 64);
186*cd192fa9SAndroid Build Coastguard Worker
187*cd192fa9SAndroid Build Coastguard Worker return (((uint64_t)(X[13]) << 32) + X[0]);
188*cd192fa9SAndroid Build Coastguard Worker }
189*cd192fa9SAndroid Build Coastguard Worker
190*cd192fa9SAndroid Build Coastguard Worker /**
191*cd192fa9SAndroid Build Coastguard Worker * smix(B, r, N, V, XY):
192*cd192fa9SAndroid Build Coastguard Worker * Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
193*cd192fa9SAndroid Build Coastguard Worker * the temporary storage V must be 128rN bytes in length; the temporary
194*cd192fa9SAndroid Build Coastguard Worker * storage XY must be 256r + 64 bytes in length. The value N must be a
195*cd192fa9SAndroid Build Coastguard Worker * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
196*cd192fa9SAndroid Build Coastguard Worker * multiple of 64 bytes.
197*cd192fa9SAndroid Build Coastguard Worker */
198*cd192fa9SAndroid Build Coastguard Worker static void
smix(uint8_t * B,size_t r,uint64_t N,void * V,void * XY)199*cd192fa9SAndroid Build Coastguard Worker smix(uint8_t * B, size_t r, uint64_t N, void * V, void * XY)
200*cd192fa9SAndroid Build Coastguard Worker {
201*cd192fa9SAndroid Build Coastguard Worker __m128i * X = XY;
202*cd192fa9SAndroid Build Coastguard Worker __m128i * Y = (void *)((uintptr_t)(XY) + 128 * r);
203*cd192fa9SAndroid Build Coastguard Worker __m128i * Z = (void *)((uintptr_t)(XY) + 256 * r);
204*cd192fa9SAndroid Build Coastguard Worker uint32_t * X32 = (void *)X;
205*cd192fa9SAndroid Build Coastguard Worker uint64_t i, j;
206*cd192fa9SAndroid Build Coastguard Worker size_t k;
207*cd192fa9SAndroid Build Coastguard Worker
208*cd192fa9SAndroid Build Coastguard Worker /* 1: X <-- B */
209*cd192fa9SAndroid Build Coastguard Worker for (k = 0; k < 2 * r; k++) {
210*cd192fa9SAndroid Build Coastguard Worker for (i = 0; i < 16; i++) {
211*cd192fa9SAndroid Build Coastguard Worker X32[k * 16 + i] =
212*cd192fa9SAndroid Build Coastguard Worker le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]);
213*cd192fa9SAndroid Build Coastguard Worker }
214*cd192fa9SAndroid Build Coastguard Worker }
215*cd192fa9SAndroid Build Coastguard Worker
216*cd192fa9SAndroid Build Coastguard Worker /* 2: for i = 0 to N - 1 do */
217*cd192fa9SAndroid Build Coastguard Worker for (i = 0; i < N; i += 2) {
218*cd192fa9SAndroid Build Coastguard Worker /* 3: V_i <-- X */
219*cd192fa9SAndroid Build Coastguard Worker blkcpy((void *)((uintptr_t)(V) + i * 128 * r), X, 128 * r);
220*cd192fa9SAndroid Build Coastguard Worker
221*cd192fa9SAndroid Build Coastguard Worker /* 4: X <-- H(X) */
222*cd192fa9SAndroid Build Coastguard Worker blockmix_salsa8(X, Y, Z, r);
223*cd192fa9SAndroid Build Coastguard Worker
224*cd192fa9SAndroid Build Coastguard Worker /* 3: V_i <-- X */
225*cd192fa9SAndroid Build Coastguard Worker blkcpy((void *)((uintptr_t)(V) + (i + 1) * 128 * r),
226*cd192fa9SAndroid Build Coastguard Worker Y, 128 * r);
227*cd192fa9SAndroid Build Coastguard Worker
228*cd192fa9SAndroid Build Coastguard Worker /* 4: X <-- H(X) */
229*cd192fa9SAndroid Build Coastguard Worker blockmix_salsa8(Y, X, Z, r);
230*cd192fa9SAndroid Build Coastguard Worker }
231*cd192fa9SAndroid Build Coastguard Worker
232*cd192fa9SAndroid Build Coastguard Worker /* 6: for i = 0 to N - 1 do */
233*cd192fa9SAndroid Build Coastguard Worker for (i = 0; i < N; i += 2) {
234*cd192fa9SAndroid Build Coastguard Worker /* 7: j <-- Integerify(X) mod N */
235*cd192fa9SAndroid Build Coastguard Worker j = integerify(X, r) & (N - 1);
236*cd192fa9SAndroid Build Coastguard Worker
237*cd192fa9SAndroid Build Coastguard Worker /* 8: X <-- H(X \xor V_j) */
238*cd192fa9SAndroid Build Coastguard Worker blkxor(X, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
239*cd192fa9SAndroid Build Coastguard Worker blockmix_salsa8(X, Y, Z, r);
240*cd192fa9SAndroid Build Coastguard Worker
241*cd192fa9SAndroid Build Coastguard Worker /* 7: j <-- Integerify(X) mod N */
242*cd192fa9SAndroid Build Coastguard Worker j = integerify(Y, r) & (N - 1);
243*cd192fa9SAndroid Build Coastguard Worker
244*cd192fa9SAndroid Build Coastguard Worker /* 8: X <-- H(X \xor V_j) */
245*cd192fa9SAndroid Build Coastguard Worker blkxor(Y, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
246*cd192fa9SAndroid Build Coastguard Worker blockmix_salsa8(Y, X, Z, r);
247*cd192fa9SAndroid Build Coastguard Worker }
248*cd192fa9SAndroid Build Coastguard Worker
249*cd192fa9SAndroid Build Coastguard Worker /* 10: B' <-- X */
250*cd192fa9SAndroid Build Coastguard Worker for (k = 0; k < 2 * r; k++) {
251*cd192fa9SAndroid Build Coastguard Worker for (i = 0; i < 16; i++) {
252*cd192fa9SAndroid Build Coastguard Worker le32enc(&B[(k * 16 + (i * 5 % 16)) * 4],
253*cd192fa9SAndroid Build Coastguard Worker X32[k * 16 + i]);
254*cd192fa9SAndroid Build Coastguard Worker }
255*cd192fa9SAndroid Build Coastguard Worker }
256*cd192fa9SAndroid Build Coastguard Worker }
257*cd192fa9SAndroid Build Coastguard Worker
258*cd192fa9SAndroid Build Coastguard Worker /**
259*cd192fa9SAndroid Build Coastguard Worker * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
260*cd192fa9SAndroid Build Coastguard Worker * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
261*cd192fa9SAndroid Build Coastguard Worker * p, buflen) and write the result into buf. The parameters r, p, and buflen
262*cd192fa9SAndroid Build Coastguard Worker * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
263*cd192fa9SAndroid Build Coastguard Worker * must be a power of 2 greater than 1.
264*cd192fa9SAndroid Build Coastguard Worker *
265*cd192fa9SAndroid Build Coastguard Worker * Return 0 on success; or -1 on error.
266*cd192fa9SAndroid Build Coastguard Worker */
267*cd192fa9SAndroid Build Coastguard Worker int
crypto_scrypt(const uint8_t * passwd,size_t passwdlen,const uint8_t * salt,size_t saltlen,uint64_t N,uint32_t r,uint32_t p,uint8_t * buf,size_t buflen)268*cd192fa9SAndroid Build Coastguard Worker crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
269*cd192fa9SAndroid Build Coastguard Worker const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
270*cd192fa9SAndroid Build Coastguard Worker uint8_t * buf, size_t buflen)
271*cd192fa9SAndroid Build Coastguard Worker {
272*cd192fa9SAndroid Build Coastguard Worker void * B0, * V0, * XY0;
273*cd192fa9SAndroid Build Coastguard Worker uint8_t * B;
274*cd192fa9SAndroid Build Coastguard Worker uint32_t * V;
275*cd192fa9SAndroid Build Coastguard Worker uint32_t * XY;
276*cd192fa9SAndroid Build Coastguard Worker uint32_t i;
277*cd192fa9SAndroid Build Coastguard Worker
278*cd192fa9SAndroid Build Coastguard Worker /* Sanity-check parameters. */
279*cd192fa9SAndroid Build Coastguard Worker #if SIZE_MAX > UINT32_MAX
280*cd192fa9SAndroid Build Coastguard Worker if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
281*cd192fa9SAndroid Build Coastguard Worker errno = EFBIG;
282*cd192fa9SAndroid Build Coastguard Worker goto err0;
283*cd192fa9SAndroid Build Coastguard Worker }
284*cd192fa9SAndroid Build Coastguard Worker #endif
285*cd192fa9SAndroid Build Coastguard Worker if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
286*cd192fa9SAndroid Build Coastguard Worker errno = EFBIG;
287*cd192fa9SAndroid Build Coastguard Worker goto err0;
288*cd192fa9SAndroid Build Coastguard Worker }
289*cd192fa9SAndroid Build Coastguard Worker if (((N & (N - 1)) != 0) || (N == 0)) {
290*cd192fa9SAndroid Build Coastguard Worker errno = EINVAL;
291*cd192fa9SAndroid Build Coastguard Worker goto err0;
292*cd192fa9SAndroid Build Coastguard Worker }
293*cd192fa9SAndroid Build Coastguard Worker if ((r > SIZE_MAX / 128 / p) ||
294*cd192fa9SAndroid Build Coastguard Worker #if SIZE_MAX / 256 <= UINT32_MAX
295*cd192fa9SAndroid Build Coastguard Worker (r > (SIZE_MAX - 64) / 256) ||
296*cd192fa9SAndroid Build Coastguard Worker #endif
297*cd192fa9SAndroid Build Coastguard Worker (N > SIZE_MAX / 128 / r)) {
298*cd192fa9SAndroid Build Coastguard Worker errno = ENOMEM;
299*cd192fa9SAndroid Build Coastguard Worker goto err0;
300*cd192fa9SAndroid Build Coastguard Worker }
301*cd192fa9SAndroid Build Coastguard Worker
302*cd192fa9SAndroid Build Coastguard Worker /* Allocate memory. */
303*cd192fa9SAndroid Build Coastguard Worker #ifdef HAVE_POSIX_MEMALIGN
304*cd192fa9SAndroid Build Coastguard Worker if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0)
305*cd192fa9SAndroid Build Coastguard Worker goto err0;
306*cd192fa9SAndroid Build Coastguard Worker B = (uint8_t *)(B0);
307*cd192fa9SAndroid Build Coastguard Worker if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)
308*cd192fa9SAndroid Build Coastguard Worker goto err1;
309*cd192fa9SAndroid Build Coastguard Worker XY = (uint32_t *)(XY0);
310*cd192fa9SAndroid Build Coastguard Worker #ifndef MAP_ANON
311*cd192fa9SAndroid Build Coastguard Worker if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0)
312*cd192fa9SAndroid Build Coastguard Worker goto err2;
313*cd192fa9SAndroid Build Coastguard Worker V = (uint32_t *)(V0);
314*cd192fa9SAndroid Build Coastguard Worker #endif
315*cd192fa9SAndroid Build Coastguard Worker #else
316*cd192fa9SAndroid Build Coastguard Worker if ((B0 = malloc(128 * r * p + 63)) == NULL)
317*cd192fa9SAndroid Build Coastguard Worker goto err0;
318*cd192fa9SAndroid Build Coastguard Worker B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63));
319*cd192fa9SAndroid Build Coastguard Worker if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)
320*cd192fa9SAndroid Build Coastguard Worker goto err1;
321*cd192fa9SAndroid Build Coastguard Worker XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
322*cd192fa9SAndroid Build Coastguard Worker #ifndef MAP_ANON
323*cd192fa9SAndroid Build Coastguard Worker if ((V0 = malloc(128 * r * N + 63)) == NULL)
324*cd192fa9SAndroid Build Coastguard Worker goto err2;
325*cd192fa9SAndroid Build Coastguard Worker V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
326*cd192fa9SAndroid Build Coastguard Worker #endif
327*cd192fa9SAndroid Build Coastguard Worker #endif
328*cd192fa9SAndroid Build Coastguard Worker #ifdef MAP_ANON
329*cd192fa9SAndroid Build Coastguard Worker if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
330*cd192fa9SAndroid Build Coastguard Worker #ifdef MAP_NOCORE
331*cd192fa9SAndroid Build Coastguard Worker MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
332*cd192fa9SAndroid Build Coastguard Worker #else
333*cd192fa9SAndroid Build Coastguard Worker MAP_ANON | MAP_PRIVATE,
334*cd192fa9SAndroid Build Coastguard Worker #endif
335*cd192fa9SAndroid Build Coastguard Worker -1, 0)) == MAP_FAILED)
336*cd192fa9SAndroid Build Coastguard Worker goto err2;
337*cd192fa9SAndroid Build Coastguard Worker V = (uint32_t *)(V0);
338*cd192fa9SAndroid Build Coastguard Worker #endif
339*cd192fa9SAndroid Build Coastguard Worker
340*cd192fa9SAndroid Build Coastguard Worker /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
341*cd192fa9SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_PBKDF2
342*cd192fa9SAndroid Build Coastguard Worker PKCS5_PBKDF2_HMAC((const char *)passwd, passwdlen, salt, saltlen, 1, EVP_sha256(), p * 128 * r, B);
343*cd192fa9SAndroid Build Coastguard Worker #else
344*cd192fa9SAndroid Build Coastguard Worker PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
345*cd192fa9SAndroid Build Coastguard Worker #endif
346*cd192fa9SAndroid Build Coastguard Worker
347*cd192fa9SAndroid Build Coastguard Worker /* 2: for i = 0 to p - 1 do */
348*cd192fa9SAndroid Build Coastguard Worker for (i = 0; i < p; i++) {
349*cd192fa9SAndroid Build Coastguard Worker /* 3: B_i <-- MF(B_i, N) */
350*cd192fa9SAndroid Build Coastguard Worker smix(&B[i * 128 * r], r, N, V, XY);
351*cd192fa9SAndroid Build Coastguard Worker }
352*cd192fa9SAndroid Build Coastguard Worker
353*cd192fa9SAndroid Build Coastguard Worker /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
354*cd192fa9SAndroid Build Coastguard Worker #ifdef USE_OPENSSL_PBKDF2
355*cd192fa9SAndroid Build Coastguard Worker PKCS5_PBKDF2_HMAC((const char *)passwd, passwdlen, B, p * 128 * r, 1, EVP_sha256(), buflen, buf);
356*cd192fa9SAndroid Build Coastguard Worker #else
357*cd192fa9SAndroid Build Coastguard Worker PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
358*cd192fa9SAndroid Build Coastguard Worker #endif
359*cd192fa9SAndroid Build Coastguard Worker
360*cd192fa9SAndroid Build Coastguard Worker /* Free memory. */
361*cd192fa9SAndroid Build Coastguard Worker #ifdef MAP_ANON
362*cd192fa9SAndroid Build Coastguard Worker if (munmap(V0, 128 * r * N))
363*cd192fa9SAndroid Build Coastguard Worker goto err2;
364*cd192fa9SAndroid Build Coastguard Worker #else
365*cd192fa9SAndroid Build Coastguard Worker free(V0);
366*cd192fa9SAndroid Build Coastguard Worker #endif
367*cd192fa9SAndroid Build Coastguard Worker free(XY0);
368*cd192fa9SAndroid Build Coastguard Worker free(B0);
369*cd192fa9SAndroid Build Coastguard Worker
370*cd192fa9SAndroid Build Coastguard Worker /* Success! */
371*cd192fa9SAndroid Build Coastguard Worker return (0);
372*cd192fa9SAndroid Build Coastguard Worker
373*cd192fa9SAndroid Build Coastguard Worker err2:
374*cd192fa9SAndroid Build Coastguard Worker free(XY0);
375*cd192fa9SAndroid Build Coastguard Worker err1:
376*cd192fa9SAndroid Build Coastguard Worker free(B0);
377*cd192fa9SAndroid Build Coastguard Worker err0:
378*cd192fa9SAndroid Build Coastguard Worker /* Failure! */
379*cd192fa9SAndroid Build Coastguard Worker return (-1);
380*cd192fa9SAndroid Build Coastguard Worker }
381