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
7.75k
#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
9.42k
{
49
9.42k
    HKDF_PKEY_CTX *kctx;
50
51
9.42k
    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
9.42k
    ctx->data = kctx;
57
58
9.42k
    return 1;
59
9.42k
}
60
61
static void pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx)
62
9.42k
{
63
9.42k
    HKDF_PKEY_CTX *kctx = ctx->data;
64
9.42k
    OPENSSL_clear_free(kctx->salt, kctx->salt_len);
65
9.42k
    OPENSSL_clear_free(kctx->key, kctx->key_len);
66
9.42k
    OPENSSL_cleanse(kctx->info, kctx->info_len);
67
9.42k
    OPENSSL_free(kctx);
68
9.42k
}
69
70
static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
71
37.6k
{
72
37.6k
    HKDF_PKEY_CTX *kctx = ctx->data;
73
74
37.6k
    switch (type) {
75
9.42k
    case EVP_PKEY_CTRL_HKDF_MD:
76
9.42k
        if (p2 == NULL)
77
0
            return 0;
78
79
9.42k
        kctx->md = p2;
80
9.42k
        return 1;
81
82
9.42k
    case EVP_PKEY_CTRL_HKDF_MODE:
83
9.42k
        kctx->mode = p1;
84
9.42k
        return 1;
85
86
1.66k
    case EVP_PKEY_CTRL_HKDF_SALT:
87
1.66k
        if (p1 == 0 || p2 == NULL)
88
564
            return 1;
89
90
1.10k
        if (p1 < 0)
91
0
            return 0;
92
93
1.10k
        if (kctx->salt != NULL)
94
0
            OPENSSL_clear_free(kctx->salt, kctx->salt_len);
95
96
1.10k
        kctx->salt = OPENSSL_memdup(p2, p1);
97
1.10k
        if (kctx->salt == NULL)
98
0
            return 0;
99
100
1.10k
        kctx->salt_len = p1;
101
1.10k
        return 1;
102
103
9.42k
    case EVP_PKEY_CTRL_HKDF_KEY:
104
9.42k
        if (p1 < 0)
105
0
            return 0;
106
107
9.42k
        if (kctx->key != NULL)
108
0
            OPENSSL_clear_free(kctx->key, kctx->key_len);
109
110
9.42k
        kctx->key = OPENSSL_memdup(p2, p1);
111
9.42k
        if (kctx->key == NULL)
112
0
            return 0;
113
114
9.42k
        kctx->key_len  = p1;
115
9.42k
        return 1;
116
117
7.75k
    case EVP_PKEY_CTRL_HKDF_INFO:
118
7.75k
        if (p1 == 0 || p2 == NULL)
119
0
            return 1;
120
121
7.75k
        if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len))
122
0
            return 0;
123
124
7.75k
        memcpy(kctx->info + kctx->info_len, p2, p1);
125
7.75k
        kctx->info_len += p1;
126
7.75k
        return 1;
127
128
0
    default:
129
0
        return -2;
130
131
37.6k
    }
132
37.6k
}
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
9.42k
{
180
9.42k
    HKDF_PKEY_CTX *kctx = ctx->data;
181
182
9.42k
    OPENSSL_clear_free(kctx->key, kctx->key_len);
183
9.42k
    OPENSSL_clear_free(kctx->salt, kctx->salt_len);
184
9.42k
    OPENSSL_cleanse(kctx->info, kctx->info_len);
185
9.42k
    memset(kctx, 0, sizeof(*kctx));
186
187
9.42k
    return 1;
188
9.42k
}
189
190
static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
191
                            size_t *keylen)
192
9.42k
{
193
9.42k
    HKDF_PKEY_CTX *kctx = ctx->data;
194
195
9.42k
    if (kctx->md == NULL) {
196
0
        KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
197
0
        return 0;
198
0
    }
199
9.42k
    if (kctx->key == NULL) {
200
0
        KDFerr(KDF_F_PKEY_HKDF_DERIVE, KDF_R_MISSING_KEY);
201
0
        return 0;
202
0
    }
203
204
9.42k
    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
1.66k
    case EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY:
211
1.66k
        if (key == NULL) {
212
0
            *keylen = EVP_MD_size(kctx->md);
213
0
            return 1;
214
0
        }
215
1.66k
        return HKDF_Extract(kctx->md, kctx->salt, kctx->salt_len, kctx->key,
216
1.66k
                            kctx->key_len, key, keylen) != NULL;
217
218
7.75k
    case EVP_PKEY_HKDEF_MODE_EXPAND_ONLY:
219
7.75k
        return HKDF_Expand(kctx->md, kctx->key, kctx->key_len, kctx->info,
220
7.75k
                           kctx->info_len, key, *keylen) != NULL;
221
222
0
    default:
223
0
        return 0;
224
9.42k
    }
225
9.42k
}
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
1.66k
{
281
1.66k
    unsigned int tmp_len;
282
283
1.66k
    if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len))
284
0
        return NULL;
285
286
1.66k
    *prk_len = tmp_len;
287
1.66k
    return prk;
288
1.66k
}
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
7.75k
{
295
7.75k
    HMAC_CTX *hmac;
296
7.75k
    unsigned char *ret = NULL;
297
298
7.75k
    unsigned int i;
299
300
7.75k
    unsigned char prev[EVP_MAX_MD_SIZE];
301
302
7.75k
    size_t done_len = 0, dig_len = EVP_MD_size(evp_md);
303
304
7.75k
    size_t n = okm_len / dig_len;
305
7.75k
    if (okm_len % dig_len)
306
2.43k
        n++;
307
308
7.75k
    if (n > 255 || okm == NULL)
309
0
        return NULL;
310
311
7.75k
    if ((hmac = HMAC_CTX_new()) == NULL)
312
0
        return NULL;
313
314
7.75k
    if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
315
0
        goto err;
316
317
15.5k
    for (i = 1; i <= n; i++) {
318
7.75k
        size_t copy_len;
319
7.75k
        const unsigned char ctr = i;
320
321
7.75k
        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
7.75k
        if (!HMAC_Update(hmac, info, info_len))
330
0
            goto err;
331
332
7.75k
        if (!HMAC_Update(hmac, &ctr, 1))
333
0
            goto err;
334
335
7.75k
        if (!HMAC_Final(hmac, prev, NULL))
336
0
            goto err;
337
338
7.75k
        copy_len = (done_len + dig_len > okm_len) ?
339
2.43k
                       okm_len - done_len :
340
7.75k
                       dig_len;
341
342
7.75k
        memcpy(okm + done_len, prev, copy_len);
343
344
7.75k
        done_len += copy_len;
345
7.75k
    }
346
7.75k
    ret = okm;
347
348
7.75k
 err:
349
7.75k
    OPENSSL_cleanse(prev, sizeof(prev));
350
7.75k
    HMAC_CTX_free(hmac);
351
7.75k
    return ret;
352
7.75k
}