]>
Commit | Line | Data |
---|---|---|
5a285add | 1 | /* |
f0efeea2 | 2 | * Copyright 2018-2019 The OpenSSL Project Authors. All Rights Reserved. |
5a285add DM |
3 | * |
4 | * Licensed under the Apache License 2.0 (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 <stdarg.h> | |
12 | #include <string.h> | |
13 | #include <openssl/hmac.h> | |
14 | #include <openssl/evp.h> | |
15 | #include <openssl/kdf.h> | |
16 | #include "internal/cryptlib.h" | |
17 | #include "internal/evp_int.h" | |
18 | #include "kdf_local.h" | |
19 | ||
f0efeea2 SL |
20 | /* Constants specified in SP800-132 */ |
21 | #define KDF_PBKDF2_MIN_KEY_LEN_BITS 112 | |
22 | #define KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO 0xFFFFFFFF | |
23 | #define KDF_PBKDF2_MIN_ITERATIONS 1000 | |
24 | #define KDF_PBKDF2_MIN_SALT_LEN (128 / 8) | |
25 | /* | |
26 | * For backwards compatibility reasons, | |
27 | * Extra checks are done by default in fips mode only. | |
28 | */ | |
29 | #ifdef FIPS_MODE | |
30 | # define KDF_PBKDF2_DEFAULT_CHECKS 1 | |
31 | #else | |
32 | # define KDF_PBKDF2_DEFAULT_CHECKS 0 | |
33 | #endif /* FIPS_MODE */ | |
34 | ||
5a285add DM |
35 | static void kdf_pbkdf2_reset(EVP_KDF_IMPL *impl); |
36 | static void kdf_pbkdf2_init(EVP_KDF_IMPL *impl); | |
f0efeea2 SL |
37 | static int pbkdf2_derive(const char *pass, size_t passlen, |
38 | const unsigned char *salt, int saltlen, int iter, | |
39 | const EVP_MD *digest, unsigned char *key, | |
40 | size_t keylen, int extra_checks); | |
5a285add DM |
41 | |
42 | struct evp_kdf_impl_st { | |
43 | unsigned char *pass; | |
44 | size_t pass_len; | |
45 | unsigned char *salt; | |
46 | size_t salt_len; | |
47 | int iter; | |
48 | const EVP_MD *md; | |
f0efeea2 | 49 | int lower_bound_checks; |
5a285add DM |
50 | }; |
51 | ||
52 | static EVP_KDF_IMPL *kdf_pbkdf2_new(void) | |
53 | { | |
54 | EVP_KDF_IMPL *impl; | |
55 | ||
56 | impl = OPENSSL_zalloc(sizeof(*impl)); | |
57 | if (impl == NULL) { | |
58 | KDFerr(KDF_F_KDF_PBKDF2_NEW, ERR_R_MALLOC_FAILURE); | |
59 | return NULL; | |
60 | } | |
61 | kdf_pbkdf2_init(impl); | |
62 | return impl; | |
63 | } | |
64 | ||
65 | static void kdf_pbkdf2_free(EVP_KDF_IMPL *impl) | |
66 | { | |
67 | kdf_pbkdf2_reset(impl); | |
68 | OPENSSL_free(impl); | |
69 | } | |
70 | ||
71 | static void kdf_pbkdf2_reset(EVP_KDF_IMPL *impl) | |
72 | { | |
73 | OPENSSL_free(impl->salt); | |
74 | OPENSSL_clear_free(impl->pass, impl->pass_len); | |
75 | memset(impl, 0, sizeof(*impl)); | |
76 | kdf_pbkdf2_init(impl); | |
77 | } | |
78 | ||
79 | static void kdf_pbkdf2_init(EVP_KDF_IMPL *impl) | |
80 | { | |
81 | impl->iter = PKCS5_DEFAULT_ITER; | |
82 | impl->md = EVP_sha1(); | |
f0efeea2 | 83 | impl->lower_bound_checks = KDF_PBKDF2_DEFAULT_CHECKS; |
5a285add DM |
84 | } |
85 | ||
86 | static int pbkdf2_set_membuf(unsigned char **buffer, size_t *buflen, | |
87 | const unsigned char *new_buffer, | |
88 | size_t new_buflen) | |
89 | { | |
90 | if (new_buffer == NULL) | |
91 | return 1; | |
92 | ||
93 | OPENSSL_clear_free(*buffer, *buflen); | |
94 | ||
95 | if (new_buflen > 0) { | |
96 | *buffer = OPENSSL_memdup(new_buffer, new_buflen); | |
97 | } else { | |
98 | *buffer = OPENSSL_malloc(1); | |
99 | } | |
100 | if (*buffer == NULL) { | |
101 | KDFerr(KDF_F_PBKDF2_SET_MEMBUF, ERR_R_MALLOC_FAILURE); | |
102 | return 0; | |
103 | } | |
104 | ||
105 | *buflen = new_buflen; | |
106 | return 1; | |
107 | } | |
108 | ||
109 | static int kdf_pbkdf2_ctrl(EVP_KDF_IMPL *impl, int cmd, va_list args) | |
110 | { | |
f0efeea2 | 111 | int iter, pkcs5, min_iter; |
5a285add DM |
112 | const unsigned char *p; |
113 | size_t len; | |
114 | const EVP_MD *md; | |
115 | ||
116 | switch (cmd) { | |
f0efeea2 SL |
117 | case EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE: |
118 | pkcs5 = va_arg(args, int); | |
119 | impl->lower_bound_checks = (pkcs5 == 0) ? 1 : 0; | |
120 | return 1; | |
5a285add DM |
121 | case EVP_KDF_CTRL_SET_PASS: |
122 | p = va_arg(args, const unsigned char *); | |
123 | len = va_arg(args, size_t); | |
124 | return pbkdf2_set_membuf(&impl->pass, &impl->pass_len, p, len); | |
125 | ||
126 | case EVP_KDF_CTRL_SET_SALT: | |
127 | p = va_arg(args, const unsigned char *); | |
128 | len = va_arg(args, size_t); | |
f0efeea2 SL |
129 | if (impl->lower_bound_checks != 0 && len < KDF_PBKDF2_MIN_SALT_LEN) { |
130 | KDFerr(KDF_F_KDF_PBKDF2_CTRL, KDF_R_INVALID_SALT_LEN); | |
131 | return 0; | |
132 | } | |
5a285add DM |
133 | return pbkdf2_set_membuf(&impl->salt, &impl->salt_len, p, len); |
134 | ||
135 | case EVP_KDF_CTRL_SET_ITER: | |
136 | iter = va_arg(args, int); | |
f0efeea2 SL |
137 | min_iter = impl->lower_bound_checks != 0 ? KDF_PBKDF2_MIN_ITERATIONS : 1; |
138 | if (iter < min_iter) { | |
139 | KDFerr(KDF_F_KDF_PBKDF2_CTRL, KDF_R_INVALID_ITERATION_COUNT); | |
5a285add | 140 | return 0; |
f0efeea2 | 141 | } |
5a285add DM |
142 | impl->iter = iter; |
143 | return 1; | |
144 | ||
145 | case EVP_KDF_CTRL_SET_MD: | |
146 | md = va_arg(args, const EVP_MD *); | |
f0efeea2 SL |
147 | if (md == NULL) { |
148 | KDFerr(KDF_F_KDF_PBKDF2_CTRL, KDF_R_VALUE_MISSING); | |
5a285add | 149 | return 0; |
f0efeea2 | 150 | } |
5a285add DM |
151 | |
152 | impl->md = md; | |
153 | return 1; | |
154 | ||
155 | default: | |
156 | return -2; | |
157 | } | |
158 | } | |
159 | ||
160 | static int kdf_pbkdf2_ctrl_str(EVP_KDF_IMPL *impl, const char *type, | |
161 | const char *value) | |
162 | { | |
163 | if (value == NULL) { | |
164 | KDFerr(KDF_F_KDF_PBKDF2_CTRL_STR, KDF_R_VALUE_MISSING); | |
165 | return 0; | |
166 | } | |
167 | ||
168 | if (strcmp(type, "pass") == 0) | |
169 | return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_PASS, | |
170 | value); | |
171 | ||
172 | if (strcmp(type, "hexpass") == 0) | |
173 | return kdf_hex2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_PASS, | |
174 | value); | |
175 | ||
176 | if (strcmp(type, "salt") == 0) | |
177 | return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_SALT, | |
178 | value); | |
179 | ||
180 | if (strcmp(type, "hexsalt") == 0) | |
181 | return kdf_hex2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_SALT, | |
182 | value); | |
183 | ||
184 | if (strcmp(type, "iter") == 0) | |
185 | return call_ctrl(kdf_pbkdf2_ctrl, impl, EVP_KDF_CTRL_SET_ITER, | |
186 | atoi(value)); | |
187 | ||
188 | if (strcmp(type, "digest") == 0) | |
189 | return kdf_md2ctrl(impl, kdf_pbkdf2_ctrl, EVP_KDF_CTRL_SET_MD, value); | |
190 | ||
f0efeea2 SL |
191 | if (strcmp(type, "pkcs5") == 0) |
192 | return kdf_str2ctrl(impl, kdf_pbkdf2_ctrl, | |
193 | EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE, value); | |
5a285add DM |
194 | return -2; |
195 | } | |
196 | ||
197 | static int kdf_pbkdf2_derive(EVP_KDF_IMPL *impl, unsigned char *key, | |
198 | size_t keylen) | |
199 | { | |
200 | if (impl->pass == NULL) { | |
201 | KDFerr(KDF_F_KDF_PBKDF2_DERIVE, KDF_R_MISSING_PASS); | |
202 | return 0; | |
203 | } | |
204 | ||
205 | if (impl->salt == NULL) { | |
206 | KDFerr(KDF_F_KDF_PBKDF2_DERIVE, KDF_R_MISSING_SALT); | |
207 | return 0; | |
208 | } | |
209 | ||
f0efeea2 SL |
210 | return pbkdf2_derive((char *)impl->pass, impl->pass_len, |
211 | impl->salt, impl->salt_len, impl->iter, | |
212 | impl->md, key, keylen, impl->lower_bound_checks); | |
5a285add DM |
213 | } |
214 | ||
d2ba8123 | 215 | const EVP_KDF pbkdf2_kdf_meth = { |
5a285add DM |
216 | EVP_KDF_PBKDF2, |
217 | kdf_pbkdf2_new, | |
218 | kdf_pbkdf2_free, | |
219 | kdf_pbkdf2_reset, | |
220 | kdf_pbkdf2_ctrl, | |
221 | kdf_pbkdf2_ctrl_str, | |
222 | NULL, | |
223 | kdf_pbkdf2_derive | |
224 | }; | |
225 | ||
226 | /* | |
227 | * This is an implementation of PKCS#5 v2.0 password based encryption key | |
228 | * derivation function PBKDF2. SHA1 version verified against test vectors | |
229 | * posted by Peter Gutmann to the PKCS-TNG mailing list. | |
f0efeea2 SL |
230 | * |
231 | * The constraints specified by SP800-132 have been added i.e. | |
232 | * - Check the range of the key length. | |
233 | * - Minimum iteration count of 1000. | |
234 | * - Randomly-generated portion of the salt shall be at least 128 bits. | |
5a285add | 235 | */ |
f0efeea2 SL |
236 | static int pbkdf2_derive(const char *pass, size_t passlen, |
237 | const unsigned char *salt, int saltlen, int iter, | |
238 | const EVP_MD *digest, unsigned char *key, | |
239 | size_t keylen, int lower_bound_checks) | |
5a285add DM |
240 | { |
241 | int ret = 0; | |
242 | unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; | |
243 | int cplen, j, k, tkeylen, mdlen; | |
244 | unsigned long i = 1; | |
245 | HMAC_CTX *hctx_tpl = NULL, *hctx = NULL; | |
246 | ||
247 | mdlen = EVP_MD_size(digest); | |
f0efeea2 SL |
248 | if (mdlen <= 0) |
249 | return 0; | |
250 | ||
251 | /* | |
252 | * This check should always be done because keylen / mdlen >= (2^32 - 1) | |
253 | * results in an overflow of the loop counter 'i'. | |
254 | */ | |
255 | if ((keylen / mdlen) >= KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO) { | |
256 | KDFerr(KDF_F_PBKDF2_DERIVE, KDF_R_INVALID_KEY_LEN); | |
5a285add | 257 | return 0; |
f0efeea2 SL |
258 | } |
259 | ||
260 | if (lower_bound_checks) { | |
261 | if ((keylen * 8) < KDF_PBKDF2_MIN_KEY_LEN_BITS) { | |
262 | KDFerr(KDF_F_PBKDF2_DERIVE, KDF_R_INVALID_KEY_LEN); | |
263 | return 0; | |
264 | } | |
265 | if (saltlen < KDF_PBKDF2_MIN_SALT_LEN) { | |
266 | KDFerr(KDF_F_PBKDF2_DERIVE, KDF_R_INVALID_SALT_LEN); | |
267 | return 0; | |
268 | } | |
269 | if (iter < KDF_PBKDF2_MIN_ITERATIONS) { | |
270 | KDFerr(KDF_F_PBKDF2_DERIVE, KDF_R_INVALID_ITERATION_COUNT); | |
271 | return 0; | |
272 | } | |
273 | } | |
5a285add DM |
274 | |
275 | hctx_tpl = HMAC_CTX_new(); | |
276 | if (hctx_tpl == NULL) | |
277 | return 0; | |
278 | p = key; | |
279 | tkeylen = keylen; | |
280 | if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) | |
281 | goto err; | |
282 | hctx = HMAC_CTX_new(); | |
283 | if (hctx == NULL) | |
284 | goto err; | |
285 | while (tkeylen) { | |
286 | if (tkeylen > mdlen) | |
287 | cplen = mdlen; | |
288 | else | |
289 | cplen = tkeylen; | |
290 | /* | |
291 | * We are unlikely to ever use more than 256 blocks (5120 bits!) but | |
292 | * just in case... | |
293 | */ | |
294 | itmp[0] = (unsigned char)((i >> 24) & 0xff); | |
295 | itmp[1] = (unsigned char)((i >> 16) & 0xff); | |
296 | itmp[2] = (unsigned char)((i >> 8) & 0xff); | |
297 | itmp[3] = (unsigned char)(i & 0xff); | |
298 | if (!HMAC_CTX_copy(hctx, hctx_tpl)) | |
299 | goto err; | |
300 | if (!HMAC_Update(hctx, salt, saltlen) | |
301 | || !HMAC_Update(hctx, itmp, 4) | |
302 | || !HMAC_Final(hctx, digtmp, NULL)) | |
303 | goto err; | |
304 | memcpy(p, digtmp, cplen); | |
305 | for (j = 1; j < iter; j++) { | |
306 | if (!HMAC_CTX_copy(hctx, hctx_tpl)) | |
307 | goto err; | |
308 | if (!HMAC_Update(hctx, digtmp, mdlen) | |
309 | || !HMAC_Final(hctx, digtmp, NULL)) | |
310 | goto err; | |
311 | for (k = 0; k < cplen; k++) | |
312 | p[k] ^= digtmp[k]; | |
313 | } | |
314 | tkeylen -= cplen; | |
315 | i++; | |
316 | p += cplen; | |
317 | } | |
318 | ret = 1; | |
319 | ||
320 | err: | |
321 | HMAC_CTX_free(hctx); | |
322 | HMAC_CTX_free(hctx_tpl); | |
323 | return ret; | |
324 | } |