diff options
author | Andy Polyakov <appro@openssl.org> | 2014-09-12 00:13:20 +0200 |
---|---|---|
committer | Andy Polyakov <appro@openssl.org> | 2014-09-12 00:13:20 +0200 |
commit | f54be179aa4cbbd944728771d7d59ed588158a12 (patch) | |
tree | 0dc5e2fa108f0db85230a0ce2d040eb7597642b4 /crypto/ec/ec_lib.c | |
parent | 902b30df193afc3417a96ba72a81ed390bd50de3 (diff) |
Reserve option to use BN_mod_exp_mont_consttime in ECDSA.
Submitted by Shay Gueron, Intel Corp.
RT: 3149
Reviewed-by: Rich Salz <rsalz@openssl.org>
Diffstat (limited to 'crypto/ec/ec_lib.c')
-rw-r--r-- | crypto/ec/ec_lib.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index a295a84f2b..0a182d4229 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -101,6 +101,7 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) ret->meth = meth; ret->extra_data = NULL; + ret->mont_data = NULL; ret->generator = NULL; BN_init(&ret->order); @@ -132,6 +133,9 @@ void EC_GROUP_free(EC_GROUP *group) EC_EX_DATA_free_all_data(&group->extra_data); + if (group->mont_data) + BN_MONT_CTX_free(group->mont_data); + if (group->generator != NULL) EC_POINT_free(group->generator); BN_free(&group->order); @@ -155,6 +159,9 @@ void EC_GROUP_clear_free(EC_GROUP *group) EC_EX_DATA_clear_free_all_data(&group->extra_data); + if (group->mont_data) + BN_MONT_CTX_free(group->mont_data); + if (group->generator != NULL) EC_POINT_clear_free(group->generator); BN_clear_free(&group->order); @@ -200,6 +207,25 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) return 0; } + if (src->mont_data != NULL) + { + if (dest->mont_data == NULL) + { + dest->mont_data = BN_MONT_CTX_new(); + if (dest->mont_data == NULL) return 0; + } + if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data)) return 0; + } + else + { + /* src->generator == NULL */ + if (dest->mont_data != NULL) + { + BN_MONT_CTX_free(dest->mont_data); + dest->mont_data = NULL; + } + } + if (src->generator != NULL) { if (dest->generator == NULL) @@ -309,6 +335,11 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIG else BN_zero(&group->cofactor); + /* We ignore the return value because some groups have an order with + * factors of two, which makes the Montgomery setup fail. + * |group->mont_data| will be NULL in this case. */ + ec_precompute_mont_data(group); + return 1; } @@ -318,6 +349,10 @@ const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) return group->generator; } +BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group) + { + return group->mont_data; + } int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { @@ -1097,3 +1132,39 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group) else return 0; /* cannot tell whether precomputation has been performed */ } + +/* ec_precompute_mont_data sets |group->mont_data| from |group->order| and + * returns one on success. On error it returns zero. */ +int ec_precompute_mont_data(EC_GROUP *group) + { + BN_CTX *ctx = BN_CTX_new(); + int ret = 0; + + if (group->mont_data) + { + BN_MONT_CTX_free(group->mont_data); + group->mont_data = NULL; + } + + if (ctx == NULL) + goto err; + + group->mont_data = BN_MONT_CTX_new(); + if (!group->mont_data) + goto err; + + if (!BN_MONT_CTX_set(group->mont_data, &group->order, ctx)) + { + BN_MONT_CTX_free(group->mont_data); + group->mont_data = NULL; + goto err; + } + + ret = 1; + +err: + + if (ctx) + BN_CTX_free(ctx); + return ret; + } |