Coverage Report

Created: 2018-08-29 13:53

/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