Coverage Report

Created: 2023-09-25 06:41

/src/openssl111/crypto/kdf/hkdf.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2016-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
545
#define HKDF_MAXBUF 1024
19
20
static unsigned char *HKDF(const EVP_MD *evp_md,
21
                           const unsigned char *salt, size_t salt_len,
22
                           const unsigned char *key, size_t key_len,
23
                           const unsigned char *info, size_t info_len,
24
                           unsigned char *okm, size_t okm_len);
25
26
static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
27
                                   const unsigned char *salt, size_t salt_len,
28
                                   const unsigned char *key, size_t key_len,
29
                                   unsigned char *prk, size_t *prk_len);
30
31
static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
32
                                  const unsigned char *prk, size_t prk_len,
33
                                  const unsigned char *info, size_t info_len,
34
                                  unsigned char *okm, size_t okm_len);
35
36
typedef struct {
37
    int mode;
38
    const EVP_MD *md;
39
    unsigned char *salt;
40
    size_t salt_len;
41
    unsigned char *key;
42
    size_t key_len;
43
    unsigned char info[HKDF_MAXBUF];
44
    size_t info_len;
45
} HKDF_PKEY_CTX;
46
47
static int pkey_hkdf_init(EVP_PKEY_CTX *ctx)
48
763
{
49
763
    HKDF_PKEY_CTX *kctx;
50
51
763
    if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) {
52
0
        KDFerr(KDF_F_PKEY_HKDF_INIT, ERR_R_MALLOC_FAILURE);
53
0
        return 0;
54
0
    }
55
56
763
    ctx->data = kctx;
57
58
763
    return 1;
59
763
}
60
61
static void pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx)
62
763
{
63
763
    HKDF_PKEY_CTX *kctx = ctx->data;
64
763
    OPENSSL_clear_free(kctx->salt, kctx->salt_len);
65
763
    OPENSSL_clear_free(kctx->key, kctx->key_len);
66
763
    OPENSSL_cleanse(kctx->info, kctx->info_len);
67
763
    OPENSSL_free(kctx);
68
763
}
69
70
static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
71
3.05k
{
72
3.05k
    HKDF_PKEY_CTX *kctx = ctx->data;
73
74
3.05k
    switch (type) {
75
763
    case EVP_PKEY_CTRL_HKDF_MD:
76
763
        if (p2 == NULL)
77
0
            return 0;
78
79
763
        kctx->md = p2;
80
763
        return 1;
81
82
763
    case EVP_PKEY_CTRL_HKDF_MODE:
83
763
        kctx->mode = p1;
84
763
        return 1;
85
86
218
    case EVP_PKEY_CTRL_HKDF_SALT:
87
218
        if (p1 == 0 || p2 == NULL)
88
109
            return 1;
89
90
109
        if (p1 < 0)
91
0
            return 0;
92
93
109
        if (kctx->salt != NULL)
94
0
            OPENSSL_clear_free(kctx->salt, kctx->salt_len);
95
96
109
        kctx->salt = OPENSSL_memdup(p2, p1);
97
109
        if (kctx->salt == NULL)
98
0
            return 0;
99
100
109
        kctx->salt_len = p1;
101
109
        return 1;
102
103
763
    case EVP_PKEY_CTRL_HKDF_KEY:
104
763
        if (p1 < 0)
105
0
            return 0;
106
107
763
        if (kctx->key != NULL)
108
0
            OPENSSL_clear_free(kctx->key, kctx->key_len);
109
110
763
        kctx->key = OPENSSL_memdup(p2, p1);
111
763
        if (kctx->key == NULL)
112
0
            return 0;
113
114
763
        kctx->key_len  = p1;
115
763
        return 1;
116
117
545
    case EVP_PKEY_CTRL_HKDF_INFO:
118
545
        if (p1 == 0 || p2 == NULL)
119
0
            return 1;
120
121
545
        if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len))
122
0
            return 0;
123
124
545
        memcpy(kctx->info + kctx->info_len, p2, p1);
125
545
        kctx->info_len += p1;
126
545
        return 1;
127
128
0
    default:
129
0
        return -2;
130
131
3.05k
    }
132
3.05k
}
133
134
static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
135
                              const char *value)
136
0
{
137
0
    if (strcmp(type, "mode") == 0) {
138
0
        int mode;
139
140
0
        if (strcmp(value, "EXTRACT_AND_EXPAND") == 0)
141
0
            mode = EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND;
142
0
        else if (strcmp(value, "EXTRACT_ONLY") == 0)
143
0
            mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY;
144
0
        else if (strcmp(value, "EXPAND_ONLY") == 0)
145
0
            mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
146
0
        else
147
0
            return 0;
148
149
0
        return EVP_PKEY_CTX_hkdf_mode(ctx, mode);
150
0
    }
151
152
0
    if (strcmp(type, "md") == 0)
153
0
        return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_DERIVE,
154
0
                               EVP_PKEY_CTRL_HKDF_MD, value);
155
156
0
    if (strcmp(type, "salt") == 0)
157
0
        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
158
159
0
    if (strcmp(type, "hexsalt") == 0)
160
0
        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
161
162
0
    if (strcmp(type, "key") == 0)
163
0
        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
164
165
0
    if (strcmp(type, "hexkey") == 0)
166
0
        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
167
168
0
    if (strcmp(type, "info") == 0)
169
0
        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
170
171
0
    if (strcmp(type, "hexinfo") == 0)
172
0
        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
173
174
0
    KDFerr(KDF_F_PKEY_HKDF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE);
175
0
    return -2;
176
0
}
177
178
static int pkey_hkdf_derive_init(EVP_PKEY_CTX *ctx)
179
763
{
180
763
    HKDF_PKEY_CTX *kctx = ctx->data;
181
182
763
    OPENSSL_clear_free(kctx->key, kctx->key_len);
183
763
    OPENSSL_clear_free(kctx->salt, kctx->salt_len);
184
763
    OPENSSL_cleanse(kctx->info, kctx->info_len);
185
763
    memset(kctx, 0, sizeof(*kctx));
186
187
763
    return 1;
188
763
}
189
190
static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
191
                            size_t *keylen)
192
763
{
193
763
    HKDF_PKEY_CTX *kctx = ctx->data;
194
195
763
    if (kctx->md == NULL) {
196
0
        KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
197
0
        return 0;
198
0
    }
199
763
    if (kctx->key == NULL) {
200
0
        KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_KEY);
201
0
        return 0;
202
0
    }
203
204
763
    switch (kctx->mode) {
205
0
    case EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND:
206
0
        return HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
207
0
                    kctx->key_len, kctx->info, kctx->info_len, key,
208
0
                    *keylen) != NULL;
209
210
218
    case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY:
211
218
        if (key == NULL) {
212
0
            *keylen = EVP_MD_size(kctx->md);
213
0
            return 1;
214
0
        }
215
218
        return HKDF_Extract(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
216
218
                            kctx->key_len, key, keylen) != NULL;
217
218
545
    case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY:
219
545
        return HKDF_Expand(kctx->md, kctx->key, kctx->key_len, kctx->info,
220
545
                           kctx->info_len, key, *keylen) != NULL;
221
222
0
    default:
223
0
        return 0;
224
763
    }
225
763
}
226
227
const EVP_PKEY_METHOD hkdf_pkey_meth = {
228
    EVP_PKEY_HKDF,
229
    0,
230
    pkey_hkdf_init,
231
    0,
232
    pkey_hkdf_cleanup,
233
234
    0, 0,
235
    0, 0,
236
237
    0,
238
    0,
239
240
    0,
241
    0,
242
243
    0, 0,
244
245
    0, 0, 0, 0,
246
247
    0, 0,
248
249
    0, 0,
250
251
    pkey_hkdf_derive_init,
252
    pkey_hkdf_derive,
253
    pkey_hkdf_ctrl,
254
    pkey_hkdf_ctrl_str
255
};
256
257
static unsigned char *HKDF(const EVP_MD *evp_md,
258
                           const unsigned char *salt, size_t salt_len,
259
                           const unsigned char *key, size_t key_len,
260
                           const unsigned char *info, size_t info_len,
261
                           unsigned char *okm, size_t okm_len)
262
0
{
263
0
    unsigned char prk[EVP_MAX_MD_SIZE];
264
0
    unsigned char *ret;
265
0
    size_t prk_len;
266
267
0
    if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, &prk_len))
268
0
        return NULL;
269
270
0
    ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
271
0
    OPENSSL_cleanse(prk, sizeof(prk));
272
273
0
    return ret;
274
0
}
275
276
static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
277
                                   const unsigned char *salt, size_t salt_len,
278
                                   const unsigned char *key, size_t key_len,
279
                                   unsigned char *prk, size_t *prk_len)
280
218
{
281
218
    unsigned int tmp_len;
282
283
218
    if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len))
284
0
        return NULL;
285
286
218
    *prk_len = tmp_len;
287
218
    return prk;
288
218
}
289
290
static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
291
                                  const unsigned char *prk, size_t prk_len,
292
                                  const unsigned char *info, size_t info_len,
293
                                  unsigned char *okm, size_t okm_len)
294
545
{
295
545
    HMAC_CTX *hmac;
296
545
    unsigned char *ret = NULL;
297
298
545
    unsigned int i;
299
300
545
    unsigned char prev[EVP_MAX_MD_SIZE];
301
302
545
    size_t done_len = 0, dig_len = EVP_MD_size(evp_md);
303
304
545
    size_t n = okm_len / dig_len;
305
545
    if (okm_len % dig_len)
306
171
        n++;
307
308
545
    if (n > 255 || okm == NULL)
309
0
        return NULL;
310
311
545
    if ((hmac = HMAC_CTX_new()) == NULL)
312
0
        return NULL;
313
314
545
    if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
315
0
        goto err;
316
317
1.09k
    for (i = 1; i <= n; i++) {
318
545
        size_t copy_len;
319
545
        const unsigned char ctr = i;
320
321
545
        if (i > 1) {
322
0
            if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL))
323
0
                goto err;
324
325
0
            if (!HMAC_Update(hmac, prev, dig_len))
326
0
                goto err;
327
0
        }
328
329
545
        if (!HMAC_Update(hmac, info, info_len))
330
0
            goto err;
331
332
545
        if (!HMAC_Update(hmac, &ctr, 1))
333
0
            goto err;
334
335
545
        if (!HMAC_Final(hmac, prev, NULL))
336
0
            goto err;
337
338
545
        copy_len = (done_len + dig_len > okm_len) ?
339
171
                       okm_len - done_len :
340
545
                       dig_len;
341
342
545
        memcpy(okm + done_len, prev, copy_len);
343
344
545
        done_len += copy_len;
345
545
    }
346
545
    ret = okm;
347
348
545
 err:
349
545
    OPENSSL_cleanse(prev, sizeof(prev));
350
545
    HMAC_CTX_free(hmac);
351
545
    return ret;
352
545
}