Coverage Report

Created: 2023-06-08 06:41

/src/openssl111/crypto/dh/dh_pmeth.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2006-2019 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/asn1t.h>
13
#include <openssl/x509.h>
14
#include <openssl/evp.h>
15
#include "dh_local.h"
16
#include <openssl/bn.h>
17
#include <openssl/dsa.h>
18
#include <openssl/objects.h>
19
#include "crypto/evp.h"
20
21
/* DH pkey context structure */
22
23
typedef struct {
24
    /* Parameter gen parameters */
25
    int prime_len;
26
    int generator;
27
    int use_dsa;
28
    int subprime_len;
29
    int pad;
30
    /* message digest used for parameter generation */
31
    const EVP_MD *md;
32
    int rfc5114_param;
33
    int param_nid;
34
    /* Keygen callback info */
35
    int gentmp[2];
36
    /* KDF (if any) to use for DH */
37
    char kdf_type;
38
    /* OID to use for KDF */
39
    ASN1_OBJECT *kdf_oid;
40
    /* Message digest to use for key derivation */
41
    const EVP_MD *kdf_md;
42
    /* User key material */
43
    unsigned char *kdf_ukm;
44
    size_t kdf_ukmlen;
45
    /* KDF output length */
46
    size_t kdf_outlen;
47
} DH_PKEY_CTX;
48
49
static int pkey_dh_init(EVP_PKEY_CTX *ctx)
50
0
{
51
0
    DH_PKEY_CTX *dctx;
52
53
0
    if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
54
0
        DHerr(DH_F_PKEY_DH_INIT, ERR_R_MALLOC_FAILURE);
55
0
        return 0;
56
0
    }
57
0
    dctx->prime_len = 2048;
58
0
    dctx->subprime_len = -1;
59
0
    dctx->generator = 2;
60
0
    dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
61
62
0
    ctx->data = dctx;
63
0
    ctx->keygen_info = dctx->gentmp;
64
0
    ctx->keygen_info_count = 2;
65
66
0
    return 1;
67
0
}
68
69
static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
70
0
{
71
0
    DH_PKEY_CTX *dctx = ctx->data;
72
0
    if (dctx != NULL) {
73
0
        OPENSSL_free(dctx->kdf_ukm);
74
0
        ASN1_OBJECT_free(dctx->kdf_oid);
75
0
        OPENSSL_free(dctx);
76
0
    }
77
0
}
78
79
80
static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
81
0
{
82
0
    DH_PKEY_CTX *dctx, *sctx;
83
0
    if (!pkey_dh_init(dst))
84
0
        return 0;
85
0
    sctx = src->data;
86
0
    dctx = dst->data;
87
0
    dctx->prime_len = sctx->prime_len;
88
0
    dctx->subprime_len = sctx->subprime_len;
89
0
    dctx->generator = sctx->generator;
90
0
    dctx->use_dsa = sctx->use_dsa;
91
0
    dctx->pad = sctx->pad;
92
0
    dctx->md = sctx->md;
93
0
    dctx->rfc5114_param = sctx->rfc5114_param;
94
0
    dctx->param_nid = sctx->param_nid;
95
96
0
    dctx->kdf_type = sctx->kdf_type;
97
0
    dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
98
0
    if (dctx->kdf_oid == NULL)
99
0
        return 0;
100
0
    dctx->kdf_md = sctx->kdf_md;
101
0
    if (sctx->kdf_ukm != NULL) {
102
0
        dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
103
0
        if (dctx->kdf_ukm == NULL)
104
0
          return 0;
105
0
        dctx->kdf_ukmlen = sctx->kdf_ukmlen;
106
0
    }
107
0
    dctx->kdf_outlen = sctx->kdf_outlen;
108
0
    return 1;
109
0
}
110
111
static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
112
0
{
113
0
    DH_PKEY_CTX *dctx = ctx->data;
114
0
    switch (type) {
115
0
    case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
116
0
        if (p1 < 256)
117
0
            return -2;
118
0
        dctx->prime_len = p1;
119
0
        return 1;
120
121
0
    case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
122
0
        if (dctx->use_dsa == 0)
123
0
            return -2;
124
0
        dctx->subprime_len = p1;
125
0
        return 1;
126
127
0
    case EVP_PKEY_CTRL_DH_PAD:
128
0
        dctx->pad = p1;
129
0
        return 1;
130
131
0
    case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
132
0
        if (dctx->use_dsa)
133
0
            return -2;
134
0
        dctx->generator = p1;
135
0
        return 1;
136
137
0
    case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
138
#ifdef OPENSSL_NO_DSA
139
        if (p1 != 0)
140
            return -2;
141
#else
142
0
        if (p1 < 0 || p1 > 2)
143
0
            return -2;
144
0
#endif
145
0
        dctx->use_dsa = p1;
146
0
        return 1;
147
148
0
    case EVP_PKEY_CTRL_DH_RFC5114:
149
0
        if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
150
0
            return -2;
151
0
        dctx->rfc5114_param = p1;
152
0
        return 1;
153
154
0
    case EVP_PKEY_CTRL_DH_NID:
155
0
        if (p1 <= 0 || dctx->rfc5114_param != 0)
156
0
            return -2;
157
0
        dctx->param_nid = p1;
158
0
        return 1;
159
160
0
    case EVP_PKEY_CTRL_PEER_KEY:
161
        /* Default behaviour is OK */
162
0
        return 1;
163
164
0
    case EVP_PKEY_CTRL_DH_KDF_TYPE:
165
0
        if (p1 == -2)
166
0
            return dctx->kdf_type;
167
#ifdef OPENSSL_NO_CMS
168
        if (p1 != EVP_PKEY_DH_KDF_NONE)
169
#else
170
0
        if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
171
0
#endif
172
0
            return -2;
173
0
        dctx->kdf_type = p1;
174
0
        return 1;
175
176
0
    case EVP_PKEY_CTRL_DH_KDF_MD:
177
0
        dctx->kdf_md = p2;
178
0
        return 1;
179
180
0
    case EVP_PKEY_CTRL_GET_DH_KDF_MD:
181
0
        *(const EVP_MD **)p2 = dctx->kdf_md;
182
0
        return 1;
183
184
0
    case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
185
0
        if (p1 <= 0)
186
0
            return -2;
187
0
        dctx->kdf_outlen = (size_t)p1;
188
0
        return 1;
189
190
0
    case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
191
0
        *(int *)p2 = dctx->kdf_outlen;
192
0
        return 1;
193
194
0
    case EVP_PKEY_CTRL_DH_KDF_UKM:
195
0
        OPENSSL_free(dctx->kdf_ukm);
196
0
        dctx->kdf_ukm = p2;
197
0
        if (p2)
198
0
            dctx->kdf_ukmlen = p1;
199
0
        else
200
0
            dctx->kdf_ukmlen = 0;
201
0
        return 1;
202
203
0
    case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
204
0
        *(unsigned char **)p2 = dctx->kdf_ukm;
205
0
        return dctx->kdf_ukmlen;
206
207
0
    case EVP_PKEY_CTRL_DH_KDF_OID:
208
0
        ASN1_OBJECT_free(dctx->kdf_oid);
209
0
        dctx->kdf_oid = p2;
210
0
        return 1;
211
212
0
    case EVP_PKEY_CTRL_GET_DH_KDF_OID:
213
0
        *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
214
0
        return 1;
215
216
0
    default:
217
0
        return -2;
218
219
0
    }
220
0
}
221
222
static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
223
                            const char *type, const char *value)
224
0
{
225
0
    if (strcmp(type, "dh_paramgen_prime_len") == 0) {
226
0
        int len;
227
0
        len = atoi(value);
228
0
        return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
229
0
    }
230
0
    if (strcmp(type, "dh_rfc5114") == 0) {
231
0
        DH_PKEY_CTX *dctx = ctx->data;
232
0
        int len;
233
0
        len = atoi(value);
234
0
        if (len < 0 || len > 3)
235
0
            return -2;
236
0
        dctx->rfc5114_param = len;
237
0
        return 1;
238
0
    }
239
0
    if (strcmp(type, "dh_param") == 0) {
240
0
        DH_PKEY_CTX *dctx = ctx->data;
241
0
        int nid = OBJ_sn2nid(value);
242
243
0
        if (nid == NID_undef) {
244
0
            DHerr(DH_F_PKEY_DH_CTRL_STR, DH_R_INVALID_PARAMETER_NAME);
245
0
            return -2;
246
0
        }
247
0
        dctx->param_nid = nid;
248
0
        return 1;
249
0
    }
250
0
    if (strcmp(type, "dh_paramgen_generator") == 0) {
251
0
        int len;
252
0
        len = atoi(value);
253
0
        return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
254
0
    }
255
0
    if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
256
0
        int len;
257
0
        len = atoi(value);
258
0
        return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
259
0
    }
260
0
    if (strcmp(type, "dh_paramgen_type") == 0) {
261
0
        int typ;
262
0
        typ = atoi(value);
263
0
        return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
264
0
    }
265
0
    if (strcmp(type, "dh_pad") == 0) {
266
0
        int pad;
267
0
        pad = atoi(value);
268
0
        return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
269
0
    }
270
0
    return -2;
271
0
}
272
273
#ifndef OPENSSL_NO_DSA
274
275
extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
276
                                const EVP_MD *evpmd,
277
                                const unsigned char *seed_in, size_t seed_len,
278
                                unsigned char *seed_out, int *counter_ret,
279
                                unsigned long *h_ret, BN_GENCB *cb);
280
281
extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
282
                                 const EVP_MD *evpmd,
283
                                 const unsigned char *seed_in,
284
                                 size_t seed_len, int idx,
285
                                 unsigned char *seed_out, int *counter_ret,
286
                                 unsigned long *h_ret, BN_GENCB *cb);
287
288
static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
289
0
{
290
0
    DSA *ret;
291
0
    int rv = 0;
292
0
    int prime_len = dctx->prime_len;
293
0
    int subprime_len = dctx->subprime_len;
294
0
    const EVP_MD *md = dctx->md;
295
0
    if (dctx->use_dsa > 2)
296
0
        return NULL;
297
0
    ret = DSA_new();
298
0
    if (ret == NULL)
299
0
        return NULL;
300
0
    if (subprime_len == -1) {
301
0
        if (prime_len >= 2048)
302
0
            subprime_len = 256;
303
0
        else
304
0
            subprime_len = 160;
305
0
    }
306
0
    if (md == NULL) {
307
0
        if (prime_len >= 2048)
308
0
            md = EVP_sha256();
309
0
        else
310
0
            md = EVP_sha1();
311
0
    }
312
0
    if (dctx->use_dsa == 1)
313
0
        rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
314
0
                                  NULL, 0, NULL, NULL, NULL, pcb);
315
0
    else if (dctx->use_dsa == 2)
316
0
        rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
317
0
                                   NULL, 0, -1, NULL, NULL, NULL, pcb);
318
0
    if (rv <= 0) {
319
0
        DSA_free(ret);
320
0
        return NULL;
321
0
    }
322
0
    return ret;
323
0
}
324
325
#endif
326
327
static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
328
0
{
329
0
    DH *dh = NULL;
330
0
    DH_PKEY_CTX *dctx = ctx->data;
331
0
    BN_GENCB *pcb;
332
0
    int ret;
333
0
    if (dctx->rfc5114_param) {
334
0
        switch (dctx->rfc5114_param) {
335
0
        case 1:
336
0
            dh = DH_get_1024_160();
337
0
            break;
338
339
0
        case 2:
340
0
            dh = DH_get_2048_224();
341
0
            break;
342
343
0
        case 3:
344
0
            dh = DH_get_2048_256();
345
0
            break;
346
347
0
        default:
348
0
            return -2;
349
0
        }
350
0
        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
351
0
        return 1;
352
0
    }
353
354
0
    if (dctx->param_nid != 0) {
355
0
        if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
356
0
            return 0;
357
0
        EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
358
0
        return 1;
359
0
    }
360
361
0
    if (ctx->pkey_gencb) {
362
0
        pcb = BN_GENCB_new();
363
0
        if (pcb == NULL)
364
0
            return 0;
365
0
        evp_pkey_set_cb_translate(pcb, ctx);
366
0
    } else
367
0
        pcb = NULL;
368
0
#ifndef OPENSSL_NO_DSA
369
0
    if (dctx->use_dsa) {
370
0
        DSA *dsa_dh;
371
0
        dsa_dh = dsa_dh_generate(dctx, pcb);
372
0
        BN_GENCB_free(pcb);
373
0
        if (dsa_dh == NULL)
374
0
            return 0;
375
0
        dh = DSA_dup_DH(dsa_dh);
376
0
        DSA_free(dsa_dh);
377
0
        if (!dh)
378
0
            return 0;
379
0
        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
380
0
        return 1;
381
0
    }
382
0
#endif
383
0
    dh = DH_new();
384
0
    if (dh == NULL) {
385
0
        BN_GENCB_free(pcb);
386
0
        return 0;
387
0
    }
388
0
    ret = DH_generate_parameters_ex(dh,
389
0
                                    dctx->prime_len, dctx->generator, pcb);
390
0
    BN_GENCB_free(pcb);
391
0
    if (ret)
392
0
        EVP_PKEY_assign_DH(pkey, dh);
393
0
    else
394
0
        DH_free(dh);
395
0
    return ret;
396
0
}
397
398
static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
399
0
{
400
0
    DH_PKEY_CTX *dctx = ctx->data;
401
0
    DH *dh = NULL;
402
403
0
    if (ctx->pkey == NULL && dctx->param_nid == 0) {
404
0
        DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
405
0
        return 0;
406
0
    }
407
0
    if (dctx->param_nid != 0)
408
0
        dh = DH_new_by_nid(dctx->param_nid);
409
0
    else
410
0
        dh = DH_new();
411
0
    if (dh == NULL)
412
0
        return 0;
413
0
    EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
414
    /* Note: if error return, pkey is freed by parent routine */
415
0
    if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
416
0
        return 0;
417
0
    return DH_generate_key(pkey->pkey.dh);
418
0
}
419
420
static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
421
                          size_t *keylen)
422
0
{
423
0
    int ret;
424
0
    DH *dh;
425
0
    DH_PKEY_CTX *dctx = ctx->data;
426
0
    BIGNUM *dhpub;
427
0
    if (!ctx->pkey || !ctx->peerkey) {
428
0
        DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
429
0
        return 0;
430
0
    }
431
0
    dh = ctx->pkey->pkey.dh;
432
0
    dhpub = ctx->peerkey->pkey.dh->pub_key;
433
0
    if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
434
0
        if (key == NULL) {
435
0
            *keylen = DH_size(dh);
436
0
            return 1;
437
0
        }
438
0
        if (dctx->pad)
439
0
            ret = DH_compute_key_padded(key, dhpub, dh);
440
0
        else
441
0
            ret = DH_compute_key(key, dhpub, dh);
442
0
        if (ret < 0)
443
0
            return ret;
444
0
        *keylen = ret;
445
0
        return 1;
446
0
    }
447
0
#ifndef OPENSSL_NO_CMS
448
0
    else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
449
450
0
        unsigned char *Z = NULL;
451
0
        size_t Zlen = 0;
452
0
        if (!dctx->kdf_outlen || !dctx->kdf_oid)
453
0
            return 0;
454
0
        if (key == NULL) {
455
0
            *keylen = dctx->kdf_outlen;
456
0
            return 1;
457
0
        }
458
0
        if (*keylen != dctx->kdf_outlen)
459
0
            return 0;
460
0
        ret = 0;
461
0
        Zlen = DH_size(dh);
462
0
        Z = OPENSSL_malloc(Zlen);
463
0
        if (Z == NULL) {
464
0
            goto err;
465
0
        }
466
0
        if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
467
0
            goto err;
468
0
        if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
469
0
                          dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
470
0
            goto err;
471
0
        *keylen = dctx->kdf_outlen;
472
0
        ret = 1;
473
0
 err:
474
0
        OPENSSL_clear_free(Z, Zlen);
475
0
        return ret;
476
0
    }
477
0
#endif
478
0
    return 0;
479
0
}
480
481
const EVP_PKEY_METHOD dh_pkey_meth = {
482
    EVP_PKEY_DH,
483
    0,
484
    pkey_dh_init,
485
    pkey_dh_copy,
486
    pkey_dh_cleanup,
487
488
    0,
489
    pkey_dh_paramgen,
490
491
    0,
492
    pkey_dh_keygen,
493
494
    0,
495
    0,
496
497
    0,
498
    0,
499
500
    0, 0,
501
502
    0, 0, 0, 0,
503
504
    0, 0,
505
506
    0, 0,
507
508
    0,
509
    pkey_dh_derive,
510
511
    pkey_dh_ctrl,
512
    pkey_dh_ctrl_str
513
};
514
515
const EVP_PKEY_METHOD dhx_pkey_meth = {
516
    EVP_PKEY_DHX,
517
    0,
518
    pkey_dh_init,
519
    pkey_dh_copy,
520
    pkey_dh_cleanup,
521
522
    0,
523
    pkey_dh_paramgen,
524
525
    0,
526
    pkey_dh_keygen,
527
528
    0,
529
    0,
530
531
    0,
532
    0,
533
534
    0, 0,
535
536
    0, 0, 0, 0,
537
538
    0, 0,
539
540
    0, 0,
541
542
    0,
543
    pkey_dh_derive,
544
545
    pkey_dh_ctrl,
546
    pkey_dh_ctrl_str
547
};