Coverage Report

Created: 2025-06-13 06:58

/src/openssl31/crypto/dh/dh_lib.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (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
/*
11
 * DH low level APIs are deprecated for public use, but still ok for
12
 * internal use.
13
 */
14
#include "internal/deprecated.h"
15
16
#include <stdio.h>
17
#include <openssl/bn.h>
18
#ifndef FIPS_MODULE
19
# include <openssl/engine.h>
20
#endif
21
#include <openssl/obj_mac.h>
22
#include <openssl/core_names.h>
23
#include "internal/cryptlib.h"
24
#include "internal/refcount.h"
25
#include "crypto/evp.h"
26
#include "crypto/dh.h"
27
#include "dh_local.h"
28
29
static DH *dh_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx);
30
31
#ifndef FIPS_MODULE
32
int DH_set_method(DH *dh, const DH_METHOD *meth)
33
0
{
34
    /*
35
     * NB: The caller is specifically setting a method, so it's not up to us
36
     * to deal with which ENGINE it comes from.
37
     */
38
0
    const DH_METHOD *mtmp;
39
0
    mtmp = dh->meth;
40
0
    if (mtmp->finish)
41
0
        mtmp->finish(dh);
42
0
#ifndef OPENSSL_NO_ENGINE
43
0
    ENGINE_finish(dh->engine);
44
0
    dh->engine = NULL;
45
0
#endif
46
0
    dh->meth = meth;
47
0
    if (meth->init)
48
0
        meth->init(dh);
49
0
    return 1;
50
0
}
51
52
const DH_METHOD *ossl_dh_get_method(const DH *dh)
53
17.4k
{
54
17.4k
    return dh->meth;
55
17.4k
}
56
# ifndef OPENSSL_NO_DEPRECATED_3_0
57
DH *DH_new(void)
58
230k
{
59
230k
    return dh_new_intern(NULL, NULL);
60
230k
}
61
# endif
62
63
DH *DH_new_method(ENGINE *engine)
64
0
{
65
0
    return dh_new_intern(engine, NULL);
66
0
}
67
#endif /* !FIPS_MODULE */
68
69
DH *ossl_dh_new_ex(OSSL_LIB_CTX *libctx)
70
14.7k
{
71
14.7k
    return dh_new_intern(NULL, libctx);
72
14.7k
}
73
74
static DH *dh_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx)
75
108k
{
76
108k
    DH *ret = OPENSSL_zalloc(sizeof(*ret));
77
78
108k
    if (ret == NULL) {
79
0
        ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
80
0
        return NULL;
81
0
    }
82
83
108k
    ret->references = 1;
84
108k
    ret->lock = CRYPTO_THREAD_lock_new();
85
108k
    if (ret->lock == NULL) {
86
0
        ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
87
0
        OPENSSL_free(ret);
88
0
        return NULL;
89
0
    }
90
91
108k
    ret->libctx = libctx;
92
108k
    ret->meth = DH_get_default_method();
93
108k
#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE)
94
108k
    ret->flags = ret->meth->flags;  /* early default init */
95
108k
    if (engine) {
96
0
        if (!ENGINE_init(engine)) {
97
0
            ERR_raise(ERR_LIB_DH, ERR_R_ENGINE_LIB);
98
0
            goto err;
99
0
        }
100
0
        ret->engine = engine;
101
0
    } else
102
108k
        ret->engine = ENGINE_get_default_DH();
103
108k
    if (ret->engine) {
104
0
        ret->meth = ENGINE_get_DH(ret->engine);
105
0
        if (ret->meth == NULL) {
106
0
            ERR_raise(ERR_LIB_DH, ERR_R_ENGINE_LIB);
107
0
            goto err;
108
0
        }
109
0
    }
110
108k
#endif
111
112
108k
    ret->flags = ret->meth->flags;
113
114
108k
#ifndef FIPS_MODULE
115
108k
    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data))
116
0
        goto err;
117
108k
#endif /* FIPS_MODULE */
118
119
108k
    ossl_ffc_params_init(&ret->params);
120
121
108k
    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
122
0
        ERR_raise(ERR_LIB_DH, ERR_R_INIT_FAIL);
123
0
        goto err;
124
0
    }
125
126
108k
    return ret;
127
128
0
 err:
129
0
    DH_free(ret);
130
0
    return NULL;
131
108k
}
132
133
void DH_free(DH *r)
134
643k
{
135
643k
    int i;
136
137
643k
    if (r == NULL)
138
359k
        return;
139
140
283k
    CRYPTO_DOWN_REF(&r->references, &i, r->lock);
141
283k
    REF_PRINT_COUNT("DH", r);
142
283k
    if (i > 0)
143
38.3k
        return;
144
244k
    REF_ASSERT_ISNT(i < 0);
145
146
244k
    if (r->meth != NULL && r->meth->finish != NULL)
147
244k
        r->meth->finish(r);
148
244k
#if !defined(FIPS_MODULE)
149
244k
# if !defined(OPENSSL_NO_ENGINE)
150
244k
    ENGINE_finish(r->engine);
151
244k
# endif
152
244k
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data);
153
244k
#endif
154
155
244k
    CRYPTO_THREAD_lock_free(r->lock);
156
157
244k
    ossl_ffc_params_cleanup(&r->params);
158
244k
    BN_clear_free(r->pub_key);
159
244k
    BN_clear_free(r->priv_key);
160
244k
    OPENSSL_free(r);
161
244k
}
162
163
int DH_up_ref(DH *r)
164
38.3k
{
165
38.3k
    int i;
166
167
38.3k
    if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
168
0
        return 0;
169
170
38.3k
    REF_PRINT_COUNT("DH", r);
171
38.3k
    REF_ASSERT_ISNT(i < 2);
172
38.3k
    return ((i > 1) ? 1 : 0);
173
38.3k
}
174
175
void ossl_dh_set0_libctx(DH *d, OSSL_LIB_CTX *libctx)
176
35.1k
{
177
35.1k
    d->libctx = libctx;
178
35.1k
}
179
180
#ifndef FIPS_MODULE
181
int DH_set_ex_data(DH *d, int idx, void *arg)
182
0
{
183
0
    return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
184
0
}
185
186
void *DH_get_ex_data(const DH *d, int idx)
187
0
{
188
0
    return CRYPTO_get_ex_data(&d->ex_data, idx);
189
0
}
190
#endif
191
192
int DH_bits(const DH *dh)
193
49.8k
{
194
49.8k
    if (dh->params.p != NULL)
195
49.8k
        return BN_num_bits(dh->params.p);
196
0
    return -1;
197
49.8k
}
198
199
int DH_size(const DH *dh)
200
56.6k
{
201
56.6k
    if (dh->params.p != NULL)
202
56.6k
        return BN_num_bytes(dh->params.p);
203
0
    return -1;
204
56.6k
}
205
206
int DH_security_bits(const DH *dh)
207
49.8k
{
208
49.8k
    int N;
209
210
49.8k
    if (dh->params.q != NULL)
211
25.7k
        N = BN_num_bits(dh->params.q);
212
24.0k
    else if (dh->length)
213
7.01k
        N = dh->length;
214
17.0k
    else
215
17.0k
        N = -1;
216
49.8k
    if (dh->params.p != NULL)
217
49.8k
        return BN_security_bits(BN_num_bits(dh->params.p), N);
218
0
    return -1;
219
49.8k
}
220
221
void DH_get0_pqg(const DH *dh,
222
                 const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
223
8.21k
{
224
8.21k
    ossl_ffc_params_get0_pqg(&dh->params, p, q, g);
225
8.21k
}
226
227
int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
228
26.5k
{
229
    /*
230
     * If the fields p and g in dh are NULL, the corresponding input
231
     * parameters MUST be non-NULL.  q may remain NULL.
232
     */
233
26.5k
    if ((dh->params.p == NULL && p == NULL)
234
26.5k
        || (dh->params.g == NULL && g == NULL))
235
0
        return 0;
236
237
26.5k
    ossl_ffc_params_set0_pqg(&dh->params, p, q, g);
238
26.5k
    ossl_dh_cache_named_group(dh);
239
26.5k
    dh->dirty_cnt++;
240
26.5k
    return 1;
241
26.5k
}
242
243
long DH_get_length(const DH *dh)
244
66.0k
{
245
66.0k
    return dh->length;
246
66.0k
}
247
248
int DH_set_length(DH *dh, long length)
249
0
{
250
0
    dh->length = length;
251
0
    dh->dirty_cnt++;
252
0
    return 1;
253
0
}
254
255
void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
256
87.7k
{
257
87.7k
    if (pub_key != NULL)
258
83.5k
        *pub_key = dh->pub_key;
259
87.7k
    if (priv_key != NULL)
260
61.0k
        *priv_key = dh->priv_key;
261
87.7k
}
262
263
int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
264
6.79k
{
265
6.79k
    if (pub_key != NULL) {
266
6.66k
        BN_clear_free(dh->pub_key);
267
6.66k
        dh->pub_key = pub_key;
268
6.66k
    }
269
6.79k
    if (priv_key != NULL) {
270
135
        BN_clear_free(dh->priv_key);
271
135
        dh->priv_key = priv_key;
272
135
    }
273
274
6.79k
    dh->dirty_cnt++;
275
6.79k
    return 1;
276
6.79k
}
277
278
const BIGNUM *DH_get0_p(const DH *dh)
279
5.14k
{
280
5.14k
    return dh->params.p;
281
5.14k
}
282
283
const BIGNUM *DH_get0_q(const DH *dh)
284
0
{
285
0
    return dh->params.q;
286
0
}
287
288
const BIGNUM *DH_get0_g(const DH *dh)
289
50
{
290
50
    return dh->params.g;
291
50
}
292
293
const BIGNUM *DH_get0_priv_key(const DH *dh)
294
12.2k
{
295
12.2k
    return dh->priv_key;
296
12.2k
}
297
298
const BIGNUM *DH_get0_pub_key(const DH *dh)
299
17.5k
{
300
17.5k
    return dh->pub_key;
301
17.5k
}
302
303
void DH_clear_flags(DH *dh, int flags)
304
52.8k
{
305
52.8k
    dh->flags &= ~flags;
306
52.8k
}
307
308
int DH_test_flags(const DH *dh, int flags)
309
75
{
310
75
    return dh->flags & flags;
311
75
}
312
313
void DH_set_flags(DH *dh, int flags)
314
52.8k
{
315
52.8k
    dh->flags |= flags;
316
52.8k
}
317
318
#ifndef FIPS_MODULE
319
ENGINE *DH_get0_engine(DH *dh)
320
0
{
321
0
    return dh->engine;
322
0
}
323
#endif /*FIPS_MODULE */
324
325
FFC_PARAMS *ossl_dh_get0_params(DH *dh)
326
91.4k
{
327
91.4k
    return &dh->params;
328
91.4k
}
329
int ossl_dh_get0_nid(const DH *dh)
330
0
{
331
0
    return dh->params.nid;
332
0
}