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;