2 * Copyright 2020 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
12 #include <openssl/core_names.h>
13 #include <openssl/params.h>
14 #include <openssl/err.h>
15 #include <openssl/dh.h>
16 #include "crypto/dh.h"
17 #include "crypto/evp.h"
19 static int dh_paramgen_check(EVP_PKEY_CTX *ctx)
21 if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
22 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
23 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
26 /* If key type not DH return error */
27 if (ctx->pmeth != NULL
28 && ctx->pmeth->pkey_id != EVP_PKEY_DH
29 && ctx->pmeth->pkey_id != EVP_PKEY_DHX)
34 static int dh_param_derive_check(EVP_PKEY_CTX *ctx)
36 if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
37 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
38 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
41 /* If key type not DH return error */
42 if (ctx->pmeth != NULL
43 && ctx->pmeth->pkey_id != EVP_PKEY_DH
44 && ctx->pmeth->pkey_id != EVP_PKEY_DHX)
49 int EVP_PKEY_CTX_set_dh_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex)
52 OSSL_PARAM params[2], *p = params;
54 if ((ret = dh_paramgen_check(ctx)) <= 0)
57 *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GINDEX, &gindex);
58 *p = OSSL_PARAM_construct_end();
60 return EVP_PKEY_CTX_set_params(ctx, params);
63 int EVP_PKEY_CTX_set_dh_paramgen_seed(EVP_PKEY_CTX *ctx,
64 const unsigned char *seed,
68 OSSL_PARAM params[2], *p = params;
70 if ((ret = dh_paramgen_check(ctx)) <= 0)
73 *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_FFC_SEED,
74 (void *)seed, seedlen);
75 *p = OSSL_PARAM_construct_end();
77 return EVP_PKEY_CTX_set_params(ctx, params);
80 int EVP_PKEY_CTX_set_dh_paramgen_type(EVP_PKEY_CTX *ctx, int typ)
83 OSSL_PARAM params[2], *p = params;
86 if ((ret = dh_paramgen_check(ctx)) <= 0)
89 /* TODO(3.0): Remove this eventually when no more legacy */
90 if (ctx->op.keymgmt.genctx == NULL)
91 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
92 EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL);
94 name = dh_gen_type_id2name(typ);
97 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE,
99 *p = OSSL_PARAM_construct_end();
101 return EVP_PKEY_CTX_set_params(ctx, params);
104 int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits)
107 OSSL_PARAM params[2], *p = params;
110 if ((ret = dh_paramgen_check(ctx)) <= 0)
113 /* TODO(3.0): Remove this eventually when no more legacy */
114 if (ctx->op.keymgmt.genctx == NULL)
115 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
116 EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, pbits,
118 *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_PBITS, &bits);
119 *p = OSSL_PARAM_construct_end();
120 return EVP_PKEY_CTX_set_params(ctx, params);
123 int EVP_PKEY_CTX_set_dh_paramgen_subprime_len(EVP_PKEY_CTX *ctx, int qbits)
126 OSSL_PARAM params[2], *p = params;
127 size_t bits2 = qbits;
129 if ((ret = dh_paramgen_check(ctx)) <= 0)
132 /* TODO(3.0): Remove this eventually when no more legacy */
133 if (ctx->op.keymgmt.genctx == NULL)
134 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
135 EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, qbits,
137 *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_QBITS, &bits2);
138 *p = OSSL_PARAM_construct_end();
140 return EVP_PKEY_CTX_set_params(ctx, params);
143 int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen)
146 OSSL_PARAM params[2], *p = params;
148 if ((ret = dh_paramgen_check(ctx)) <= 0)
151 /* TODO(3.0): Remove this eventually when no more legacy */
152 if (ctx->op.keymgmt.genctx == NULL)
153 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
154 EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL);
155 *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_DH_GENERATOR, &gen);
156 *p = OSSL_PARAM_construct_end();
158 return EVP_PKEY_CTX_set_params(ctx, params);
161 int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen)
164 OSSL_PARAM params[2], *p = params;
167 if ((ret = dh_paramgen_check(ctx)) <= 0)
170 /* TODO(3.0): Remove this eventually when no more legacy */
171 if (ctx->op.keymgmt.genctx == NULL)
172 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN,
173 EVP_PKEY_CTRL_DH_RFC5114, gen, NULL);
174 name = ossl_ffc_named_group_get_name(ossl_ffc_uid_to_dh_named_group(gen));
178 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
180 *p = OSSL_PARAM_construct_end();
181 return EVP_PKEY_CTX_set_params(ctx, params);
184 int EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX *ctx, int gen)
186 return EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen);
189 int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid)
192 OSSL_PARAM params[2], *p = params;
195 if ((ret = dh_paramgen_check(ctx)) <= 0)
198 /* TODO(3.0): Remove this eventually when no more legacy */
199 if (ctx->op.keymgmt.genctx == NULL)
200 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH,
201 EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
202 EVP_PKEY_CTRL_DH_NID, nid, NULL);
203 name = ossl_ffc_named_group_get_name(ossl_ffc_uid_to_dh_named_group(nid));
207 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
209 *p = OSSL_PARAM_construct_end();
210 return EVP_PKEY_CTX_set_params(ctx, params);
213 int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
215 OSSL_PARAM dh_pad_params[2];
216 unsigned int upad = pad;
218 /* We use EVP_PKEY_CTX_ctrl return values */
219 if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
220 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
224 /* TODO(3.0): Remove this eventually when no more legacy */
225 if (ctx->op.kex.exchprovctx == NULL)
226 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE,
227 EVP_PKEY_CTRL_DH_PAD, pad, NULL);
229 dh_pad_params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD, &upad);
230 dh_pad_params[1] = OSSL_PARAM_construct_end();
232 return EVP_PKEY_CTX_set_params(ctx, dh_pad_params);
235 int EVP_PKEY_CTX_set_dh_kdf_type(EVP_PKEY_CTX *ctx, int kdf)
238 const char *kdf_type;
239 OSSL_PARAM params[2], *p = params;
241 ret = dh_param_derive_check(ctx);
245 /* TODO(3.0): Remove this eventually when no more legacy */
246 if (ctx->op.kex.exchprovctx == NULL)
247 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
248 EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL);
250 case EVP_PKEY_DH_KDF_NONE:
253 case EVP_PKEY_DH_KDF_X9_42:
254 kdf_type = OSSL_KDF_NAME_X942KDF_ASN1;
259 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
261 * Cast away the const. This is read
262 * only so should be safe
264 (char *)kdf_type, 0);
265 *p = OSSL_PARAM_construct_end();
267 ret = evp_pkey_ctx_set_params_strict(ctx, params);
269 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
270 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
277 int EVP_PKEY_CTX_get_dh_kdf_type(EVP_PKEY_CTX *ctx)
280 char kdf_type[80]; /* 80 should be big enough */
281 OSSL_PARAM params[2], *p = params;
283 ret = dh_param_derive_check(ctx);
287 /* TODO(3.0): Remove this eventually when no more legacy */
288 if (ctx->op.kex.exchprovctx == NULL)
289 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
290 EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL);
291 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
292 kdf_type, sizeof(kdf_type));
293 *p = OSSL_PARAM_construct_end();
295 ret = evp_pkey_ctx_get_params_strict(ctx, params);
297 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
298 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
300 } else if (ret != 1) {
304 if (kdf_type[0] == '\0')
305 return EVP_PKEY_DH_KDF_NONE;
306 else if (strcmp(kdf_type, OSSL_KDF_NAME_X942KDF_ASN1) == 0)
307 return EVP_PKEY_DH_KDF_X9_42;
312 int EVP_PKEY_CTX_set0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT *oid)
315 OSSL_PARAM params[2], *p = params;
316 const char *oid_name;
318 ret = dh_param_derive_check(ctx);
322 /* TODO(3.0): Remove this eventually when no more legacy */
323 if (ctx->op.kex.exchprovctx == NULL)
324 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
325 EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)(oid));
326 oid_name = OBJ_nid2sn(OBJ_obj2nid(oid));
328 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG,
329 (char *)oid_name, 0);
330 *p = OSSL_PARAM_construct_end();
331 ret = evp_pkey_ctx_set_params_strict(ctx, params);
333 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
334 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
341 int EVP_PKEY_CTX_get0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT **oid)
344 OSSL_PARAM params[2], *p = params;
345 char oid_name[80]; /* 80 should be big enough */
347 ret = dh_param_derive_check(ctx);
351 /* TODO(3.0): Remove this eventually when no more legacy */
352 if (ctx->op.kex.exchprovctx == NULL)
353 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
354 EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)(oid));
355 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG,
356 oid_name, sizeof(oid_name));
357 *p = OSSL_PARAM_construct_end();
359 ret = evp_pkey_ctx_get_params_strict(ctx, params);
361 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
362 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
364 } else if (ret != 1) {
367 nid = OBJ_sn2nid(oid_name);
368 if (nid == NID_undef)
369 nid = OBJ_ln2nid(oid_name);
370 *oid = (nid == NID_undef ? NULL : OBJ_nid2obj(nid));
374 int EVP_PKEY_CTX_set_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
377 OSSL_PARAM params[2], *p = params;
378 const char *md_name = NULL;
380 ret = dh_param_derive_check(ctx);
384 /* TODO(3.0): Remove this eventually when no more legacy */
385 if (ctx->op.kex.exchprovctx == NULL)
386 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
387 EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)(md));
388 md_name = (md == NULL) ? "" : EVP_MD_name(md);
390 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
392 * Cast away the const. This is read
393 * only so should be safe
396 *p = OSSL_PARAM_construct_end();
398 ret = evp_pkey_ctx_set_params_strict(ctx, params);
400 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
401 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
407 int EVP_PKEY_CTX_get_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
410 char name[80] = ""; /* 80 should be big enough */
411 OSSL_PARAM params[2], *p = params;
413 ret = dh_param_derive_check(ctx);
417 /* TODO(3.0): Remove this eventually when no more legacy */
418 if (ctx->op.kex.exchprovctx == NULL)
419 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
420 EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)(pmd));
421 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
423 *p = OSSL_PARAM_construct_end();
425 ret = evp_pkey_ctx_get_params_strict(ctx, params);
427 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
428 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
430 } else if (ret != 1) {
434 /* May be NULL meaning "unknown" */
435 *pmd = EVP_get_digestbyname(name);
440 int EVP_PKEY_CTX_set_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int inlen)
444 OSSL_PARAM params[2], *p = params;
446 ret = dh_param_derive_check(ctx);
450 /* TODO(3.0): Remove this eventually when no more legacy */
451 if (ctx->op.kex.exchprovctx == NULL)
452 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
453 EVP_PKEY_CTRL_DH_KDF_OUTLEN, inlen, NULL);
456 * This would ideally be -1 or 0, but we have to retain compatibility
457 * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if
463 *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
465 *p = OSSL_PARAM_construct_end();
467 ret = evp_pkey_ctx_set_params_strict(ctx, params);
469 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
470 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
476 int EVP_PKEY_CTX_get_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen)
479 size_t len = UINT_MAX;
480 OSSL_PARAM params[2], *p = params;
482 ret = dh_param_derive_check(ctx);
486 /* TODO(3.0): Remove this eventually when no more legacy */
487 if (ctx->op.kex.exchprovctx == NULL)
488 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
489 EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0,
491 *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
493 *p = OSSL_PARAM_construct_end();
495 ret = evp_pkey_ctx_get_params_strict(ctx, params);
497 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
498 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
500 } else if (ret != 1) {
512 int EVP_PKEY_CTX_set0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len)
515 OSSL_PARAM params[2], *p = params;
520 ret = dh_param_derive_check(ctx);
524 /* TODO(3.0): Remove this eventually when no more legacy */
525 if (ctx->op.kex.exchprovctx == NULL)
526 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
527 EVP_PKEY_CTRL_DH_KDF_UKM, len, (void *)(ukm));
529 *p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM,
531 * Cast away the const. This is read
532 * only so should be safe
536 *p = OSSL_PARAM_construct_end();
538 ret = evp_pkey_ctx_set_params_strict(ctx, params);
540 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
541 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
549 int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
553 OSSL_PARAM params[2], *p = params;
555 ret = dh_param_derive_check(ctx);
559 /* TODO(3.0): Remove this eventually when no more legacy */
560 if (ctx->op.kex.exchprovctx == NULL)
561 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
562 EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)(pukm));
564 *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM,
566 *p = OSSL_PARAM_construct_end();
568 ret = evp_pkey_ctx_get_params_strict(ctx, params);
570 ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
571 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
573 } else if (ret != 1) {
577 ukmlen = params[0].return_size;
578 if (ukmlen > INT_MAX)