Coverage Report

Created: 2026-07-12 07:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl36/providers/implementations/exchange/dh_exch.c
Line
Count
Source
1
/*
2
 * Copyright 2019-2026 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
/* clang-format off */
10
11
/* clang-format on */
12
13
/*
14
 * DH low level APIs are deprecated for public use, but still ok for
15
 * internal use.
16
 */
17
#include "internal/deprecated.h"
18
19
#include <string.h>
20
#include <openssl/crypto.h>
21
#include <openssl/core_dispatch.h>
22
#include <openssl/core_names.h>
23
#include <openssl/dh.h>
24
#include <openssl/err.h>
25
#include <openssl/proverr.h>
26
#include <openssl/params.h>
27
#include "internal/cryptlib.h"
28
#include "prov/providercommon.h"
29
#include "prov/implementations.h"
30
#include "prov/provider_ctx.h"
31
#include "prov/securitycheck.h"
32
#include "crypto/dh.h"
33
34
static OSSL_FUNC_keyexch_newctx_fn dh_newctx;
35
static OSSL_FUNC_keyexch_init_fn dh_init;
36
static OSSL_FUNC_keyexch_set_peer_fn dh_set_peer;
37
static OSSL_FUNC_keyexch_derive_fn dh_derive;
38
static OSSL_FUNC_keyexch_freectx_fn dh_freectx;
39
static OSSL_FUNC_keyexch_dupctx_fn dh_dupctx;
40
static OSSL_FUNC_keyexch_set_ctx_params_fn dh_set_ctx_params;
41
static OSSL_FUNC_keyexch_settable_ctx_params_fn dh_settable_ctx_params;
42
static OSSL_FUNC_keyexch_get_ctx_params_fn dh_get_ctx_params;
43
static OSSL_FUNC_keyexch_gettable_ctx_params_fn dh_gettable_ctx_params;
44
45
/*
46
 * This type is only really used to handle some legacy related functionality.
47
 * If you need to use other KDF's (such as SSKDF) just use PROV_DH_KDF_NONE
48
 * here and then create and run a KDF after the key is derived.
49
 * Note that X942 has 2 variants of key derivation:
50
 *   (1) DH_KDF_X9_42_ASN1 - which contains an ANS1 encoded object that has
51
 *   the counter embedded in it.
52
 *   (2) DH_KDF_X941_CONCAT - which is the same as ECDH_X963_KDF (which can be
53
 *       done by creating a "X963KDF".
54
 */
55
enum kdf_type {
56
    PROV_DH_KDF_NONE = 0,
57
    PROV_DH_KDF_X9_42_ASN1
58
};
59
60
/*
61
 * What's passed as an actual key is defined by the KEYMGMT interface.
62
 * We happen to know that our KEYMGMT simply passes DH structures, so
63
 * we use that here too.
64
 */
65
66
typedef struct {
67
    OSSL_LIB_CTX *libctx;
68
    DH *dh;
69
    DH *dhpeer;
70
    unsigned int pad : 1;
71
72
    /* DH KDF */
73
    /* KDF (if any) to use for DH */
74
    enum kdf_type kdf_type;
75
    /* Message digest to use for key derivation */
76
    EVP_MD *kdf_md;
77
    /* User key material */
78
    unsigned char *kdf_ukm;
79
    size_t kdf_ukmlen;
80
    /* KDF output length */
81
    size_t kdf_outlen;
82
    char *kdf_cekalg;
83
    OSSL_FIPS_IND_DECLARE
84
} PROV_DH_CTX;
85
86
static void *dh_newctx(void *provctx)
87
4.78k
{
88
4.78k
    PROV_DH_CTX *pdhctx;
89
90
4.78k
    if (!ossl_prov_is_running())
91
0
        return NULL;
92
93
4.78k
    pdhctx = OPENSSL_zalloc(sizeof(PROV_DH_CTX));
94
4.78k
    if (pdhctx == NULL)
95
0
        return NULL;
96
4.78k
    OSSL_FIPS_IND_INIT(pdhctx)
97
4.78k
    pdhctx->libctx = PROV_LIBCTX_OF(provctx);
98
4.78k
    pdhctx->kdf_type = PROV_DH_KDF_NONE;
99
4.78k
    return pdhctx;
100
4.78k
}
101
102
#ifdef FIPS_MODULE
103
static int dh_check_key(PROV_DH_CTX *ctx)
104
{
105
    int key_approved = ossl_dh_check_key(ctx->dh);
106
107
    if (!key_approved) {
108
        if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
109
                ctx->libctx, "DH Init", "DH Key",
110
                ossl_fips_config_securitycheck_enabled)) {
111
            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
112
            return 0;
113
        }
114
    }
115
    return 1;
116
}
117
118
static int digest_check(PROV_DH_CTX *ctx, const EVP_MD *md)
119
{
120
    return ossl_fips_ind_digest_exch_check(OSSL_FIPS_IND_GET(ctx),
121
        OSSL_FIPS_IND_SETTABLE1, ctx->libctx,
122
        md, "DH Set Ctx");
123
}
124
#endif
125
126
static int dh_init(void *vpdhctx, void *vdh, const OSSL_PARAM params[])
127
2.90k
{
128
2.90k
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
129
130
2.90k
    if (!ossl_prov_is_running()
131
2.90k
        || pdhctx == NULL
132
2.90k
        || vdh == NULL
133
2.90k
        || !DH_up_ref(vdh))
134
0
        return 0;
135
2.90k
    DH_free(pdhctx->dh);
136
2.90k
    pdhctx->dh = vdh;
137
2.90k
    pdhctx->kdf_type = PROV_DH_KDF_NONE;
138
139
2.90k
    OSSL_FIPS_IND_SET_APPROVED(pdhctx)
140
2.90k
    if (!dh_set_ctx_params(pdhctx, params))
141
0
        return 0;
142
#ifdef FIPS_MODULE
143
    if (!dh_check_key(pdhctx))
144
        return 0;
145
#endif
146
2.90k
    return 1;
147
2.90k
}
148
149
/* The 2 parties must share the same domain parameters */
150
static int dh_match_params(DH *priv, DH *peer)
151
3.57k
{
152
3.57k
    int ret;
153
3.57k
    int ignore_q = 1;
154
3.57k
    FFC_PARAMS *dhparams_priv = ossl_dh_get0_params(priv);
155
3.57k
    FFC_PARAMS *dhparams_peer = ossl_dh_get0_params(peer);
156
157
3.57k
    if (dhparams_priv != NULL && dhparams_priv->q != NULL)
158
524
        ignore_q = 0;
159
3.57k
    ret = dhparams_priv != NULL
160
3.57k
        && dhparams_peer != NULL
161
3.57k
        && ossl_ffc_params_cmp(dhparams_priv, dhparams_peer, ignore_q);
162
3.57k
    if (!ret)
163
3.57k
        ERR_raise(ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS);
164
3.57k
    return ret;
165
3.57k
}
166
167
static int dh_set_peer(void *vpdhctx, void *vdh)
168
4.47k
{
169
4.47k
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
170
171
4.47k
    if (!ossl_prov_is_running()
172
4.47k
        || pdhctx == NULL
173
4.47k
        || vdh == NULL
174
4.47k
        || !dh_match_params(vdh, pdhctx->dh)
175
4.47k
        || !DH_up_ref(vdh))
176
0
        return 0;
177
4.47k
    DH_free(pdhctx->dhpeer);
178
4.47k
    pdhctx->dhpeer = vdh;
179
4.47k
    return 1;
180
4.47k
}
181
182
static int dh_plain_derive(void *vpdhctx,
183
    unsigned char *secret, size_t *secretlen,
184
    size_t outlen, unsigned int pad)
185
8.95k
{
186
8.95k
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
187
8.95k
    int ret;
188
8.95k
    size_t dhsize;
189
8.95k
    const BIGNUM *pub_key = NULL;
190
191
8.95k
    if (pdhctx->dh == NULL || pdhctx->dhpeer == NULL) {
192
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
193
0
        return 0;
194
0
    }
195
196
8.95k
    dhsize = (size_t)DH_size(pdhctx->dh);
197
8.95k
    if (secret == NULL) {
198
4.47k
        *secretlen = dhsize;
199
4.47k
        return 1;
200
4.47k
    }
201
4.47k
    if (outlen < dhsize) {
202
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
203
0
        return 0;
204
0
    }
205
206
4.47k
    DH_get0_key(pdhctx->dhpeer, &pub_key, NULL);
207
4.47k
    if (pad)
208
120
        ret = DH_compute_key_padded(secret, pub_key, pdhctx->dh);
209
4.35k
    else
210
4.35k
        ret = DH_compute_key(secret, pub_key, pdhctx->dh);
211
4.47k
    if (ret <= 0)
212
0
        return 0;
213
214
4.47k
    *secretlen = ret;
215
4.47k
    return 1;
216
4.47k
}
217
218
static int dh_X9_42_kdf_derive(void *vpdhctx, unsigned char *secret,
219
    size_t *secretlen, size_t outlen)
220
0
{
221
0
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
222
0
    unsigned char *stmp = NULL;
223
0
    size_t stmplen;
224
0
    int ret = 0;
225
226
0
    if (secret == NULL) {
227
0
        *secretlen = pdhctx->kdf_outlen;
228
0
        return 1;
229
0
    }
230
231
0
    if (pdhctx->kdf_outlen > outlen) {
232
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
233
0
        return 0;
234
0
    }
235
0
    if (!dh_plain_derive(pdhctx, NULL, &stmplen, 0, 1))
236
0
        return 0;
237
0
    if ((stmp = OPENSSL_secure_malloc(stmplen)) == NULL)
238
0
        return 0;
239
0
    if (!dh_plain_derive(pdhctx, stmp, &stmplen, stmplen, 1))
240
0
        goto err;
241
242
    /* Do KDF stuff */
243
0
    if (pdhctx->kdf_type == PROV_DH_KDF_X9_42_ASN1) {
244
0
        if (!ossl_dh_kdf_X9_42_asn1(secret, pdhctx->kdf_outlen,
245
0
                stmp, stmplen,
246
0
                pdhctx->kdf_cekalg,
247
0
                pdhctx->kdf_ukm,
248
0
                pdhctx->kdf_ukmlen,
249
0
                pdhctx->kdf_md,
250
0
                pdhctx->libctx, NULL))
251
0
            goto err;
252
0
    }
253
0
    *secretlen = pdhctx->kdf_outlen;
254
0
    ret = 1;
255
0
err:
256
0
    OPENSSL_secure_clear_free(stmp, stmplen);
257
0
    return ret;
258
0
}
259
260
static int dh_derive(void *vpdhctx, unsigned char *secret,
261
    size_t *psecretlen, size_t outlen)
262
8.95k
{
263
8.95k
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
264
265
8.95k
    if (!ossl_prov_is_running())
266
0
        return 0;
267
268
8.95k
    switch (pdhctx->kdf_type) {
269
8.95k
    case PROV_DH_KDF_NONE:
270
8.95k
        return dh_plain_derive(pdhctx, secret, psecretlen, outlen,
271
8.95k
            pdhctx->pad);
272
0
    case PROV_DH_KDF_X9_42_ASN1:
273
0
        return dh_X9_42_kdf_derive(pdhctx, secret, psecretlen, outlen);
274
0
    default:
275
0
        break;
276
8.95k
    }
277
0
    return 0;
278
8.95k
}
279
280
static void dh_freectx(void *vpdhctx)
281
4.78k
{
282
4.78k
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
283
284
4.78k
    OPENSSL_free(pdhctx->kdf_cekalg);
285
4.78k
    DH_free(pdhctx->dh);
286
4.78k
    DH_free(pdhctx->dhpeer);
287
4.78k
    EVP_MD_free(pdhctx->kdf_md);
288
4.78k
    OPENSSL_clear_free(pdhctx->kdf_ukm, pdhctx->kdf_ukmlen);
289
290
4.78k
    OPENSSL_free(pdhctx);
291
4.78k
}
292
293
static void *dh_dupctx(void *vpdhctx)
294
0
{
295
0
    PROV_DH_CTX *srcctx = (PROV_DH_CTX *)vpdhctx;
296
0
    PROV_DH_CTX *dstctx;
297
298
0
    if (!ossl_prov_is_running())
299
0
        return NULL;
300
301
0
    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
302
0
    if (dstctx == NULL)
303
0
        return NULL;
304
305
0
    *dstctx = *srcctx;
306
0
    dstctx->dh = NULL;
307
0
    dstctx->dhpeer = NULL;
308
0
    dstctx->kdf_md = NULL;
309
0
    dstctx->kdf_ukm = NULL;
310
0
    dstctx->kdf_cekalg = NULL;
311
312
0
    if (srcctx->dh != NULL && !DH_up_ref(srcctx->dh))
313
0
        goto err;
314
0
    else
315
0
        dstctx->dh = srcctx->dh;
316
317
0
    if (srcctx->dhpeer != NULL && !DH_up_ref(srcctx->dhpeer))
318
0
        goto err;
319
0
    else
320
0
        dstctx->dhpeer = srcctx->dhpeer;
321
322
0
    if (srcctx->kdf_md != NULL && !EVP_MD_up_ref(srcctx->kdf_md))
323
0
        goto err;
324
0
    else
325
0
        dstctx->kdf_md = srcctx->kdf_md;
326
327
    /* Duplicate UKM data if present */
328
0
    if (srcctx->kdf_ukm != NULL && srcctx->kdf_ukmlen > 0) {
329
0
        dstctx->kdf_ukm = OPENSSL_memdup(srcctx->kdf_ukm,
330
0
            srcctx->kdf_ukmlen);
331
0
        if (dstctx->kdf_ukm == NULL)
332
0
            goto err;
333
0
    }
334
335
0
    if (srcctx->kdf_cekalg != NULL) {
336
0
        dstctx->kdf_cekalg = OPENSSL_strdup(srcctx->kdf_cekalg);
337
0
        if (dstctx->kdf_cekalg == NULL)
338
0
            goto err;
339
0
    }
340
341
0
    return dstctx;
342
0
err:
343
0
    dh_freectx(dstctx);
344
0
    return NULL;
345
0
}
346
347
/* clang-format off */
348
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
349
#ifndef dh_set_ctx_params_list
350
static const OSSL_PARAM dh_set_ctx_params_list[] = {
351
    OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL),
352
    OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0),
353
    OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0),
354
    OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS, NULL, 0),
355
    OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL),
356
    OSSL_PARAM_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0),
357
    OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0),
358
# if defined(FIPS_MODULE)
359
    OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_FIPS_KEY_CHECK, NULL),
360
# endif
361
# if defined(FIPS_MODULE)
362
    OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_FIPS_DIGEST_CHECK, NULL),
363
# endif
364
    OSSL_PARAM_END
365
};
366
#endif
367
368
#ifndef dh_set_ctx_params_st
369
struct dh_set_ctx_params_st {
370
    OSSL_PARAM *cekalg;
371
    OSSL_PARAM *digest;
372
# if defined(FIPS_MODULE)
373
    OSSL_PARAM *ind_d;
374
# endif
375
# if defined(FIPS_MODULE)
376
    OSSL_PARAM *ind_k;
377
# endif
378
    OSSL_PARAM *kdf;
379
    OSSL_PARAM *len;
380
    OSSL_PARAM *pad;
381
    OSSL_PARAM *propq;
382
    OSSL_PARAM *ukm;
383
};
384
#endif
385
386
#ifndef dh_set_ctx_params_decoder
387
static int dh_set_ctx_params_decoder
388
    (const OSSL_PARAM *p, struct dh_set_ctx_params_st *r)
389
1.61k
{
390
1.61k
    const char *s;
391
392
1.61k
    memset(r, 0, sizeof(*r));
393
1.61k
    if (p != NULL)
394
240
        for (; (s = p->key) != NULL; p++)
395
120
            switch(s[0]) {
396
0
            default:
397
0
                break;
398
0
            case 'c':
399
0
                if (ossl_likely(strcmp("ekalg", s + 1) == 0)) {
400
                    /* OSSL_KDF_PARAM_CEK_ALG */
401
0
                    if (ossl_unlikely(r->cekalg != NULL)) {
402
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
403
0
                                       "param %s is repeated", s);
404
0
                        return 0;
405
0
                    }
406
0
                    r->cekalg = (OSSL_PARAM *)p;
407
0
                }
408
0
                break;
409
0
            case 'd':
410
# if defined(FIPS_MODULE)
411
                if (ossl_likely(strcmp("igest-check", s + 1) == 0)) {
412
                    /* OSSL_EXCHANGE_PARAM_FIPS_DIGEST_CHECK */
413
                    if (ossl_unlikely(r->ind_d != NULL)) {
414
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
415
                                       "param %s is repeated", s);
416
                        return 0;
417
                    }
418
                    r->ind_d = (OSSL_PARAM *)p;
419
                }
420
# endif
421
0
                break;
422
0
            case 'k':
423
0
                switch(s[1]) {
424
0
                default:
425
0
                    break;
426
0
                case 'd':
427
0
                    switch(s[2]) {
428
0
                    default:
429
0
                        break;
430
0
                    case 'f':
431
0
                        switch(s[3]) {
432
0
                        default:
433
0
                            break;
434
0
                        case '-':
435
0
                            switch(s[4]) {
436
0
                            default:
437
0
                                break;
438
0
                            case 'd':
439
0
                                switch(s[5]) {
440
0
                                default:
441
0
                                    break;
442
0
                                case 'i':
443
0
                                    switch(s[6]) {
444
0
                                    default:
445
0
                                        break;
446
0
                                    case 'g':
447
0
                                        switch(s[7]) {
448
0
                                        default:
449
0
                                            break;
450
0
                                        case 'e':
451
0
                                            switch(s[8]) {
452
0
                                            default:
453
0
                                                break;
454
0
                                            case 's':
455
0
                                                switch(s[9]) {
456
0
                                                default:
457
0
                                                    break;
458
0
                                                case 't':
459
0
                                                    switch(s[10]) {
460
0
                                                    default:
461
0
                                                        break;
462
0
                                                    case '-':
463
0
                                                        if (ossl_likely(strcmp("props", s + 11) == 0)) {
464
                                                            /* OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS */
465
0
                                                            if (ossl_unlikely(r->propq != NULL)) {
466
0
                                                                ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
467
0
                                                                               "param %s is repeated", s);
468
0
                                                                return 0;
469
0
                                                            }
470
0
                                                            r->propq = (OSSL_PARAM *)p;
471
0
                                                        }
472
0
                                                        break;
473
0
                                                    case '\0':
474
0
                                                        if (ossl_unlikely(r->digest != NULL)) {
475
0
                                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
476
0
                                                                           "param %s is repeated", s);
477
0
                                                            return 0;
478
0
                                                        }
479
0
                                                        r->digest = (OSSL_PARAM *)p;
480
0
                                                    }
481
0
                                                }
482
0
                                            }
483
0
                                        }
484
0
                                    }
485
0
                                }
486
0
                                break;
487
0
                            case 'o':
488
0
                                if (ossl_likely(strcmp("utlen", s + 5) == 0)) {
489
                                    /* OSSL_EXCHANGE_PARAM_KDF_OUTLEN */
490
0
                                    if (ossl_unlikely(r->len != NULL)) {
491
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
492
0
                                                       "param %s is repeated", s);
493
0
                                        return 0;
494
0
                                    }
495
0
                                    r->len = (OSSL_PARAM *)p;
496
0
                                }
497
0
                                break;
498
0
                            case 't':
499
0
                                if (ossl_likely(strcmp("ype", s + 5) == 0)) {
500
                                    /* OSSL_EXCHANGE_PARAM_KDF_TYPE */
501
0
                                    if (ossl_unlikely(r->kdf != NULL)) {
502
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
503
0
                                                       "param %s is repeated", s);
504
0
                                        return 0;
505
0
                                    }
506
0
                                    r->kdf = (OSSL_PARAM *)p;
507
0
                                }
508
0
                                break;
509
0
                            case 'u':
510
0
                                if (ossl_likely(strcmp("km", s + 5) == 0)) {
511
                                    /* OSSL_EXCHANGE_PARAM_KDF_UKM */
512
0
                                    if (ossl_unlikely(r->ukm != NULL)) {
513
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
514
0
                                                       "param %s is repeated", s);
515
0
                                        return 0;
516
0
                                    }
517
0
                                    r->ukm = (OSSL_PARAM *)p;
518
0
                                }
519
0
                            }
520
0
                        }
521
0
                    }
522
0
                    break;
523
0
                case 'e':
524
# if defined(FIPS_MODULE)
525
                    if (ossl_likely(strcmp("y-check", s + 2) == 0)) {
526
                        /* OSSL_EXCHANGE_PARAM_FIPS_KEY_CHECK */
527
                        if (ossl_unlikely(r->ind_k != NULL)) {
528
                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
529
                                           "param %s is repeated", s);
530
                            return 0;
531
                        }
532
                        r->ind_k = (OSSL_PARAM *)p;
533
                    }
534
# endif
535
0
                    break;
536
0
                }
537
0
                break;
538
120
            case 'p':
539
120
                if (ossl_likely(strcmp("ad", s + 1) == 0)) {
540
                    /* OSSL_EXCHANGE_PARAM_PAD */
541
120
                    if (ossl_unlikely(r->pad != NULL)) {
542
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
543
0
                                       "param %s is repeated", s);
544
0
                        return 0;
545
0
                    }
546
120
                    r->pad = (OSSL_PARAM *)p;
547
120
                }
548
120
            }
549
1.61k
    return 1;
550
1.61k
}
551
#endif
552
/* End of machine generated */
553
/* clang-format on */
554
555
static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[])
556
1.61k
{
557
1.61k
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
558
1.61k
    struct dh_set_ctx_params_st p;
559
1.61k
    unsigned int pad;
560
1.61k
    char name[80] = { '\0' }; /* should be big enough */
561
1.61k
    char *str = NULL;
562
563
1.61k
    if (pdhctx == NULL || !dh_set_ctx_params_decoder(params, &p))
564
0
        return 0;
565
566
1.61k
    if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(pdhctx, OSSL_FIPS_IND_SETTABLE0, p.ind_k))
567
0
        return 0;
568
1.61k
    if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(pdhctx, OSSL_FIPS_IND_SETTABLE1, p.ind_d))
569
0
        return 0;
570
571
1.61k
    if (p.kdf != NULL) {
572
0
        str = name;
573
0
        if (!OSSL_PARAM_get_utf8_string(p.kdf, &str, sizeof(name)))
574
0
            return 0;
575
576
0
        if (name[0] == '\0')
577
0
            pdhctx->kdf_type = PROV_DH_KDF_NONE;
578
0
        else if (strcmp(name, OSSL_KDF_NAME_X942KDF_ASN1) == 0)
579
0
            pdhctx->kdf_type = PROV_DH_KDF_X9_42_ASN1;
580
0
        else
581
0
            return 0;
582
0
    }
583
584
1.61k
    if (p.digest != NULL) {
585
0
        char mdprops[80] = { '\0' }; /* should be big enough */
586
587
0
        str = name;
588
0
        if (!OSSL_PARAM_get_utf8_string(p.digest, &str, sizeof(name)))
589
0
            return 0;
590
591
0
        str = mdprops;
592
0
        if (p.propq != NULL) {
593
0
            if (!OSSL_PARAM_get_utf8_string(p.propq, &str, sizeof(mdprops)))
594
0
                return 0;
595
0
        }
596
597
0
        EVP_MD_free(pdhctx->kdf_md);
598
0
        pdhctx->kdf_md = EVP_MD_fetch(pdhctx->libctx, name, mdprops);
599
0
        if (pdhctx->kdf_md == NULL)
600
0
            return 0;
601
        /* XOF digests are not allowed */
602
0
        if (EVP_MD_xof(pdhctx->kdf_md)) {
603
0
            ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);
604
0
            return 0;
605
0
        }
606
#ifdef FIPS_MODULE
607
        if (!digest_check(pdhctx, pdhctx->kdf_md)) {
608
            EVP_MD_free(pdhctx->kdf_md);
609
            pdhctx->kdf_md = NULL;
610
            return 0;
611
        }
612
#endif
613
0
    }
614
615
1.61k
    if (p.len != NULL) {
616
0
        size_t outlen;
617
618
0
        if (!OSSL_PARAM_get_size_t(p.len, &outlen))
619
0
            return 0;
620
0
        pdhctx->kdf_outlen = outlen;
621
0
    }
622
623
1.61k
    if (p.ukm != NULL) {
624
0
        void *tmp_ukm = NULL;
625
0
        size_t tmp_ukmlen;
626
627
0
        OPENSSL_free(pdhctx->kdf_ukm);
628
0
        pdhctx->kdf_ukm = NULL;
629
0
        pdhctx->kdf_ukmlen = 0;
630
        /* ukm is an optional field so it can be NULL */
631
0
        if (p.ukm->data != NULL && p.ukm->data_size != 0) {
632
0
            if (!OSSL_PARAM_get_octet_string(p.ukm, &tmp_ukm, 0, &tmp_ukmlen))
633
0
                return 0;
634
0
            pdhctx->kdf_ukm = tmp_ukm;
635
0
            pdhctx->kdf_ukmlen = tmp_ukmlen;
636
0
        }
637
0
    }
638
639
1.61k
    if (p.pad != NULL) {
640
120
        if (!OSSL_PARAM_get_uint(p.pad, &pad))
641
0
            return 0;
642
120
        pdhctx->pad = pad ? 1 : 0;
643
120
    }
644
645
1.61k
    if (p.cekalg != NULL) {
646
0
        str = name;
647
648
0
        OPENSSL_free(pdhctx->kdf_cekalg);
649
0
        pdhctx->kdf_cekalg = NULL;
650
0
        if (p.cekalg->data != NULL && p.cekalg->data_size != 0) {
651
0
            if (!OSSL_PARAM_get_utf8_string(p.cekalg, &str, sizeof(name)))
652
0
                return 0;
653
0
            pdhctx->kdf_cekalg = OPENSSL_strdup(name);
654
0
            if (pdhctx->kdf_cekalg == NULL)
655
0
                return 0;
656
0
        }
657
0
    }
658
1.61k
    return 1;
659
1.61k
}
660
661
static const OSSL_PARAM *dh_settable_ctx_params(ossl_unused void *vpdhctx,
662
    ossl_unused void *provctx)
663
137
{
664
137
    return dh_set_ctx_params_list;
665
137
}
666
667
/* clang-format off */
668
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
669
#ifndef dh_get_ctx_params_list
670
static const OSSL_PARAM dh_get_ctx_params_list[] = {
671
    OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0),
672
    OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0),
673
    OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL),
674
    OSSL_PARAM_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0),
675
    OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0),
676
# if defined(FIPS_MODULE)
677
    OSSL_PARAM_int(OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR, NULL),
678
# endif
679
    OSSL_PARAM_END
680
};
681
#endif
682
683
#ifndef dh_get_ctx_params_st
684
struct dh_get_ctx_params_st {
685
    OSSL_PARAM *cekalg;
686
    OSSL_PARAM *digest;
687
# if defined(FIPS_MODULE)
688
    OSSL_PARAM *ind;
689
# endif
690
    OSSL_PARAM *kdf;
691
    OSSL_PARAM *len;
692
    OSSL_PARAM *ukm;
693
};
694
#endif
695
696
#ifndef dh_get_ctx_params_decoder
697
static int dh_get_ctx_params_decoder
698
    (const OSSL_PARAM *p, struct dh_get_ctx_params_st *r)
699
0
{
700
0
    const char *s;
701
702
0
    memset(r, 0, sizeof(*r));
703
0
    if (p != NULL)
704
0
        for (; (s = p->key) != NULL; p++)
705
0
            switch(s[0]) {
706
0
            default:
707
0
                break;
708
0
            case 'c':
709
0
                if (ossl_likely(strcmp("ekalg", s + 1) == 0)) {
710
                    /* OSSL_KDF_PARAM_CEK_ALG */
711
0
                    if (ossl_unlikely(r->cekalg != NULL)) {
712
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
713
0
                                       "param %s is repeated", s);
714
0
                        return 0;
715
0
                    }
716
0
                    r->cekalg = (OSSL_PARAM *)p;
717
0
                }
718
0
                break;
719
0
            case 'f':
720
# if defined(FIPS_MODULE)
721
                if (ossl_likely(strcmp("ips-indicator", s + 1) == 0)) {
722
                    /* OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR */
723
                    if (ossl_unlikely(r->ind != NULL)) {
724
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
725
                                       "param %s is repeated", s);
726
                        return 0;
727
                    }
728
                    r->ind = (OSSL_PARAM *)p;
729
                }
730
# endif
731
0
                break;
732
0
            case 'k':
733
0
                switch(s[1]) {
734
0
                default:
735
0
                    break;
736
0
                case 'd':
737
0
                    switch(s[2]) {
738
0
                    default:
739
0
                        break;
740
0
                    case 'f':
741
0
                        switch(s[3]) {
742
0
                        default:
743
0
                            break;
744
0
                        case '-':
745
0
                            switch(s[4]) {
746
0
                            default:
747
0
                                break;
748
0
                            case 'd':
749
0
                                if (ossl_likely(strcmp("igest", s + 5) == 0)) {
750
                                    /* OSSL_EXCHANGE_PARAM_KDF_DIGEST */
751
0
                                    if (ossl_unlikely(r->digest != NULL)) {
752
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
753
0
                                                       "param %s is repeated", s);
754
0
                                        return 0;
755
0
                                    }
756
0
                                    r->digest = (OSSL_PARAM *)p;
757
0
                                }
758
0
                                break;
759
0
                            case 'o':
760
0
                                if (ossl_likely(strcmp("utlen", s + 5) == 0)) {
761
                                    /* OSSL_EXCHANGE_PARAM_KDF_OUTLEN */
762
0
                                    if (ossl_unlikely(r->len != NULL)) {
763
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
764
0
                                                       "param %s is repeated", s);
765
0
                                        return 0;
766
0
                                    }
767
0
                                    r->len = (OSSL_PARAM *)p;
768
0
                                }
769
0
                                break;
770
0
                            case 't':
771
0
                                if (ossl_likely(strcmp("ype", s + 5) == 0)) {
772
                                    /* OSSL_EXCHANGE_PARAM_KDF_TYPE */
773
0
                                    if (ossl_unlikely(r->kdf != NULL)) {
774
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
775
0
                                                       "param %s is repeated", s);
776
0
                                        return 0;
777
0
                                    }
778
0
                                    r->kdf = (OSSL_PARAM *)p;
779
0
                                }
780
0
                                break;
781
0
                            case 'u':
782
0
                                if (ossl_likely(strcmp("km", s + 5) == 0)) {
783
                                    /* OSSL_EXCHANGE_PARAM_KDF_UKM */
784
0
                                    if (ossl_unlikely(r->ukm != NULL)) {
785
0
                                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
786
0
                                                       "param %s is repeated", s);
787
0
                                        return 0;
788
0
                                    }
789
0
                                    r->ukm = (OSSL_PARAM *)p;
790
0
                                }
791
0
                            }
792
0
                        }
793
0
                    }
794
0
                }
795
0
            }
796
0
    return 1;
797
0
}
798
#endif
799
/* End of machine generated */
800
/* clang-format on */
801
802
static const OSSL_PARAM *dh_gettable_ctx_params(ossl_unused void *vpdhctx,
803
    ossl_unused void *provctx)
804
0
{
805
0
    return dh_get_ctx_params_list;
806
0
}
807
808
static int dh_get_ctx_params(void *vpdhctx, OSSL_PARAM params[])
809
0
{
810
0
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
811
0
    struct dh_get_ctx_params_st p;
812
813
0
    if (pdhctx == NULL || !dh_get_ctx_params_decoder(params, &p))
814
0
        return 0;
815
816
0
    if (p.kdf != NULL) {
817
0
        const char *kdf_type = NULL;
818
819
0
        switch (pdhctx->kdf_type) {
820
0
        case PROV_DH_KDF_NONE:
821
0
            kdf_type = "";
822
0
            break;
823
0
        case PROV_DH_KDF_X9_42_ASN1:
824
0
            kdf_type = OSSL_KDF_NAME_X942KDF_ASN1;
825
0
            break;
826
0
        default:
827
0
            return 0;
828
0
        }
829
830
0
        if (!OSSL_PARAM_set_utf8_string(p.kdf, kdf_type))
831
0
            return 0;
832
0
    }
833
834
0
    if (p.digest != NULL
835
0
        && !OSSL_PARAM_set_utf8_string(p.digest, pdhctx->kdf_md == NULL ? "" : EVP_MD_get0_name(pdhctx->kdf_md))) {
836
0
        return 0;
837
0
    }
838
839
0
    if (p.len != NULL && !OSSL_PARAM_set_size_t(p.len, pdhctx->kdf_outlen))
840
0
        return 0;
841
842
0
    if (p.ukm != NULL
843
0
        && !OSSL_PARAM_set_octet_ptr(p.ukm, pdhctx->kdf_ukm, pdhctx->kdf_ukmlen))
844
0
        return 0;
845
846
0
    if (p.cekalg != NULL
847
0
        && !OSSL_PARAM_set_utf8_string(p.cekalg, pdhctx->kdf_cekalg == NULL ? "" : pdhctx->kdf_cekalg))
848
0
        return 0;
849
850
0
    if (!OSSL_FIPS_IND_GET_CTX_FROM_PARAM(pdhctx, p.ind))
851
0
        return 0;
852
0
    return 1;
853
0
}
854
855
const OSSL_DISPATCH ossl_dh_keyexch_functions[] = {
856
    { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx },
857
    { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init },
858
    { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))dh_derive },
859
    { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))dh_set_peer },
860
    { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))dh_freectx },
861
    { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))dh_dupctx },
862
    { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))dh_set_ctx_params },
863
    { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS,
864
        (void (*)(void))dh_settable_ctx_params },
865
    { OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))dh_get_ctx_params },
866
    { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS,
867
        (void (*)(void))dh_gettable_ctx_params },
868
    OSSL_DISPATCH_END
869
};