]>
Commit | Line | Data |
---|---|---|
a95fb9e3 DSH |
1 | /* |
2 | * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project | |
3 | * 2015. | |
4 | */ | |
5 | /* ==================================================================== | |
6 | * Copyright (c) 2015 The OpenSSL Project. All rights reserved. | |
7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | |
11 | * | |
12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | |
14 | * | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in | |
17 | * the documentation and/or other materials provided with the | |
18 | * distribution. | |
19 | * | |
20 | * 3. All advertising materials mentioning features or use of this | |
21 | * software must display the following acknowledgment: | |
22 | * "This product includes software developed by the OpenSSL Project | |
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | |
24 | * | |
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
26 | * endorse or promote products derived from this software without | |
27 | * prior written permission. For written permission, please contact | |
28 | * licensing@OpenSSL.org. | |
29 | * | |
30 | * 5. Products derived from this software may not be called "OpenSSL" | |
31 | * nor may "OpenSSL" appear in their names without prior written | |
32 | * permission of the OpenSSL Project. | |
33 | * | |
34 | * 6. Redistributions of any form whatsoever must retain the following | |
35 | * acknowledgment: | |
36 | * "This product includes software developed by the OpenSSL Project | |
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | |
38 | * | |
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | |
51 | * ==================================================================== | |
52 | * | |
53 | * This product includes cryptographic software written by Eric Young | |
54 | * (eay@cryptsoft.com). This product includes software written by Tim | |
55 | * Hudson (tjh@cryptsoft.com). | |
56 | * | |
57 | */ | |
58 | ||
59 | #include <stddef.h> | |
60 | #include <stdio.h> | |
61 | #include <string.h> | |
62 | #include <openssl/evp.h> | |
fef034f8 | 63 | #include <openssl/err.h> |
a95fb9e3 DSH |
64 | #include <internal/numbers.h> |
65 | ||
b0809bc8 RS |
66 | #ifndef OPENSSL_NO_SCRYPT |
67 | ||
a95fb9e3 DSH |
68 | #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) |
69 | static void salsa208_word_specification(uint32_t inout[16]) | |
70 | { | |
71 | int i; | |
72 | uint32_t x[16]; | |
73 | memcpy(x, inout, sizeof(x)); | |
74 | for (i = 8; i > 0; i -= 2) { | |
75 | x[4] ^= R(x[0] + x[12], 7); | |
76 | x[8] ^= R(x[4] + x[0], 9); | |
77 | x[12] ^= R(x[8] + x[4], 13); | |
78 | x[0] ^= R(x[12] + x[8], 18); | |
79 | x[9] ^= R(x[5] + x[1], 7); | |
80 | x[13] ^= R(x[9] + x[5], 9); | |
81 | x[1] ^= R(x[13] + x[9], 13); | |
82 | x[5] ^= R(x[1] + x[13], 18); | |
83 | x[14] ^= R(x[10] + x[6], 7); | |
84 | x[2] ^= R(x[14] + x[10], 9); | |
85 | x[6] ^= R(x[2] + x[14], 13); | |
86 | x[10] ^= R(x[6] + x[2], 18); | |
87 | x[3] ^= R(x[15] + x[11], 7); | |
88 | x[7] ^= R(x[3] + x[15], 9); | |
89 | x[11] ^= R(x[7] + x[3], 13); | |
90 | x[15] ^= R(x[11] + x[7], 18); | |
91 | x[1] ^= R(x[0] + x[3], 7); | |
92 | x[2] ^= R(x[1] + x[0], 9); | |
93 | x[3] ^= R(x[2] + x[1], 13); | |
94 | x[0] ^= R(x[3] + x[2], 18); | |
95 | x[6] ^= R(x[5] + x[4], 7); | |
96 | x[7] ^= R(x[6] + x[5], 9); | |
97 | x[4] ^= R(x[7] + x[6], 13); | |
98 | x[5] ^= R(x[4] + x[7], 18); | |
99 | x[11] ^= R(x[10] + x[9], 7); | |
100 | x[8] ^= R(x[11] + x[10], 9); | |
101 | x[9] ^= R(x[8] + x[11], 13); | |
102 | x[10] ^= R(x[9] + x[8], 18); | |
103 | x[12] ^= R(x[15] + x[14], 7); | |
104 | x[13] ^= R(x[12] + x[15], 9); | |
105 | x[14] ^= R(x[13] + x[12], 13); | |
106 | x[15] ^= R(x[14] + x[13], 18); | |
107 | } | |
108 | for (i = 0; i < 16; ++i) | |
109 | inout[i] += x[i]; | |
110 | OPENSSL_cleanse(x, sizeof(x)); | |
111 | } | |
112 | ||
113 | static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r) | |
114 | { | |
115 | uint64_t i, j; | |
116 | uint32_t X[16], *pB; | |
117 | ||
118 | memcpy(X, B + (r * 2 - 1) * 16, sizeof(X)); | |
119 | pB = B; | |
120 | for (i = 0; i < r * 2; i++) { | |
121 | for (j = 0; j < 16; j++) | |
122 | X[j] ^= *pB++; | |
123 | salsa208_word_specification(X); | |
124 | memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X)); | |
125 | } | |
126 | OPENSSL_cleanse(X, sizeof(X)); | |
127 | } | |
128 | ||
129 | static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N, | |
130 | uint32_t *X, uint32_t *T, uint32_t *V) | |
131 | { | |
132 | unsigned char *pB; | |
133 | uint32_t *pV; | |
134 | uint64_t i, k; | |
135 | ||
136 | /* Convert from little endian input */ | |
137 | for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) { | |
138 | *pV = *pB++; | |
139 | *pV |= *pB++ << 8; | |
140 | *pV |= *pB++ << 16; | |
3003e0a4 | 141 | *pV |= (uint32_t)*pB++ << 24; |
a95fb9e3 DSH |
142 | } |
143 | ||
144 | for (i = 1; i < N; i++, pV += 32 * r) | |
145 | scryptBlockMix(pV, pV - 32 * r, r); | |
146 | ||
147 | scryptBlockMix(X, V + (N - 1) * 32 * r, r); | |
148 | ||
149 | for (i = 0; i < N; i++) { | |
150 | uint32_t j; | |
151 | j = X[16 * (2 * r - 1)] % N; | |
152 | pV = V + 32 * r * j; | |
153 | for (k = 0; k < 32 * r; k++) | |
154 | T[k] = X[k] ^ *pV++; | |
155 | scryptBlockMix(X, T, r); | |
156 | } | |
157 | /* Convert output to little endian */ | |
158 | for (i = 0, pB = B; i < 32 * r; i++) { | |
159 | uint32_t xtmp = X[i]; | |
160 | *pB++ = xtmp & 0xff; | |
161 | *pB++ = (xtmp >> 8) & 0xff; | |
162 | *pB++ = (xtmp >> 16) & 0xff; | |
163 | *pB++ = (xtmp >> 24) & 0xff; | |
164 | } | |
165 | } | |
166 | ||
167 | #ifndef SIZE_MAX | |
168 | # define SIZE_MAX ((size_t)-1) | |
169 | #endif | |
170 | ||
171 | /* | |
172 | * Maximum power of two that will fit in uint64_t: this should work on | |
173 | * most (all?) platforms. | |
174 | */ | |
175 | ||
176 | #define LOG2_UINT64_MAX (sizeof(uint64_t) * 8 - 1) | |
177 | ||
178 | /* | |
179 | * Maximum value of p * r: | |
180 | * p <= ((2^32-1) * hLen) / MFLen => | |
181 | * p <= ((2^32-1) * 32) / (128 * r) => | |
182 | * p * r <= (2^30-1) | |
183 | * | |
184 | */ | |
185 | ||
186 | #define SCRYPT_PR_MAX ((1 << 30) - 1) | |
187 | ||
188 | /* | |
189 | * Maximum permitted memory allow this to be overridden with Configuration | |
190 | * option: e.g. -DSCRYPT_MAX_MEM=0 for maximum possible. | |
191 | */ | |
192 | ||
193 | #ifdef SCRYPT_MAX_MEM | |
194 | # if SCRYPT_MAX_MEM == 0 | |
195 | # undef SCRYPT_MAX_MEM | |
196 | /* | |
197 | * Although we could theoretically allocate SIZE_MAX memory that would leave | |
198 | * no memory available for anything else so set limit as half that. | |
199 | */ | |
200 | # define SCRYPT_MAX_MEM (SIZE_MAX/2) | |
201 | # endif | |
202 | #else | |
203 | /* Default memory limit: 32 MB */ | |
204 | # define SCRYPT_MAX_MEM (1024 * 1024 * 32) | |
205 | #endif | |
206 | ||
207 | int EVP_PBE_scrypt(const char *pass, size_t passlen, | |
208 | const unsigned char *salt, size_t saltlen, | |
209 | uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, | |
210 | unsigned char *key, size_t keylen) | |
211 | { | |
212 | int rv = 0; | |
213 | unsigned char *B; | |
214 | uint32_t *X, *V, *T; | |
215 | uint64_t i, Blen, Vlen; | |
cc9c5689 | 216 | size_t allocsize; |
a95fb9e3 DSH |
217 | |
218 | /* Sanity check parameters */ | |
219 | /* initial check, r,p must be non zero, N >= 2 and a power of 2 */ | |
220 | if (r == 0 || p == 0 || N < 2 || (N & (N - 1))) | |
221 | return 0; | |
222 | /* Check p * r < SCRYPT_PR_MAX avoiding overflow */ | |
223 | if (p > SCRYPT_PR_MAX / r) | |
224 | return 0; | |
225 | ||
226 | /* | |
227 | * Need to check N: if 2^(128 * r / 8) overflows limit this is | |
228 | * automatically satisfied since N <= UINT64_MAX. | |
229 | */ | |
230 | ||
231 | if (16 * r <= LOG2_UINT64_MAX) { | |
19f7130b | 232 | if (N >= (((uint64_t)1) << (16 * r))) |
a95fb9e3 DSH |
233 | return 0; |
234 | } | |
235 | ||
236 | /* Memory checks: check total allocated buffer size fits in uint64_t */ | |
237 | ||
238 | /* | |
239 | * B size in section 5 step 1.S | |
240 | * Note: we know p * 128 * r < UINT64_MAX because we already checked | |
241 | * p * r < SCRYPT_PR_MAX | |
242 | */ | |
243 | Blen = p * 128 * r; | |
244 | ||
245 | /* | |
cc9c5689 DM |
246 | * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in |
247 | * uint64_t and also size_t (their sizes are unrelated). | |
a95fb9e3 DSH |
248 | * This is combined size V, X and T (section 4) |
249 | */ | |
250 | i = UINT64_MAX / (32 * sizeof(uint32_t)); | |
251 | if (N + 2 > i / r) | |
252 | return 0; | |
253 | Vlen = 32 * r * (N + 2) * sizeof(uint32_t); | |
254 | ||
255 | /* check total allocated size fits in uint64_t */ | |
256 | if (Blen > UINT64_MAX - Vlen) | |
257 | return 0; | |
cc9c5689 DM |
258 | /* check total allocated size fits in size_t */ |
259 | if (Blen > SIZE_MAX - Vlen) | |
260 | return 0; | |
261 | ||
262 | allocsize = (size_t)(Blen + Vlen); | |
a95fb9e3 DSH |
263 | |
264 | if (maxmem == 0) | |
265 | maxmem = SCRYPT_MAX_MEM; | |
266 | ||
cc9c5689 | 267 | if (allocsize > maxmem) { |
fef034f8 | 268 | EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED); |
a95fb9e3 | 269 | return 0; |
fef034f8 | 270 | } |
a95fb9e3 DSH |
271 | |
272 | /* If no key return to indicate parameters are OK */ | |
273 | if (key == NULL) | |
274 | return 1; | |
275 | ||
cc9c5689 | 276 | B = OPENSSL_malloc(allocsize); |
90945fa3 | 277 | if (B == NULL) |
a95fb9e3 DSH |
278 | return 0; |
279 | X = (uint32_t *)(B + Blen); | |
280 | T = X + 32 * r; | |
281 | V = T + 32 * r; | |
282 | if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(), | |
283 | Blen, B) == 0) | |
284 | goto err; | |
285 | ||
286 | for (i = 0; i < p; i++) | |
287 | scryptROMix(B + 128 * r * i, r, N, X, T, V); | |
288 | ||
289 | if (PKCS5_PBKDF2_HMAC(pass, passlen, B, Blen, 1, EVP_sha256(), | |
290 | keylen, key) == 0) | |
291 | goto err; | |
292 | rv = 1; | |
a95fb9e3 | 293 | err: |
cc9c5689 | 294 | OPENSSL_clear_free(B, allocsize); |
a95fb9e3 DSH |
295 | return rv; |
296 | } | |
b0809bc8 | 297 | #endif |