Don't use function wrappers for EC_METHOD.

The weird function thing is a remnant of OpenSSL and I think something
weird involving Windows and symbols exported from dlls. These aren't
exposed in the public API, so have everything point to the tables
directly.

This is in preparation for making built-in EC_GROUPs static. (The static
EC_GROUPs won't be able to call a function wrapper.)

BUG=20

Change-Id: If33888430f32e51f48936db4046769aa1894e3aa
Reviewed-on: https://boringssl-review.googlesource.com/10346
Reviewed-by: Adam Langley <agl@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/ec/ec.c b/crypto/ec/ec.c
index 35c2601..271fb50 100644
--- a/crypto/ec/ec.c
+++ b/crypto/ec/ec.c
@@ -229,14 +229,14 @@
         /* 1.3.132.0.35 */
         {0x2b, 0x81, 0x04, 0x00, 0x23}, 5,
         &P521,
-        NULL,
+        &EC_GFp_mont_method,
       },
     {
         NID_secp384r1,
         /* 1.3.132.0.34 */
         {0x2b, 0x81, 0x04, 0x00, 0x22}, 5,
         &P384,
-        NULL,
+        &EC_GFp_mont_method,
     },
     {
         NID_X9_62_prime256v1,
@@ -246,12 +246,12 @@
 #if defined(BORINGSSL_USE_INT128_CODE)
 #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
     !defined(OPENSSL_SMALL)
-        EC_GFp_nistz256_method,
+        &EC_GFp_nistz256_method,
 #else
-        EC_GFp_nistp256_method,
+        &EC_GFp_nistp256_method,
 #endif
 #else
-        NULL,
+        &EC_GFp_mont_method,
 #endif
     },
     {
@@ -260,9 +260,9 @@
         {0x2b, 0x81, 0x04, 0x00, 0x21}, 5,
         &P224,
 #if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL)
-        EC_GFp_nistp224_method,
+        &EC_GFp_nistp224_method,
 #else
-        NULL,
+        &EC_GFp_mont_method,
 #endif
     },
     {NID_undef, {0}, 0, NULL, NULL},
@@ -365,10 +365,7 @@
 
 EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
                                  const BIGNUM *b, BN_CTX *ctx) {
-  const EC_METHOD *meth = EC_GFp_mont_method();
-  EC_GROUP *ret;
-
-  ret = ec_group_new(meth);
+  EC_GROUP *ret = ec_group_new(&EC_GFp_mont_method);
   if (ret == NULL) {
     return NULL;
   }
@@ -409,7 +406,6 @@
   EC_GROUP *group = NULL;
   EC_POINT *P = NULL;
   BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
-  const EC_METHOD *meth;
   int ok = 0;
 
   BN_CTX *ctx = BN_CTX_new();
@@ -429,18 +425,11 @@
     goto err;
   }
 
-  if (curve->method != 0) {
-    meth = curve->method();
-    if (((group = ec_group_new(meth)) == NULL) ||
-        (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
-      goto err;
-    }
-  } else {
-    if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
-      goto err;
-    }
+  group = ec_group_new(curve->method);
+  if (group == NULL ||
+      !group->meth->group_set_curve(group, p, a, b, ctx)) {
+    OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
+    goto err;
   }
 
   if ((P = EC_POINT_new(group)) == NULL) {
diff --git a/crypto/ec/ec_montgomery.c b/crypto/ec/ec_montgomery.c
index 4c1e3b4..f344c29 100644
--- a/crypto/ec/ec_montgomery.c
+++ b/crypto/ec/ec_montgomery.c
@@ -294,8 +294,7 @@
   return ret;
 }
 
-const EC_METHOD *EC_GFp_mont_method(void) {
-  static const EC_METHOD ret = {
+const EC_METHOD EC_GFp_mont_method = {
     ec_GFp_mont_group_init,
     ec_GFp_mont_group_finish,
     ec_GFp_mont_group_copy,
@@ -306,7 +305,4 @@
     ec_GFp_mont_field_sqr,
     ec_GFp_mont_field_encode,
     ec_GFp_mont_field_decode,
-  };
-
-  return &ret;
-}
+};
\ No newline at end of file
diff --git a/crypto/ec/internal.h b/crypto/ec/internal.h
index 10770d9..b3c2a71 100644
--- a/crypto/ec/internal.h
+++ b/crypto/ec/internal.h
@@ -109,7 +109,7 @@
                       BN_CTX *); /* e.g. from Montgomery */
 } /* EC_METHOD */;
 
-const EC_METHOD* EC_GFp_mont_method(void);
+extern const EC_METHOD EC_GFp_mont_method;
 
 struct ec_group_st {
   const EC_METHOD *meth;
@@ -222,12 +222,12 @@
 
 void ec_GFp_nistp_recode_scalar_bits(uint8_t *sign, uint8_t *digit, uint8_t in);
 
-const EC_METHOD *EC_GFp_nistp224_method(void);
-const EC_METHOD *EC_GFp_nistp256_method(void);
+extern const EC_METHOD EC_GFp_nistp224_method;
+extern const EC_METHOD EC_GFp_nistp256_method;
 
-/* Returns GFp methods using montgomery multiplication, with x86-64
- * optimized P256. See http://eprint.iacr.org/2013/816. */
-const EC_METHOD *EC_GFp_nistz256_method(void);
+/* EC_GFp_nistz256_method is a GFp method using montgomery multiplication, with
+ * x86-64 optimized P256. See http://eprint.iacr.org/2013/816. */
+extern const EC_METHOD EC_GFp_nistz256_method;
 
 struct ec_key_st {
   EC_GROUP *group;
@@ -262,7 +262,7 @@
   uint8_t oid[8];
   uint8_t oid_len;
   const struct curve_data *data;
-  const EC_METHOD *(*method)(void);
+  const EC_METHOD *method;
 };
 
 /* OPENSSL_built_in_curves is terminated with an entry where |nid| is
diff --git a/crypto/ec/p224-64.c b/crypto/ec/p224-64.c
index 1b09cb9..be85ad6 100644
--- a/crypto/ec/p224-64.c
+++ b/crypto/ec/p224-64.c
@@ -1179,19 +1179,17 @@
   return ret;
 }
 
-const EC_METHOD *EC_GFp_nistp224_method(void) {
-  static const EC_METHOD ret = {ec_GFp_simple_group_init,
-                                ec_GFp_simple_group_finish,
-                                ec_GFp_simple_group_copy,
-                                ec_GFp_simple_group_set_curve,
-                                ec_GFp_nistp224_point_get_affine_coordinates,
-                                ec_GFp_nistp224_points_mul,
-                                ec_GFp_simple_field_mul,
-                                ec_GFp_simple_field_sqr,
-                                0 /* field_encode */,
-                                0 /* field_decode */};
-
-  return &ret;
-}
+const EC_METHOD EC_GFp_nistp224_method = {
+    ec_GFp_simple_group_init,
+    ec_GFp_simple_group_finish,
+    ec_GFp_simple_group_copy,
+    ec_GFp_simple_group_set_curve,
+    ec_GFp_nistp224_point_get_affine_coordinates,
+    ec_GFp_nistp224_points_mul,
+    ec_GFp_simple_field_mul,
+    ec_GFp_simple_field_sqr,
+    NULL /* field_encode */,
+    NULL /* field_decode */,
+};
 
 #endif  /* 64_BIT && !WINDOWS && !SMALL */
diff --git a/crypto/ec/p256-64.c b/crypto/ec/p256-64.c
index 31bf0ad..6a57a73 100644
--- a/crypto/ec/p256-64.c
+++ b/crypto/ec/p256-64.c
@@ -1734,19 +1734,17 @@
   return ret;
 }
 
-const EC_METHOD *EC_GFp_nistp256_method(void) {
-  static const EC_METHOD ret = {
-      ec_GFp_simple_group_init,
-      ec_GFp_simple_group_finish,
-      ec_GFp_simple_group_copy,
-      ec_GFp_simple_group_set_curve,
-      ec_GFp_nistp256_point_get_affine_coordinates,
-      ec_GFp_nistp256_points_mul,
-      ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr,
-      0 /* field_encode */, 0 /* field_decode */,
-  };
-
-  return &ret;
-}
+const EC_METHOD EC_GFp_nistp256_method = {
+    ec_GFp_simple_group_init,
+    ec_GFp_simple_group_finish,
+    ec_GFp_simple_group_copy,
+    ec_GFp_simple_group_set_curve,
+    ec_GFp_nistp256_point_get_affine_coordinates,
+    ec_GFp_nistp256_points_mul,
+    ec_GFp_simple_field_mul,
+    ec_GFp_simple_field_sqr,
+    NULL /* field_encode */,
+    NULL /* field_decode */,
+};
 
 #endif  /* 64_BIT && !WINDOWS */
diff --git a/crypto/ec/p256-x86_64.c b/crypto/ec/p256-x86_64.c
index 3f509db..a5906e4 100644
--- a/crypto/ec/p256-x86_64.c
+++ b/crypto/ec/p256-x86_64.c
@@ -556,22 +556,19 @@
   return 1;
 }
 
-const EC_METHOD *EC_GFp_nistz256_method(void) {
-  static const EC_METHOD ret = {
-      ec_GFp_mont_group_init,
-      ec_GFp_mont_group_finish,
-      ec_GFp_mont_group_copy,
-      ec_GFp_mont_group_set_curve,
-      ecp_nistz256_get_affine,
-      ecp_nistz256_points_mul,
-      ec_GFp_mont_field_mul,
-      ec_GFp_mont_field_sqr,
-      ec_GFp_mont_field_encode,
-      ec_GFp_mont_field_decode,
-  };
 
-  return &ret;
-}
+const EC_METHOD EC_GFp_nistz256_method = {
+    ec_GFp_mont_group_init,
+    ec_GFp_mont_group_finish,
+    ec_GFp_mont_group_copy,
+    ec_GFp_mont_group_set_curve,
+    ecp_nistz256_get_affine,
+    ecp_nistz256_points_mul,
+    ec_GFp_mont_field_mul,
+    ec_GFp_mont_field_sqr,
+    ec_GFp_mont_field_encode,
+    ec_GFp_mont_field_decode,
+};
 
 #endif /* !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
           !defined(OPENSSL_SMALL) */