Coverage Report

Created: 2023-09-25 06:45

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