2 * Copyright 2020-2023 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"
12 #include <openssl/core_names.h>
13 #include <openssl/err.h>
14 #include <openssl/ec.h>
15 #include "crypto/evp.h"
16 #include "crypto/ec.h"
19 * This file is meant to contain functions to provide EVP_PKEY support for EC
24 int evp_pkey_ctx_getset_ecdh_param_checks(const EVP_PKEY_CTX
*ctx
)
26 if (ctx
== NULL
|| !EVP_PKEY_CTX_IS_DERIVE_OP(ctx
)) {
27 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
28 /* Uses the same return values as EVP_PKEY_CTX_ctrl */
32 /* If key type not EC return error */
33 if (evp_pkey_ctx_is_legacy(ctx
)
34 && ctx
->pmeth
!= NULL
&& ctx
->pmeth
->pkey_id
!= EVP_PKEY_EC
)
40 int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX
*ctx
, int cofactor_mode
)
43 OSSL_PARAM params
[2], *p
= params
;
45 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
50 * Valid input values are:
53 * * -1 for reset to default for associated priv key
55 if (cofactor_mode
< -1 || cofactor_mode
> 1) {
56 /* Uses the same return value of pkey_ec_ctrl() */
60 *p
++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE
,
62 *p
++ = OSSL_PARAM_construct_end();
64 ret
= evp_pkey_ctx_set_params_strict(ctx
, params
);
66 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
70 int EVP_PKEY_CTX_get_ecdh_cofactor_mode(EVP_PKEY_CTX
*ctx
)
73 OSSL_PARAM params
[2], *p
= params
;
75 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
79 *p
++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE
,
81 *p
++ = OSSL_PARAM_construct_end();
83 ret
= evp_pkey_ctx_get_params_strict(ctx
, params
);
87 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
91 if (mode
< 0 || mode
> 1) {
93 * The provider should return either 0 or 1, any other value is a
108 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
109 * simply because that's easier.
111 int EVP_PKEY_CTX_set_ecdh_kdf_type(EVP_PKEY_CTX
*ctx
, int kdf
)
113 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
, EVP_PKEY_OP_DERIVE
,
114 EVP_PKEY_CTRL_EC_KDF_TYPE
, kdf
, NULL
);
118 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
119 * simply because that's easier.
121 int EVP_PKEY_CTX_get_ecdh_kdf_type(EVP_PKEY_CTX
*ctx
)
123 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
, EVP_PKEY_OP_DERIVE
,
124 EVP_PKEY_CTRL_EC_KDF_TYPE
, -2, NULL
);
128 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
129 * simply because that's easier.
131 int EVP_PKEY_CTX_set_ecdh_kdf_md(EVP_PKEY_CTX
*ctx
, const EVP_MD
*md
)
133 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
, EVP_PKEY_OP_DERIVE
,
134 EVP_PKEY_CTRL_EC_KDF_MD
, 0, (void *)(md
));
138 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
139 * simply because that's easier.
141 int EVP_PKEY_CTX_get_ecdh_kdf_md(EVP_PKEY_CTX
*ctx
, const EVP_MD
**pmd
)
143 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
, EVP_PKEY_OP_DERIVE
,
144 EVP_PKEY_CTRL_GET_EC_KDF_MD
, 0, (void *)(pmd
));
147 int EVP_PKEY_CTX_set_ecdh_kdf_outlen(EVP_PKEY_CTX
*ctx
, int outlen
)
151 OSSL_PARAM params
[2], *p
= params
;
153 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
159 * This would ideally be -1 or 0, but we have to retain compatibility
160 * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if
166 *p
++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN
,
168 *p
++ = OSSL_PARAM_construct_end();
170 ret
= evp_pkey_ctx_set_params_strict(ctx
, params
);
172 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
176 int EVP_PKEY_CTX_get_ecdh_kdf_outlen(EVP_PKEY_CTX
*ctx
, int *plen
)
178 size_t len
= UINT_MAX
;
180 OSSL_PARAM params
[2], *p
= params
;
182 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
186 *p
++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN
,
188 *p
++ = OSSL_PARAM_construct_end();
190 ret
= evp_pkey_ctx_get_params_strict(ctx
, params
);
194 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
210 int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX
*ctx
, unsigned char *ukm
, int len
)
213 OSSL_PARAM params
[2], *p
= params
;
215 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
219 *p
++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM
,
221 * Cast away the const. This is read
222 * only so should be safe
226 *p
++ = OSSL_PARAM_construct_end();
228 ret
= evp_pkey_ctx_set_params_strict(ctx
, params
);
232 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
242 #ifndef OPENSSL_NO_DEPRECATED_3_0
243 int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX
*ctx
, unsigned char **pukm
)
247 OSSL_PARAM params
[2], *p
= params
;
249 ret
= evp_pkey_ctx_getset_ecdh_param_checks(ctx
);
253 *p
++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM
,
255 *p
++ = OSSL_PARAM_construct_end();
257 ret
= evp_pkey_ctx_get_params_strict(ctx
, params
);
261 ERR_raise(ERR_LIB_EVP
, EVP_R_COMMAND_NOT_SUPPORTED
);
265 ukmlen
= params
[0].return_size
;
266 if (ukmlen
<= INT_MAX
)
280 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
281 * simply because that's easier.
282 * ASN1_OBJECT (which would be converted to text internally)?
284 int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX
*ctx
, int nid
)
286 int keytype
= nid
== EVP_PKEY_SM2
? EVP_PKEY_SM2
: EVP_PKEY_EC
;
288 return EVP_PKEY_CTX_ctrl(ctx
, keytype
, EVP_PKEY_OP_TYPE_GEN
,
289 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID
,
294 * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
295 * simply because that's easier.
297 int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX
*ctx
, int param_enc
)
299 return EVP_PKEY_CTX_ctrl(ctx
, EVP_PKEY_EC
, EVP_PKEY_OP_TYPE_GEN
,
300 EVP_PKEY_CTRL_EC_PARAM_ENC
, param_enc
, NULL
);