diff options
author | Nicola Tuveri <nic.tuv@gmail.com> | 2018-07-08 10:39:39 +0300 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2018-07-16 10:17:40 +0100 |
commit | 01ad66f85d22fd001582b5f2e6e18db8b820c550 (patch) | |
tree | e9fc5b120ead1fc093bcac475ad9f025dff831b2 /crypto/ec/ec_mult.c | |
parent | f45846f50036343778d7575578e7115e92a3fce1 (diff) |
EC2M Lopez-Dahab ladder: use it also for ECDSA verify
By default `ec_scalar_mul_ladder` (which uses the Lopez-Dahab ladder
implementation) is used only for (k * Generator) or (k * VariablePoint).
ECDSA verification uses (a * Generator + b * VariablePoint): this commit
forces the use of `ec_scalar_mul_ladder` also for the ECDSA verification
path, while using the default wNAF implementation for any other case.
With this commit `ec_scalar_mul_ladder` loses the static attribute, and
is added to ec_lcl.h so EC_METHODs can directly use it.
While working on a new custom EC_POINTs_mul implementation, I realized
that many checks (e.g. all the points being compatible with the given
EC_GROUP, creating a temporary BN_CTX if `ctx == NULL`, check for the
corner case `scalar == NULL && num == 0`) were duplicated again and
again in every single implementation (and actually some
implementations lacked some of the tests).
I thought that it makes way more sense for those checks that are
independent from the actual implementation and should always be done, to
be moved in the EC_POINTs_mul wrapper: so this commit also includes
these changes.
Reviewed-by: Andy Polyakov <appro@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6690)
Diffstat (limited to 'crypto/ec/ec_mult.c')
-rw-r--r-- | crypto/ec/ec_mult.c | 41 |
1 files changed, 13 insertions, 28 deletions
diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c index 55cbfa105d..7e1b3650e7 100644 --- a/crypto/ec/ec_mult.c +++ b/crypto/ec/ec_mult.c @@ -121,6 +121,9 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre) * `scalar` cannot be NULL and should be in the range [0,n) otherwise all * constant time bets are off (where n is the cardinality of the EC group). * + * This function expects `group->order` and `group->cardinality` to be well + * defined and non-zero: it fails with an error code otherwise. + * * NB: This says nothing about the constant-timeness of the ladder step * implementation (i.e., the default implementation is based on EC_POINT_add and * EC_POINT_dbl, which of course are not constant time themselves) or the @@ -128,9 +131,11 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre) * * The product is stored in `r`. * + * This is an internal function: callers are in charge of ensuring that the + * input parameters `group`, `r`, `scalar` and `ctx` are not NULL. + * * Returns 1 on success, 0 otherwise. */ -static int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx) @@ -141,15 +146,20 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, BIGNUM *k = NULL; BIGNUM *lambda = NULL; BIGNUM *cardinality = NULL; - BN_CTX *new_ctx = NULL; int ret = 0; /* early exit if the input point is the point at infinity */ if (point != NULL && EC_POINT_is_at_infinity(group, point)) return EC_POINT_set_to_infinity(group, r); - if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) + if (BN_is_zero(group->order)) { + ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_ORDER); return 0; + } + if (BN_is_zero(group->cofactor)) { + ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_COFACTOR); + return 0; + } BN_CTX_start(ctx); @@ -370,7 +380,6 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, EC_POINT_free(p); EC_POINT_free(s); BN_CTX_end(ctx); - BN_CTX_free(new_ctx); return ret; } @@ -402,7 +411,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) { - BN_CTX *new_ctx = NULL; const EC_POINT *generator = NULL; EC_POINT *tmp = NULL; size_t totalnum; @@ -427,15 +435,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, * precomputation is not available */ int ret = 0; - if (!ec_point_is_compat(r, group)) { - ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - - if ((scalar == NULL) && (num == 0)) { - return EC_POINT_set_to_infinity(group, r); - } - if (!BN_is_zero(group->order) && !BN_is_zero(group->cofactor)) { /*- * Handle the common cases where the scalar is secret, enforcing a @@ -465,19 +464,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, } } - for (i = 0; i < num; i++) { - if (!ec_point_is_compat(points[i], group)) { - ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - } - if (scalar != NULL) { generator = EC_GROUP_get0_generator(group); if (generator == NULL) { @@ -784,7 +770,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, ret = 1; err: - BN_CTX_free(new_ctx); EC_POINT_free(tmp); OPENSSL_free(wsize); OPENSSL_free(wNAF_len); |