Push BIGNUM out of EC_METHOD's affine coordinates hook. This is in preparation for removing the BIGNUM from cmp_x_coordinate. Change-Id: Id8394248e3019a4897c238289f039f436a13679d Reviewed-on: https://boringssl-review.googlesource.com/c/33064 Reviewed-by: Adam Langley <agl@google.com> Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/fipsmodule/ec/ec.c b/crypto/fipsmodule/ec/ec.c index eecd76b..ba101fe 100644 --- a/crypto/fipsmodule/ec/ec.c +++ b/crypto/fipsmodule/ec/ec.c
@@ -743,7 +743,15 @@ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); return 0; } - return group->meth->point_get_affine_coordinates(group, &point->raw, x, y); + EC_FELEM x_felem, y_felem; + if (!group->meth->point_get_affine_coordinates(group, &point->raw, + x == NULL ? NULL : &x_felem, + y == NULL ? NULL : &y_felem) || + (x != NULL && !bn_set_words(x, x_felem.words, group->field.width)) || + (y != NULL && !bn_set_words(y, y_felem.words, group->field.width))) { + return 0; + } + return 1; } int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
diff --git a/crypto/fipsmodule/ec/ec_montgomery.c b/crypto/fipsmodule/ec/ec_montgomery.c index 90bd8ce..4961a7c 100644 --- a/crypto/fipsmodule/ec/ec_montgomery.c +++ b/crypto/fipsmodule/ec/ec_montgomery.c
@@ -182,7 +182,7 @@ static int ec_GFp_mont_point_get_affine_coordinates(const EC_GROUP *group, const EC_RAW_POINT *point, - BIGNUM *x, BIGNUM *y) { + EC_FELEM *x, EC_FELEM *y) { if (ec_GFp_simple_is_at_infinity(group, point)) { OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); return 0; @@ -201,20 +201,12 @@ ec_GFp_mont_felem_from_montgomery(group, &z1, &z1); if (x != NULL) { - EC_FELEM tmp; - ec_GFp_mont_felem_mul(group, &tmp, &point->X, &z1); - if (!bn_set_words(x, tmp.words, group->field.width)) { - return 0; - } + ec_GFp_mont_felem_mul(group, x, &point->X, &z1); } if (y != NULL) { - EC_FELEM tmp; ec_GFp_mont_felem_mul(group, &z1, &z1, &z2); - ec_GFp_mont_felem_mul(group, &tmp, &point->Y, &z1); - if (!bn_set_words(y, tmp.words, group->field.width)) { - return 0; - } + ec_GFp_mont_felem_mul(group, y, &point->Y, &z1); } return 1;
diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h index 056fa7c..4afaef9 100644 --- a/crypto/fipsmodule/ec/internal.h +++ b/crypto/fipsmodule/ec/internal.h
@@ -124,8 +124,15 @@ void (*group_finish)(EC_GROUP *); int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); - int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_RAW_POINT *, - BIGNUM *x, BIGNUM *y); + + // point_get_affine_coordinates sets |*x| and |*y| to the affine coordinates + // of |p|. Either |x| or |y| may be NULL to omit it. It returns one on success + // and zero if |p| is the point at infinity. + // + // Note: unlike |EC_FELEM|s used as intermediate values internal to the + // |EC_METHOD|, |*x| and |*y| are not encoded in Montgomery form. + int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_RAW_POINT *p, + EC_FELEM *x, EC_FELEM *y); // add sets |r| to |a| + |b|. void (*add)(const EC_GROUP *group, EC_RAW_POINT *r, const EC_RAW_POINT *a,
diff --git a/crypto/fipsmodule/ec/p224-64.c b/crypto/fipsmodule/ec/p224-64.c index 27bfc36..49d5328 100644 --- a/crypto/fipsmodule/ec/p224-64.c +++ b/crypto/fipsmodule/ec/p224-64.c
@@ -203,13 +203,6 @@ } } -// From internal representation to OpenSSL BIGNUM -static BIGNUM *p224_felem_to_BN(BIGNUM *out, const p224_felem in) { - p224_felem_bytearray b_out; - p224_felem_to_bin28(b_out, in); - return BN_le2bn(b_out, sizeof(b_out), out); -} - static void p224_generic_to_felem(p224_felem out, const EC_FELEM *in) { p224_bin28_to_felem(out, in->bytes); } @@ -971,7 +964,8 @@ // Takes the Jacobian coordinates (X, Y, Z) of a point and returns // (X', Y') = (X/Z^2, Y/Z^3) static int ec_GFp_nistp224_point_get_affine_coordinates( - const EC_GROUP *group, const EC_RAW_POINT *point, BIGNUM *x, BIGNUM *y) { + const EC_GROUP *group, const EC_RAW_POINT *point, EC_FELEM *x, + EC_FELEM *y) { if (ec_GFp_simple_is_at_infinity(group, point)) { OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); return 0; @@ -990,10 +984,7 @@ p224_felem_mul(tmp, x_in, z1); p224_felem_reduce(x_in, tmp); p224_felem_contract(x_out, x_in); - if (!p224_felem_to_BN(x, x_out)) { - OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); - return 0; - } + p224_felem_to_generic(x, x_out); } if (y != NULL) { @@ -1004,10 +995,7 @@ p224_felem_mul(tmp, y_in, z1); p224_felem_reduce(y_in, tmp); p224_felem_contract(y_out, y_in); - if (!p224_felem_to_BN(y, y_out)) { - OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); - return 0; - } + p224_felem_to_generic(y, y_out); } return 1;
diff --git a/crypto/fipsmodule/ec/p256-x86_64.c b/crypto/fipsmodule/ec/p256-x86_64.c index 265904c..e7f4909 100644 --- a/crypto/fipsmodule/ec/p256-x86_64.c +++ b/crypto/fipsmodule/ec/p256-x86_64.c
@@ -444,8 +444,8 @@ } static int ecp_nistz256_get_affine(const EC_GROUP *group, - const EC_RAW_POINT *point, BIGNUM *x, - BIGNUM *y) { + const EC_RAW_POINT *point, EC_FELEM *x, + EC_FELEM *y) { if (ec_GFp_simple_is_at_infinity(group, point)) { OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); return 0; @@ -464,22 +464,12 @@ ecp_nistz256_from_mont(z_inv2, z_inv2); if (x != NULL) { - BN_ULONG x_aff[P256_LIMBS]; - ecp_nistz256_mul_mont(x_aff, z_inv2, point->X.words); - if (!bn_set_words(x, x_aff, P256_LIMBS)) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - return 0; - } + ecp_nistz256_mul_mont(x->words, z_inv2, point->X.words); } if (y != NULL) { - BN_ULONG y_aff[P256_LIMBS]; ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2); - ecp_nistz256_mul_mont(y_aff, z_inv3, point->Y.words); - if (!bn_set_words(y, y_aff, P256_LIMBS)) { - OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); - return 0; - } + ecp_nistz256_mul_mont(y->words, z_inv3, point->Y.words); } return 1;
diff --git a/third_party/fiat/p256.c b/third_party/fiat/p256.c index b6f3f49..c8e42a3 100644 --- a/third_party/fiat/p256.c +++ b/third_party/fiat/p256.c
@@ -895,14 +895,6 @@ fe_mul(x, x, kOne); } -// BN_* compatability wrappers - -static BIGNUM *fe_to_BN(BIGNUM *out, const fe in) { - uint8_t tmp[NBYTES]; - fe_tobytes(tmp, in); - return BN_le2bn(tmp, NBYTES, out); -} - static void fe_from_generic(fe out, const EC_FELEM *in) { fe_frombytes(out, in->bytes); } @@ -1631,8 +1623,8 @@ // Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = // (X/Z^2, Y/Z^3). static int ec_GFp_nistp256_point_get_affine_coordinates( - const EC_GROUP *group, const EC_RAW_POINT *point, BIGNUM *x_out, - BIGNUM *y_out) { + const EC_GROUP *group, const EC_RAW_POINT *point, EC_FELEM *x_out, + EC_FELEM *y_out) { if (ec_GFp_simple_is_at_infinity(group, point)) { OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); return 0; @@ -1652,10 +1644,7 @@ fe x; fe_from_generic(x, &point->X); fe_mul(x, x, z1); - if (!fe_to_BN(x_out, x)) { - OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); - return 0; - } + fe_to_generic(x_out, x); } if (y_out != NULL) { @@ -1663,10 +1652,7 @@ fe_from_generic(y, &point->Y); fe_mul(z1, z1, z2); fe_mul(y, y, z1); - if (!fe_to_BN(y_out, y)) { - OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); - return 0; - } + fe_to_generic(y_out, y); } return 1;