From eaa93660fa7be62891e2623769b71e381fdff5ff Mon Sep 17 00:00:00 2001 From: tb <> Date: Sat, 17 Nov 2018 18:55:41 +0000 Subject: Implement coordinate blinding for EC_POINT as an additional mitigation for the portsmash vulnerability. OpenBSD 6.4 errata 003 --- src/lib/libcrypto/ec/ecp_smpl.c | 74 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) (limited to 'src/lib/libcrypto/ec/ecp_smpl.c') diff --git a/src/lib/libcrypto/ec/ecp_smpl.c b/src/lib/libcrypto/ec/ecp_smpl.c index a25fd1df84..c2049ec2df 100644 --- a/src/lib/libcrypto/ec/ecp_smpl.c +++ b/src/lib/libcrypto/ec/ecp_smpl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ecp_smpl.c,v 1.22 2018/07/16 17:32:39 tb Exp $ */ +/* $OpenBSD: ecp_smpl.c,v 1.22.2.1 2018/11/17 18:55:41 tb Exp $ */ /* Includes code written by Lenka Fibikova * for the OpenSSL project. * Includes code written by Bodo Moeller for the OpenSSL project. @@ -107,7 +107,8 @@ EC_GFp_simple_method(void) .mul_single_ct = ec_GFp_simple_mul_single_ct, .mul_double_nonct = ec_GFp_simple_mul_double_nonct, .field_mul = ec_GFp_simple_field_mul, - .field_sqr = ec_GFp_simple_field_sqr + .field_sqr = ec_GFp_simple_field_sqr, + .blind_coordinates = ec_GFp_simple_blind_coordinates, }; return &ret; @@ -1406,13 +1407,73 @@ ec_GFp_simple_field_mul(const EC_GROUP * group, BIGNUM * r, const BIGNUM * a, co return BN_mod_mul(r, a, b, &group->field, ctx); } - int ec_GFp_simple_field_sqr(const EC_GROUP * group, BIGNUM * r, const BIGNUM * a, BN_CTX * ctx) { return BN_mod_sqr(r, a, &group->field, ctx); } +/* + * Apply randomization of EC point projective coordinates: + * + * (X, Y, Z) = (lambda^2 * X, lambda^3 * Y, lambda * Z) + * + * where lambda is in the interval [1, group->field). + */ +int +ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) +{ + BIGNUM *lambda = NULL; + BIGNUM *tmp = NULL; + int ret = 0; + + BN_CTX_start(ctx); + if ((lambda = BN_CTX_get(ctx)) == NULL) + goto err; + if ((tmp = BN_CTX_get(ctx)) == NULL) + goto err; + + /* Generate lambda in [1, group->field - 1] */ + do { + if (!BN_rand_range(lambda, &group->field)) + goto err; + } while (BN_is_zero(lambda)); + + if (group->meth->field_encode != NULL && + !group->meth->field_encode(group, lambda, lambda, ctx)) + goto err; + + /* Z = lambda * Z */ + if (!group->meth->field_mul(group, &p->Z, lambda, &p->Z, ctx)) + goto err; + + /* tmp = lambda^2 */ + if (!group->meth->field_sqr(group, tmp, lambda, ctx)) + goto err; + + /* X = lambda^2 * X */ + if (!group->meth->field_mul(group, &p->X, tmp, &p->X, ctx)) + goto err; + + /* tmp = lambda^3 */ + if (!group->meth->field_mul(group, tmp, tmp, lambda, ctx)) + goto err; + + /* Y = lambda^3 * Y */ + if (!group->meth->field_mul(group, &p->Y, tmp, &p->Y, ctx)) + goto err; + + /* Disable optimized arithmetics after replacing Z by lambda * Z. */ + p->Z_is_one = 0; + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + + #define EC_POINT_BN_set_flags(P, flags) do { \ BN_set_flags(&(P)->X, (flags)); \ BN_set_flags(&(P)->Y, (flags)); \ @@ -1537,6 +1598,13 @@ ec_GFp_simple_mul_ct(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, (bn_wexpand(&r->Z, group_top) == NULL)) goto err; + /* + * Apply coordinate blinding for EC_POINT if the underlying EC_METHOD + * implements it. + */ + if (!ec_point_blind_coordinates(group, s, ctx)) + goto err; + /* top bit is a 1, in a fixed pos */ if (!EC_POINT_copy(r, s)) goto err; -- cgit v1.2.3-55-g6feb