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
10 #include "internal/deprecated.h"
14 #include <openssl/core_names.h>
15 #include <openssl/err.h>
16 #include <openssl/ec.h>
17 #include "crypto/evp.h"
18 #include "crypto/ec.h"
21 * This file is meant to contain functions to provide EVP_PKEY support for EC
26 int evp_pkey_ctx_getset_ecdh_param_checks(const EVP_PKEY_CTX
*ctx
)
28 if (ctx
== NULL
|| !EVP_PKEY_CTX_IS_DERIVE_OP(ctx
)) {
29 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
30 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
34 /* If key type not EC return error */
35 if (ctx
->pmeth
!= NULL
&& ctx
->pmeth
->pkey_id
!= EVP_PKEY_EC
)
41 int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX
*ctx
, int cofactor_mode
)
44 OSSL_PARAM params
[2], *p
= params
;
46 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
51 * Valid input values are:
54 * * -1 for reset to default for associated priv key
56 if (cofactor_mode
< -1 || cofactor_mode
> 1) {
57 /* Uses the same return value of pkey_ec_ctrl() */
61 /* TODO(3.0): Remove this eventually when no more legacy */
62 if (ctx
->op
.kex
.exchprovctx
== NULL
)
63 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
65 EVP_PKEY_CTRL_EC_ECDH_COFACTOR
,
68 *p
++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE
,
70 *p
++ = OSSL_PARAM_construct_end();
72 ret
= evp_pkey_ctx_set_params_strict(ctx
, params
);
74 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
75 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
82 int EVP_PKEY_CTX_get_ecdh_cofactor_mode(EVP_PKEY_CTX
*ctx
)
85 OSSL_PARAM params
[2], *p
= params
;
87 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
91 /* TODO(3.0): Remove this eventually when no more legacy */
92 if (ctx
->op
.kex
.exchprovctx
== NULL
)
93 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
95 EVP_PKEY_CTRL_EC_ECDH_COFACTOR
, -2, NULL
);
97 *p
++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE
,
99 *p
++ = OSSL_PARAM_construct_end();
101 ret
= evp_pkey_ctx_get_params_strict(ctx
, params
);
103 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
104 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
106 } else if (ret
!= 1) {
110 if (mode
< 0 || mode
> 1) {
112 * The provider should return either 0 or 1, any other value is a
121 int EVP_PKEY_CTX_set_ecdh_kdf_type(EVP_PKEY_CTX
*ctx
, int kdf
)
124 const char *kdf_type
;
125 OSSL_PARAM params
[2], *p
= params
;
127 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
132 case EVP_PKEY_ECDH_KDF_NONE
:
135 case EVP_PKEY_ECDH_KDF_X9_63
:
136 kdf_type
= OSSL_KDF_NAME_X963KDF
;
142 /* TODO(3.0): Remove this eventually when no more legacy */
143 if (ctx
->op
.kex
.exchprovctx
== NULL
)
144 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
146 EVP_PKEY_CTRL_EC_KDF_TYPE
, kdf
, NULL
);
148 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE
,
150 * Cast away the const. This is read
151 * only so should be safe
153 (char *)kdf_type
, 0);
154 *p
++ = OSSL_PARAM_construct_end();
156 ret
= evp_pkey_ctx_set_params_strict(ctx
, params
);
158 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
159 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
166 int EVP_PKEY_CTX_get_ecdh_kdf_type(EVP_PKEY_CTX
*ctx
)
169 /* 80 should be big enough */
171 OSSL_PARAM params
[2], *p
= params
;
173 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
177 /* TODO(3.0): Remove this eventually when no more legacy */
178 if (ctx
->op
.kex
.exchprovctx
== NULL
)
179 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
181 EVP_PKEY_CTRL_EC_KDF_TYPE
, -2, NULL
);
183 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE
,
184 kdf_type
, sizeof(kdf_type
));
185 *p
++ = OSSL_PARAM_construct_end();
187 ret
= evp_pkey_ctx_get_params_strict(ctx
, params
);
189 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
190 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
192 } else if (ret
!= 1) {
196 if (kdf_type
[0] == '\0')
197 return EVP_PKEY_ECDH_KDF_NONE
;
198 else if (strcmp(kdf_type
, OSSL_KDF_NAME_X963KDF
) == 0)
199 return EVP_PKEY_ECDH_KDF_X9_63
;
204 int EVP_PKEY_CTX_set_ecdh_kdf_md(EVP_PKEY_CTX
*ctx
, const EVP_MD
*md
)
207 OSSL_PARAM params
[2], *p
= params
;
208 const char *md_name
= NULL
;
210 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
214 /* TODO(3.0): Remove this eventually when no more legacy */
215 if (ctx
->op
.kex
.exchprovctx
== NULL
)
216 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
218 EVP_PKEY_CTRL_EC_KDF_MD
, 0, (void *)(md
));
220 md_name
= (md
== NULL
) ? "" : EVP_MD_name(md
);
222 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST
,
224 * Cast away the const. This is read
225 * only so should be safe
228 *p
++ = OSSL_PARAM_construct_end();
230 ret
= evp_pkey_ctx_set_params_strict(ctx
, params
);
232 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
233 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
239 int EVP_PKEY_CTX_get_ecdh_kdf_md(EVP_PKEY_CTX
*ctx
, const EVP_MD
**pmd
)
241 /* 80 should be big enough */
244 OSSL_PARAM params
[2], *p
= params
;
246 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
250 /* TODO(3.0): Remove this eventually when no more legacy */
251 if (ctx
->op
.kex
.exchprovctx
== NULL
)
252 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
254 EVP_PKEY_CTRL_GET_EC_KDF_MD
, 0, (void *)(pmd
));
256 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST
,
258 *p
++ = OSSL_PARAM_construct_end();
260 ret
= evp_pkey_ctx_get_params_strict(ctx
, params
);
262 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
263 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
265 } else if (ret
!= 1) {
269 /* May be NULL meaning "unknown" */
270 *pmd
= EVP_get_digestbyname(name
);
275 int EVP_PKEY_CTX_set_ecdh_kdf_outlen(EVP_PKEY_CTX
*ctx
, int in
)
279 OSSL_PARAM params
[2], *p
= params
;
281 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
285 /* TODO(3.0): Remove this eventually when no more legacy */
286 if (ctx
->op
.kex
.exchprovctx
== NULL
)
287 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
289 EVP_PKEY_CTRL_EC_KDF_OUTLEN
, in
, NULL
);
293 * This would ideally be -1 or 0, but we have to retain compatibility
294 * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if
300 *p
++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN
,
302 *p
++ = OSSL_PARAM_construct_end();
304 ret
= evp_pkey_ctx_set_params_strict(ctx
, params
);
306 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
307 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
313 int EVP_PKEY_CTX_get_ecdh_kdf_outlen(EVP_PKEY_CTX
*ctx
, int *plen
)
315 size_t len
= UINT_MAX
;
317 OSSL_PARAM params
[2], *p
= params
;
319 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
323 /* TODO(3.0): Remove this eventually when no more legacy */
324 if (ctx
->op
.kex
.exchprovctx
== NULL
)
325 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
327 EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN
, 0,
330 *p
++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN
,
332 *p
++ = OSSL_PARAM_construct_end();
334 ret
= evp_pkey_ctx_get_params_strict(ctx
, params
);
336 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
337 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
339 } else if (ret
!= 1) {
351 int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX
*ctx
, unsigned char *ukm
, int len
)
354 OSSL_PARAM params
[2], *p
= params
;
356 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
360 /* TODO(3.0): Remove this eventually when no more legacy */
361 if (ctx
->op
.kex
.exchprovctx
== NULL
)
362 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
364 EVP_PKEY_CTRL_EC_KDF_UKM
, len
, (void *)(ukm
));
366 *p
++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM
,
368 * Cast away the const. This is read
369 * only so should be safe
373 *p
++ = OSSL_PARAM_construct_end();
375 ret
= evp_pkey_ctx_set_params_strict(ctx
, params
);
377 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
378 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
386 int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX
*ctx
, unsigned char **pukm
)
390 OSSL_PARAM params
[3], *p
= params
;
392 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
396 /* TODO(3.0): Remove this eventually when no more legacy */
397 if (ctx
->op
.kex
.exchprovctx
== NULL
)
398 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
400 EVP_PKEY_CTRL_GET_EC_KDF_UKM
, 0,
403 *p
++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM
,
405 *p
++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_UKM_LEN
,
407 *p
++ = OSSL_PARAM_construct_end();
409 ret
= evp_pkey_ctx_get_params_strict(ctx
, params
);
411 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
412 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
414 } else if (ret
!= 1) {
418 if (ukmlen
> INT_MAX
)
425 int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX
*ctx
, int nid
)
427 if (ctx
== NULL
|| !EVP_PKEY_CTX_IS_GEN_OP(ctx
)) {
428 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
429 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
433 /* Legacy: if key type not EC return error */
434 if (ctx
->pmeth
!= NULL
435 && EVP_PKEY_type(ctx
->pmeth
->pkey_id
) != EVP_PKEY_EC
)
438 if (ctx
->op
.keymgmt
.genctx
== NULL
)
439 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
440 EVP_PKEY_OP_PARAMGEN
|EVP_PKEY_OP_KEYGEN
,
441 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID
,
444 return EVP_PKEY_CTX_set_group_name(ctx
, OBJ_nid2sn(nid
));
447 int evp_pkey_ctx_set_ec_param_enc_prov(EVP_PKEY_CTX
*ctx
, int param_enc
)
449 const char *enc
= NULL
;
450 OSSL_PARAM params
[2], *p
= params
;
451 int ret
= -2; /* Assume unsupported */
454 || !EVP_PKEY_CTX_IS_GEN_OP(ctx
)
455 || ctx
->op
.keymgmt
.genctx
== NULL
)
459 case OPENSSL_EC_EXPLICIT_CURVE
:
460 enc
= OSSL_PKEY_EC_ENCODING_EXPLICIT
;
462 case OPENSSL_EC_NAMED_CURVE
:
463 enc
= OSSL_PKEY_EC_ENCODING_GROUP
;
469 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING
,
471 *p
= OSSL_PARAM_construct_end();
473 ret
= evp_pkey_ctx_set_params_strict(ctx
, params
);
476 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
480 int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX
*ctx
, int param_enc
)
482 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
483 EVP_PKEY_OP_PARAMGEN
|EVP_PKEY_OP_KEYGEN
,
484 EVP_PKEY_CTRL_EC_PARAM_ENC
, param_enc
, NULL
);