2 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
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
11 * DH low level APIs are deprecated for public use, but still ok for
14 #include "internal/deprecated.h"
16 #include <string.h> /* strcmp */
17 #include <openssl/core_dispatch.h>
18 #include <openssl/core_names.h>
19 #include <openssl/bn.h>
20 #include <openssl/err.h>
21 #include "prov/implementations.h"
22 #include "prov/providercommon.h"
23 #include "prov/provider_ctx.h"
24 #include "crypto/dh.h"
25 #include "internal/sizes.h"
27 static OSSL_FUNC_keymgmt_new_fn dh_newdata
;
28 static OSSL_FUNC_keymgmt_free_fn dh_freedata
;
29 static OSSL_FUNC_keymgmt_gen_init_fn dh_gen_init
;
30 static OSSL_FUNC_keymgmt_gen_init_fn dhx_gen_init
;
31 static OSSL_FUNC_keymgmt_gen_set_template_fn dh_gen_set_template
;
32 static OSSL_FUNC_keymgmt_gen_set_params_fn dh_gen_set_params
;
33 static OSSL_FUNC_keymgmt_gen_settable_params_fn dh_gen_settable_params
;
34 static OSSL_FUNC_keymgmt_gen_fn dh_gen
;
35 static OSSL_FUNC_keymgmt_gen_cleanup_fn dh_gen_cleanup
;
36 static OSSL_FUNC_keymgmt_load_fn dh_load
;
37 static OSSL_FUNC_keymgmt_get_params_fn dh_get_params
;
38 static OSSL_FUNC_keymgmt_gettable_params_fn dh_gettable_params
;
39 static OSSL_FUNC_keymgmt_set_params_fn dh_set_params
;
40 static OSSL_FUNC_keymgmt_settable_params_fn dh_settable_params
;
41 static OSSL_FUNC_keymgmt_has_fn dh_has
;
42 static OSSL_FUNC_keymgmt_match_fn dh_match
;
43 static OSSL_FUNC_keymgmt_validate_fn dh_validate
;
44 static OSSL_FUNC_keymgmt_import_fn dh_import
;
45 static OSSL_FUNC_keymgmt_import_types_fn dh_import_types
;
46 static OSSL_FUNC_keymgmt_export_fn dh_export
;
47 static OSSL_FUNC_keymgmt_export_types_fn dh_export_types
;
48 static OSSL_FUNC_keymgmt_dup_fn dh_dup
;
50 #define DH_POSSIBLE_SELECTIONS \
51 (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
56 FFC_PARAMS
*ffc_params
;
58 /* All these parameters are used for parameter generation only */
59 /* If there is a group name then the remaining parameters are not needed */
63 unsigned char *seed
; /* optional FIPS186-4 param for testing */
65 int gindex
; /* optional FIPS186-4 generator index (ignored if -1) */
66 int gen_type
; /* see dhtype2id */
67 int generator
; /* Used by DH_PARAMGEN_TYPE_GENERATOR in non fips mode only */
79 static int dh_gen_type_name2id_w_default(const char *name
, int type
)
81 if (strcmp(name
, "default") == 0) {
83 if (type
== DH_FLAG_TYPE_DHX
)
84 return DH_PARAMGEN_TYPE_FIPS_186_4
;
86 return DH_PARAMGEN_TYPE_GROUP
;
88 if (type
== DH_FLAG_TYPE_DHX
)
89 return DH_PARAMGEN_TYPE_FIPS_186_2
;
91 return DH_PARAMGEN_TYPE_GENERATOR
;
95 return ossl_dh_gen_type_name2id(name
);
98 static void *dh_newdata(void *provctx
)
102 if (ossl_prov_is_running()) {
103 dh
= ossl_dh_new_ex(PROV_LIBCTX_OF(provctx
));
105 DH_clear_flags(dh
, DH_FLAG_TYPE_MASK
);
106 DH_set_flags(dh
, DH_FLAG_TYPE_DH
);
112 static void *dhx_newdata(void *provctx
)
116 dh
= ossl_dh_new_ex(PROV_LIBCTX_OF(provctx
));
118 DH_clear_flags(dh
, DH_FLAG_TYPE_MASK
);
119 DH_set_flags(dh
, DH_FLAG_TYPE_DHX
);
124 static void dh_freedata(void *keydata
)
129 static int dh_has(const void *keydata
, int selection
)
131 const DH
*dh
= keydata
;
134 if (!ossl_prov_is_running() || dh
== NULL
)
136 if ((selection
& DH_POSSIBLE_SELECTIONS
) == 0)
137 return 1; /* the selection is not missing */
139 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0)
140 ok
= ok
&& (DH_get0_pub_key(dh
) != NULL
);
141 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0)
142 ok
= ok
&& (DH_get0_priv_key(dh
) != NULL
);
143 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0)
144 ok
= ok
&& (DH_get0_p(dh
) != NULL
&& DH_get0_g(dh
) != NULL
);
148 static int dh_match(const void *keydata1
, const void *keydata2
, int selection
)
150 const DH
*dh1
= keydata1
;
151 const DH
*dh2
= keydata2
;
154 if (!ossl_prov_is_running())
157 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0)
158 ok
= ok
&& BN_cmp(DH_get0_pub_key(dh1
), DH_get0_pub_key(dh2
)) == 0;
159 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0)
160 ok
= ok
&& BN_cmp(DH_get0_priv_key(dh1
), DH_get0_priv_key(dh2
)) == 0;
161 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0) {
162 FFC_PARAMS
*dhparams1
= ossl_dh_get0_params((DH
*)dh1
);
163 FFC_PARAMS
*dhparams2
= ossl_dh_get0_params((DH
*)dh2
);
165 ok
= ok
&& ossl_ffc_params_cmp(dhparams1
, dhparams2
, 1);
170 static int dh_import(void *keydata
, int selection
, const OSSL_PARAM params
[])
175 if (!ossl_prov_is_running() || dh
== NULL
)
178 if ((selection
& DH_POSSIBLE_SELECTIONS
) == 0)
181 if ((selection
& OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
) != 0)
182 ok
= ok
&& ossl_dh_params_fromdata(dh
, params
);
184 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) != 0)
185 ok
= ok
&& ossl_dh_key_fromdata(dh
, params
);
190 static int dh_export(void *keydata
, int selection
, OSSL_CALLBACK
*param_cb
,
194 OSSL_PARAM_BLD
*tmpl
= NULL
;
195 OSSL_PARAM
*params
= NULL
;
198 if (!ossl_prov_is_running() || dh
== NULL
)
201 tmpl
= OSSL_PARAM_BLD_new();
205 if ((selection
& OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
) != 0)
206 ok
= ok
&& ossl_dh_params_todata(dh
, tmpl
, NULL
);
207 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) != 0)
208 ok
= ok
&& ossl_dh_key_todata(dh
, tmpl
, NULL
);
211 || (params
= OSSL_PARAM_BLD_to_param(tmpl
)) == NULL
) {
215 ok
= param_cb(params
, cbarg
);
216 OSSL_PARAM_free(params
);
218 OSSL_PARAM_BLD_free(tmpl
);
222 /* IMEXPORT = IMPORT + EXPORT */
224 # define DH_IMEXPORTABLE_PARAMETERS \
225 OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, NULL, 0), \
226 OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_Q, NULL, 0), \
227 OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_G, NULL, 0), \
228 OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_COFACTOR, NULL, 0), \
229 OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL), \
230 OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL), \
231 OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL), \
232 OSSL_PARAM_int(OSSL_PKEY_PARAM_DH_PRIV_LEN, NULL), \
233 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0), \
234 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0)
235 # define DH_IMEXPORTABLE_PUBLIC_KEY \
236 OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)
237 # define DH_IMEXPORTABLE_PRIVATE_KEY \
238 OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
239 static const OSSL_PARAM dh_all_types
[] = {
240 DH_IMEXPORTABLE_PARAMETERS
,
241 DH_IMEXPORTABLE_PUBLIC_KEY
,
242 DH_IMEXPORTABLE_PRIVATE_KEY
,
245 static const OSSL_PARAM dh_parameter_types
[] = {
246 DH_IMEXPORTABLE_PARAMETERS
,
249 static const OSSL_PARAM dh_key_types
[] = {
250 DH_IMEXPORTABLE_PUBLIC_KEY
,
251 DH_IMEXPORTABLE_PRIVATE_KEY
,
254 static const OSSL_PARAM
*dh_types
[] = {
255 NULL
, /* Index 0 = none of them */
256 dh_parameter_types
, /* Index 1 = parameter types */
257 dh_key_types
, /* Index 2 = key types */
258 dh_all_types
/* Index 3 = 1 + 2 */
261 static const OSSL_PARAM
*dh_imexport_types(int selection
)
265 if ((selection
& OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
) != 0)
267 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) != 0)
269 return dh_types
[type_select
];
272 static const OSSL_PARAM
*dh_import_types(int selection
)
274 return dh_imexport_types(selection
);
277 static const OSSL_PARAM
*dh_export_types(int selection
)
279 return dh_imexport_types(selection
);
282 static ossl_inline
int dh_get_params(void *key
, OSSL_PARAM params
[])
287 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_BITS
)) != NULL
288 && !OSSL_PARAM_set_int(p
, DH_bits(dh
)))
290 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_SECURITY_BITS
)) != NULL
291 && !OSSL_PARAM_set_int(p
, DH_security_bits(dh
)))
293 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_MAX_SIZE
)) != NULL
294 && !OSSL_PARAM_set_int(p
, DH_size(dh
)))
296 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY
)) != NULL
) {
297 if (p
->data_type
!= OSSL_PARAM_OCTET_STRING
)
299 p
->return_size
= ossl_dh_key2buf(dh
, (unsigned char **)&p
->data
,
301 if (p
->return_size
== 0)
305 return ossl_dh_params_todata(dh
, NULL
, params
)
306 && ossl_dh_key_todata(dh
, NULL
, params
);
309 static const OSSL_PARAM dh_params
[] = {
310 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS
, NULL
),
311 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS
, NULL
),
312 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE
, NULL
),
313 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY
, NULL
, 0),
314 DH_IMEXPORTABLE_PARAMETERS
,
315 DH_IMEXPORTABLE_PUBLIC_KEY
,
316 DH_IMEXPORTABLE_PRIVATE_KEY
,
320 static const OSSL_PARAM
*dh_gettable_params(void *provctx
)
325 static const OSSL_PARAM dh_known_settable_params
[] = {
326 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY
, NULL
, 0),
330 static const OSSL_PARAM
*dh_settable_params(void *provctx
)
332 return dh_known_settable_params
;
335 static int dh_set_params(void *key
, const OSSL_PARAM params
[])
340 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY
);
342 && (p
->data_type
!= OSSL_PARAM_OCTET_STRING
343 || !ossl_dh_buf2key(dh
, p
->data
, p
->data_size
)))
349 static int dh_validate_public(const DH
*dh
, int checktype
)
351 const BIGNUM
*pub_key
= NULL
;
354 DH_get0_key(dh
, &pub_key
, NULL
);
358 /* The partial test is only valid for named group's with q = (p - 1) / 2 */
359 if (checktype
== OSSL_KEYMGMT_VALIDATE_QUICK_CHECK
360 && ossl_dh_is_named_safe_prime_group(dh
))
361 return ossl_dh_check_pub_key_partial(dh
, pub_key
, &res
);
363 return DH_check_pub_key(dh
, pub_key
, &res
);
366 static int dh_validate_private(const DH
*dh
)
369 const BIGNUM
*priv_key
= NULL
;
371 DH_get0_key(dh
, NULL
, &priv_key
);
372 if (priv_key
== NULL
)
374 return ossl_dh_check_priv_key(dh
, priv_key
, &status
);;
377 static int dh_validate(const void *keydata
, int selection
, int checktype
)
379 const DH
*dh
= keydata
;
382 if (!ossl_prov_is_running())
385 if ((selection
& DH_POSSIBLE_SELECTIONS
) == 0)
386 return 1; /* nothing to validate */
388 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0) {
390 * Both of these functions check parameters. DH_check_params_ex()
391 * performs a lightweight check (e.g. it does not check that p is a
394 if (checktype
== OSSL_KEYMGMT_VALIDATE_QUICK_CHECK
)
395 ok
= ok
&& DH_check_params_ex(dh
);
397 ok
= ok
&& DH_check_ex(dh
);
400 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0)
401 ok
= ok
&& dh_validate_public(dh
, checktype
);
403 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0)
404 ok
= ok
&& dh_validate_private(dh
);
406 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
)
407 == OSSL_KEYMGMT_SELECT_KEYPAIR
)
408 ok
= ok
&& ossl_dh_check_pairwise(dh
);
412 static void *dh_gen_init_base(void *provctx
, int selection
,
413 const OSSL_PARAM params
[], int type
)
415 OSSL_LIB_CTX
*libctx
= PROV_LIBCTX_OF(provctx
);
416 struct dh_gen_ctx
*gctx
= NULL
;
418 if (!ossl_prov_is_running())
421 if ((selection
& (OSSL_KEYMGMT_SELECT_KEYPAIR
422 | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
)) == 0)
425 if ((gctx
= OPENSSL_zalloc(sizeof(*gctx
))) != NULL
) {
426 gctx
->selection
= selection
;
427 gctx
->libctx
= libctx
;
432 gctx
->gen_type
= (type
== DH_FLAG_TYPE_DHX
)
433 ? DH_PARAMGEN_TYPE_FIPS_186_4
434 : DH_PARAMGEN_TYPE_GROUP
;
436 gctx
->gen_type
= (type
== DH_FLAG_TYPE_DHX
)
437 ? DH_PARAMGEN_TYPE_FIPS_186_2
438 : DH_PARAMGEN_TYPE_GENERATOR
;
443 gctx
->generator
= DH_GENERATOR_2
;
444 gctx
->dh_type
= type
;
446 if (!dh_gen_set_params(gctx
, params
)) {
453 static void *dh_gen_init(void *provctx
, int selection
,
454 const OSSL_PARAM params
[])
456 return dh_gen_init_base(provctx
, selection
, params
, DH_FLAG_TYPE_DH
);
459 static void *dhx_gen_init(void *provctx
, int selection
,
460 const OSSL_PARAM params
[])
462 return dh_gen_init_base(provctx
, selection
, params
, DH_FLAG_TYPE_DHX
);
465 static int dh_gen_set_template(void *genctx
, void *templ
)
467 struct dh_gen_ctx
*gctx
= genctx
;
470 if (!ossl_prov_is_running() || gctx
== NULL
|| dh
== NULL
)
472 gctx
->ffc_params
= ossl_dh_get0_params(dh
);
476 static int dh_set_gen_seed(struct dh_gen_ctx
*gctx
, unsigned char *seed
,
479 OPENSSL_clear_free(gctx
->seed
, gctx
->seedlen
);
482 if (seed
!= NULL
&& seedlen
> 0) {
483 gctx
->seed
= OPENSSL_memdup(seed
, seedlen
);
484 if (gctx
->seed
== NULL
)
486 gctx
->seedlen
= seedlen
;
491 static int dh_gen_set_params(void *genctx
, const OSSL_PARAM params
[])
493 struct dh_gen_ctx
*gctx
= genctx
;
502 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_FFC_TYPE
);
504 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
505 || ((gctx
->gen_type
=
506 dh_gen_type_name2id_w_default(p
->data
, gctx
->dh_type
)) == -1)) {
507 ERR_raise(ERR_LIB_PROV
, ERR_R_PASSED_INVALID_ARGUMENT
);
511 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_GROUP_NAME
);
513 const DH_NAMED_GROUP
*group
= NULL
;
515 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
516 || (group
= ossl_ffc_name_to_dh_named_group(p
->data
)) == NULL
517 || ((gctx
->group_nid
=
518 ossl_ffc_named_group_get_uid(group
)) == NID_undef
)) {
519 ERR_raise(ERR_LIB_PROV
, ERR_R_PASSED_INVALID_ARGUMENT
);
522 gctx
->gen_type
= DH_PARAMGEN_TYPE_GROUP
;
524 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_DH_GENERATOR
);
525 if (p
!= NULL
&& !OSSL_PARAM_get_int(p
, &gctx
->generator
))
527 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_FFC_GINDEX
);
528 if (p
!= NULL
&& !OSSL_PARAM_get_int(p
, &gctx
->gindex
))
530 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_FFC_PCOUNTER
);
531 if (p
!= NULL
&& !OSSL_PARAM_get_int(p
, &gctx
->pcounter
))
533 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_FFC_H
);
534 if (p
!= NULL
&& !OSSL_PARAM_get_int(p
, &gctx
->hindex
))
536 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_FFC_SEED
);
538 && (p
->data_type
!= OSSL_PARAM_OCTET_STRING
539 || !dh_set_gen_seed(gctx
, p
->data
, p
->data_size
)))
542 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_FFC_PBITS
)) != NULL
543 && !OSSL_PARAM_get_size_t(p
, &gctx
->pbits
))
545 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_FFC_QBITS
)) != NULL
546 && !OSSL_PARAM_get_size_t(p
, &gctx
->qbits
))
548 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_FFC_DIGEST
);
550 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
552 OPENSSL_free(gctx
->mdname
);
553 gctx
->mdname
= OPENSSL_strdup(p
->data
);
554 if (gctx
->mdname
== NULL
)
557 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS
);
559 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
561 OPENSSL_free(gctx
->mdprops
);
562 gctx
->mdprops
= OPENSSL_strdup(p
->data
);
563 if (gctx
->mdprops
== NULL
)
566 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_DH_PRIV_LEN
);
567 if (p
!= NULL
&& !OSSL_PARAM_get_int(p
, &gctx
->priv_len
))
572 static const OSSL_PARAM
*dh_gen_settable_params(ossl_unused
void *genctx
,
573 ossl_unused
void *provctx
)
575 static OSSL_PARAM settable
[] = {
576 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME
, NULL
, 0),
577 OSSL_PARAM_int(OSSL_PKEY_PARAM_DH_PRIV_LEN
, NULL
),
578 OSSL_PARAM_int(OSSL_PKEY_PARAM_DH_GENERATOR
, NULL
),
579 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE
, NULL
, 0),
580 OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_PBITS
, NULL
),
581 OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_QBITS
, NULL
),
582 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST
, NULL
, 0),
583 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST_PROPS
, NULL
, 0),
584 OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX
, NULL
),
585 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED
, NULL
, 0),
586 OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER
, NULL
),
587 OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H
, NULL
),
593 static int dh_gencb(int p
, int n
, BN_GENCB
*cb
)
595 struct dh_gen_ctx
*gctx
= BN_GENCB_get_arg(cb
);
596 OSSL_PARAM params
[] = { OSSL_PARAM_END
, OSSL_PARAM_END
, OSSL_PARAM_END
};
598 params
[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL
, &p
);
599 params
[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION
, &n
);
601 return gctx
->cb(params
, gctx
->cbarg
);
604 static void *dh_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
607 struct dh_gen_ctx
*gctx
= genctx
;
609 BN_GENCB
*gencb
= NULL
;
612 if (!ossl_prov_is_running() || gctx
== NULL
)
615 /* For parameter generation - If there is a group name just create it */
616 if (gctx
->gen_type
== DH_PARAMGEN_TYPE_GROUP
617 && gctx
->ffc_params
== NULL
) {
618 /* Select a named group if there is not one already */
619 if (gctx
->group_nid
== NID_undef
)
620 gctx
->group_nid
= ossl_dh_get_named_group_uid_from_size(gctx
->pbits
);
621 if (gctx
->group_nid
== NID_undef
)
623 dh
= ossl_dh_new_by_nid_ex(gctx
->libctx
, gctx
->group_nid
);
626 ffc
= ossl_dh_get0_params(dh
);
628 dh
= ossl_dh_new_ex(gctx
->libctx
);
631 ffc
= ossl_dh_get0_params(dh
);
633 /* Copy the template value if one was passed */
634 if (gctx
->ffc_params
!= NULL
635 && !ossl_ffc_params_copy(ffc
, gctx
->ffc_params
))
638 if (!ossl_ffc_params_set_seed(ffc
, gctx
->seed
, gctx
->seedlen
))
640 if (gctx
->gindex
!= -1) {
641 ossl_ffc_params_set_gindex(ffc
, gctx
->gindex
);
642 if (gctx
->pcounter
!= -1)
643 ossl_ffc_params_set_pcounter(ffc
, gctx
->pcounter
);
644 } else if (gctx
->hindex
!= 0) {
645 ossl_ffc_params_set_h(ffc
, gctx
->hindex
);
647 if (gctx
->mdname
!= NULL
) {
648 if (!ossl_ffc_set_digest(ffc
, gctx
->mdname
, gctx
->mdprops
))
653 gencb
= BN_GENCB_new();
655 BN_GENCB_set(gencb
, dh_gencb
, genctx
);
657 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0) {
659 * NOTE: The old safe prime generator code is not used in fips mode,
660 * (i.e internally it ignores the generator and chooses a named
661 * group based on pbits.
663 if (gctx
->gen_type
== DH_PARAMGEN_TYPE_GENERATOR
)
664 ret
= DH_generate_parameters_ex(dh
, gctx
->pbits
,
665 gctx
->generator
, gencb
);
667 ret
= ossl_dh_generate_ffc_parameters(dh
, gctx
->gen_type
,
668 gctx
->pbits
, gctx
->qbits
,
675 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) != 0) {
676 if (ffc
->p
== NULL
|| ffc
->g
== NULL
)
678 if (gctx
->priv_len
> 0)
679 DH_set_length(dh
, (long)gctx
->priv_len
);
680 ossl_ffc_params_enable_flags(ffc
, FFC_PARAM_FLAG_VALIDATE_LEGACY
,
681 gctx
->gen_type
== DH_PARAMGEN_TYPE_FIPS_186_2
);
682 if (DH_generate_key(dh
) <= 0)
685 DH_clear_flags(dh
, DH_FLAG_TYPE_MASK
);
686 DH_set_flags(dh
, gctx
->dh_type
);
694 BN_GENCB_free(gencb
);
698 static void dh_gen_cleanup(void *genctx
)
700 struct dh_gen_ctx
*gctx
= genctx
;
705 OPENSSL_free(gctx
->mdname
);
706 OPENSSL_free(gctx
->mdprops
);
707 OPENSSL_clear_free(gctx
->seed
, gctx
->seedlen
);
711 static void *dh_load(const void *reference
, size_t reference_sz
)
715 if (ossl_prov_is_running() && reference_sz
== sizeof(dh
)) {
716 /* The contents of the reference is the address to our object */
717 dh
= *(DH
**)reference
;
718 /* We grabbed, so we detach it */
719 *(DH
**)reference
= NULL
;
725 static void *dh_dup(const void *keydata_from
, int selection
)
727 if (ossl_prov_is_running())
728 return ossl_dh_dup(keydata_from
, selection
);
732 const OSSL_DISPATCH ossl_dh_keymgmt_functions
[] = {
733 { OSSL_FUNC_KEYMGMT_NEW
, (void (*)(void))dh_newdata
},
734 { OSSL_FUNC_KEYMGMT_GEN_INIT
, (void (*)(void))dh_gen_init
},
735 { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE
, (void (*)(void))dh_gen_set_template
},
736 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS
, (void (*)(void))dh_gen_set_params
},
737 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS
,
738 (void (*)(void))dh_gen_settable_params
},
739 { OSSL_FUNC_KEYMGMT_GEN
, (void (*)(void))dh_gen
},
740 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP
, (void (*)(void))dh_gen_cleanup
},
741 { OSSL_FUNC_KEYMGMT_LOAD
, (void (*)(void))dh_load
},
742 { OSSL_FUNC_KEYMGMT_FREE
, (void (*)(void))dh_freedata
},
743 { OSSL_FUNC_KEYMGMT_GET_PARAMS
, (void (*) (void))dh_get_params
},
744 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS
, (void (*) (void))dh_gettable_params
},
745 { OSSL_FUNC_KEYMGMT_SET_PARAMS
, (void (*) (void))dh_set_params
},
746 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS
, (void (*) (void))dh_settable_params
},
747 { OSSL_FUNC_KEYMGMT_HAS
, (void (*)(void))dh_has
},
748 { OSSL_FUNC_KEYMGMT_MATCH
, (void (*)(void))dh_match
},
749 { OSSL_FUNC_KEYMGMT_VALIDATE
, (void (*)(void))dh_validate
},
750 { OSSL_FUNC_KEYMGMT_IMPORT
, (void (*)(void))dh_import
},
751 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES
, (void (*)(void))dh_import_types
},
752 { OSSL_FUNC_KEYMGMT_EXPORT
, (void (*)(void))dh_export
},
753 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES
, (void (*)(void))dh_export_types
},
754 { OSSL_FUNC_KEYMGMT_DUP
, (void (*)(void))dh_dup
},
758 /* For any DH key, we use the "DH" algorithms regardless of sub-type. */
759 static const char *dhx_query_operation_name(int operation_id
)
764 const OSSL_DISPATCH ossl_dhx_keymgmt_functions
[] = {
765 { OSSL_FUNC_KEYMGMT_NEW
, (void (*)(void))dhx_newdata
},
766 { OSSL_FUNC_KEYMGMT_GEN_INIT
, (void (*)(void))dhx_gen_init
},
767 { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE
, (void (*)(void))dh_gen_set_template
},
768 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS
, (void (*)(void))dh_gen_set_params
},
769 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS
,
770 (void (*)(void))dh_gen_settable_params
},
771 { OSSL_FUNC_KEYMGMT_GEN
, (void (*)(void))dh_gen
},
772 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP
, (void (*)(void))dh_gen_cleanup
},
773 { OSSL_FUNC_KEYMGMT_LOAD
, (void (*)(void))dh_load
},
774 { OSSL_FUNC_KEYMGMT_FREE
, (void (*)(void))dh_freedata
},
775 { OSSL_FUNC_KEYMGMT_GET_PARAMS
, (void (*) (void))dh_get_params
},
776 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS
, (void (*) (void))dh_gettable_params
},
777 { OSSL_FUNC_KEYMGMT_SET_PARAMS
, (void (*) (void))dh_set_params
},
778 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS
, (void (*) (void))dh_settable_params
},
779 { OSSL_FUNC_KEYMGMT_HAS
, (void (*)(void))dh_has
},
780 { OSSL_FUNC_KEYMGMT_MATCH
, (void (*)(void))dh_match
},
781 { OSSL_FUNC_KEYMGMT_VALIDATE
, (void (*)(void))dh_validate
},
782 { OSSL_FUNC_KEYMGMT_IMPORT
, (void (*)(void))dh_import
},
783 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES
, (void (*)(void))dh_import_types
},
784 { OSSL_FUNC_KEYMGMT_EXPORT
, (void (*)(void))dh_export
},
785 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES
, (void (*)(void))dh_export_types
},
786 { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME
,
787 (void (*)(void))dhx_query_operation_name
},
788 { OSSL_FUNC_KEYMGMT_DUP
, (void (*)(void))dh_dup
},