Fix build when bcm.c is split up.

Some of the ec files now reference ECDSA_R_BAD_SIGNATURE. Instead, lift the
error-pushing to ecdsa.c.

Change-Id: Ice3e7a22c5099756599df0ab0b215c0752ada4ee
Reviewed-on: https://boringssl-review.googlesource.com/c/32984
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@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 4c557a1..9644abe 100644
--- a/crypto/fipsmodule/ec/ec.c
+++ b/crypto/fipsmodule/ec/ec.c
@@ -911,9 +911,9 @@
   return 1;
 }
 
-int ec_cmp_x_coordinate(const EC_GROUP *group, const EC_POINT *p,
-                        const BIGNUM *r, BN_CTX *ctx) {
-  return group->meth->cmp_x_coordinate(group, p, r, ctx);
+int ec_cmp_x_coordinate(int *out_result, const EC_GROUP *group,
+                        const EC_POINT *p, const BIGNUM *r, BN_CTX *ctx) {
+  return group->meth->cmp_x_coordinate(out_result, group, p, r, ctx);
 }
 
 int ec_field_element_to_scalar(const EC_GROUP *group, BIGNUM *r) {
diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h
index 0588fb5..e84e670 100644
--- a/crypto/fipsmodule/ec/internal.h
+++ b/crypto/fipsmodule/ec/internal.h
@@ -179,9 +179,10 @@
                                        const EC_SCALAR *in);
 
   // cmp_x_coordinate compares the x (affine) coordinate of |p|, mod the group
-  // order, with |r|. It returns one if they are equal and zero otherwise.
-  int (*cmp_x_coordinate)(const EC_GROUP *group, const EC_POINT *p,
-                          const BIGNUM *r, BN_CTX *ctx);
+  // order, with |r|. On error it returns zero. Otherwise it sets |*out_result|
+  // to one iff the values match.
+  int (*cmp_x_coordinate)(int *out_result, const EC_GROUP *group,
+                          const EC_POINT *p, const BIGNUM *r, BN_CTX *ctx);
 } /* EC_METHOD */;
 
 const EC_METHOD *EC_GFp_mont_method(void);
@@ -308,10 +309,10 @@
     const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx);
 
 // ec_cmp_x_coordinate compares the x (affine) coordinate of |p| with |r|. It
-// returns one if they are equal and zero otherwise. The |ctx| must have been
-// started by the caller.
-int ec_cmp_x_coordinate(const EC_GROUP *group, const EC_POINT *p,
-                        const BIGNUM *r, BN_CTX *ctx);
+// returns zero on error. Otherwise it sets |*out_result| to one iff the values
+// match.
+int ec_cmp_x_coordinate(int *out_result, const EC_GROUP *group,
+                        const EC_POINT *p, const BIGNUM *r, BN_CTX *ctx);
 
 // ec_field_element_to_scalar reduces |r| modulo |group->order|. |r| must
 // previously have been reduced modulo |group->field|.
@@ -365,9 +366,11 @@
                                            const EC_SCALAR *a);
 
 // ec_GFp_simple_cmp_x_coordinate compares the x (affine) coordinate of |p|, mod
-// the group order, with |r|. It returns one on success or zero otherwise.
-int ec_GFp_simple_cmp_x_coordinate(const EC_GROUP *group, const EC_POINT *p,
-                                   const BIGNUM *r, BN_CTX *ctx);
+// the group order, with |r|. It returns zero on error. Otherwise it sets
+// |*out_result| to one iff the values match.
+int ec_GFp_simple_cmp_x_coordinate(int *out_result, const EC_GROUP *group,
+                                   const EC_POINT *p, const BIGNUM *r,
+                                   BN_CTX *ctx);
 
 // method functions in montgomery.c
 int ec_GFp_mont_group_init(EC_GROUP *);
diff --git a/crypto/fipsmodule/ec/p256-x86_64.c b/crypto/fipsmodule/ec/p256-x86_64.c
index 4008aa4..265904c 100644
--- a/crypto/fipsmodule/ec/p256-x86_64.c
+++ b/crypto/fipsmodule/ec/p256-x86_64.c
@@ -610,9 +610,11 @@
   return 1;
 }
 
-static int ecp_nistz256_cmp_x_coordinate(const EC_GROUP *group,
+static int ecp_nistz256_cmp_x_coordinate(int *out_result, const EC_GROUP *group,
                                          const EC_POINT *p, const BIGNUM *r,
                                          BN_CTX *ctx) {
+  *out_result = 0;
+
   if (ec_GFp_simple_is_at_infinity(group, &p->raw)) {
     OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
     return 0;
@@ -632,6 +634,7 @@
   ecp_nistz256_from_mont(X, p->raw.X.words);
 
   if (OPENSSL_memcmp(r_Z2, X, sizeof(r_Z2)) == 0) {
+    *out_result = 1;
     return 1;
   }
 
@@ -652,12 +655,12 @@
     bn_add_words(r_words, r_words, P256_ORDER, P256_LIMBS);
     ecp_nistz256_mul_mont(r_Z2, r_words, Z2_mont);
     if (OPENSSL_memcmp(r_Z2, X, sizeof(r_Z2)) == 0) {
+      *out_result = 1;
       return 1;
     }
   }
 
-  OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
-  return 0;
+  return 1;
 }
 
 DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistz256_method) {
diff --git a/crypto/fipsmodule/ec/simple.c b/crypto/fipsmodule/ec/simple.c
index f875f22..93a0d72 100644
--- a/crypto/fipsmodule/ec/simple.c
+++ b/crypto/fipsmodule/ec/simple.c
@@ -372,9 +372,10 @@
 
 // Compares the x (affine) coordinate of the point p with x.
 // Return 1 on success 0 otherwise
-// Assumption: the caller starts the BN_CTX.
-int ec_GFp_simple_cmp_x_coordinate(const EC_GROUP *group, const EC_POINT *p,
-                                   const BIGNUM *r, BN_CTX *ctx) {
+int ec_GFp_simple_cmp_x_coordinate(int *out_result, const EC_GROUP *group,
+                                   const EC_POINT *p, const BIGNUM *r,
+                                   BN_CTX *ctx) {
+  *out_result = 0;
   int ret = 0;
   BN_CTX_start(ctx);
 
@@ -395,11 +396,7 @@
   }
 
   // The signature is correct iff |X| is equal to |r|.
-  if (BN_ucmp(X, r) != 0) {
-    OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
-    goto out;
-  }
-
+  *out_result = (BN_ucmp(X, r) == 0);
   ret = 1;
 
 out:
diff --git a/crypto/fipsmodule/ecdsa/ecdsa.c b/crypto/fipsmodule/ecdsa/ecdsa.c
index 7ec4565..80371c3 100644
--- a/crypto/fipsmodule/ecdsa/ecdsa.c
+++ b/crypto/fipsmodule/ecdsa/ecdsa.c
@@ -191,7 +191,18 @@
     goto err;
   }
 
-  ret = ec_cmp_x_coordinate(group, point, sig->r, ctx);
+  int match;
+  if (!ec_cmp_x_coordinate(&match, group, point, sig->r, ctx)) {
+    OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
+    goto err;
+  }
+
+  if (!match) {
+    OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
+    goto err;
+  }
+
+  ret = 1;
 
 err:
   BN_CTX_free(ctx);