Coverage Report

Created: 2023-06-08 06:40

/src/openssl111/crypto/kdf/tls1_prf.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 <stdio.h>
11
#include "internal/cryptlib.h"
12
#include <openssl/kdf.h>
13
#include <openssl/evp.h>
14
#include "crypto/evp.h"
15
16
static int tls1_prf_alg(const EVP_MD *md,
17
                        const unsigned char *sec, size_t slen,
18
                        const unsigned char *seed, size_t seed_len,
19
                        unsigned char *out, size_t olen);
20
21
14.1k
#define TLS1_PRF_MAXBUF 1024
22
23
/* TLS KDF pkey context structure */
24
25
typedef struct {
26
    /* Digest to use for PRF */
27
    const EVP_MD *md;
28
    /* Secret value to use for PRF */
29
    unsigned char *sec;
30
    size_t seclen;
31
    /* Buffer of concatenated seed data */
32
    unsigned char seed[TLS1_PRF_MAXBUF];
33
    size_t seedlen;
34
} TLS1_PRF_PKEY_CTX;
35
36
static int pkey_tls1_prf_init(EVP_PKEY_CTX *ctx)
37
5.48k
{
38
5.48k
    TLS1_PRF_PKEY_CTX *kctx;
39
40
5.48k
    if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL) {
41
0
        KDFerr(KDF_F_PKEY_TLS1_PRF_INIT, ERR_R_MALLOC_FAILURE);
42
0
        return 0;
43
0
    }
44
5.48k
    ctx->data = kctx;
45
46
5.48k
    return 1;
47
5.48k
}
48
49
static void pkey_tls1_prf_cleanup(EVP_PKEY_CTX *ctx)
50
5.48k
{
51
5.48k
    TLS1_PRF_PKEY_CTX *kctx = ctx->data;
52
5.48k
    OPENSSL_clear_free(kctx->sec, kctx->seclen);
53
5.48k
    OPENSSL_cleanse(kctx->seed, kctx->seedlen);
54
5.48k
    OPENSSL_free(kctx);
55
5.48k
}
56
57
static int pkey_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
58
38.3k
{
59
38.3k
    TLS1_PRF_PKEY_CTX *kctx = ctx->data;
60
38.3k
    switch (type) {
61
5.48k
    case EVP_PKEY_CTRL_TLS_MD:
62
5.48k
        kctx->md = p2;
63
5.48k
        return 1;
64
65
5.48k
    case EVP_PKEY_CTRL_TLS_SECRET:
66
5.48k
        if (p1 < 0)
67
0
            return 0;
68
5.48k
        if (kctx->sec != NULL)
69
0
            OPENSSL_clear_free(kctx->sec, kctx->seclen);
70
5.48k
        OPENSSL_cleanse(kctx->seed, kctx->seedlen);
71
5.48k
        kctx->seedlen = 0;
72
5.48k
        kctx->sec = OPENSSL_memdup(p2, p1);
73
5.48k
        if (kctx->sec == NULL)
74
0
            return 0;
75
5.48k
        kctx->seclen  = p1;
76
5.48k
        return 1;
77
78
27.4k
    case EVP_PKEY_CTRL_TLS_SEED:
79
27.4k
        if (p1 == 0 || p2 == NULL)
80
13.2k
            return 1;
81
14.1k
        if (p1 < 0 || p1 > (int)(TLS1_PRF_MAXBUF - kctx->seedlen))
82
0
            return 0;
83
14.1k
        memcpy(kctx->seed + kctx->seedlen, p2, p1);
84
14.1k
        kctx->seedlen += p1;
85
14.1k
        return 1;
86
87
0
    default:
88
0
        return -2;
89
90
38.3k
    }
91
38.3k
}
92
93
static int pkey_tls1_prf_ctrl_str(EVP_PKEY_CTX *ctx,
94
                                  const char *type, const char *value)
95
0
{
96
0
    if (value == NULL) {
97
0
        KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING);
98
0
        return 0;
99
0
    }
100
0
    if (strcmp(type, "md") == 0) {
101
0
        TLS1_PRF_PKEY_CTX *kctx = ctx->data;
102
103
0
        const EVP_MD *md = EVP_get_digestbyname(value);
104
0
        if (md == NULL) {
105
0
            KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_INVALID_DIGEST);
106
0
            return 0;
107
0
        }
108
0
        kctx->md = md;
109
0
        return 1;
110
0
    }
111
0
    if (strcmp(type, "secret") == 0)
112
0
        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
113
0
    if (strcmp(type, "hexsecret") == 0)
114
0
        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
115
0
    if (strcmp(type, "seed") == 0)
116
0
        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value);
117
0
    if (strcmp(type, "hexseed") == 0)
118
0
        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value);
119
120
0
    KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE);
121
0
    return -2;
122
0
}
123
124
static int pkey_tls1_prf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
125
                                size_t *keylen)
126
5.48k
{
127
5.48k
    TLS1_PRF_PKEY_CTX *kctx = ctx->data;
128
5.48k
    if (kctx->md == NULL) {
129
0
        KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_MESSAGE_DIGEST);
130
0
        return 0;
131
0
    }
132
5.48k
    if (kctx->sec == NULL) {
133
0
        KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SECRET);
134
0
        return 0;
135
0
    }
136
5.48k
    if (kctx->seedlen == 0) {
137
0
        KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SEED);
138
0
        return 0;
139
0
    }
140
5.48k
    return tls1_prf_alg(kctx->md, kctx->sec, kctx->seclen,
141
5.48k
                        kctx->seed, kctx->seedlen,
142
5.48k
                        key, *keylen);
143
5.48k
}
144
145
const EVP_PKEY_METHOD tls1_prf_pkey_meth = {
146
    EVP_PKEY_TLS1_PRF,
147
    0,
148
    pkey_tls1_prf_init,
149
    0,
150
    pkey_tls1_prf_cleanup,
151
152
    0, 0,
153
    0, 0,
154
155
    0,
156
    0,
157
158
    0,
159
    0,
160
161
    0, 0,
162
163
    0, 0, 0, 0,
164
165
    0, 0,
166
167
    0, 0,
168
169
    0,
170
    pkey_tls1_prf_derive,
171
    pkey_tls1_prf_ctrl,
172
    pkey_tls1_prf_ctrl_str
173
};
174
175
static int tls1_prf_P_hash(const EVP_MD *md,
176
                           const unsigned char *sec, size_t sec_len,
177
                           const unsigned char *seed, size_t seed_len,
178
                           unsigned char *out, size_t olen)
179
7.93k
{
180
7.93k
    int chunk;
181
7.93k
    EVP_MD_CTX *ctx = NULL, *ctx_tmp = NULL, *ctx_init = NULL;
182
7.93k
    EVP_PKEY *mac_key = NULL;
183
7.93k
    unsigned char A1[EVP_MAX_MD_SIZE];
184
7.93k
    size_t A1_len;
185
7.93k
    int ret = 0;
186
187
7.93k
    chunk = EVP_MD_size(md);
188
7.93k
    if (!ossl_assert(chunk > 0))
189
0
        goto err;
190
191
7.93k
    ctx = EVP_MD_CTX_new();
192
7.93k
    ctx_tmp = EVP_MD_CTX_new();
193
7.93k
    ctx_init = EVP_MD_CTX_new();
194
7.93k
    if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL)
195
0
        goto err;
196
7.93k
    EVP_MD_CTX_set_flags(ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
197
7.93k
    mac_key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
198
7.93k
    if (mac_key == NULL)
199
0
        goto err;
200
7.93k
    if (!EVP_DigestSignInit(ctx_init, NULL, md, NULL, mac_key))
201
0
        goto err;
202
7.93k
    if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
203
0
        goto err;
204
7.93k
    if (seed != NULL && !EVP_DigestSignUpdate(ctx, seed, seed_len))
205
0
        goto err;
206
7.93k
    if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
207
0
        goto err;
208
209
23.0k
    for (;;) {
210
        /* Reinit mac contexts */
211
23.0k
        if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
212
0
            goto err;
213
23.0k
        if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
214
0
            goto err;
215
23.0k
        if (olen > (size_t)chunk && !EVP_MD_CTX_copy_ex(ctx_tmp, ctx))
216
0
            goto err;
217
23.0k
        if (seed && !EVP_DigestSignUpdate(ctx, seed, seed_len))
218
0
            goto err;
219
220
23.0k
        if (olen > (size_t)chunk) {
221
15.0k
            size_t mac_len;
222
15.0k
            if (!EVP_DigestSignFinal(ctx, out, &mac_len))
223
0
                goto err;
224
15.0k
            out += mac_len;
225
15.0k
            olen -= mac_len;
226
            /* calc the next A1 value */
227
15.0k
            if (!EVP_DigestSignFinal(ctx_tmp, A1, &A1_len))
228
0
                goto err;
229
15.0k
        } else {                /* last one */
230
231
7.93k
            if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
232
0
                goto err;
233
7.93k
            memcpy(out, A1, olen);
234
7.93k
            break;
235
7.93k
        }
236
23.0k
    }
237
7.93k
    ret = 1;
238
7.93k
 err:
239
7.93k
    EVP_PKEY_free(mac_key);
240
7.93k
    EVP_MD_CTX_free(ctx);
241
7.93k
    EVP_MD_CTX_free(ctx_tmp);
242
7.93k
    EVP_MD_CTX_free(ctx_init);
243
7.93k
    OPENSSL_cleanse(A1, sizeof(A1));
244
7.93k
    return ret;
245
7.93k
}
246
247
static int tls1_prf_alg(const EVP_MD *md,
248
                        const unsigned char *sec, size_t slen,
249
                        const unsigned char *seed, size_t seed_len,
250
                        unsigned char *out, size_t olen)
251
5.48k
{
252
253
5.48k
    if (EVP_MD_type(md) == NID_md5_sha1) {
254
2.45k
        size_t i;
255
2.45k
        unsigned char *tmp;
256
2.45k
        if (!tls1_prf_P_hash(EVP_md5(), sec, slen/2 + (slen & 1),
257
2.45k
                         seed, seed_len, out, olen))
258
0
            return 0;
259
260
2.45k
        if ((tmp = OPENSSL_malloc(olen)) == NULL) {
261
0
            KDFerr(KDF_F_TLS1_PRF_ALG, ERR_R_MALLOC_FAILURE);
262
0
            return 0;
263
0
        }
264
2.45k
        if (!tls1_prf_P_hash(EVP_sha1(), sec + slen/2, slen/2 + (slen & 1),
265
2.45k
                         seed, seed_len, tmp, olen)) {
266
0
            OPENSSL_clear_free(tmp, olen);
267
0
            return 0;
268
0
        }
269
130k
        for (i = 0; i < olen; i++)
270
128k
            out[i] ^= tmp[i];
271
2.45k
        OPENSSL_clear_free(tmp, olen);
272
2.45k
        return 1;
273
2.45k
    }
274
3.03k
    if (!tls1_prf_P_hash(md, sec, slen, seed, seed_len, out, olen))
275
0
        return 0;
276
277
3.03k
    return 1;
278
3.03k
}