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