Coverage Report

Created: 2023-06-08 06:41

/src/openssl111/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 "crypto/evp.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
36
0
    while (*nptr) {
37
0
        unsigned int digit;
38
0
        uint64_t new_value;
39
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
            /* 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
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
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
0
    kctx->N = 1 << 20;
71
0
    kctx->r = 8;
72
0
    kctx->p = 1;
73
0
    kctx->maxmem_bytes = 1025 * 1024 * 1024;
74
75
0
    ctx->data = kctx;
76
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
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
96
0
    if (new_buflen < 0)
97
0
        return 0;
98
99
0
    if (*buffer != NULL)
100
0
        OPENSSL_clear_free(*buffer, *buflen);
101
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
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
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
130
0
    case EVP_PKEY_CTRL_SCRYPT_SALT:
131
0
        return pkey_scrypt_set_membuf(&kctx->salt, &kctx->salt_len, p2, p1);
132
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
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
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
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
161
0
    default:
162
0
        return -2;
163
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
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
0
{
182
0
    if (value == NULL) {
183
0
        KDFerr(KDF_F_PKEY_SCRYPT_CTRL_STR, KDF_R_VALUE_MISSING);
184
0
        return 0;
185
0
    }
186
187
0
    if (strcmp(type, "pass") == 0)
188
0
        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_PASS, value);
189
190
0
    if (strcmp(type, "hexpass") == 0)
191
0
        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_PASS, value);
192
193
0
    if (strcmp(type, "salt") == 0)
194
0
        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SCRYPT_SALT, value);
195
196
0
    if (strcmp(type, "hexsalt") == 0)
197
0
        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SCRYPT_SALT, value);
198
199
0
    if (strcmp(type, "N") == 0)
200
0
        return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_N, value);
201
202
0
    if (strcmp(type, "r") == 0)
203
0
        return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_R, value);
204
205
0
    if (strcmp(type, "p") == 0)
206
0
        return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_P, value);
207
208
0
    if (strcmp(type, "maxmem_bytes") == 0)
209
0
        return pkey_scrypt_ctrl_uint64(ctx, EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES,
210
0
                                       value);
211
212
0
    KDFerr(KDF_F_PKEY_SCRYPT_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE);
213
0
    return -2;
214
0
}
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
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
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
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