diff options
author | jkim <jkim@FreeBSD.org> | 2015-10-23 19:46:02 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2015-10-23 19:46:02 +0000 |
commit | 64cb0c902e312216cdc4c826fc0be9ba9e1bf4da (patch) | |
tree | ae816a5a768ec78af3610e509ca39507b33aa9f7 /crypto/ecdsa | |
parent | e5911a7a89e76432a8d4607068e9171b30272e08 (diff) | |
download | FreeBSD-src-64cb0c902e312216cdc4c826fc0be9ba9e1bf4da.zip FreeBSD-src-64cb0c902e312216cdc4c826fc0be9ba9e1bf4da.tar.gz |
Import OpenSSL 1.0.2d.
Diffstat (limited to 'crypto/ecdsa')
-rw-r--r-- | crypto/ecdsa/ecdsa.h | 75 | ||||
-rw-r--r-- | crypto/ecdsa/ecs_err.c | 1 | ||||
-rw-r--r-- | crypto/ecdsa/ecs_lib.c | 77 | ||||
-rw-r--r-- | crypto/ecdsa/ecs_locl.h | 6 | ||||
-rw-r--r-- | crypto/ecdsa/ecs_ossl.c | 28 |
5 files changed, 183 insertions, 4 deletions
diff --git a/crypto/ecdsa/ecdsa.h b/crypto/ecdsa/ecdsa.h index faf76b1..c4016ac 100644 --- a/crypto/ecdsa/ecdsa.h +++ b/crypto/ecdsa/ecdsa.h @@ -228,6 +228,80 @@ int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg); void *ECDSA_get_ex_data(EC_KEY *d, int idx); +/** Allocates and initialize a ECDSA_METHOD structure + * \param ecdsa_method pointer to ECDSA_METHOD to copy. (May be NULL) + * \return pointer to a ECDSA_METHOD structure or NULL if an error occurred + */ + +ECDSA_METHOD *ECDSA_METHOD_new(ECDSA_METHOD *ecdsa_method); + +/** frees a ECDSA_METHOD structure + * \param ecdsa_method pointer to the ECDSA_METHOD structure + */ +void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method); + +/** Sets application specific data in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param app application specific data to set + */ + +void ECDSA_METHOD_set_app_data(ECDSA_METHOD *ecdsa_method, void *app); + +/** Returns application specific data from a ECDSA_METHOD structure + * \param ecdsa_method pointer to ECDSA_METHOD structure + * \return pointer to application specific data. + */ + +void *ECDSA_METHOD_get_app_data(ECDSA_METHOD *ecdsa_method); + +/** Set the ECDSA_do_sign function in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param ecdsa_do_sign a funtion of type ECDSA_do_sign + */ + +void ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method, + ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char + *dgst, int dgst_len, + const BIGNUM *inv, + const BIGNUM *rp, + EC_KEY *eckey)); + +/** Set the ECDSA_sign_setup function in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param ecdsa_sign_setup a funtion of type ECDSA_sign_setup + */ + +void ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method, + int (*ecdsa_sign_setup) (EC_KEY *eckey, + BN_CTX *ctx, + BIGNUM **kinv, + BIGNUM **r)); + +/** Set the ECDSA_do_verify function in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param ecdsa_do_verify a funtion of type ECDSA_do_verify + */ + +void ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method, + int (*ecdsa_do_verify) (const unsigned char + *dgst, int dgst_len, + const ECDSA_SIG *sig, + EC_KEY *eckey)); + +void ECDSA_METHOD_set_flags(ECDSA_METHOD *ecdsa_method, int flags); + +/** Set the flags field in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param flags flags value to set + */ + +void ECDSA_METHOD_set_name(ECDSA_METHOD *ecdsa_method, char *name); + +/** Set the name field in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param name name to set + */ + /* BEGIN ERROR CODES */ /* * The following lines are auto generated by the script mkerr.pl. Any changes @@ -242,6 +316,7 @@ void ERR_load_ECDSA_strings(void); # define ECDSA_F_ECDSA_DATA_NEW_METHOD 100 # define ECDSA_F_ECDSA_DO_SIGN 101 # define ECDSA_F_ECDSA_DO_VERIFY 102 +# define ECDSA_F_ECDSA_METHOD_NEW 105 # define ECDSA_F_ECDSA_SIGN_SETUP 103 /* Reason codes. */ diff --git a/crypto/ecdsa/ecs_err.c b/crypto/ecdsa/ecs_err.c index 6fc64a0..f1fa7b5 100644 --- a/crypto/ecdsa/ecs_err.c +++ b/crypto/ecdsa/ecs_err.c @@ -74,6 +74,7 @@ static ERR_STRING_DATA ECDSA_str_functs[] = { {ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD), "ECDSA_DATA_NEW_METHOD"}, {ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN), "ECDSA_do_sign"}, {ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"}, + {ERR_FUNC(ECDSA_F_ECDSA_METHOD_NEW), "ECDSA_METHOD_new"}, {ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"}, {0, NULL} }; diff --git a/crypto/ecdsa/ecs_lib.c b/crypto/ecdsa/ecs_lib.c index 0f2d343..1c02310 100644 --- a/crypto/ecdsa/ecs_lib.c +++ b/crypto/ecdsa/ecs_lib.c @@ -275,3 +275,80 @@ void *ECDSA_get_ex_data(EC_KEY *d, int idx) return NULL; return (CRYPTO_get_ex_data(&ecdsa->ex_data, idx)); } + +ECDSA_METHOD *ECDSA_METHOD_new(ECDSA_METHOD *ecdsa_meth) +{ + ECDSA_METHOD *ret; + + ret = OPENSSL_malloc(sizeof(ECDSA_METHOD)); + if (ret == NULL) { + ECDSAerr(ECDSA_F_ECDSA_METHOD_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (ecdsa_meth) + *ret = *ecdsa_meth; + else { + ret->ecdsa_sign_setup = 0; + ret->ecdsa_do_sign = 0; + ret->ecdsa_do_verify = 0; + ret->name = NULL; + ret->flags = 0; + } + ret->flags |= ECDSA_METHOD_FLAG_ALLOCATED; + return ret; +} + +void ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method, + ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char + *dgst, int dgst_len, + const BIGNUM *inv, + const BIGNUM *rp, + EC_KEY *eckey)) +{ + ecdsa_method->ecdsa_do_sign = ecdsa_do_sign; +} + +void ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method, + int (*ecdsa_sign_setup) (EC_KEY *eckey, + BN_CTX *ctx, + BIGNUM **kinv, + BIGNUM **r)) +{ + ecdsa_method->ecdsa_sign_setup = ecdsa_sign_setup; +} + +void ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method, + int (*ecdsa_do_verify) (const unsigned char + *dgst, int dgst_len, + const ECDSA_SIG *sig, + EC_KEY *eckey)) +{ + ecdsa_method->ecdsa_do_verify = ecdsa_do_verify; +} + +void ECDSA_METHOD_set_flags(ECDSA_METHOD *ecdsa_method, int flags) +{ + ecdsa_method->flags = flags | ECDSA_METHOD_FLAG_ALLOCATED; +} + +void ECDSA_METHOD_set_name(ECDSA_METHOD *ecdsa_method, char *name) +{ + ecdsa_method->name = name; +} + +void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method) +{ + if (ecdsa_method->flags & ECDSA_METHOD_FLAG_ALLOCATED) + OPENSSL_free(ecdsa_method); +} + +void ECDSA_METHOD_set_app_data(ECDSA_METHOD *ecdsa_method, void *app) +{ + ecdsa_method->app_data = app; +} + +void *ECDSA_METHOD_get_app_data(ECDSA_METHOD *ecdsa_method) +{ + return ecdsa_method->app_data; +} diff --git a/crypto/ecdsa/ecs_locl.h b/crypto/ecdsa/ecs_locl.h index 76b2caf..d3a5efc 100644 --- a/crypto/ecdsa/ecs_locl.h +++ b/crypto/ecdsa/ecs_locl.h @@ -79,9 +79,13 @@ struct ecdsa_method { int (*finish) (EC_KEY *eckey); # endif int flags; - char *app_data; + void *app_data; }; +/* The ECDSA_METHOD was allocated and can be freed */ + +# define ECDSA_METHOD_FLAG_ALLOCATED 0x2 + /* * If this flag is set the ECDSA method is FIPS compliant and can be used in * FIPS mode. This is set in the validated module method. If an application diff --git a/crypto/ecdsa/ecs_ossl.c b/crypto/ecdsa/ecs_ossl.c index 4c5fa6b..dd76960 100644 --- a/crypto/ecdsa/ecs_ossl.c +++ b/crypto/ecdsa/ecs_ossl.c @@ -179,10 +179,32 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, while (BN_is_zero(r)); /* compute the inverse of k */ - if (!BN_mod_inverse(k, k, order, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); - goto err; + if (EC_GROUP_get_mont_data(group) != NULL) { + /* + * We want inverse in constant time, therefore we utilize the fact + * order must be prime and use Fermats Little Theorem instead. + */ + if (!BN_set_word(X, 2)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + if (!BN_mod_sub(X, order, X, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + BN_set_flags(X, BN_FLG_CONSTTIME); + if (!BN_mod_exp_mont_consttime + (k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + } else { + if (!BN_mod_inverse(k, k, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } } + /* clear old values if necessary */ if (*rp != NULL) BN_clear_free(*rp); |