VirtualBox

source: vbox/trunk/src/libs/openssl-1.1.1g/crypto/kdf/scrypt.c@ 83916

Last change on this file since 83916 was 83916, checked in by vboxsync, 5 years ago

openssl-1.1.1g: Applied and adjusted our OpenSSL changes to 1.1.1g. bugref:9719

File size: 6.5 KB
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 "crypto/evp.h"
17
18#ifndef OPENSSL_NO_SCRYPT
19
20static int atou64(const char *nptr, uint64_t *result);
21
22typedef 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 */
32static int atou64(const char *nptr, uint64_t *result)
33{
34 uint64_t value = 0;
35
36 while (*nptr) {
37 unsigned int digit;
38 uint64_t new_value;
39
40 if ((*nptr < '0') || (*nptr > '9')) {
41 return 0;
42 }
43 digit = (unsigned int)(*nptr - '0');
44 new_value = (value * 10) + digit;
45 if ((new_value < digit) || ((new_value - digit) / 10 != value)) {
46 /* Overflow */
47 return 0;
48 }
49 value = new_value;
50 nptr++;
51 }
52 *result = value;
53 return 1;
54}
55
56static int pkey_scrypt_init(EVP_PKEY_CTX *ctx)
57{
58 SCRYPT_PKEY_CTX *kctx;
59
60 kctx = OPENSSL_zalloc(sizeof(*kctx));
61 if (kctx == NULL) {
62 KDFerr(KDF_F_PKEY_SCRYPT_INIT, ERR_R_MALLOC_FAILURE);
63 return 0;
64 }
65
66 /* Default values are the most conservative recommendation given in the
67 * original paper of C. Percival. Derivation uses roughly 1 GiB of memory
68 * for this parameter choice (approx. 128 * r * (N + p) bytes).
69 */
70 kctx->N = 1 << 20;
71 kctx->r = 8;
72 kctx->p = 1;
73 kctx->maxmem_bytes = 1025 * 1024 * 1024;
74
75 ctx->data = kctx;
76
77 return 1;
78}
79
80static void pkey_scrypt_cleanup(EVP_PKEY_CTX *ctx)
81{
82 SCRYPT_PKEY_CTX *kctx = ctx->data;
83
84 OPENSSL_clear_free(kctx->salt, kctx->salt_len);
85 OPENSSL_clear_free(kctx->pass, kctx->pass_len);
86 OPENSSL_free(kctx);
87}
88
89static int pkey_scrypt_set_membuf(unsigned char **buffer, size_t *buflen,
90 const unsigned char *new_buffer,
91 const int new_buflen)
92{
93 if (new_buffer == NULL)
94 return 1;
95
96 if (new_buflen < 0)
97 return 0;
98
99 if (*buffer != NULL)
100 OPENSSL_clear_free(*buffer, *buflen);
101
102 if (new_buflen > 0) {
103 *buffer = OPENSSL_memdup(new_buffer, new_buflen);
104 } else {
105 *buffer = OPENSSL_malloc(1);
106 }
107 if (*buffer == NULL) {
108 KDFerr(KDF_F_PKEY_SCRYPT_SET_MEMBUF, ERR_R_MALLOC_FAILURE);
109 return 0;
110 }
111
112 *buflen = new_buflen;
113 return 1;
114}
115
116static int is_power_of_two(uint64_t value)
117{
118 return (value != 0) && ((value & (value - 1)) == 0);
119}
120
121static int pkey_scrypt_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
122{
123 SCRYPT_PKEY_CTX *kctx = ctx->data;
124 uint64_t u64_value;
125
126 switch (type) {
127 case EVP_PKEY_CTRL_PASS:
128 return pkey_scrypt_set_membuf(&kctx->pass, &kctx->pass_len, p2, p1);
129
130 case EVP_PKEY_CTRL_SCRYPT_SALT:
131 return pkey_scrypt_set_membuf(&kctx->salt, &kctx->salt_len, p2, p1);
132
133 case EVP_PKEY_CTRL_SCRYPT_N:
134 u64_value = *((uint64_t *)p2);
135 if ((u64_value <= 1) || !is_power_of_two(u64_value))
136 return 0;
137 kctx->N = u64_value;
138 return 1;
139
140 case EVP_PKEY_CTRL_SCRYPT_R:
141 u64_value = *((uint64_t *)p2);
142 if (u64_value < 1)
143 return 0;
144 kctx->r = u64_value;
145 return 1;
146
147 case EVP_PKEY_CTRL_SCRYPT_P:
148 u64_value = *((uint64_t *)p2);
149 if (u64_value < 1)
150 return 0;
151 kctx->p = u64_value;
152 return 1;
153
154 case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES:
155 u64_value = *((uint64_t *)p2);
156 if (u64_value < 1)
157 return 0;
158 kctx->maxmem_bytes = u64_value;
159 return 1;
160
161 default:
162 return -2;
163
164 }
165}
166
167static int pkey_scrypt_ctrl_uint64(EVP_PKEY_CTX *ctx, int type,
168 const char *value)
169{
170 uint64_t int_value;
171
172 if (!atou64(value, &int_value)) {
173 KDFerr(KDF_F_PKEY_SCRYPT_CTRL_UINT64, KDF_R_VALUE_ERROR);
174 return 0;
175 }
176 return pkey_scrypt_ctrl(ctx, type, 0, &int_value);
177}
178
179static 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
216static int pkey_scrypt_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
217 size_t *keylen)
218{
219 SCRYPT_PKEY_CTX *kctx = ctx->data;
220
221 if (kctx->pass == NULL) {
222 KDFerr(KDF_F_PKEY_SCRYPT_DERIVE, KDF_R_MISSING_PASS);
223 return 0;
224 }
225
226 if (kctx->salt == NULL) {
227 KDFerr(KDF_F_PKEY_SCRYPT_DERIVE, KDF_R_MISSING_SALT);
228 return 0;
229 }
230
231 return EVP_PBE_scrypt((char *)kctx->pass, kctx->pass_len, kctx->salt,
232 kctx->salt_len, kctx->N, kctx->r, kctx->p,
233 kctx->maxmem_bytes, key, *keylen);
234}
235
236const 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
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette