2 * Copyright 2020-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
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 (evp_pkey_ctx_is_legacy(ctx
)
36 && ctx
->pmeth
!= NULL
&& ctx
->pmeth
->pkey_id
!= EVP_PKEY_EC
)
42 int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX
*ctx
, int cofactor_mode
)
45 OSSL_PARAM params
[2], *p
= params
;
47 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
52 * Valid input values are:
55 * * -1 for reset to default for associated priv key
57 if (cofactor_mode
< -1 || cofactor_mode
> 1) {
58 /* Uses the same return value of pkey_ec_ctrl() */
62 *p
++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE
,
64 *p
++ = OSSL_PARAM_construct_end();
66 ret
= evp_pkey_ctx_set_params_strict(ctx
, params
);
68 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
72 int EVP_PKEY_CTX_get_ecdh_cofactor_mode(EVP_PKEY_CTX
*ctx
)
75 OSSL_PARAM params
[2], *p
= params
;
77 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
81 *p
++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE
,
83 *p
++ = OSSL_PARAM_construct_end();
85 ret
= evp_pkey_ctx_get_params_strict(ctx
, params
);
89 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
93 if (mode
< 0 || mode
> 1) {
95 * The provider should return either 0 or 1, any other value is a
110 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
111 * simply because that's easier.
113 int EVP_PKEY_CTX_set_ecdh_kdf_type(EVP_PKEY_CTX
*ctx
, int kdf
)
115 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
, EVP_PKEY_OP_DERIVE
,
116 EVP_PKEY_CTRL_EC_KDF_TYPE
, kdf
, NULL
);
120 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
121 * simply because that's easier.
123 int EVP_PKEY_CTX_get_ecdh_kdf_type(EVP_PKEY_CTX
*ctx
)
125 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
, EVP_PKEY_OP_DERIVE
,
126 EVP_PKEY_CTRL_EC_KDF_TYPE
, -2, NULL
);
130 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
131 * simply because that's easier.
132 * TODO(3.0) Should this be deprecated in favor of passing a name?
134 int EVP_PKEY_CTX_set_ecdh_kdf_md(EVP_PKEY_CTX
*ctx
, const EVP_MD
*md
)
136 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
, EVP_PKEY_OP_DERIVE
,
137 EVP_PKEY_CTRL_EC_KDF_MD
, 0, (void *)(md
));
141 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
142 * simply because that's easier.
143 * TODO(3.0) Should this be deprecated in favor of getting a name?
145 int EVP_PKEY_CTX_get_ecdh_kdf_md(EVP_PKEY_CTX
*ctx
, const EVP_MD
**pmd
)
147 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
, EVP_PKEY_OP_DERIVE
,
148 EVP_PKEY_CTRL_GET_EC_KDF_MD
, 0, (void *)(pmd
));
151 int EVP_PKEY_CTX_set_ecdh_kdf_outlen(EVP_PKEY_CTX
*ctx
, int outlen
)
155 OSSL_PARAM params
[2], *p
= params
;
157 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
163 * This would ideally be -1 or 0, but we have to retain compatibility
164 * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if
170 *p
++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN
,
172 *p
++ = OSSL_PARAM_construct_end();
174 ret
= evp_pkey_ctx_set_params_strict(ctx
, params
);
176 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
180 int EVP_PKEY_CTX_get_ecdh_kdf_outlen(EVP_PKEY_CTX
*ctx
, int *plen
)
182 size_t len
= UINT_MAX
;
184 OSSL_PARAM params
[2], *p
= params
;
186 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
190 *p
++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN
,
192 *p
++ = OSSL_PARAM_construct_end();
194 ret
= evp_pkey_ctx_get_params_strict(ctx
, params
);
198 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
214 int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX
*ctx
, unsigned char *ukm
, int len
)
217 OSSL_PARAM params
[2], *p
= params
;
219 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
223 *p
++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM
,
225 * Cast away the const. This is read
226 * only so should be safe
230 *p
++ = OSSL_PARAM_construct_end();
232 ret
= evp_pkey_ctx_set_params_strict(ctx
, params
);
236 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
246 #ifndef OPENSSL_NO_DEPRECATED_3_0
247 int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX
*ctx
, unsigned char **pukm
)
251 OSSL_PARAM params
[2], *p
= params
;
253 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
257 /* TODO(3.0): Remove this eventually when no more legacy */
258 if (ctx
->op
.kex
.exchprovctx
== NULL
)
259 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
,
261 EVP_PKEY_CTRL_GET_EC_KDF_UKM
, 0,
264 *p
++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM
,
266 *p
++ = OSSL_PARAM_construct_end();
268 ret
= evp_pkey_ctx_get_params_strict(ctx
, params
);
272 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
276 ukmlen
= params
[0].return_size
;
277 if (ukmlen
<= INT_MAX
)
291 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
292 * simply because that's easier.
293 * TODO(3.0) Should this be deprecated in favor of setting a name or an
294 * ASN1_OBJECT (which would be converted to text internally)?
296 int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX
*ctx
, int nid
)
298 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
, EVP_PKEY_OP_TYPE_GEN
,
299 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID
,
304 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
305 * simply because that's easier.
307 int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX
*ctx
, int param_enc
)
309 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
, EVP_PKEY_OP_TYPE_GEN
,
310 EVP_PKEY_CTRL_EC_PARAM_ENC
, param_enc
, NULL
);