diff options
author | Theo Buehler <tb@cvs.openbsd.org> | 2019-01-19 01:12:49 +0000 |
---|---|---|
committer | Theo Buehler <tb@cvs.openbsd.org> | 2019-01-19 01:12:49 +0000 |
commit | 941fa43c7de04eb0e1693a810ef5a5bd62e1b29f (patch) | |
tree | 4b1babff2ca1ed47ba21cdff3f5e02e2b9a2dda9 /lib | |
parent | 750422d3073ea431791631d8ce4c9e3ece05dc82 (diff) |
Partial port of EC_KEY_METHOD from OpenSSL 1.1.
This commit adds missing API for ECDH/ECDSA_verify.
from markus
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libcrypto/Symbols.list | 6 | ||||
-rw-r--r-- | lib/libcrypto/ec/ec.h | 12 | ||||
-rw-r--r-- | lib/libcrypto/ec/ec_key.c | 13 | ||||
-rw-r--r-- | lib/libcrypto/ec/ec_kmeth.c | 112 | ||||
-rw-r--r-- | lib/libcrypto/ec/ec_lcl.h | 17 | ||||
-rw-r--r-- | lib/libcrypto/ecdh/ech_key.c | 22 | ||||
-rw-r--r-- | lib/libcrypto/ecdsa/ecdsa.h | 13 | ||||
-rw-r--r-- | lib/libcrypto/ecdsa/ecs_ossl.c | 42 | ||||
-rw-r--r-- | lib/libcrypto/ecdsa/ecs_vrf.c | 39 |
9 files changed, 213 insertions, 63 deletions
diff --git a/lib/libcrypto/Symbols.list b/lib/libcrypto/Symbols.list index 2734fed62a2..98518fcf725 100644 --- a/lib/libcrypto/Symbols.list +++ b/lib/libcrypto/Symbols.list @@ -956,11 +956,17 @@ EC_GROUP_set_generator EC_GROUP_set_point_conversion_form EC_GROUP_set_seed EC_KEY_METHOD_free +EC_KEY_METHOD_get_compute_key EC_KEY_METHOD_get_init +EC_KEY_METHOD_get_keygen EC_KEY_METHOD_get_sign +EC_KEY_METHOD_get_verify EC_KEY_METHOD_new +EC_KEY_METHOD_set_compute_key EC_KEY_METHOD_set_init +EC_KEY_METHOD_set_keygen EC_KEY_METHOD_set_sign +EC_KEY_METHOD_set_verify EC_KEY_OpenSSL EC_KEY_check_key EC_KEY_clear_flags diff --git a/lib/libcrypto/ec/ec.h b/lib/libcrypto/ec/ec.h index 1173459dae2..0b8d2cb3555 100644 --- a/lib/libcrypto/ec/ec.h +++ b/lib/libcrypto/ec/ec.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ec.h,v 1.14 2019/01/19 01:07:00 tb Exp $ */ +/* $OpenBSD: ec.h,v 1.15 2019/01/19 01:12:48 tb Exp $ */ /* * Originally written by Bodo Moeller for the OpenSSL project. */ @@ -966,6 +966,11 @@ void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, 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_set_keygen(EC_KEY_METHOD *meth, + int (*keygen)(EC_KEY *key)); +void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, + int (*ckey)(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen))); void EC_KEY_METHOD_get_init(EC_KEY_METHOD *meth, int (**pinit)(EC_KEY *key), void (**pfinish)(EC_KEY *key), @@ -973,6 +978,11 @@ void EC_KEY_METHOD_get_init(EC_KEY_METHOD *meth, 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)); +void EC_KEY_METHOD_get_keygen(EC_KEY_METHOD *meth, + int (**pkeygen)(EC_KEY *key)); +void EC_KEY_METHOD_get_compute_key(EC_KEY_METHOD *meth, + int (**pck)(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen))); EC_KEY *ECParameters_dup(EC_KEY *key); diff --git a/lib/libcrypto/ec/ec_key.c b/lib/libcrypto/ec/ec_key.c index f57e078c7f9..1d0a03ac883 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.23 2019/01/19 01:07:00 tb Exp $ */ +/* $OpenBSD: ec_key.c,v 1.24 2019/01/19 01:12:48 tb Exp $ */ /* * Written by Nils Larsch for the OpenSSL project. */ @@ -247,9 +247,18 @@ EC_KEY_get_ex_data(const EC_KEY *r, int idx) return CRYPTO_get_ex_data(&r->ex_data, idx); } -int +int EC_KEY_generate_key(EC_KEY *eckey) { + if (eckey->meth->keygen != NULL) + return eckey->meth->keygen(eckey); + ECerror(EC_R_NOT_IMPLEMENTED); + return 0; +} + +int +ossl_ec_key_gen(EC_KEY *eckey) +{ int ok = 0; BN_CTX *ctx = NULL; BIGNUM *priv_key = NULL, *order = NULL; diff --git a/lib/libcrypto/ec/ec_kmeth.c b/lib/libcrypto/ec/ec_kmeth.c index b714c622364..158f542d40e 100644 --- a/lib/libcrypto/ec/ec_kmeth.c +++ b/lib/libcrypto/ec/ec_kmeth.c @@ -72,9 +72,15 @@ static const EC_KEY_METHOD openssl_ec_key_method = { .set_private = NULL, .set_public = NULL, + .keygen = ossl_ec_key_gen, + .compute_key = ossl_ecdh_compute_key, + .sign = ossl_ecdsa_sign, .sign_setup = ossl_ecdsa_sign_setup, .sign_sig = ossl_ecdsa_sign_sig, + + .verify = ossl_ecdsa_verify, + .verify_sig = ossl_ecdsa_verify_sig, }; const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method; @@ -197,6 +203,65 @@ 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)) +{ + 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_set_keygen(EC_KEY_METHOD *meth, int (*keygen)(EC_KEY *key)) +{ + meth->keygen = keygen; +} + +void +EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, + int (*ckey)(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen))) +{ + meth->compute_key = ckey; +} + +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; +} + +void +EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth, + int (*verify)(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey), + int (*verify_sig)(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey)) +{ + meth->verify = verify; + meth->verify_sig = verify_sig; +} + + +void EC_KEY_METHOD_get_init(EC_KEY_METHOD *meth, int (**pinit)(EC_KEY *key), void (**pfinish)(EC_KEY *key), @@ -220,20 +285,20 @@ EC_KEY_METHOD_get_init(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)) +EC_KEY_METHOD_get_keygen(EC_KEY_METHOD *meth, + int (**pkeygen)(EC_KEY *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; + if (pkeygen != NULL) + *pkeygen = meth->keygen; +} + +void +EC_KEY_METHOD_get_compute_key(EC_KEY_METHOD *meth, + int (**pck)(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen))) +{ + if (pck != NULL) + *pck = meth->compute_key; } void @@ -256,17 +321,14 @@ EC_KEY_METHOD_get_sign(EC_KEY_METHOD *meth, } 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)) +EC_KEY_METHOD_get_verify(EC_KEY_METHOD *meth, + int (**pverify)(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey), + int (**pverify_sig)(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey)) { - meth->sign = sign; - meth->sign_setup = sign_setup; - meth->sign_sig = sign_sig; + if (pverify != NULL) + *pverify = meth->verify; + if (pverify_sig != NULL) + *pverify_sig = meth->verify_sig; } diff --git a/lib/libcrypto/ec/ec_lcl.h b/lib/libcrypto/ec/ec_lcl.h index cff0892e892..8948e51d698 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.12 2019/01/19 01:07:00 tb Exp $ */ +/* $OpenBSD: ec_lcl.h,v 1.13 2019/01/19 01:12:48 tb Exp $ */ /* * Originally written by Bodo Moeller for the OpenSSL project. */ @@ -457,6 +457,9 @@ struct ec_key_method_st { 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 (*keygen)(EC_KEY *key); + int (*compute_key)(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen)); 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); @@ -465,10 +468,22 @@ struct ec_key_method_st { ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey); + int (*verify)(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); + int (*verify_sig)(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); } /* EC_KEY_METHOD */; #define EC_KEY_METHOD_DYNAMIC 1 +int ossl_ec_key_gen(EC_KEY *eckey); +int ossl_ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, void *out, size_t *outlen)); +int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey); +int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); + /* 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/ecdh/ech_key.c b/lib/libcrypto/ecdh/ech_key.c index 6911f1e3419..378912cacba 100644 --- a/lib/libcrypto/ecdh/ech_key.c +++ b/lib/libcrypto/ecdh/ech_key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ech_key.c,v 1.8 2018/09/02 17:20:31 tb Exp $ */ +/* $OpenBSD: ech_key.c,v 1.9 2019/01/19 01:12:48 tb Exp $ */ /* ==================================================================== * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. * @@ -78,6 +78,7 @@ #include <openssl/sha.h> #include "ech_locl.h" +#include "ec_lcl.h" static int ecdh_compute_key(void *out, size_t len, const EC_POINT *pub_key, EC_KEY *ecdh, @@ -215,13 +216,26 @@ ECDH_OpenSSL(void) return &openssl_ecdh_meth; } +/* replace w/ ecdh_compute_key() when ECDH_METHOD gets removed */ int -ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, +ossl_ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *eckey, void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)) { - ECDH_DATA *ecdh = ecdh_check(eckey); - if (ecdh == NULL) + ECDH_DATA *ecdh; + + if ((ecdh = ecdh_check(eckey)) == NULL) return 0; return ecdh->meth->compute_key(out, outlen, pub_key, eckey, KDF); } + +int +ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + EC_KEY *eckey, + void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)) +{ + if (eckey->meth->compute_key != NULL) + return eckey->meth->compute_key(out, outlen, pub_key, eckey, KDF); + ECerror(EC_R_NOT_IMPLEMENTED); + return 0; +} diff --git a/lib/libcrypto/ecdsa/ecdsa.h b/lib/libcrypto/ecdsa/ecdsa.h index 12d6677ce3a..71b8825436b 100644 --- a/lib/libcrypto/ecdsa/ecdsa.h +++ b/lib/libcrypto/ecdsa/ecdsa.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ecdsa.h,v 1.6 2019/01/19 01:07:00 tb Exp $ */ +/* $OpenBSD: ecdsa.h,v 1.7 2019/01/19 01:12:48 tb Exp $ */ /** * \file crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions * \author Written by Nils Larsch for the OpenSSL project @@ -279,6 +279,11 @@ void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, 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_set_verify(EC_KEY_METHOD *meth, + int (*verify)(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey), + int (*verify_sig)(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, 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, @@ -288,6 +293,12 @@ void EC_KEY_METHOD_get_sign(EC_KEY_METHOD *meth, ECDSA_SIG *(**psign_sig)(const unsigned char *dgst, int dgst_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)); +void EC_KEY_METHOD_get_verify(EC_KEY_METHOD *meth, + int (**pverify)(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey), + int (**pverify_sig)(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey)); + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes diff --git a/lib/libcrypto/ecdsa/ecs_ossl.c b/lib/libcrypto/ecdsa/ecs_ossl.c index 4e05cb9aac4..791a5c48e1f 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.17 2019/01/19 01:07:00 tb Exp $ */ +/* $OpenBSD: ecs_ossl.c,v 1.18 2019/01/19 01:12:48 tb Exp $ */ /* * Written by Nils Larsch for the OpenSSL project */ @@ -56,6 +56,8 @@ * */ +#include <string.h> + #include <openssl/opensslconf.h> #include <openssl/err.h> @@ -421,6 +423,32 @@ ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, return ecdsa->meth->ecdsa_do_sign(dgst, dgst_len, in_kinv, in_r, eckey); } +int +ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) +{ + ECDSA_SIG *s; + unsigned char *der = NULL; + const unsigned char *p = sigbuf; + int derlen = -1; + int ret = -1; + + if ((s = ECDSA_SIG_new()) == NULL) + return (ret); + if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) + goto err; + /* Ensure signature uses DER and doesn't have trailing garbage */ + derlen = i2d_ECDSA_SIG(s, &der); + if (derlen != sig_len || memcmp(sigbuf, der, derlen)) + goto err; + ret = ECDSA_do_verify(dgst, dgst_len, s, eckey); + + err: + freezero(der, derlen); + ECDSA_SIG_free(s); + return (ret); +} + static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey) @@ -524,3 +552,15 @@ ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_POINT_free(point); return ret; } + +/* replace w/ ecdsa_do_verify() when ECDSA_METHOD gets removed */ +int +ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) +{ + ECDSA_DATA *ecdsa; + + if ((ecdsa = ecdsa_check(eckey)) == NULL) + return 0; + return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey); +} diff --git a/lib/libcrypto/ecdsa/ecs_vrf.c b/lib/libcrypto/ecdsa/ecs_vrf.c index 270af94c0da..4c1bc85e068 100644 --- a/lib/libcrypto/ecdsa/ecs_vrf.c +++ b/lib/libcrypto/ecdsa/ecs_vrf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ecs_vrf.c,v 1.6 2017/05/02 03:59:44 deraadt Exp $ */ +/* $OpenBSD: ecs_vrf.c,v 1.7 2019/01/19 01:12:48 tb Exp $ */ /* * Written by Nils Larsch for the OpenSSL project */ @@ -56,10 +56,10 @@ * */ -#include <string.h> #include <openssl/opensslconf.h> #include "ecs_locl.h" +#include "ec_lcl.h" #ifndef OPENSSL_NO_ENGINE #include <openssl/engine.h> #endif @@ -73,11 +73,10 @@ int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey) { - ECDSA_DATA *ecdsa = ecdsa_check(eckey); - - if (ecdsa == NULL) - return 0; - return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey); + if (eckey->meth->verify_sig != NULL) + return eckey->meth->verify_sig(dgst, dgst_len, sig, eckey); + ECDSAerror(EVP_R_METHOD_NOT_SUPPORTED); + return 0; } /* returns @@ -89,25 +88,9 @@ int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len, const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) { - ECDSA_SIG *s; - unsigned char *der = NULL; - const unsigned char *p = sigbuf; - int derlen = -1; - int ret = -1; - - s = ECDSA_SIG_new(); - if (s == NULL) - return (ret); - if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) - goto err; - /* Ensure signature uses DER and doesn't have trailing garbage */ - derlen = i2d_ECDSA_SIG(s, &der); - if (derlen != sig_len || memcmp(sigbuf, der, derlen)) - goto err; - ret = ECDSA_do_verify(dgst, dgst_len, s, eckey); - -err: - freezero(der, derlen); - ECDSA_SIG_free(s); - return (ret); + if (eckey->meth->verify != NULL) + return eckey->meth->verify(type, dgst, dgst_len, + sigbuf, sig_len, eckey); + ECDSAerror(EVP_R_METHOD_NOT_SUPPORTED); + return 0; } |