summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTheo Buehler <tb@cvs.openbsd.org>2019-01-19 01:07:01 +0000
committerTheo Buehler <tb@cvs.openbsd.org>2019-01-19 01:07:01 +0000
commit750422d3073ea431791631d8ce4c9e3ece05dc82 (patch)
tree4b3f27443052c32bf76b44605537f48f02ca68c2 /lib
parent8c516a51f6e52ddc7e20170e560608a1c4695b6e (diff)
Partial port of EC_KEY_METHOD from OpenSSL 1.1.
This commit adds init/free, support for signing, setting and getting the method, engine support as well as extra data. from markus
Diffstat (limited to 'lib')
-rw-r--r--lib/libcrypto/Makefile10
-rw-r--r--lib/libcrypto/Symbols.list13
-rw-r--r--lib/libcrypto/crypto.h3
-rw-r--r--lib/libcrypto/ec/ec.h31
-rw-r--r--lib/libcrypto/ec/ec_key.c91
-rw-r--r--lib/libcrypto/ec/ec_kmeth.c272
-rw-r--r--lib/libcrypto/ec/ec_lcl.h30
-rw-r--r--lib/libcrypto/ecdsa/ecdsa.h22
-rw-r--r--lib/libcrypto/ecdsa/ecs_locl.h10
-rw-r--r--lib/libcrypto/ecdsa/ecs_ossl.c39
-rw-r--r--lib/libcrypto/ecdsa/ecs_sign.c38
-rw-r--r--lib/libcrypto/engine/eng_fat.c11
-rw-r--r--lib/libcrypto/engine/eng_int.h3
-rw-r--r--lib/libcrypto/engine/eng_list.c5
-rw-r--r--lib/libcrypto/engine/engine.h14
-rw-r--r--lib/libcrypto/engine/tb_eckey.c123
16 files changed, 659 insertions, 56 deletions
diff --git a/lib/libcrypto/Makefile b/lib/libcrypto/Makefile
index 8e39d92ab43..66f511761b5 100644
--- a/lib/libcrypto/Makefile
+++ b/lib/libcrypto/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.30 2018/11/11 06:53:31 tb Exp $
+# $OpenBSD: Makefile,v 1.31 2019/01/19 01:07:00 tb Exp $
LIB= crypto
LIBREBUILD=y
@@ -31,6 +31,10 @@ CFLAGS+= -I${LCRYPTO_SRC}
CFLAGS+= -I${LCRYPTO_SRC}/asn1 -I${LCRYPTO_SRC}/bn -I${LCRYPTO_SRC}/evp
CFLAGS+= -I${LCRYPTO_SRC}/modes
+# XXX FIXME ecdsa and ec should be merged
+CFLAGS+= -I${LCRYPTO_SRC}/ecdsa
+CFLAGS+= -I${LCRYPTO_SRC}/ec
+
VERSION_SCRIPT= Symbols.map
SYMBOL_LIST= ${.CURDIR}/Symbols.list
@@ -125,7 +129,7 @@ SRCS+= dso_openssl.c
# ec/
SRCS+= ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c
SRCS+= ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c
-SRCS+= ec2_smpl.c ec2_mult.c ec_ameth.c ec_pmeth.c eck_prn.c
+SRCS+= ec2_smpl.c ec2_mult.c ec_ameth.c ec_pmeth.c ec_kmeth.c eck_prn.c
SRCS+= ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c
SRCS+= ecp_oct.c ec2_oct.c ec_oct.c
@@ -139,7 +143,7 @@ SRCS+= ecs_lib.c ecs_asn1.c ecs_ossl.c ecs_sign.c ecs_vrf.c ecs_err.c
SRCS+= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c
SRCS+= eng_table.c eng_pkey.c eng_fat.c eng_all.c
SRCS+= tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c
-SRCS+= tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c
+SRCS+= tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c tb_eckey.c
SRCS+= eng_openssl.c eng_cnf.c eng_dyn.c
# XXX unnecessary? handled in EVP now...
# SRCS+= eng_aesni.c # local addition
diff --git a/lib/libcrypto/Symbols.list b/lib/libcrypto/Symbols.list
index c4b78dbef22..2734fed62a2 100644
--- a/lib/libcrypto/Symbols.list
+++ b/lib/libcrypto/Symbols.list
@@ -955,6 +955,13 @@ EC_GROUP_set_curve_name
EC_GROUP_set_generator
EC_GROUP_set_point_conversion_form
EC_GROUP_set_seed
+EC_KEY_METHOD_free
+EC_KEY_METHOD_get_init
+EC_KEY_METHOD_get_sign
+EC_KEY_METHOD_new
+EC_KEY_METHOD_set_init
+EC_KEY_METHOD_set_sign
+EC_KEY_OpenSSL
EC_KEY_check_key
EC_KEY_clear_flags
EC_KEY_copy
@@ -965,9 +972,12 @@ EC_KEY_get0_group
EC_KEY_get0_private_key
EC_KEY_get0_public_key
EC_KEY_get_conv_form
+EC_KEY_get_default_method
EC_KEY_get_enc_flags
+EC_KEY_get_ex_data
EC_KEY_get_flags
EC_KEY_get_key_method_data
+EC_KEY_get_method
EC_KEY_insert_key_method_data
EC_KEY_new
EC_KEY_new_by_curve_name
@@ -976,9 +986,12 @@ EC_KEY_print
EC_KEY_print_fp
EC_KEY_set_asn1_flag
EC_KEY_set_conv_form
+EC_KEY_set_default_method
EC_KEY_set_enc_flags
+EC_KEY_set_ex_data
EC_KEY_set_flags
EC_KEY_set_group
+EC_KEY_set_method
EC_KEY_set_private_key
EC_KEY_set_public_key
EC_KEY_set_public_key_affine_coordinates
diff --git a/lib/libcrypto/crypto.h b/lib/libcrypto/crypto.h
index 8d549da8b54..7de8abb437e 100644
--- a/lib/libcrypto/crypto.h
+++ b/lib/libcrypto/crypto.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: crypto.h,v 1.49 2018/11/11 16:32:28 bcook Exp $ */
+/* $OpenBSD: crypto.h,v 1.50 2019/01/19 01:07:00 tb Exp $ */
/* ====================================================================
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
*
@@ -286,6 +286,7 @@ DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS)
#define CRYPTO_EX_INDEX_ECDH 13
#define CRYPTO_EX_INDEX_COMP 14
#define CRYPTO_EX_INDEX_STORE 15
+#define CRYPTO_EX_INDEX_EC_KEY 16
/* Dynamically assigned indexes start from this value (don't use directly, use
* via CRYPTO_ex_data_new_class). */
diff --git a/lib/libcrypto/ec/ec.h b/lib/libcrypto/ec/ec.h
index d9df48603a0..1173459dae2 100644
--- a/lib/libcrypto/ec/ec.h
+++ b/lib/libcrypto/ec/ec.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ec.h,v 1.13 2018/05/19 10:37:02 tb Exp $ */
+/* $OpenBSD: ec.h,v 1.14 2019/01/19 01:07:00 tb Exp $ */
/*
* Originally written by Bodo Moeller for the OpenSSL project.
*/
@@ -705,6 +705,7 @@ int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
/********************************************************************/
typedef struct ec_key_st EC_KEY;
+typedef struct ec_key_method_st EC_KEY_METHOD;
/* some values for the encoding_flag */
#define EC_PKEY_NO_PARAMETERS 0x001
@@ -945,6 +946,34 @@ int ECParameters_print_fp(FILE *fp, const EC_KEY *key);
*/
int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
+#define EC_KEY_get_ex_new_index(l, p, newf, dupf, freef) \
+ CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_EC_KEY, l, p, newf, dupf, freef)
+int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg);
+void *EC_KEY_get_ex_data(const EC_KEY *key, int idx);
+
+const EC_KEY_METHOD *EC_KEY_OpenSSL(void);
+const EC_KEY_METHOD *EC_KEY_get_default_method(void);
+void EC_KEY_set_default_method(const EC_KEY_METHOD *meth);
+const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key);
+int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth);
+EC_KEY *EC_KEY_new_method(ENGINE *engine);
+EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth);
+void EC_KEY_METHOD_free(EC_KEY_METHOD *meth);
+void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth,
+ int (*init)(EC_KEY *key),
+ void (*finish)(EC_KEY *key),
+ int (*copy)(EC_KEY *dest, const EC_KEY *src),
+ int (*set_group)(EC_KEY *key, const EC_GROUP *grp),
+ int (*set_private)(EC_KEY *key, const BIGNUM *priv_key),
+ int (*set_public)(EC_KEY *key, const EC_POINT *pub_key));
+void EC_KEY_METHOD_get_init(EC_KEY_METHOD *meth,
+ int (**pinit)(EC_KEY *key),
+ void (**pfinish)(EC_KEY *key),
+ int (**pcopy)(EC_KEY *dest, const EC_KEY *src),
+ int (**pset_group)(EC_KEY *key, const EC_GROUP *grp),
+ int (**pset_private)(EC_KEY *key, const BIGNUM *priv_key),
+ int (**pset_public)(EC_KEY *key, const EC_POINT *pub_key));
+
EC_KEY *ECParameters_dup(EC_KEY *key);
#ifndef __cplusplus
diff --git a/lib/libcrypto/ec/ec_key.c b/lib/libcrypto/ec/ec_key.c
index fcdf461d20c..f57e078c7f9 100644
--- a/lib/libcrypto/ec/ec_key.c
+++ b/lib/libcrypto/ec/ec_key.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ec_key.c,v 1.22 2018/11/09 23:39:45 tb Exp $ */
+/* $OpenBSD: ec_key.c,v 1.23 2019/01/19 01:07:00 tb Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
@@ -65,30 +65,18 @@
#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+
#include "bn_lcl.h"
#include "ec_lcl.h"
-#include <openssl/err.h>
EC_KEY *
EC_KEY_new(void)
{
- EC_KEY *ret;
-
- ret = malloc(sizeof(EC_KEY));
- if (ret == NULL) {
- ECerror(ERR_R_MALLOC_FAILURE);
- return (NULL);
- }
- ret->version = 1;
- ret->flags = 0;
- ret->group = NULL;
- ret->pub_key = NULL;
- ret->priv_key = NULL;
- ret->enc_flag = 0;
- ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
- ret->references = 1;
- ret->method_data = NULL;
- return (ret);
+ return EC_KEY_new_method(NULL);
}
EC_KEY *
@@ -102,6 +90,11 @@ EC_KEY_new_by_curve_name(int nid)
EC_KEY_free(ret);
return NULL;
}
+ if (ret->meth->set_group != NULL &&
+ ret->meth->set_group(ret, ret->group) == 0) {
+ EC_KEY_free(ret);
+ return NULL;
+ }
return ret;
}
@@ -117,6 +110,14 @@ EC_KEY_free(EC_KEY * r)
if (i > 0)
return;
+ if (r->meth != NULL && r->meth->finish != NULL)
+ r->meth->finish(r);
+
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE_finish(r->engine);
+#endif
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data);
+
EC_GROUP_free(r->group);
EC_POINT_free(r->pub_key);
BN_clear_free(r->priv_key);
@@ -135,6 +136,15 @@ EC_KEY_copy(EC_KEY * dest, const EC_KEY * src)
ECerror(ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
+ if (src->meth != dest->meth) {
+ if (dest->meth != NULL && dest->meth->finish != NULL)
+ dest->meth->finish(dest);
+#ifndef OPENSSL_NO_ENGINE
+ if (ENGINE_finish(dest->engine) == 0)
+ return 0;
+ dest->engine = NULL;
+#endif
+ }
/* copy the parameters */
if (src->group) {
const EC_METHOD *meth = EC_GROUP_method_of(src->group);
@@ -184,14 +194,32 @@ EC_KEY_copy(EC_KEY * dest, const EC_KEY * src)
dest->version = src->version;
dest->flags = src->flags;
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, &dest->ex_data,
+ &((EC_KEY *)src)->ex_data)) /* XXX const */
+ return NULL;
+
+ if (src->meth != dest->meth) {
+#ifndef OPENSSL_NO_ENGINE
+ if (src->engine != NULL && ENGINE_init(src->engine) == 0)
+ return 0;
+ dest->engine = src->engine;
+#endif
+ dest->meth = src->meth;
+ }
+
+ if (src->meth != NULL && src->meth->copy != NULL &&
+ src->meth->copy(dest, src) == 0)
+ return 0;
+
return dest;
}
EC_KEY *
EC_KEY_dup(const EC_KEY * ec_key)
{
- EC_KEY *ret = EC_KEY_new();
- if (ret == NULL)
+ EC_KEY *ret;
+
+ if ((ret = EC_KEY_new_method(ec_key->engine)) == NULL)
return NULL;
if (EC_KEY_copy(ret, ec_key) == NULL) {
EC_KEY_free(ret);
@@ -207,6 +235,18 @@ EC_KEY_up_ref(EC_KEY * r)
return ((i > 1) ? 1 : 0);
}
+int
+EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg)
+{
+ return CRYPTO_set_ex_data(&r->ex_data, idx, arg);
+}
+
+void *
+EC_KEY_get_ex_data(const EC_KEY *r, int idx)
+{
+ return CRYPTO_get_ex_data(&r->ex_data, idx);
+}
+
int
EC_KEY_generate_key(EC_KEY *eckey)
{
@@ -407,6 +447,9 @@ EC_KEY_get0_group(const EC_KEY * key)
int
EC_KEY_set_group(EC_KEY * key, const EC_GROUP * group)
{
+ if (key->meth->set_group != NULL &&
+ key->meth->set_group(key, group) == 0)
+ return 0;
EC_GROUP_free(key->group);
key->group = EC_GROUP_dup(group);
return (key->group == NULL) ? 0 : 1;
@@ -421,6 +464,9 @@ EC_KEY_get0_private_key(const EC_KEY * key)
int
EC_KEY_set_private_key(EC_KEY * key, const BIGNUM * priv_key)
{
+ if (key->meth->set_private != NULL &&
+ key->meth->set_private(key, priv_key) == 0)
+ return 0;
BN_clear_free(key->priv_key);
key->priv_key = BN_dup(priv_key);
return (key->priv_key == NULL) ? 0 : 1;
@@ -435,6 +481,9 @@ EC_KEY_get0_public_key(const EC_KEY * key)
int
EC_KEY_set_public_key(EC_KEY * key, const EC_POINT * pub_key)
{
+ if (key->meth->set_public != NULL &&
+ key->meth->set_public(key, pub_key) == 0)
+ return 0;
EC_POINT_free(key->pub_key);
key->pub_key = EC_POINT_dup(pub_key, key->group);
return (key->pub_key == NULL) ? 0 : 1;
diff --git a/lib/libcrypto/ec/ec_kmeth.c b/lib/libcrypto/ec/ec_kmeth.c
new file mode 100644
index 00000000000..b714c622364
--- /dev/null
+++ b/lib/libcrypto/ec/ec_kmeth.c
@@ -0,0 +1,272 @@
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2015 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/ec.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+
+#include "ec_lcl.h"
+#include "ecs_locl.h"
+
+static const EC_KEY_METHOD openssl_ec_key_method = {
+ .name = "OpenSSL EC_KEY method",
+ .flags = 0,
+
+ .init = NULL,
+ .finish = NULL,
+ .copy = NULL,
+
+ .set_group = NULL,
+ .set_private = NULL,
+ .set_public = NULL,
+
+ .sign = ossl_ecdsa_sign,
+ .sign_setup = ossl_ecdsa_sign_setup,
+ .sign_sig = ossl_ecdsa_sign_sig,
+};
+
+const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method;
+
+const EC_KEY_METHOD *
+EC_KEY_OpenSSL(void)
+{
+ return &openssl_ec_key_method;
+}
+
+const EC_KEY_METHOD *
+EC_KEY_get_default_method(void)
+{
+ return default_ec_key_meth;
+}
+
+void
+EC_KEY_set_default_method(const EC_KEY_METHOD *meth)
+{
+ if (meth == NULL)
+ default_ec_key_meth = &openssl_ec_key_method;
+ else
+ default_ec_key_meth = meth;
+}
+
+const EC_KEY_METHOD *
+EC_KEY_get_method(const EC_KEY *key)
+{
+ return key->meth;
+}
+
+int
+EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth)
+{
+ void (*finish)(EC_KEY *key) = key->meth->finish;
+
+ if (finish != NULL)
+ finish(key);
+
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE_finish(key->engine);
+ key->engine = NULL;
+#endif
+
+ key->meth = meth;
+ if (meth->init != NULL)
+ return meth->init(key);
+ return 1;
+}
+
+EC_KEY *
+EC_KEY_new_method(ENGINE *engine)
+{
+ EC_KEY *ret;
+
+ if ((ret = calloc(1, sizeof(EC_KEY))) == NULL) {
+ ECerror(ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ ret->meth = EC_KEY_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+ if (engine != NULL) {
+ if (!ENGINE_init(engine)) {
+ ECerror(ERR_R_ENGINE_LIB);
+ goto err;
+ }
+ ret->engine = engine;
+ } else
+ ret->engine = ENGINE_get_default_EC();
+ if (ret->engine) {
+ ret->meth = ENGINE_get_EC(ret->engine);
+ if (ret->meth == NULL) {
+ ECerror(ERR_R_ENGINE_LIB);
+ goto err;
+ }
+ }
+#endif
+ ret->version = 1;
+ ret->flags = 0;
+ ret->group = NULL;
+ ret->pub_key = NULL;
+ ret->priv_key = NULL;
+ ret->enc_flag = 0;
+ ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
+ ret->references = 1;
+ ret->method_data = NULL;
+
+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data))
+ goto err;
+ if (ret->meth->init != NULL && ret->meth->init(ret) == 0)
+ goto err;
+
+ return ret;
+
+ err:
+ EC_KEY_free(ret);
+ return NULL;
+}
+
+EC_KEY_METHOD *
+EC_KEY_METHOD_new(const EC_KEY_METHOD *meth)
+{
+ EC_KEY_METHOD *ret;
+
+ if ((ret = malloc(sizeof(*meth))) == NULL)
+ return NULL;
+ if (meth != NULL)
+ *ret = *meth;
+ ret->flags |= EC_KEY_METHOD_DYNAMIC;
+ return ret;
+}
+
+void
+EC_KEY_METHOD_free(EC_KEY_METHOD *meth)
+{
+ if (meth == NULL)
+ return;
+ if (meth->flags & EC_KEY_METHOD_DYNAMIC)
+ free(meth);
+}
+
+void
+EC_KEY_METHOD_get_init(EC_KEY_METHOD *meth,
+ int (**pinit)(EC_KEY *key),
+ void (**pfinish)(EC_KEY *key),
+ int (**pcopy)(EC_KEY *dest, const EC_KEY *src),
+ int (**pset_group)(EC_KEY *key, const EC_GROUP *grp),
+ int (**pset_private)(EC_KEY *key, const BIGNUM *priv_key),
+ int (**pset_public)(EC_KEY *key, const EC_POINT *pub_key))
+{
+ if (pinit != NULL)
+ *pinit = meth->init;
+ if (pfinish != NULL)
+ *pfinish = meth->finish;
+ if (pcopy != NULL)
+ *pcopy = meth->copy;
+ if (pset_group != NULL)
+ *pset_group = meth->set_group;
+ if (pset_private != NULL)
+ *pset_private = meth->set_private;
+ if (pset_public != NULL)
+ *pset_public = meth->set_public;
+}
+
+void
+EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth,
+ int (*init)(EC_KEY *key),
+ void (*finish)(EC_KEY *key),
+ int (*copy)(EC_KEY *dest, const EC_KEY *src),
+ int (*set_group)(EC_KEY *key, const EC_GROUP *grp),
+ int (*set_private)(EC_KEY *key, const BIGNUM *priv_key),
+ int (*set_public)(EC_KEY *key, const EC_POINT *pub_key))
+{
+ meth->init = init;
+ meth->finish = finish;
+ meth->copy = copy;
+ meth->set_group = set_group;
+ meth->set_private = set_private;
+ meth->set_public = set_public;
+}
+
+void
+EC_KEY_METHOD_get_sign(EC_KEY_METHOD *meth,
+ int (**psign)(int type, const unsigned char *dgst,
+ int dlen, unsigned char *sig, unsigned int *siglen,
+ const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey),
+ int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
+ BIGNUM **kinvp, BIGNUM **rp),
+ ECDSA_SIG *(**psign_sig)(const unsigned char *dgst,
+ int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r,
+ EC_KEY *eckey))
+{
+ if (psign != NULL)
+ *psign = meth->sign;
+ if (psign_setup != NULL)
+ *psign_setup = meth->sign_setup;
+ if (psign_sig != NULL)
+ *psign_sig = meth->sign_sig;
+}
+
+void
+EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth,
+ int (*sign)(int type, const unsigned char *dgst,
+ int dlen, unsigned char *sig, unsigned int *siglen,
+ const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey),
+ int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
+ BIGNUM **kinvp, BIGNUM **rp),
+ ECDSA_SIG *(*sign_sig)(const unsigned char *dgst,
+ int dgst_len, const BIGNUM *in_kinv,
+ const BIGNUM *in_r, EC_KEY *eckey))
+{
+ meth->sign = sign;
+ meth->sign_setup = sign_setup;
+ meth->sign_sig = sign_sig;
+}
diff --git a/lib/libcrypto/ec/ec_lcl.h b/lib/libcrypto/ec/ec_lcl.h
index c177246f369..cff0892e892 100644
--- a/lib/libcrypto/ec/ec_lcl.h
+++ b/lib/libcrypto/ec/ec_lcl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ec_lcl.h,v 1.11 2018/11/05 20:18:21 tb Exp $ */
+/* $OpenBSD: ec_lcl.h,v 1.12 2019/01/19 01:07:00 tb Exp $ */
/*
* Originally written by Bodo Moeller for the OpenSSL project.
*/
@@ -73,6 +73,7 @@
#include <openssl/obj_mac.h>
#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
#include <openssl/bn.h>
__BEGIN_HIDDEN_DECLS
@@ -245,6 +246,9 @@ struct ec_group_st {
} /* EC_GROUP */;
struct ec_key_st {
+ const EC_KEY_METHOD *meth;
+ ENGINE *engine;
+
int version;
EC_GROUP *group;
@@ -259,6 +263,7 @@ struct ec_key_st {
int flags;
EC_EXTRA_DATA *method_data;
+ CRYPTO_EX_DATA ex_data;
} /* EC_KEY */;
/* Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs only
@@ -441,6 +446,29 @@ int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
const EC_METHOD *EC_GFp_nistz256_method(void);
#endif
+/* EC_METHOD definitions */
+
+struct ec_key_method_st {
+ const char *name;
+ int32_t flags;
+ int (*init)(EC_KEY *key);
+ void (*finish)(EC_KEY *key);
+ int (*copy)(EC_KEY *dest, const EC_KEY *src);
+ int (*set_group)(EC_KEY *key, const EC_GROUP *grp);
+ int (*set_private)(EC_KEY *key, const BIGNUM *priv_key);
+ int (*set_public)(EC_KEY *key, const EC_POINT *pub_key);
+ int (*sign)(int type, const unsigned char *dgst, int dlen, unsigned char
+ *sig, unsigned int *siglen, const BIGNUM *kinv,
+ const BIGNUM *r, EC_KEY *eckey);
+ int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+ BIGNUM **rp);
+ ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgst_len,
+ const BIGNUM *in_kinv, const BIGNUM *in_r,
+ EC_KEY *eckey);
+} /* EC_KEY_METHOD */;
+
+#define EC_KEY_METHOD_DYNAMIC 1
+
/* method functions in ecp_nistp521.c */
int ec_GFp_nistp521_group_init(EC_GROUP *group);
int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
diff --git a/lib/libcrypto/ecdsa/ecdsa.h b/lib/libcrypto/ecdsa/ecdsa.h
index 9c53230a884..12d6677ce3a 100644
--- a/lib/libcrypto/ecdsa/ecdsa.h
+++ b/lib/libcrypto/ecdsa/ecdsa.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ecdsa.h,v 1.5 2018/03/17 15:24:44 tb Exp $ */
+/* $OpenBSD: ecdsa.h,v 1.6 2019/01/19 01:07:00 tb Exp $ */
/**
* \file crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions
* \author Written by Nils Larsch for the OpenSSL project
@@ -269,6 +269,26 @@ int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
void *ECDSA_get_ex_data(EC_KEY *d, int idx);
+/* XXX should be in ec.h, but needs ECDSA_SIG */
+void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth,
+ int (*sign)(int type, const unsigned char *dgst,
+ int dlen, unsigned char *sig, unsigned int *siglen,
+ const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey),
+ int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
+ BIGNUM **kinvp, BIGNUM **rp),
+ ECDSA_SIG *(*sign_sig)(const unsigned char *dgst,
+ int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r,
+ EC_KEY *eckey));
+void EC_KEY_METHOD_get_sign(EC_KEY_METHOD *meth,
+ int (**psign)(int type, const unsigned char *dgst,
+ int dlen, unsigned char *sig, unsigned int *siglen,
+ const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey),
+ int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
+ BIGNUM **kinvp, BIGNUM **rp),
+ ECDSA_SIG *(**psign_sig)(const unsigned char *dgst,
+ int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r,
+ EC_KEY *eckey));
+
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
diff --git a/lib/libcrypto/ecdsa/ecs_locl.h b/lib/libcrypto/ecdsa/ecs_locl.h
index 94e88743321..0a9f17908ba 100644
--- a/lib/libcrypto/ecdsa/ecs_locl.h
+++ b/lib/libcrypto/ecdsa/ecs_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ecs_locl.h,v 1.5 2016/12/21 15:49:29 jsing Exp $ */
+/* $OpenBSD: ecs_locl.h,v 1.6 2019/01/19 01:07:00 tb Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project
*/
@@ -81,6 +81,14 @@ typedef struct ecdsa_data_st {
*/
ECDSA_DATA *ecdsa_check(EC_KEY *eckey);
+int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+ BIGNUM **rp);
+int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
+ unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
+ const BIGNUM *r, EC_KEY *eckey);
+ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
+ const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey);
+
__END_HIDDEN_DECLS
#endif /* HEADER_ECS_LOCL_H */
diff --git a/lib/libcrypto/ecdsa/ecs_ossl.c b/lib/libcrypto/ecdsa/ecs_ossl.c
index 87d80642df7..4e05cb9aac4 100644
--- a/lib/libcrypto/ecdsa/ecs_ossl.c
+++ b/lib/libcrypto/ecdsa/ecs_ossl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ecs_ossl.c,v 1.16 2018/07/10 21:36:02 tb Exp $ */
+/* $OpenBSD: ecs_ossl.c,v 1.17 2019/01/19 01:07:00 tb Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project
*/
@@ -111,6 +111,21 @@ ecdsa_prepare_digest(const unsigned char *dgst, int dgst_len, BIGNUM *order,
return 1;
}
+int
+ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
+ unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)
+{
+ ECDSA_SIG *s;
+
+ if ((s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey)) == NULL) {
+ *siglen = 0;
+ return 0;
+ }
+ *siglen = i2d_ECDSA_SIG(s, &sig);
+ ECDSA_SIG_free(s);
+ return 1;
+}
+
static int
ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
{
@@ -234,6 +249,16 @@ ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
return (ret);
}
+/* replace w/ ecdsa_sign_setup() when ECDSA_METHOD gets removed */
+int
+ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+{
+ ECDSA_DATA *ecdsa;
+
+ if ((ecdsa = ecdsa_check(eckey)) == NULL)
+ return 0;
+ return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp);
+}
static ECDSA_SIG *
ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
@@ -384,6 +409,18 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
return ret;
}
+/* replace w/ ecdsa_do_sign() when ECDSA_METHOD gets removed */
+ECDSA_SIG *
+ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
+ const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
+{
+ ECDSA_DATA *ecdsa;
+
+ if ((ecdsa = ecdsa_check(eckey)) == NULL)
+ return NULL;
+ return ecdsa->meth->ecdsa_do_sign(dgst, dgst_len, in_kinv, in_r, eckey);
+}
+
static int
ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig,
EC_KEY *eckey)
diff --git a/lib/libcrypto/ecdsa/ecs_sign.c b/lib/libcrypto/ecdsa/ecs_sign.c
index 029a0cb562c..5beb853b94a 100644
--- a/lib/libcrypto/ecdsa/ecs_sign.c
+++ b/lib/libcrypto/ecdsa/ecs_sign.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ecs_sign.c,v 1.6 2015/02/08 13:35:07 jsing Exp $ */
+/* $OpenBSD: ecs_sign.c,v 1.7 2019/01/19 01:07:00 tb Exp $ */
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
@@ -55,11 +55,13 @@
#include <openssl/opensslconf.h>
-#include "ecs_locl.h"
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
+#include "ecs_locl.h"
+#include "ec_lcl.h"
+
ECDSA_SIG *
ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
{
@@ -70,11 +72,10 @@ ECDSA_SIG *
ECDSA_do_sign_ex(const unsigned char *dgst, int dlen, const BIGNUM *kinv,
const BIGNUM *rp, EC_KEY *eckey)
{
- ECDSA_DATA *ecdsa = ecdsa_check(eckey);
-
- if (ecdsa == NULL)
- return NULL;
- return ecdsa->meth->ecdsa_do_sign(dgst, dlen, kinv, rp, eckey);
+ if (eckey->meth->sign_sig != NULL)
+ return eckey->meth->sign_sig(dgst, dlen, kinv, rp, eckey);
+ ECDSAerror(EVP_R_METHOD_NOT_SUPPORTED);
+ return 0;
}
int
@@ -88,24 +89,17 @@ int
ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)
{
- ECDSA_SIG *s;
-
- s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
- if (s == NULL) {
- *siglen = 0;
- return 0;
- }
- *siglen = i2d_ECDSA_SIG(s, &sig);
- ECDSA_SIG_free(s);
- return 1;
+ if (eckey->meth->sign != NULL)
+ return eckey->meth->sign(type, dgst, dlen, sig, siglen, kinv, r, eckey);
+ ECDSAerror(EVP_R_METHOD_NOT_SUPPORTED);
+ return 0;
}
int
ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
{
- ECDSA_DATA *ecdsa = ecdsa_check(eckey);
-
- if (ecdsa == NULL)
- return 0;
- return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp);
+ if (eckey->meth->sign_setup != NULL)
+ return eckey->meth->sign_setup(eckey, ctx_in, kinvp, rp);
+ ECDSAerror(EVP_R_METHOD_NOT_SUPPORTED);
+ return 0;
}
diff --git a/lib/libcrypto/engine/eng_fat.c b/lib/libcrypto/engine/eng_fat.c
index c97695a7d3b..baf1a54883d 100644
--- a/lib/libcrypto/engine/eng_fat.c
+++ b/lib/libcrypto/engine/eng_fat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: eng_fat.c,v 1.16 2017/01/29 17:49:23 beck Exp $ */
+/* $OpenBSD: eng_fat.c,v 1.17 2019/01/19 01:07:00 tb Exp $ */
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
@@ -93,6 +93,10 @@ ENGINE_set_default(ENGINE *e, unsigned int flags)
if ((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e))
return 0;
#endif
+#ifndef OPENSSL_NO_EC
+ if ((flags & ENGINE_METHOD_EC) && !ENGINE_set_default_EC(e))
+ return 0;
+#endif
if ((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
return 0;
if ((flags & ENGINE_METHOD_PKEY_METHS) &&
@@ -123,6 +127,8 @@ int_def_cb(const char *alg, int len, void *arg)
*pflags |= ENGINE_METHOD_ECDSA;
else if (!strncmp(alg, "DH", len))
*pflags |= ENGINE_METHOD_DH;
+ else if (strncmp(alg, "EC", len) == 0)
+ *pflags |= ENGINE_METHOD_EC;
else if (!strncmp(alg, "RAND", len))
*pflags |= ENGINE_METHOD_RAND;
else if (!strncmp(alg, "CIPHERS", len))
@@ -174,6 +180,9 @@ ENGINE_register_complete(ENGINE *e)
#ifndef OPENSSL_NO_ECDSA
ENGINE_register_ECDSA(e);
#endif
+#ifndef OPENSSL_NO_EC
+ ENGINE_register_EC(e);
+#endif
ENGINE_register_RAND(e);
ENGINE_register_pkey_meths(e);
return 1;
diff --git a/lib/libcrypto/engine/eng_int.h b/lib/libcrypto/engine/eng_int.h
index dbb639949d3..298c0e327fa 100644
--- a/lib/libcrypto/engine/eng_int.h
+++ b/lib/libcrypto/engine/eng_int.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: eng_int.h,v 1.9 2016/12/21 15:49:29 jsing Exp $ */
+/* $OpenBSD: eng_int.h,v 1.10 2019/01/19 01:07:00 tb Exp $ */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
@@ -159,6 +159,7 @@ struct engine_st {
const DH_METHOD *dh_meth;
const ECDH_METHOD *ecdh_meth;
const ECDSA_METHOD *ecdsa_meth;
+ const EC_KEY_METHOD *ec_meth;
const RAND_METHOD *rand_meth;
const STORE_METHOD *store_meth;
/* Cipher handling is via this callback */
diff --git a/lib/libcrypto/engine/eng_list.c b/lib/libcrypto/engine/eng_list.c
index 134866d2c69..b29b4102e40 100644
--- a/lib/libcrypto/engine/eng_list.c
+++ b/lib/libcrypto/engine/eng_list.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: eng_list.c,v 1.23 2018/08/24 19:25:31 tb Exp $ */
+/* $OpenBSD: eng_list.c,v 1.24 2019/01/19 01:07:00 tb Exp $ */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
@@ -316,6 +316,9 @@ engine_cpy(ENGINE *dest, const ENGINE *src)
#ifndef OPENSSL_NO_ECDSA
dest->ecdsa_meth = src->ecdsa_meth;
#endif
+#ifndef OPENSSL_NO_EC
+ dest->ec_meth = src->ec_meth;
+#endif
dest->rand_meth = src->rand_meth;
dest->store_meth = src->store_meth;
dest->ciphers = src->ciphers;
diff --git a/lib/libcrypto/engine/engine.h b/lib/libcrypto/engine/engine.h
index 0f603feaaf8..dc14be8e386 100644
--- a/lib/libcrypto/engine/engine.h
+++ b/lib/libcrypto/engine/engine.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: engine.h,v 1.32 2018/11/11 06:41:28 bcook Exp $ */
+/* $OpenBSD: engine.h,v 1.33 2019/01/19 01:07:00 tb Exp $ */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
@@ -87,6 +87,9 @@
#ifndef OPENSSL_NO_ECDSA
#include <openssl/ecdsa.h>
#endif
+#ifndef OPENSSL_NO_EC
+#include <openssl/ec.h>
+#endif
#include <openssl/ui.h>
#include <openssl/err.h>
#endif
@@ -112,6 +115,7 @@ extern "C" {
#define ENGINE_METHOD_STORE (unsigned int)0x0100
#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200
#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400
+#define ENGINE_METHOD_EC (unsigned int)0x0800
/* Obvious all-or-nothing cases. */
#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
#define ENGINE_METHOD_NONE (unsigned int)0x0000
@@ -353,6 +357,10 @@ int ENGINE_register_ECDSA(ENGINE *e);
void ENGINE_unregister_ECDSA(ENGINE *e);
void ENGINE_register_all_ECDSA(void);
+int ENGINE_register_EC(ENGINE *e);
+void ENGINE_unregister_EC(ENGINE *e);
+void ENGINE_register_all_EC(void);
+
int ENGINE_register_DH(ENGINE *e);
void ENGINE_unregister_DH(ENGINE *e);
void ENGINE_register_all_DH(void);
@@ -447,6 +455,7 @@ int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
+int ENGINE_set_EC(ENGINE *e, const EC_KEY_METHOD *ec_meth);
int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
@@ -486,6 +495,7 @@ const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
+const EC_KEY_METHOD *ENGINE_get_EC(const ENGINE *e);
const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
@@ -553,6 +563,7 @@ ENGINE *ENGINE_get_default_RSA(void);
ENGINE *ENGINE_get_default_DSA(void);
ENGINE *ENGINE_get_default_ECDH(void);
ENGINE *ENGINE_get_default_ECDSA(void);
+ENGINE *ENGINE_get_default_EC(void);
ENGINE *ENGINE_get_default_DH(void);
ENGINE *ENGINE_get_default_RAND(void);
/* These functions can be used to get a functional reference to perform
@@ -572,6 +583,7 @@ int ENGINE_set_default_string(ENGINE *e, const char *def_list);
int ENGINE_set_default_DSA(ENGINE *e);
int ENGINE_set_default_ECDH(ENGINE *e);
int ENGINE_set_default_ECDSA(ENGINE *e);
+int ENGINE_set_default_EC(ENGINE *e);
int ENGINE_set_default_DH(ENGINE *e);
int ENGINE_set_default_RAND(ENGINE *e);
int ENGINE_set_default_ciphers(ENGINE *e);
diff --git a/lib/libcrypto/engine/tb_eckey.c b/lib/libcrypto/engine/tb_eckey.c
new file mode 100644
index 00000000000..dd30815788f
--- /dev/null
+++ b/lib/libcrypto/engine/tb_eckey.c
@@ -0,0 +1,123 @@
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+static ENGINE_TABLE *ec_table = NULL;
+static const int dummy_nid = 1;
+
+void
+ENGINE_unregister_EC(ENGINE *e)
+{
+ engine_table_unregister(&ec_table, e);
+}
+
+static void
+engine_unregister_all_EC(void)
+{
+ engine_table_cleanup(&ec_table);
+}
+
+int
+ENGINE_register_EC(ENGINE *e)
+{
+ if (e->ec_meth)
+ return engine_table_register(&ec_table,
+ engine_unregister_all_EC, e, &dummy_nid, 1, 0);
+ return 1;
+}
+
+void
+ENGINE_register_all_EC(void)
+{
+ ENGINE *e;
+
+ for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e))
+ ENGINE_register_EC(e);
+}
+
+int
+ENGINE_set_default_EC(ENGINE *e)
+{
+ if (e->ec_meth != NULL)
+ return engine_table_register(&ec_table,
+ engine_unregister_all_EC, e, &dummy_nid, 1, 1);
+ return 1;
+}
+
+/*
+ * Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references).
+ */
+ENGINE *
+ENGINE_get_default_EC(void)
+{
+ return engine_table_select(&ec_table, dummy_nid);
+}
+
+/* Obtains an EC_KEY implementation from an ENGINE functional reference */
+const EC_KEY_METHOD *
+ENGINE_get_EC(const ENGINE *e)
+{
+ return e->ec_meth;
+}
+
+/* Sets an EC_KEY implementation in an ENGINE structure */
+int
+ENGINE_set_EC(ENGINE *e, const EC_KEY_METHOD *ec_meth)
+{
+ e->ec_meth = ec_meth;
+ return 1;
+}