Readd EC_GROUP_get_curve_GFp.

wpa_supplicant needs this in order to get the order of the coordinate
field, apparently so that they can hash to a point.

Change-Id: I92d5df7b37b67ace5f497c25f53f16bbe134aced
Reviewed-on: https://boringssl-review.googlesource.com/1622
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/ec/ec.c b/crypto/ec/ec.c
index dcb9083..34e6d90 100644
--- a/crypto/ec/ec.c
+++ b/crypto/ec/ec.c
@@ -519,6 +519,16 @@
   return !BN_is_zero(&group->cofactor);
 }
 
+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
+                           BIGNUM *out_b, BN_CTX *ctx) {
+  if (group->meth->group_get_curve == 0) {
+    OPENSSL_PUT_ERROR(EC, EC_GROUP_get_curve_GFp,
+                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    return 0;
+  }
+  return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx);
+}
+
 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
 
 int EC_GROUP_get_degree(const EC_GROUP *group) {
diff --git a/crypto/ec/ec_error.c b/crypto/ec/ec_error.c
index 3b5d158..73807c7 100644
--- a/crypto/ec/ec_error.c
+++ b/crypto/ec/ec_error.c
@@ -18,6 +18,7 @@
 
 const ERR_STRING_DATA EC_error_string_data[] = {
   {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_copy, 0), "EC_GROUP_copy"},
+  {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_get_curve_GFp, 0), "EC_GROUP_get_curve_GFp"},
   {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_get_degree, 0), "EC_GROUP_get_degree"},
   {ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_new_by_curve_name, 0), "EC_GROUP_new_by_curve_name"},
   {ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_check_key, 0), "EC_KEY_check_key"},
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index 55f1adf..47ecfca 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -133,6 +133,15 @@
 OPENSSL_EXPORT int EC_GROUP_get_cofactor(const EC_GROUP *group,
                                          BIGNUM *cofactor, BN_CTX *ctx);
 
+/* EC_GROUP_get_curve_GFp gets various parameters about a group. It sets
+ * |*out_p| to the order of the coordinate field and |*out_a| and |*out_b| to
+ * the parameters of the curve when expressed as y² = x³ + ax + b. Any of the
+ * output parameters can be NULL. It returns one on success and zero on
+ * error. */
+OPENSSL_EXPORT int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p,
+                                          BIGNUM *out_a, BIGNUM *out_b,
+                                          BN_CTX *ctx);
+
 /* EC_GROUP_get_curve_name returns a NID that identifies |group|. */
 OPENSSL_EXPORT int EC_GROUP_get_curve_name(const EC_GROUP *group);
 
@@ -351,6 +360,7 @@
 #define EC_F_EC_KEY_generate_key 155
 #define EC_F_ec_GFp_simple_set_compressed_coordinates 156
 #define EC_F_EC_POINT_add 157
+#define EC_F_EC_GROUP_get_curve_GFp 158
 #define EC_R_PKPARAMETERS2GROUP_FAILURE 100
 #define EC_R_NON_NAMED_CURVE 101
 #define EC_R_COORDINATES_OUT_OF_RANGE 102