/src/openssl/crypto/kdf/scrypt.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the OpenSSL license (the "License"). You may not use |
5 | | * this file except in compliance with the License. You can obtain a copy |
6 | | * in the file LICENSE in the source distribution or at |
7 | | * https://www.openssl.org/source/license.html |
8 | | */ |
9 | | |
10 | | #include <stdlib.h> |
11 | | #include <string.h> |
12 | | #include <openssl/hmac.h> |
13 | | #include <openssl/kdf.h> |
14 | | #include <openssl/evp.h> |
15 | | #include "internal/cryptlib.h" |
16 | | #include "internal/evp_int.h" |
17 | | |
18 | | #ifndef OPENSSL_NO_SCRYPT |
19 | | |
20 | | static int atou64(const char *nptr, uint64_t *result); |
21 | | |
22 | | typedef struct { |
23 | | unsigned char *pass; |
24 | | size_t pass_len; |
25 | | unsigned char *salt; |
26 | | size_t salt_len; |
27 | | uint64_t N, r, p; |
28 | | uint64_t maxmem_bytes; |
29 | | } SCRYPT_PKEY_CTX; |
30 | | |
31 | | /* Custom uint64_t parser since we do not have strtoull */ |
32 | | static int atou64(const char *nptr, uint64_t *result) |
33 | 0 | { |
34 | 0 | uint64_t value = 0; |
35 | 0 |
|
36 | 0 | while (*nptr) { |
37 | 0 | unsigned int digit; |
38 | 0 | uint64_t new_value; |
39 | 0 |
|
40 | 0 | if ((*nptr < '0') || (*nptr > '9')) { |
41 | 0 | return 0; |
42 | 0 | } |
43 | 0 | digit = (unsigned int)(*nptr - '0'); |
44 | 0 | new_value = (value * 10) + digit; |
45 | 0 | if ((new_value < digit) || ((new_value - digit) / 10 != value)) { |
46 | 0 | /* Overflow */ |
47 | 0 | return 0; |
48 | 0 | } |
49 | 0 | value = new_value; |
50 | 0 | nptr++; |
51 | 0 | } |
52 | 0 | *result = value; |
53 | 0 | return 1; |
54 | 0 | } |
55 | | |
56 | | static int pkey_scrypt_init(EVP_PKEY_CTX *ctx) |
57 | 0 | { |
58 | 0 | SCRYPT_PKEY_CTX *kctx; |
59 | 0 |
|
60 | 0 | kctx = OPENSSL_zalloc(sizeof(*kctx)); |
61 | 0 | if (kctx == NULL) { |
62 | 0 | KDFerr(KDF_F_PKEY_SCRYPT_INIT, ERR_R_MALLOC_FAILURE); |
63 | 0 | return 0; |
64 | 0 | } |
65 | 0 |
|
66 | 0 | /* Default values are the most conservative recommendation given in the |
67 | 0 | * original paper of C. Percival. Derivation uses roughly 1 GiB of memory |
68 | 0 | * for this parameter choice (approx. 128 * r * (N + p) bytes). |
69 | 0 | */ |
70 | 0 | kctx->N = 1 << 20; |
71 | 0 | kctx->r = 8; |
72 | 0 | kctx->p = 1; |
73 | 0 | kctx->maxmem_bytes = 1025 * 1024 * 1024; |
74 | 0 |
|
75 | 0 | ctx->data = kctx; |
76 | 0 |
|
77 | 0 | return 1; |
78 | 0 | } |
79 | | |
80 | | static void pkey_scrypt_cleanup(EVP_PKEY_CTX *ctx) |
81 | 0 | { |
82 | 0 | SCRYPT_PKEY_CTX *kctx = ctx->data; |
83 | 0 |
|
84 | 0 | OPENSSL_clear_free(kctx->salt, kctx->salt_len); |
85 | 0 | OPENSSL_clear_free(kctx->pass, kctx->pass_len); |
86 | 0 | OPENSSL_free(kctx); |
87 | 0 | } |
88 | | |
89 | | static int pkey_scrypt_set_membuf(unsigned char **buffer, size_t *buflen, |
90 | | const unsigned char *new_buffer, |
91 | | const int new_buflen) |
92 | 0 | { |
93 | 0 | if (new_buffer == NULL) |
94 | 0 | return 1; |
95 | 0 | |
96 | 0 | if (new_buflen < 0) |
97 | 0 | return 0; |
98 | 0 | |
99 | 0 | if (*buffer != NULL) |
100 | 0 | OPENSSL_clear_free(*buffer, *buflen); |
101 | 0 |
|
102 | 0 | if (new_buflen > 0) { |
103 | 0 | *buffer = OPENSSL_memdup(new_buffer, new_buflen); |
104 | 0 | } else { |
105 | 0 | *buffer = OPENSSL_malloc(1); |
106 | 0 | } |
107 | 0 | if (*buffer == NULL) { |
108 | 0 | KDFerr(KDF_F_PKEY_SCRYPT_SET_MEMBUF, ERR_R_MALLOC_FAILURE); |
109 | 0 | return 0; |
110 | 0 | } |
111 | 0 |
|
112 | 0 | *buflen = new_buflen; |
113 | 0 | return 1; |
114 | 0 | } |
115 | | |
116 | | static int is_power_of_two(uint64_t value) |
117 | 0 | { |
118 | 0 | return (value != 0) && ((value & (value - 1)) == 0); |
119 | 0 | } |
120 | | |
121 | | static int pkey_scrypt_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) |
122 | 0 | { |
123 | 0 | SCRYPT_PKEY_CTX *kctx = ctx->data; |
124 | 0 | uint64_t u64_value; |
125 | 0 |
|
126 | 0 | switch (type) { |
127 | 0 | case EVP_PKEY_CTRL_PASS: |
128 | 0 | return pkey_scrypt_set_membuf(&kctx->pass, &kctx->pass_len, p2, p1); |
129 | 0 |
|
130 | 0 | case EVP_PKEY_CTRL_SCRYPT_SALT: |
131 | 0 | return pkey_scrypt_set_membuf(&kctx->salt, &kctx->salt_len, p2, p1); |
132 | 0 |
|
133 | 0 | case EVP_PKEY_CTRL_SCRYPT_N: |
134 | 0 | u64_value = *((uint64_t *)p2); |
135 | 0 | if ((u64_value <= 1) || !is_power_of_two(u64_value)) |
136 | 0 | return 0; |
137 | 0 | kctx->N = u64_value; |
138 | 0 | return 1; |
139 | 0 |
|
140 | 0 | case EVP_PKEY_CTRL_SCRYPT_R: |
141 | 0 | u64_value = *((uint64_t *)p2); |
142 | 0 | if (u64_value < 1) |
143 | 0 | return 0; |
144 | 0 | kctx->r = u64_value; |
145 | 0 | return 1; |
146 | 0 |
|
147 | 0 | case EVP_PKEY_CTRL_SCRYPT_P: |
148 | 0 | u64_value = *((uint64_t *)p2); |
149 | 0 | if (u64_value < 1) |
150 | 0 | return 0; |
151 | 0 | kctx->p = u64_value; |
152 | 0 | return 1; |
153 | 0 |
|
154 | 0 | case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES: |
155 | 0 | u64_value = *((uint64_t *)p2); |
156 | 0 | if (u64_value < 1) |
157 | 0 | return 0; |
158 | 0 | kctx->maxmem_bytes = u64_value; |
159 | 0 | return 1; |
160 | 0 |
|
161 | 0 | default: |
162 | 0 | return -2; |
163 | 0 |
|
164 | 0 | } |
165 | 0 | } |
166 | | |
167 | | static int pkey_scrypt_ctrl_uint64(EVP_PKEY_CTX *ctx, int type, |
168 | | const char *value) |
169 | 0 | { |
170 | 0 | uint64_t int_value; |
171 | 0 |
|
172 | 0 | if (!atou64(value, &int_value)) { |
173 | 0 | KDFerr(KDF_F_PKEY_SCRYPT_CTRL_UINT64, KDF_R_VALUE_ERROR); |
174 | 0 | return 0; |
175 | 0 | } |
176 | 0 | return pkey_scrypt_ctrl(ctx, type, 0, &int_value); |
177 | 0 | } |
178 | | |
179 | | static int pkey_scrypt_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, |
180 | | const char *value) |
181 | | { |
182 | | if (value == NULL) { |
183 | | KDFerr(KDF_F_PKEY_SCRYPT_CTRL_STR, KDF_R_VALUE_MISSING); |
184 | | return 0; |
185 | | } |
186 | | |
187 | | if (strcmp(type, "pass") == 0) |
188 | | return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_PASS, value); |
189 | | |
190 | | if (strcmp(type, "hexpass") == 0) |
191 | | return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_PASS, value); |
192 | | |
193 | | if (strcmp(type, "salt") == 0) |
194 | | return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SCRYPT_SALT, value); |
195 | | |
196 | | if (strcmp(type, "hexsalt") == 0) |
197 | | return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SCRYPT_SALT, value); |
198 | | |
199 | | if (strcmp(type, "N") == 0) |
200 | | return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_N, value); |
201 | | |
202 | | if (strcmp(type, "r") == 0) |
203 | | return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_R, value); |
204 | | |
205 | | if (strcmp(type, "p") == 0) |
206 | | return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_P, value); |
207 | | |
208 | | if (strcmp(type, "maxmem_bytes") == 0) |
209 | | return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, |
210 | | value); |
211 | | |
212 | | KDFerr(KDF_F_PKEY_SCRYPT_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE); |
213 | | return -2; |
214 | | } |
215 | | |
216 | | static int pkey_scrypt_derive(EVP_PKEY_CTX *ctx, unsigned char *key, |
217 | | size_t *keylen) |
218 | 0 | { |
219 | 0 | SCRYPT_PKEY_CTX *kctx = ctx->data; |
220 | 0 |
|
221 | 0 | if (kctx->pass == NULL) { |
222 | 0 | KDFerr(KDF_F_PKEY_SCRYPT_DERIVE, KDF_R_MISSING_PASS); |
223 | 0 | return 0; |
224 | 0 | } |
225 | 0 |
|
226 | 0 | if (kctx->salt == NULL) { |
227 | 0 | KDFerr(KDF_F_PKEY_SCRYPT_DERIVE, KDF_R_MISSING_SALT); |
228 | 0 | return 0; |
229 | 0 | } |
230 | 0 |
|
231 | 0 | return EVP_PBE_scrypt((char *)kctx->pass, kctx->pass_len, kctx->salt, |
232 | 0 | kctx->salt_len, kctx->N, kctx->r, kctx->p, |
233 | 0 | kctx->maxmem_bytes, key, *keylen); |
234 | 0 | } |
235 | | |
236 | | const EVP_PKEY_METHOD scrypt_pkey_meth = { |
237 | | EVP_PKEY_SCRYPT, |
238 | | 0, |
239 | | pkey_scrypt_init, |
240 | | 0, |
241 | | pkey_scrypt_cleanup, |
242 | | |
243 | | 0, 0, |
244 | | 0, 0, |
245 | | |
246 | | 0, |
247 | | 0, |
248 | | |
249 | | 0, |
250 | | 0, |
251 | | |
252 | | 0, 0, |
253 | | |
254 | | 0, 0, 0, 0, |
255 | | |
256 | | 0, 0, |
257 | | |
258 | | 0, 0, |
259 | | |
260 | | 0, |
261 | | pkey_scrypt_derive, |
262 | | pkey_scrypt_ctrl, |
263 | | pkey_scrypt_ctrl_str |
264 | | }; |
265 | | |
266 | | #endif |