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_lib.c | |
parent | f45846f50036343778d7575578e7115e92a3fce1 (diff) | |
download | openssl-01ad66f85d22fd001582b5f2e6e18db8b820c550.tar.gz |
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_lib.c')
-rw-r--r-- | crypto/ec/ec_lib.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 6a2d1b5800..457cd3593c 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -919,11 +919,38 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) { - if (group->meth->mul == 0) + int ret = 0; + size_t i = 0; + BN_CTX *new_ctx = NULL; + + if ((scalar == NULL) && (num == 0)) { + return EC_POINT_set_to_infinity(group, r); + } + + if (!ec_point_is_compat(r, group)) { + ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + for (i = 0; i < num; i++) { + if (!ec_point_is_compat(points[i], group)) { + ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + } + + if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) { + ECerr(EC_F_EC_POINTS_MUL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (group->meth->mul != NULL) + ret = group->meth->mul(group, r, scalar, num, points, scalars, ctx); + else /* use default */ - return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); + ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); - return group->meth->mul(group, r, scalar, num, points, scalars, ctx); + BN_CTX_free(new_ctx); + return ret; } int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, |