Coverage Report

Created: 2018-08-29 13:53

/src/openssl/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 "internal/evp_int.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
0
#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
0
{
38
0
    TLS1_PRF_PKEY_CTX *kctx;
39
0
40
0
    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
0
    ctx->data = kctx;
45
0
46
0
    return 1;
47
0
}
48
49
static void pkey_tls1_prf_cleanup(EVP_PKEY_CTX *ctx)
50
0
{
51
0
    TLS1_PRF_PKEY_CTX *kctx = ctx->data;
52
0
    OPENSSL_clear_free(kctx->sec, kctx->seclen);
53
0
    OPENSSL_cleanse(kctx->seed, kctx->seedlen);
54
0
    OPENSSL_free(kctx);
55
0
}
56
57
static int pkey_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
58
0
{
59
0
    TLS1_PRF_PKEY_CTX *kctx = ctx->data;
60
0
    switch (type) {
61
0
    case EVP_PKEY_CTRL_TLS_MD:
62
0
        kctx->md = p2;
63
0
        return 1;
64
0
65
0
    case EVP_PKEY_CTRL_TLS_SECRET:
66
0
        if (p1 < 0)
67
0
            return 0;
68
0
        if (kctx->sec != NULL)
69
0
            OPENSSL_clear_free(kctx->sec, kctx->seclen);
70
0
        OPENSSL_cleanse(kctx->seed, kctx->seedlen);
71
0
        kctx->seedlen = 0;
72
0
        kctx->sec = OPENSSL_memdup(p2, p1);
73
0
        if (kctx->sec == NULL)
74
0
            return 0;
75
0
        kctx->seclen  = p1;
76
0
        return 1;
77
0
78
0
    case EVP_PKEY_CTRL_TLS_SEED:
79
0
        if (p1 == 0 || p2 == NULL)
80
0
            return 1;
81
0
        if (p1 < 0 || p1 > (int)(TLS1_PRF_MAXBUF - kctx->seedlen))
82
0
            return 0;
83
0
        memcpy(kctx->seed + kctx->seedlen, p2, p1);
84
0
        kctx->seedlen += p1;
85
0
        return 1;
86
0
87
0
    default:
88
0
        return -2;
89
0
90
0
    }
91
0
}
92
93
static int pkey_tls1_prf_ctrl_str(EVP_PKEY_CTX *ctx,
94
                                  const char *type, const char *value)
95
{
96
    if (value == NULL) {
97
        KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING);
98
        return 0;
99
    }
100
    if (strcmp(type, "md") == 0) {
101
        TLS1_PRF_PKEY_CTX *kctx = ctx->data;
102
103
        const EVP_MD *md = EVP_get_digestbyname(value);
104
        if (md == NULL) {
105
            KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_INVALID_DIGEST);
106
            return 0;
107
        }
108
        kctx->md = md;
109
        return 1;
110
    }
111
    if (strcmp(type, "secret") == 0)
112
        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
113
    if (strcmp(type, "hexsecret") == 0)
114
        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
115
    if (strcmp(type, "seed") == 0)
116
        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value);
117
    if (strcmp(type, "hexseed") == 0)
118
        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value);
119
120
    KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_UNKNOWN_PARAMETER_TYPE);
121
    return -2;
122
}
123
124
static int pkey_tls1_prf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
125
                                size_t *keylen)
126
0
{
127
0
    TLS1_PRF_PKEY_CTX *kctx = ctx->data;
128
0
    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
0
    if (kctx->sec == NULL) {
133
0
        KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SECRET);
134
0
        return 0;
135
0
    }
136
0
    if (kctx->seedlen == 0) {
137
0
        KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_SEED);
138
0
        return 0;
139
0
    }
140
0
    return tls1_prf_alg(kctx->md, kctx->sec, kctx->seclen,
141
0
                        kctx->seed, kctx->seedlen,
142
0
                        key, *keylen);
143
0
}
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
0
{
180
0
    int chunk;
181
0
    EVP_MD_CTX *ctx = NULL, *ctx_tmp = NULL, *ctx_init = NULL;
182
0
    EVP_PKEY *mac_key = NULL;
183
0
    unsigned char A1[EVP_MAX_MD_SIZE];
184
0
    size_t A1_len;
185
0
    int ret = 0;
186
0
187
0
    chunk = EVP_MD_size(md);
188
0
    if (!ossl_assert(chunk > 0))
189
0
        goto err;
190
0
191
0
    ctx = EVP_MD_CTX_new();
192
0
    ctx_tmp = EVP_MD_CTX_new();
193
0
    ctx_init = EVP_MD_CTX_new();
194
0
    if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL)
195
0
        goto err;
196
0
    EVP_MD_CTX_set_flags(ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
197
0
    mac_key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
198
0
    if (mac_key == NULL)
199
0
        goto err;
200
0
    if (!EVP_DigestSignInit(ctx_init, NULL, md, NULL, mac_key))
201
0
        goto err;
202
0
    if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
203
0
        goto err;
204
0
    if (seed != NULL && !EVP_DigestSignUpdate(ctx, seed, seed_len))
205
0
        goto err;
206
0
    if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
207
0
        goto err;
208
0
209
0
    for (;;) {
210
0
        /* Reinit mac contexts */
211
0
        if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
212
0
            goto err;
213
0
        if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
214
0
            goto err;
215
0
        if (olen > (size_t)chunk && !EVP_MD_CTX_copy_ex(ctx_tmp, ctx))
216
0
            goto err;
217
0
        if (seed && !EVP_DigestSignUpdate(ctx, seed, seed_len))
218
0
            goto err;
219
0
220
0
        if (olen > (size_t)chunk) {
221
0
            size_t mac_len;
222
0
            if (!EVP_DigestSignFinal(ctx, out, &mac_len))
223
0
                goto err;
224
0
            out += mac_len;
225
0
            olen -= mac_len;
226
0
            /* calc the next A1 value */
227
0
            if (!EVP_DigestSignFinal(ctx_tmp, A1, &A1_len))
228
0
                goto err;
229
0
        } else {                /* last one */
230
0
231
0
            if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
232
0
                goto err;
233
0
            memcpy(out, A1, olen);
234
0
            break;
235
0
        }
236
0
    }
237
0
    ret = 1;
238
0
 err:
239
0
    EVP_PKEY_free(mac_key);
240
0
    EVP_MD_CTX_free(ctx);
241
0
    EVP_MD_CTX_free(ctx_tmp);
242
0
    EVP_MD_CTX_free(ctx_init);
243
0
    OPENSSL_cleanse(A1, sizeof(A1));
244
0
    return ret;
245
0
}
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
0
{
252
0
253
0
    if (EVP_MD_type(md) == NID_md5_sha1) {
254
0
        size_t i;
255
0
        unsigned char *tmp;
256
0
        if (!tls1_prf_P_hash(EVP_md5(), sec, slen/2 + (slen & 1),
257
0
                         seed, seed_len, out, olen))
258
0
            return 0;
259
0
260
0
        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
0
        if (!tls1_prf_P_hash(EVP_sha1(), sec + slen/2, slen/2 + (slen & 1),
265
0
                         seed, seed_len, tmp, olen)) {
266
0
            OPENSSL_clear_free(tmp, olen);
267
0
            return 0;
268
0
        }
269
0
        for (i = 0; i < olen; i++)
270
0
            out[i] ^= tmp[i];
271
0
        OPENSSL_clear_free(tmp, olen);
272
0
        return 1;
273
0
    }
274
0
    if (!tls1_prf_P_hash(md, sec, slen, seed, seed_len, out, olen))
275
0
        return 0;
276
0
277
0
    return 1;
278
0
}