1 /* crypto/ec/ec_kmeth.c */
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
6 /* ====================================================================
7 * Copyright (c) 2015 The OpenSSL Project. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
35 * 6. Redistributions of any form whatsoever must retain the following
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
55 #include <openssl/ec.h>
56 #ifndef OPENSSL_NO_ENGINE
57 # include <openssl/engine.h>
59 #include <openssl/err.h>
63 static const EC_KEY_METHOD openssl_ec_key_method
= {
64 "OpenSSL EC_KEY method",
68 ossl_ecdh_compute_key
,
70 ossl_ecdsa_sign_setup
,
76 static const EC_KEY_METHOD
*default_ec_key_meth
= &openssl_ec_key_method
;
78 const EC_KEY_METHOD
*EC_KEY_OpenSSL(void)
80 return &openssl_ec_key_method
;
83 const EC_KEY_METHOD
*EC_KEY_get_default_method(void)
85 return default_ec_key_meth
;
88 void EC_KEY_set_default_method(const EC_KEY_METHOD
*meth
)
91 default_ec_key_meth
= &openssl_ec_key_method
;
93 default_ec_key_meth
= meth
;
96 const EC_KEY_METHOD
*EC_KEY_get_method(const EC_KEY
*key
)
101 int EC_KEY_set_method(EC_KEY
*key
, const EC_KEY_METHOD
*meth
)
103 void (*finish
)(EC_KEY
*key
) = key
->meth
->finish
;
108 #ifndef OPENSSL_NO_ENGINE
109 if (key
->engine
!= NULL
) {
110 ENGINE_finish(key
->engine
);
116 if (meth
->init
!= NULL
)
117 return meth
->init(key
);
121 EC_KEY
*EC_KEY_new_method(ENGINE
*engine
)
123 EC_KEY
*ret
= OPENSSL_zalloc(sizeof(*ret
));
126 ECerr(EC_F_EC_KEY_NEW_METHOD
, ERR_R_MALLOC_FAILURE
);
129 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY
, ret
, &ret
->ex_data
)) {
134 ret
->meth
= EC_KEY_get_default_method();
135 #ifndef OPENSSL_NO_ENGINE
136 if (engine
!= NULL
) {
137 if (!ENGINE_init(engine
)) {
138 ECerr(EC_F_EC_KEY_NEW_METHOD
, ERR_R_ENGINE_LIB
);
142 ret
->engine
= engine
;
144 ret
->engine
= ENGINE_get_default_EC();
145 if (ret
->engine
!= NULL
) {
146 ret
->meth
= ENGINE_get_EC(ret
->engine
);
147 if (ret
->meth
== NULL
) {
148 ECerr(EC_F_EC_KEY_NEW_METHOD
, ERR_R_ENGINE_LIB
);
149 ENGINE_finish(ret
->engine
);
157 ret
->conv_form
= POINT_CONVERSION_UNCOMPRESSED
;
159 if (ret
->meth
->init
!= NULL
&& ret
->meth
->init(ret
) == 0) {
166 int ECDH_compute_key(void *out
, size_t outlen
, const EC_POINT
*pub_key
,
168 void *(*KDF
) (const void *in
, size_t inlen
, void *out
,
171 if (eckey
->meth
->compute_key
!= NULL
)
172 return eckey
->meth
->compute_key(out
, outlen
, pub_key
, eckey
, KDF
);
173 ECerr(EC_F_ECDH_COMPUTE_KEY
, EC_R_OPERATION_NOT_SUPPORTED
);
177 EC_KEY_METHOD
*EC_KEY_METHOD_new(const EC_KEY_METHOD
*meth
)
179 EC_KEY_METHOD
*ret
= OPENSSL_zalloc(sizeof(*meth
));
185 ret
->flags
|= EC_KEY_METHOD_DYNAMIC
;
189 void EC_KEY_METHOD_free(EC_KEY_METHOD
*meth
)
191 if (meth
->flags
& EC_KEY_METHOD_DYNAMIC
)
195 void EC_KEY_METHOD_set_init(EC_KEY_METHOD
*meth
,
196 int (*init
)(EC_KEY
*key
),
197 void (*finish
)(EC_KEY
*key
),
198 int (*copy
)(EC_KEY
*dest
, const EC_KEY
*src
),
199 int (*set_group
)(EC_KEY
*key
, const EC_GROUP
*grp
),
200 int (*set_private
)(EC_KEY
*key
,
201 const BIGNUM
*priv_key
),
202 int (*set_public
)(EC_KEY
*key
,
203 const EC_POINT
*pub_key
))
206 meth
->finish
= finish
;
208 meth
->set_group
= set_group
;
209 meth
->set_private
= set_private
;
210 meth
->set_public
= set_public
;
213 void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD
*meth
,
214 int (*keygen
)(EC_KEY
*key
))
216 meth
->keygen
= keygen
;
219 void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD
*meth
,
220 int (*ckey
)(void *out
,
222 const EC_POINT
*pub_key
,
224 void *(*KDF
) (const void *in
,
229 meth
->compute_key
= ckey
;
232 void EC_KEY_METHOD_set_sign(EC_KEY_METHOD
*meth
,
233 int (*sign
)(int type
, const unsigned char *dgst
,
234 int dlen
, unsigned char *sig
,
235 unsigned int *siglen
,
236 const BIGNUM
*kinv
, const BIGNUM
*r
,
238 int (*sign_setup
)(EC_KEY
*eckey
, BN_CTX
*ctx_in
,
239 BIGNUM
**kinvp
, BIGNUM
**rp
),
240 ECDSA_SIG
*(*sign_sig
)(const unsigned char *dgst
,
242 const BIGNUM
*in_kinv
,
247 meth
->sign_setup
= sign_setup
;
248 meth
->sign_sig
= sign_sig
;
251 void EC_KEY_METHOD_set_verify(EC_KEY_METHOD
*meth
,
252 int (*verify
)(int type
, const unsigned
253 char *dgst
, int dgst_len
,
254 const unsigned char *sigbuf
,
255 int sig_len
, EC_KEY
*eckey
),
256 int (*verify_sig
)(const unsigned char *dgst
,
258 const ECDSA_SIG
*sig
,
261 meth
->verify
= verify
;
262 meth
->verify_sig
= verify_sig
;
265 void EC_KEY_METHOD_get_init(EC_KEY_METHOD
*meth
,
266 int (**pinit
)(EC_KEY
*key
),
267 void (**pfinish
)(EC_KEY
*key
),
268 int (**pcopy
)(EC_KEY
*dest
, const EC_KEY
*src
),
269 int (**pset_group
)(EC_KEY
*key
,
270 const EC_GROUP
*grp
),
271 int (**pset_private
)(EC_KEY
*key
,
272 const BIGNUM
*priv_key
),
273 int (**pset_public
)(EC_KEY
*key
,
274 const EC_POINT
*pub_key
))
279 *pfinish
= meth
->finish
;
282 if (pset_group
!= NULL
)
283 *pset_group
= meth
->set_group
;
284 if (pset_private
!= NULL
)
285 *pset_private
= meth
->set_private
;
286 if (pset_public
!= NULL
)
287 *pset_public
= meth
->set_public
;
290 void EC_KEY_METHOD_get_keygen(EC_KEY_METHOD
*meth
,
291 int (**pkeygen
)(EC_KEY
*key
))
294 *pkeygen
= meth
->keygen
;
297 void EC_KEY_METHOD_get_compute_key(EC_KEY_METHOD
*meth
,
298 int (**pck
)(void *out
,
300 const EC_POINT
*pub_key
,
302 void *(*KDF
) (const void *in
,
308 *pck
= meth
->compute_key
;
311 void EC_KEY_METHOD_get_sign(EC_KEY_METHOD
*meth
,
312 int (**psign
)(int type
, const unsigned char *dgst
,
313 int dlen
, unsigned char *sig
,
314 unsigned int *siglen
,
315 const BIGNUM
*kinv
, const BIGNUM
*r
,
317 int (**psign_setup
)(EC_KEY
*eckey
, BN_CTX
*ctx_in
,
318 BIGNUM
**kinvp
, BIGNUM
**rp
),
319 ECDSA_SIG
*(**psign_sig
)(const unsigned char *dgst
,
321 const BIGNUM
*in_kinv
,
327 if (psign_setup
!= NULL
)
328 *psign_setup
= meth
->sign_setup
;
329 if (psign_sig
!= NULL
)
330 *psign_sig
= meth
->sign_sig
;
333 void EC_KEY_METHOD_get_verify(EC_KEY_METHOD
*meth
,
334 int (**pverify
)(int type
, const unsigned
335 char *dgst
, int dgst_len
,
336 const unsigned char *sigbuf
,
337 int sig_len
, EC_KEY
*eckey
),
338 int (**pverify_sig
)(const unsigned char *dgst
,
340 const ECDSA_SIG
*sig
,
344 *pverify
= meth
->verify
;
345 if (pverify_sig
!= NULL
)
346 *pverify_sig
= meth
->verify_sig
;