1 /* scrypt.c - Scrypt password-based key derivation function.
2 * Copyright (C) 2012 Simon Josefsson
3 * Copyright (C) 2013 Christian Grothoff
4 * Copyright (C) 2013 g10 Code GmbH
6 * This file is part of Libgcrypt.
8 * Libgcrypt is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser general Public License as
10 * published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * Libgcrypt is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
22 /* Adapted from the nettle, low-level cryptographics library for
23 * libgcrypt by Christian Grothoff; original license:
25 * Copyright (C) 2012 Simon Josefsson
27 * The nettle library is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU Lesser General Public License as published by
29 * the Free Software Foundation; either version 2.1 of the License, or (at your
30 * option) any later version.
32 * The nettle library is distributed in the hope that it will be useful, but
33 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
34 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
35 * License for more details.
37 * You should have received a copy of the GNU Lesser General Public License
38 * along with the nettle library; see the file COPYING.LIB. If not, write to
39 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
49 #include "kdf-internal.h"
52 /* We really need a 64 bit type for this code. */
53 #ifdef HAVE_U64_TYPEDEF
55 #define SALSA20_INPUT_LENGTH 16
57 #define ROTL32(n,x) (((x)<<(n)) | ((x)>>(32-(n))))
60 /* Reads a 64-bit integer, in network, big-endian, byte order */
61 #define READ_UINT64(p) buf_get_be64(p)
64 /* And the other, little-endian, byteorder */
65 #define LE_READ_UINT64(p) buf_get_le64(p)
67 #define LE_SWAP32(v) le_bswap32(v)
70 #define QROUND(x0, x1, x2, x3) do { \
71 x1 ^= ROTL32(7, x0 + x3); \
72 x2 ^= ROTL32(9, x1 + x0); \
73 x3 ^= ROTL32(13, x2 + x1); \
74 x0 ^= ROTL32(18, x3 + x2); \
79 _salsa20_core(u32 *dst, const u32 *src, unsigned rounds)
81 u32 x[SALSA20_INPUT_LENGTH];
84 assert ( (rounds & 1) == 0);
86 for (i = 0; i < SALSA20_INPUT_LENGTH; i++)
87 x[i] = LE_SWAP32(src[i]);
89 for (i = 0; i < rounds;i += 2)
91 QROUND(x[0], x[4], x[8], x[12]);
92 QROUND(x[5], x[9], x[13], x[1]);
93 QROUND(x[10], x[14], x[2], x[6]);
94 QROUND(x[15], x[3], x[7], x[11]);
96 QROUND(x[0], x[1], x[2], x[3]);
97 QROUND(x[5], x[6], x[7], x[4]);
98 QROUND(x[10], x[11], x[8], x[9]);
99 QROUND(x[15], x[12], x[13], x[14]);
102 for (i = 0; i < SALSA20_INPUT_LENGTH; i++)
104 u32 t = x[i] + LE_SWAP32(src[i]);
105 dst[i] = LE_SWAP32(t);
111 _scryptBlockMix (u32 r, unsigned char *B, unsigned char *tmp2)
114 unsigned char *X = tmp2;
115 unsigned char *Y = tmp2 + 64;
120 for (i = 0; i < 2 * r; i++)
123 printf ("B[%d] = ", (int)i);
124 for (j = 0; j < 64; j++)
128 printf (" %02x", B[i * 64 + j]);
135 /* X = B[2 * r - 1] */
136 memcpy (X, &B[(2 * r - 1) * 64], 64);
138 /* for i = 0 to 2 * r - 1 do */
139 for (i = 0; i <= 2 * r - 1; i++)
142 buf_xor(X, X, &B[i * 64], 64);
145 _salsa20_core ((u32*)X, (u32*)X, 8);
148 memcpy (&Y[i * 64], X, 64);
151 for (i = 0; i < r; i++)
153 memcpy (&B[i * 64], &Y[2 * i * 64], 64);
154 memcpy (&B[(r + i) * 64], &Y[(2 * i + 1) * 64], 64);
160 for (i = 0; i < 2 * r; i++)
163 printf ("B'[%d] =", (int)i);
164 for (j = 0; j < 64; j++)
168 printf (" %02x", B[i * 64 + j]);
177 _scryptROMix (u32 r, unsigned char *B, u64 N,
178 unsigned char *tmp1, unsigned char *tmp2)
180 unsigned char *X = B, *T = B;
187 for (i = 0; i < 128 * r; i++)
191 printf (" %02x", B[i]);
197 /* for i = 0 to N - 1 do */
198 for (i = 0; i <= N - 1; i++)
201 memcpy (&tmp1[i * 128 * r], X, 128 * r);
203 /* X = ScryptBlockMix (X) */
204 _scryptBlockMix (r, X, tmp2);
207 /* for i = 0 to N - 1 do */
208 for (i = 0; i <= N - 1; i++)
212 /* j = Integerify (X) mod N */
213 j = LE_READ_UINT64 (&X[128 * r - 64]) % N;
216 buf_xor (T, T, &tmp1[j * 128 * r], 128 * r);
218 /* X = scryptBlockMix (T) */
219 _scryptBlockMix (r, T, tmp2);
226 for (i = 0; i < 128 * r; i++)
230 printf (" %02x", B[i]);
240 _gcry_kdf_scrypt (const unsigned char *passwd, size_t passwdlen,
241 int algo, int subalgo,
242 const unsigned char *salt, size_t saltlen,
243 unsigned long iterations,
244 size_t dkLen, unsigned char *DK)
246 u64 N = subalgo; /* CPU/memory cost paramter. */
247 u32 r; /* Block size. */
248 u32 p = iterations; /* Parallelization parameter. */
252 unsigned char *B = NULL;
253 unsigned char *tmp1 = NULL;
254 unsigned char *tmp2 = NULL;
258 if (subalgo < 1 || !iterations)
259 return GPG_ERR_INV_VALUE;
261 if (algo == GCRY_KDF_SCRYPT)
263 else if (algo == 41) /* Hack to allow the use of all test vectors. */
266 return GPG_ERR_UNKNOWN_ALGORITHM;
270 return GPG_ERR_ENOMEM;
273 if (r128 && nbytes / r128 != p)
274 return GPG_ERR_ENOMEM;
277 if (r128 && nbytes / r128 != N)
278 return GPG_ERR_ENOMEM;
282 return GPG_ERR_ENOMEM;
284 B = xtrymalloc (p * r128);
287 ec = gpg_err_code_from_syserror ();
291 tmp1 = xtrymalloc (N * r128);
294 ec = gpg_err_code_from_syserror ();
298 tmp2 = xtrymalloc (64 + r128);
301 ec = gpg_err_code_from_syserror ();
305 ec = _gcry_kdf_pkdf2 (passwd, passwdlen, GCRY_MD_SHA256, salt, saltlen,
306 1 /* iterations */, p * r128, B);
308 for (i = 0; !ec && i < p; i++)
309 _scryptROMix (r, &B[i * r128], N, tmp1, tmp2);
311 for (i = 0; !ec && i < p; i++)
312 ec = _gcry_kdf_pkdf2 (passwd, passwdlen, GCRY_MD_SHA256, B, p * r128,
313 1 /* iterations */, dkLen, DK);
324 #endif /* HAVE_U64_TYPEDEF */