Coverage Report

Created: 2023-06-08 06:40

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