Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/dh/dh_pmeth.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3
 * 2006.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this
21
 *    software must display the following acknowledgment:
22
 *    "This product includes software developed by the OpenSSL Project
23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24
 *
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    licensing@OpenSSL.org.
29
 *
30
 * 5. Products derived from this software may not be called "OpenSSL"
31
 *    nor may "OpenSSL" appear in their names without prior written
32
 *    permission of the OpenSSL Project.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *    "This product includes software developed by the OpenSSL Project
37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38
 *
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
51
 * ====================================================================
52
 *
53
 * This product includes cryptographic software written by Eric Young
54
 * (eay@cryptsoft.com).  This product includes software written by Tim
55
 * Hudson (tjh@cryptsoft.com).
56
 *
57
 */
58
59
#include <stdio.h>
60
#include "cryptlib.h"
61
#include <openssl/asn1t.h>
62
#include <openssl/x509.h>
63
#include <openssl/evp.h>
64
#include <openssl/dh.h>
65
#include <openssl/bn.h>
66
#ifndef OPENSSL_NO_DSA
67
# include <openssl/dsa.h>
68
#endif
69
#include <openssl/objects.h>
70
#include "evp_locl.h"
71
72
/* DH pkey context structure */
73
74
typedef struct {
75
    /* Parameter gen parameters */
76
    int prime_len;
77
    int generator;
78
    int use_dsa;
79
    int subprime_len;
80
    /* message digest used for parameter generation */
81
    const EVP_MD *md;
82
    int rfc5114_param;
83
    /* Keygen callback info */
84
    int gentmp[2];
85
    /* KDF (if any) to use for DH */
86
    char kdf_type;
87
    /* OID to use for KDF */
88
    ASN1_OBJECT *kdf_oid;
89
    /* Message digest to use for key derivation */
90
    const EVP_MD *kdf_md;
91
    /* User key material */
92
    unsigned char *kdf_ukm;
93
    size_t kdf_ukmlen;
94
    /* KDF output length */
95
    size_t kdf_outlen;
96
} DH_PKEY_CTX;
97
98
static int pkey_dh_init(EVP_PKEY_CTX *ctx)
99
0
{
100
0
    DH_PKEY_CTX *dctx;
101
0
    dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX));
102
0
    if (!dctx)
103
0
        return 0;
104
0
    dctx->prime_len = 1024;
105
0
    dctx->subprime_len = -1;
106
0
    dctx->generator = 2;
107
0
    dctx->use_dsa = 0;
108
0
    dctx->md = NULL;
109
0
    dctx->rfc5114_param = 0;
110
111
0
    dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
112
0
    dctx->kdf_oid = NULL;
113
0
    dctx->kdf_md = NULL;
114
0
    dctx->kdf_ukm = NULL;
115
0
    dctx->kdf_ukmlen = 0;
116
0
    dctx->kdf_outlen = 0;
117
118
0
    ctx->data = dctx;
119
0
    ctx->keygen_info = dctx->gentmp;
120
0
    ctx->keygen_info_count = 2;
121
122
0
    return 1;
123
0
}
124
125
static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
126
0
{
127
0
    DH_PKEY_CTX *dctx, *sctx;
128
0
    if (!pkey_dh_init(dst))
129
0
        return 0;
130
0
    sctx = src->data;
131
0
    dctx = dst->data;
132
0
    dctx->prime_len = sctx->prime_len;
133
0
    dctx->subprime_len = sctx->subprime_len;
134
0
    dctx->generator = sctx->generator;
135
0
    dctx->use_dsa = sctx->use_dsa;
136
0
    dctx->md = sctx->md;
137
0
    dctx->rfc5114_param = sctx->rfc5114_param;
138
139
0
    dctx->kdf_type = sctx->kdf_type;
140
0
    dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
141
0
    if (!dctx->kdf_oid)
142
0
        return 0;
143
0
    dctx->kdf_md = sctx->kdf_md;
144
0
    if (dctx->kdf_ukm) {
145
0
        dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
146
0
        dctx->kdf_ukmlen = sctx->kdf_ukmlen;
147
0
    }
148
0
    dctx->kdf_outlen = sctx->kdf_outlen;
149
0
    return 1;
150
0
}
151
152
static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
153
0
{
154
0
    DH_PKEY_CTX *dctx = ctx->data;
155
0
    if (dctx) {
156
0
        if (dctx->kdf_ukm)
157
0
            OPENSSL_free(dctx->kdf_ukm);
158
0
        if (dctx->kdf_oid)
159
0
            ASN1_OBJECT_free(dctx->kdf_oid);
160
0
        OPENSSL_free(dctx);
161
0
    }
162
0
}
163
164
static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
165
0
{
166
0
    DH_PKEY_CTX *dctx = ctx->data;
167
0
    switch (type) {
168
0
    case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
169
0
        if (p1 < 256)
170
0
            return -2;
171
0
        dctx->prime_len = p1;
172
0
        return 1;
173
174
0
    case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
175
0
        if (dctx->use_dsa == 0)
176
0
            return -2;
177
0
        dctx->subprime_len = p1;
178
0
        return 1;
179
180
0
    case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
181
0
        if (dctx->use_dsa)
182
0
            return -2;
183
0
        dctx->generator = p1;
184
0
        return 1;
185
186
0
    case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
187
#ifdef OPENSSL_NO_DSA
188
        if (p1 != 0)
189
            return -2;
190
#else
191
0
        if (p1 < 0 || p1 > 2)
192
0
            return -2;
193
0
#endif
194
0
        dctx->use_dsa = p1;
195
0
        return 1;
196
197
0
    case EVP_PKEY_CTRL_DH_RFC5114:
198
0
        if (p1 < 1 || p1 > 3)
199
0
            return -2;
200
0
        dctx->rfc5114_param = p1;
201
0
        return 1;
202
203
0
    case EVP_PKEY_CTRL_PEER_KEY:
204
        /* Default behaviour is OK */
205
0
        return 1;
206
207
0
    case EVP_PKEY_CTRL_DH_KDF_TYPE:
208
0
        if (p1 == -2)
209
0
            return dctx->kdf_type;
210
#ifdef OPENSSL_NO_CMS
211
        if (p1 != EVP_PKEY_DH_KDF_NONE)
212
#else
213
0
        if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
214
0
#endif
215
0
            return -2;
216
0
        dctx->kdf_type = p1;
217
0
        return 1;
218
219
0
    case EVP_PKEY_CTRL_DH_KDF_MD:
220
0
        dctx->kdf_md = p2;
221
0
        return 1;
222
223
0
    case EVP_PKEY_CTRL_GET_DH_KDF_MD:
224
0
        *(const EVP_MD **)p2 = dctx->kdf_md;
225
0
        return 1;
226
227
0
    case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
228
0
        if (p1 <= 0)
229
0
            return -2;
230
0
        dctx->kdf_outlen = (size_t)p1;
231
0
        return 1;
232
233
0
    case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
234
0
        *(int *)p2 = dctx->kdf_outlen;
235
0
        return 1;
236
237
0
    case EVP_PKEY_CTRL_DH_KDF_UKM:
238
0
        if (dctx->kdf_ukm)
239
0
            OPENSSL_free(dctx->kdf_ukm);
240
0
        dctx->kdf_ukm = p2;
241
0
        if (p2)
242
0
            dctx->kdf_ukmlen = p1;
243
0
        else
244
0
            dctx->kdf_ukmlen = 0;
245
0
        return 1;
246
247
0
    case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
248
0
        *(unsigned char **)p2 = dctx->kdf_ukm;
249
0
        return dctx->kdf_ukmlen;
250
251
0
    case EVP_PKEY_CTRL_DH_KDF_OID:
252
0
        if (dctx->kdf_oid)
253
0
            ASN1_OBJECT_free(dctx->kdf_oid);
254
0
        dctx->kdf_oid = p2;
255
0
        return 1;
256
257
0
    case EVP_PKEY_CTRL_GET_DH_KDF_OID:
258
0
        *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
259
0
        return 1;
260
261
0
    default:
262
0
        return -2;
263
264
0
    }
265
0
}
266
267
static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
268
                            const char *type, const char *value)
269
0
{
270
0
    if (!strcmp(type, "dh_paramgen_prime_len")) {
271
0
        int len;
272
0
        len = atoi(value);
273
0
        return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
274
0
    }
275
0
    if (!strcmp(type, "dh_rfc5114")) {
276
0
        DH_PKEY_CTX *dctx = ctx->data;
277
0
        int len;
278
0
        len = atoi(value);
279
0
        if (len < 0 || len > 3)
280
0
            return -2;
281
0
        dctx->rfc5114_param = len;
282
0
        return 1;
283
0
    }
284
0
    if (!strcmp(type, "dh_paramgen_generator")) {
285
0
        int len;
286
0
        len = atoi(value);
287
0
        return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
288
0
    }
289
0
    if (!strcmp(type, "dh_paramgen_subprime_len")) {
290
0
        int len;
291
0
        len = atoi(value);
292
0
        return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
293
0
    }
294
0
    if (!strcmp(type, "dh_paramgen_type")) {
295
0
        int typ;
296
0
        typ = atoi(value);
297
0
        return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
298
0
    }
299
0
    return -2;
300
0
}
301
302
#ifndef OPENSSL_NO_DSA
303
304
extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
305
                                const EVP_MD *evpmd,
306
                                const unsigned char *seed_in, size_t seed_len,
307
                                unsigned char *seed_out, int *counter_ret,
308
                                unsigned long *h_ret, BN_GENCB *cb);
309
310
extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
311
                                 const EVP_MD *evpmd,
312
                                 const unsigned char *seed_in,
313
                                 size_t seed_len, int idx,
314
                                 unsigned char *seed_out, int *counter_ret,
315
                                 unsigned long *h_ret, BN_GENCB *cb);
316
317
static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
318
0
{
319
0
    DSA *ret;
320
0
    int rv = 0;
321
0
    int prime_len = dctx->prime_len;
322
0
    int subprime_len = dctx->subprime_len;
323
0
    const EVP_MD *md = dctx->md;
324
0
    if (dctx->use_dsa > 2)
325
0
        return NULL;
326
0
    ret = DSA_new();
327
0
    if (!ret)
328
0
        return NULL;
329
0
    if (subprime_len == -1) {
330
0
        if (prime_len >= 2048)
331
0
            subprime_len = 256;
332
0
        else
333
0
            subprime_len = 160;
334
0
    }
335
0
    if (md == NULL) {
336
0
        if (prime_len >= 2048)
337
0
            md = EVP_sha256();
338
0
        else
339
0
            md = EVP_sha1();
340
0
    }
341
0
    if (dctx->use_dsa == 1)
342
0
        rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
343
0
                                  NULL, 0, NULL, NULL, NULL, pcb);
344
0
    else if (dctx->use_dsa == 2)
345
0
        rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
346
0
                                   NULL, 0, -1, NULL, NULL, NULL, pcb);
347
0
    if (rv <= 0) {
348
0
        DSA_free(ret);
349
0
        return NULL;
350
0
    }
351
0
    return ret;
352
0
}
353
354
#endif
355
356
static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
357
0
{
358
0
    DH *dh = NULL;
359
0
    DH_PKEY_CTX *dctx = ctx->data;
360
0
    BN_GENCB *pcb, cb;
361
0
    int ret;
362
0
    if (dctx->rfc5114_param) {
363
0
        switch (dctx->rfc5114_param) {
364
0
        case 1:
365
0
            dh = DH_get_1024_160();
366
0
            break;
367
368
0
        case 2:
369
0
            dh = DH_get_2048_224();
370
0
            break;
371
372
0
        case 3:
373
0
            dh = DH_get_2048_256();
374
0
            break;
375
376
0
        default:
377
0
            return -2;
378
0
        }
379
0
        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
380
0
        return 1;
381
0
    }
382
383
0
    if (ctx->pkey_gencb) {
384
0
        pcb = &cb;
385
0
        evp_pkey_set_cb_translate(pcb, ctx);
386
0
    } else
387
0
        pcb = NULL;
388
0
#ifndef OPENSSL_NO_DSA
389
0
    if (dctx->use_dsa) {
390
0
        DSA *dsa_dh;
391
0
        dsa_dh = dsa_dh_generate(dctx, pcb);
392
0
        if (!dsa_dh)
393
0
            return 0;
394
0
        dh = DSA_dup_DH(dsa_dh);
395
0
        DSA_free(dsa_dh);
396
0
        if (!dh)
397
0
            return 0;
398
0
        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
399
0
        return 1;
400
0
    }
401
0
#endif
402
0
    dh = DH_new();
403
0
    if (!dh)
404
0
        return 0;
405
0
    ret = DH_generate_parameters_ex(dh,
406
0
                                    dctx->prime_len, dctx->generator, pcb);
407
408
0
    if (ret)
409
0
        EVP_PKEY_assign_DH(pkey, dh);
410
0
    else
411
0
        DH_free(dh);
412
0
    return ret;
413
0
}
414
415
static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
416
0
{
417
0
    DH *dh = NULL;
418
0
    if (ctx->pkey == NULL) {
419
0
        DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
420
0
        return 0;
421
0
    }
422
0
    dh = DH_new();
423
0
    if (!dh)
424
0
        return 0;
425
0
    EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
426
    /* Note: if error return, pkey is freed by parent routine */
427
0
    if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
428
0
        return 0;
429
0
    return DH_generate_key(pkey->pkey.dh);
430
0
}
431
432
static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
433
                          size_t *keylen)
434
0
{
435
0
    int ret;
436
0
    DH *dh;
437
0
    DH_PKEY_CTX *dctx = ctx->data;
438
0
    BIGNUM *dhpub;
439
0
    if (!ctx->pkey || !ctx->peerkey) {
440
0
        DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
441
0
        return 0;
442
0
    }
443
0
    dh = ctx->pkey->pkey.dh;
444
0
    dhpub = ctx->peerkey->pkey.dh->pub_key;
445
0
    if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
446
0
        if (key == NULL) {
447
0
            *keylen = DH_size(dh);
448
0
            return 1;
449
0
        }
450
0
        ret = DH_compute_key(key, dhpub, dh);
451
0
        if (ret < 0)
452
0
            return ret;
453
0
        *keylen = ret;
454
0
        return 1;
455
0
    }
456
0
#ifndef OPENSSL_NO_CMS
457
0
    else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
458
0
        unsigned char *Z = NULL;
459
0
        size_t Zlen = 0;
460
0
        if (!dctx->kdf_outlen || !dctx->kdf_oid)
461
0
            return 0;
462
0
        if (key == NULL) {
463
0
            *keylen = dctx->kdf_outlen;
464
0
            return 1;
465
0
        }
466
0
        if (*keylen != dctx->kdf_outlen)
467
0
            return 0;
468
0
        ret = 0;
469
0
        Zlen = DH_size(dh);
470
0
        Z = OPENSSL_malloc(Zlen);
471
0
        if (!Z) {
472
0
            goto err;
473
0
        }
474
0
        if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
475
0
            goto err;
476
0
        if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
477
0
                          dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
478
0
            goto err;
479
0
        *keylen = dctx->kdf_outlen;
480
0
        ret = 1;
481
0
 err:
482
0
        if (Z) {
483
0
            OPENSSL_cleanse(Z, Zlen);
484
0
            OPENSSL_free(Z);
485
0
        }
486
0
        return ret;
487
0
    }
488
0
#endif
489
0
    return 1;
490
0
}
491
492
const EVP_PKEY_METHOD dh_pkey_meth = {
493
    EVP_PKEY_DH,
494
    0,
495
    pkey_dh_init,
496
    pkey_dh_copy,
497
    pkey_dh_cleanup,
498
499
    0,
500
    pkey_dh_paramgen,
501
502
    0,
503
    pkey_dh_keygen,
504
505
    0,
506
    0,
507
508
    0,
509
    0,
510
511
    0, 0,
512
513
    0, 0, 0, 0,
514
515
    0, 0,
516
517
    0, 0,
518
519
    0,
520
    pkey_dh_derive,
521
522
    pkey_dh_ctrl,
523
    pkey_dh_ctrl_str
524
};
525
526
const EVP_PKEY_METHOD dhx_pkey_meth = {
527
    EVP_PKEY_DHX,
528
    0,
529
    pkey_dh_init,
530
    pkey_dh_copy,
531
    pkey_dh_cleanup,
532
533
    0,
534
    pkey_dh_paramgen,
535
536
    0,
537
    pkey_dh_keygen,
538
539
    0,
540
    0,
541
542
    0,
543
    0,
544
545
    0, 0,
546
547
    0, 0, 0, 0,
548
549
    0, 0,
550
551
    0, 0,
552
553
    0,
554
    pkey_dh_derive,
555
556
    pkey_dh_ctrl,
557
    pkey_dh_ctrl_str
558
};