Coverage Report

Created: 2025-06-13 06:57

/src/openssl/providers/implementations/exchange/dh_exch.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2019-2024 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 <string.h>
17
#include <openssl/crypto.h>
18
#include <openssl/core_dispatch.h>
19
#include <openssl/core_names.h>
20
#include <openssl/dh.h>
21
#include <openssl/err.h>
22
#include <openssl/proverr.h>
23
#include <openssl/params.h>
24
#include "prov/providercommon.h"
25
#include "prov/implementations.h"
26
#include "prov/provider_ctx.h"
27
#include "prov/securitycheck.h"
28
#include "crypto/dh.h"
29
30
static OSSL_FUNC_keyexch_newctx_fn dh_newctx;
31
static OSSL_FUNC_keyexch_init_fn dh_init;
32
static OSSL_FUNC_keyexch_set_peer_fn dh_set_peer;
33
static OSSL_FUNC_keyexch_derive_fn dh_derive;
34
static OSSL_FUNC_keyexch_freectx_fn dh_freectx;
35
static OSSL_FUNC_keyexch_dupctx_fn dh_dupctx;
36
static OSSL_FUNC_keyexch_set_ctx_params_fn dh_set_ctx_params;
37
static OSSL_FUNC_keyexch_settable_ctx_params_fn dh_settable_ctx_params;
38
static OSSL_FUNC_keyexch_get_ctx_params_fn dh_get_ctx_params;
39
static OSSL_FUNC_keyexch_gettable_ctx_params_fn dh_gettable_ctx_params;
40
41
/*
42
 * This type is only really used to handle some legacy related functionality.
43
 * If you need to use other KDF's (such as SSKDF) just use PROV_DH_KDF_NONE
44
 * here and then create and run a KDF after the key is derived.
45
 * Note that X942 has 2 variants of key derivation:
46
 *   (1) DH_KDF_X9_42_ASN1 - which contains an ANS1 encoded object that has
47
 *   the counter embedded in it.
48
 *   (2) DH_KDF_X941_CONCAT - which is the same as ECDH_X963_KDF (which can be
49
 *       done by creating a "X963KDF".
50
 */
51
enum kdf_type {
52
    PROV_DH_KDF_NONE = 0,
53
    PROV_DH_KDF_X9_42_ASN1
54
};
55
56
/*
57
 * What's passed as an actual key is defined by the KEYMGMT interface.
58
 * We happen to know that our KEYMGMT simply passes DH structures, so
59
 * we use that here too.
60
 */
61
62
typedef struct {
63
    OSSL_LIB_CTX *libctx;
64
    DH *dh;
65
    DH *dhpeer;
66
    unsigned int pad : 1;
67
68
    /* DH KDF */
69
    /* KDF (if any) to use for DH */
70
    enum kdf_type kdf_type;
71
    /* Message digest to use for key derivation */
72
    EVP_MD *kdf_md;
73
    /* User key material */
74
    unsigned char *kdf_ukm;
75
    size_t kdf_ukmlen;
76
    /* KDF output length */
77
    size_t kdf_outlen;
78
    char *kdf_cekalg;
79
    OSSL_FIPS_IND_DECLARE
80
} PROV_DH_CTX;
81
82
static void *dh_newctx(void *provctx)
83
0
{
84
0
    PROV_DH_CTX *pdhctx;
85
86
0
    if (!ossl_prov_is_running())
87
0
        return NULL;
88
89
0
    pdhctx = OPENSSL_zalloc(sizeof(PROV_DH_CTX));
90
0
    if (pdhctx == NULL)
91
0
        return NULL;
92
0
    OSSL_FIPS_IND_INIT(pdhctx)
93
0
    pdhctx->libctx = PROV_LIBCTX_OF(provctx);
94
0
    pdhctx->kdf_type = PROV_DH_KDF_NONE;
95
0
    return pdhctx;
96
0
}
97
98
#ifdef FIPS_MODULE
99
static int dh_check_key(PROV_DH_CTX *ctx)
100
{
101
    int key_approved = ossl_dh_check_key(ctx->dh);
102
103
    if (!key_approved) {
104
        if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
105
                                         ctx->libctx, "DH Init", "DH Key",
106
                                         ossl_fips_config_securitycheck_enabled)) {
107
            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
108
            return 0;
109
        }
110
    }
111
    return 1;
112
}
113
114
static int digest_check(PROV_DH_CTX *ctx, const EVP_MD *md)
115
{
116
    return ossl_fips_ind_digest_exch_check(OSSL_FIPS_IND_GET(ctx),
117
                                           OSSL_FIPS_IND_SETTABLE1, ctx->libctx,
118
                                           md, "DH Set Ctx");
119
}
120
#endif
121
122
static int dh_init(void *vpdhctx, void *vdh, const OSSL_PARAM params[])
123
0
{
124
0
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
125
126
0
    if (!ossl_prov_is_running()
127
0
            || pdhctx == NULL
128
0
            || vdh == NULL
129
0
            || !DH_up_ref(vdh))
130
0
        return 0;
131
0
    DH_free(pdhctx->dh);
132
0
    pdhctx->dh = vdh;
133
0
    pdhctx->kdf_type = PROV_DH_KDF_NONE;
134
135
0
    OSSL_FIPS_IND_SET_APPROVED(pdhctx)
136
0
    if (!dh_set_ctx_params(pdhctx, params))
137
0
        return 0;
138
#ifdef FIPS_MODULE
139
    if (!dh_check_key(pdhctx))
140
        return 0;
141
#endif
142
0
    return 1;
143
0
}
144
145
/* The 2 parties must share the same domain parameters */
146
static int dh_match_params(DH *priv, DH *peer)
147
0
{
148
0
    int ret;
149
0
    FFC_PARAMS *dhparams_priv = ossl_dh_get0_params(priv);
150
0
    FFC_PARAMS *dhparams_peer = ossl_dh_get0_params(peer);
151
152
0
    ret = dhparams_priv != NULL
153
0
          && dhparams_peer != NULL
154
0
          && ossl_ffc_params_cmp(dhparams_priv, dhparams_peer, 1);
155
0
    if (!ret)
156
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS);
157
0
    return ret;
158
0
}
159
160
static int dh_set_peer(void *vpdhctx, void *vdh)
161
0
{
162
0
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
163
164
0
    if (!ossl_prov_is_running()
165
0
            || pdhctx == NULL
166
0
            || vdh == NULL
167
0
            || !dh_match_params(vdh, pdhctx->dh)
168
0
            || !DH_up_ref(vdh))
169
0
        return 0;
170
0
    DH_free(pdhctx->dhpeer);
171
0
    pdhctx->dhpeer = vdh;
172
0
    return 1;
173
0
}
174
175
static int dh_plain_derive(void *vpdhctx,
176
                           unsigned char *secret, size_t *secretlen,
177
                           size_t outlen, unsigned int pad)
178
0
{
179
0
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
180
0
    int ret;
181
0
    size_t dhsize;
182
0
    const BIGNUM *pub_key = NULL;
183
184
0
    if (pdhctx->dh == NULL || pdhctx->dhpeer == NULL) {
185
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
186
0
        return 0;
187
0
    }
188
189
0
    dhsize = (size_t)DH_size(pdhctx->dh);
190
0
    if (secret == NULL) {
191
0
        *secretlen = dhsize;
192
0
        return 1;
193
0
    }
194
0
    if (outlen < dhsize) {
195
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
196
0
        return 0;
197
0
    }
198
199
0
    DH_get0_key(pdhctx->dhpeer, &pub_key, NULL);
200
0
    if (pad)
201
0
        ret = DH_compute_key_padded(secret, pub_key, pdhctx->dh);
202
0
    else
203
0
        ret = DH_compute_key(secret, pub_key, pdhctx->dh);
204
0
    if (ret <= 0)
205
0
        return 0;
206
207
0
    *secretlen = ret;
208
0
    return 1;
209
0
}
210
211
static int dh_X9_42_kdf_derive(void *vpdhctx, unsigned char *secret,
212
                               size_t *secretlen, size_t outlen)
213
0
{
214
0
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
215
0
    unsigned char *stmp = NULL;
216
0
    size_t stmplen;
217
0
    int ret = 0;
218
219
0
    if (secret == NULL) {
220
0
        *secretlen = pdhctx->kdf_outlen;
221
0
        return 1;
222
0
    }
223
224
0
    if (pdhctx->kdf_outlen > outlen) {
225
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
226
0
        return 0;
227
0
    }
228
0
    if (!dh_plain_derive(pdhctx, NULL, &stmplen, 0, 1))
229
0
        return 0;
230
0
    if ((stmp = OPENSSL_secure_malloc(stmplen)) == NULL)
231
0
        return 0;
232
0
    if (!dh_plain_derive(pdhctx, stmp, &stmplen, stmplen, 1))
233
0
        goto err;
234
235
    /* Do KDF stuff */
236
0
    if (pdhctx->kdf_type == PROV_DH_KDF_X9_42_ASN1) {
237
0
        if (!ossl_dh_kdf_X9_42_asn1(secret, pdhctx->kdf_outlen,
238
0
                                    stmp, stmplen,
239
0
                                    pdhctx->kdf_cekalg,
240
0
                                    pdhctx->kdf_ukm,
241
0
                                    pdhctx->kdf_ukmlen,
242
0
                                    pdhctx->kdf_md,
243
0
                                    pdhctx->libctx, NULL))
244
0
            goto err;
245
0
    }
246
0
    *secretlen = pdhctx->kdf_outlen;
247
0
    ret = 1;
248
0
err:
249
0
    OPENSSL_secure_clear_free(stmp, stmplen);
250
0
    return ret;
251
0
}
252
253
static int dh_derive(void *vpdhctx, unsigned char *secret,
254
                     size_t *psecretlen, size_t outlen)
255
0
{
256
0
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
257
258
0
    if (!ossl_prov_is_running())
259
0
        return 0;
260
261
0
    switch (pdhctx->kdf_type) {
262
0
        case PROV_DH_KDF_NONE:
263
0
            return dh_plain_derive(pdhctx, secret, psecretlen, outlen,
264
0
                                   pdhctx->pad);
265
0
        case PROV_DH_KDF_X9_42_ASN1:
266
0
            return dh_X9_42_kdf_derive(pdhctx, secret, psecretlen, outlen);
267
0
        default:
268
0
            break;
269
0
    }
270
0
    return 0;
271
0
}
272
273
static void dh_freectx(void *vpdhctx)
274
0
{
275
0
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
276
277
0
    OPENSSL_free(pdhctx->kdf_cekalg);
278
0
    DH_free(pdhctx->dh);
279
0
    DH_free(pdhctx->dhpeer);
280
0
    EVP_MD_free(pdhctx->kdf_md);
281
0
    OPENSSL_clear_free(pdhctx->kdf_ukm, pdhctx->kdf_ukmlen);
282
283
0
    OPENSSL_free(pdhctx);
284
0
}
285
286
static void *dh_dupctx(void *vpdhctx)
287
0
{
288
0
    PROV_DH_CTX *srcctx = (PROV_DH_CTX *)vpdhctx;
289
0
    PROV_DH_CTX *dstctx;
290
291
0
    if (!ossl_prov_is_running())
292
0
        return NULL;
293
294
0
    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
295
0
    if (dstctx == NULL)
296
0
        return NULL;
297
298
0
    *dstctx = *srcctx;
299
0
    dstctx->dh = NULL;
300
0
    dstctx->dhpeer = NULL;
301
0
    dstctx->kdf_md = NULL;
302
0
    dstctx->kdf_ukm = NULL;
303
0
    dstctx->kdf_cekalg = NULL;
304
305
0
    if (srcctx->dh != NULL && !DH_up_ref(srcctx->dh))
306
0
        goto err;
307
0
    else
308
0
        dstctx->dh = srcctx->dh;
309
310
0
    if (srcctx->dhpeer != NULL && !DH_up_ref(srcctx->dhpeer))
311
0
        goto err;
312
0
    else
313
0
        dstctx->dhpeer = srcctx->dhpeer;
314
315
0
    if (srcctx->kdf_md != NULL && !EVP_MD_up_ref(srcctx->kdf_md))
316
0
        goto err;
317
0
    else
318
0
        dstctx->kdf_md = srcctx->kdf_md;
319
320
    /* Duplicate UKM data if present */
321
0
    if (srcctx->kdf_ukm != NULL && srcctx->kdf_ukmlen > 0) {
322
0
        dstctx->kdf_ukm = OPENSSL_memdup(srcctx->kdf_ukm,
323
0
                                         srcctx->kdf_ukmlen);
324
0
        if (dstctx->kdf_ukm == NULL)
325
0
            goto err;
326
0
    }
327
328
0
    if (srcctx->kdf_cekalg != NULL) {
329
0
        dstctx->kdf_cekalg = OPENSSL_strdup(srcctx->kdf_cekalg);
330
0
        if (dstctx->kdf_cekalg == NULL)
331
0
            goto err;
332
0
    }
333
334
0
    return dstctx;
335
0
err:
336
0
    dh_freectx(dstctx);
337
0
    return NULL;
338
0
}
339
340
static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[])
341
0
{
342
0
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
343
0
    const OSSL_PARAM *p;
344
0
    unsigned int pad;
345
0
    char name[80] = { '\0' }; /* should be big enough */
346
0
    char *str = NULL;
347
348
0
    if (pdhctx == NULL)
349
0
        return 0;
350
0
    if (ossl_param_is_empty(params))
351
0
        return 1;
352
353
0
    if (!OSSL_FIPS_IND_SET_CTX_PARAM(pdhctx, OSSL_FIPS_IND_SETTABLE0, params,
354
0
                                     OSSL_EXCHANGE_PARAM_FIPS_KEY_CHECK))
355
0
        return  0;
356
0
    if (!OSSL_FIPS_IND_SET_CTX_PARAM(pdhctx, OSSL_FIPS_IND_SETTABLE1, params,
357
0
                                     OSSL_EXCHANGE_PARAM_FIPS_DIGEST_CHECK))
358
0
        return  0;
359
360
0
    p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_TYPE);
361
0
    if (p != NULL) {
362
0
        str = name;
363
0
        if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name)))
364
0
            return 0;
365
366
0
        if (name[0] == '\0')
367
0
            pdhctx->kdf_type = PROV_DH_KDF_NONE;
368
0
        else if (strcmp(name, OSSL_KDF_NAME_X942KDF_ASN1) == 0)
369
0
            pdhctx->kdf_type = PROV_DH_KDF_X9_42_ASN1;
370
0
        else
371
0
            return 0;
372
0
    }
373
0
    p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST);
374
0
    if (p != NULL) {
375
0
        char mdprops[80] = { '\0' }; /* should be big enough */
376
377
0
        str = name;
378
0
        if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name)))
379
0
            return 0;
380
381
0
        str = mdprops;
382
0
        p = OSSL_PARAM_locate_const(params,
383
0
                                    OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS);
384
385
0
        if (p != NULL) {
386
0
            if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops)))
387
0
                return 0;
388
0
        }
389
390
0
        EVP_MD_free(pdhctx->kdf_md);
391
0
        pdhctx->kdf_md = EVP_MD_fetch(pdhctx->libctx, name, mdprops);
392
0
        if (pdhctx->kdf_md == NULL)
393
0
            return 0;
394
        /* XOF digests are not allowed */
395
0
        if (EVP_MD_xof(pdhctx->kdf_md)) {
396
0
            ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED);
397
0
            return 0;
398
0
        }
399
#ifdef FIPS_MODULE
400
        if (!digest_check(pdhctx, pdhctx->kdf_md)) {
401
            EVP_MD_free(pdhctx->kdf_md);
402
            pdhctx->kdf_md = NULL;
403
            return 0;
404
        }
405
#endif
406
0
    }
407
408
0
    p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN);
409
0
    if (p != NULL) {
410
0
        size_t outlen;
411
412
0
        if (!OSSL_PARAM_get_size_t(p, &outlen))
413
0
            return 0;
414
0
        pdhctx->kdf_outlen = outlen;
415
0
    }
416
417
0
    p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_UKM);
418
0
    if (p != NULL) {
419
0
        void *tmp_ukm = NULL;
420
0
        size_t tmp_ukmlen;
421
422
0
        OPENSSL_free(pdhctx->kdf_ukm);
423
0
        pdhctx->kdf_ukm = NULL;
424
0
        pdhctx->kdf_ukmlen = 0;
425
        /* ukm is an optional field so it can be NULL */
426
0
        if (p->data != NULL && p->data_size != 0) {
427
0
            if (!OSSL_PARAM_get_octet_string(p, &tmp_ukm, 0, &tmp_ukmlen))
428
0
                return 0;
429
0
            pdhctx->kdf_ukm = tmp_ukm;
430
0
            pdhctx->kdf_ukmlen = tmp_ukmlen;
431
0
        }
432
0
    }
433
434
0
    p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD);
435
0
    if (p != NULL) {
436
0
        if (!OSSL_PARAM_get_uint(p, &pad))
437
0
            return 0;
438
0
        pdhctx->pad = pad ? 1 : 0;
439
0
    }
440
441
0
    p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CEK_ALG);
442
0
    if (p != NULL) {
443
0
        str = name;
444
445
0
        OPENSSL_free(pdhctx->kdf_cekalg);
446
0
        pdhctx->kdf_cekalg = NULL;
447
0
        if (p->data != NULL && p->data_size != 0) {
448
0
            if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name)))
449
0
                return 0;
450
0
            pdhctx->kdf_cekalg = OPENSSL_strdup(name);
451
0
            if (pdhctx->kdf_cekalg == NULL)
452
0
                return 0;
453
0
        }
454
0
    }
455
0
    return 1;
456
0
}
457
458
static const OSSL_PARAM known_settable_ctx_params[] = {
459
    OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL),
460
    OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0),
461
    OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0),
462
    OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS, NULL, 0),
463
    OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL),
464
    OSSL_PARAM_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0),
465
    OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0),
466
    OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_EXCHANGE_PARAM_FIPS_KEY_CHECK)
467
    OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_EXCHANGE_PARAM_FIPS_DIGEST_CHECK)
468
    OSSL_PARAM_END
469
};
470
471
static const OSSL_PARAM *dh_settable_ctx_params(ossl_unused void *vpdhctx,
472
                                                ossl_unused void *provctx)
473
0
{
474
0
    return known_settable_ctx_params;
475
0
}
476
477
static const OSSL_PARAM known_gettable_ctx_params[] = {
478
    OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0),
479
    OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0),
480
    OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL),
481
    OSSL_PARAM_DEFN(OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR,
482
                    NULL, 0),
483
    OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0),
484
    OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
485
    OSSL_PARAM_END
486
};
487
488
static const OSSL_PARAM *dh_gettable_ctx_params(ossl_unused void *vpdhctx,
489
                                                ossl_unused void *provctx)
490
0
{
491
0
    return known_gettable_ctx_params;
492
0
}
493
494
static int dh_get_ctx_params(void *vpdhctx, OSSL_PARAM params[])
495
0
{
496
0
    PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
497
0
    OSSL_PARAM *p;
498
499
0
    if (pdhctx == NULL)
500
0
        return 0;
501
502
0
    p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_TYPE);
503
0
    if (p != NULL) {
504
0
        const char *kdf_type = NULL;
505
506
0
        switch (pdhctx->kdf_type) {
507
0
            case PROV_DH_KDF_NONE:
508
0
                kdf_type = "";
509
0
                break;
510
0
            case PROV_DH_KDF_X9_42_ASN1:
511
0
                kdf_type = OSSL_KDF_NAME_X942KDF_ASN1;
512
0
                break;
513
0
            default:
514
0
                return 0;
515
0
        }
516
517
0
        if (!OSSL_PARAM_set_utf8_string(p, kdf_type))
518
0
            return 0;
519
0
    }
520
521
0
    p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST);
522
0
    if (p != NULL
523
0
            && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_md == NULL
524
0
                                           ? ""
525
0
                                           : EVP_MD_get0_name(pdhctx->kdf_md))) {
526
0
        return 0;
527
0
    }
528
529
0
    p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN);
530
0
    if (p != NULL && !OSSL_PARAM_set_size_t(p, pdhctx->kdf_outlen))
531
0
        return 0;
532
533
0
    p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_UKM);
534
0
    if (p != NULL
535
0
        && !OSSL_PARAM_set_octet_ptr(p, pdhctx->kdf_ukm, pdhctx->kdf_ukmlen))
536
0
        return 0;
537
538
0
    p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_CEK_ALG);
539
0
    if (p != NULL
540
0
            && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_cekalg == NULL
541
0
                                           ? "" :  pdhctx->kdf_cekalg))
542
0
        return 0;
543
0
    if (!OSSL_FIPS_IND_GET_CTX_PARAM(pdhctx, params))
544
0
        return 0;
545
0
    return 1;
546
0
}
547
548
const OSSL_DISPATCH ossl_dh_keyexch_functions[] = {
549
    { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx },
550
    { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init },
551
    { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))dh_derive },
552
    { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))dh_set_peer },
553
    { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))dh_freectx },
554
    { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))dh_dupctx },
555
    { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))dh_set_ctx_params },
556
    { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS,
557
      (void (*)(void))dh_settable_ctx_params },
558
    { OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))dh_get_ctx_params },
559
    { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS,
560
      (void (*)(void))dh_gettable_ctx_params },
561
    OSSL_DISPATCH_END
562
};