• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Originally written by Bodo Moeller for the OpenSSL project.
2  * ====================================================================
3  * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * 3. All advertising materials mentioning features or use of this
18  *    software must display the following acknowledgment:
19  *    "This product includes software developed by the OpenSSL Project
20  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21  *
22  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23  *    endorse or promote products derived from this software without
24  *    prior written permission. For written permission, please contact
25  *    openssl-core@openssl.org.
26  *
27  * 5. Products derived from this software may not be called "OpenSSL"
28  *    nor may "OpenSSL" appear in their names without prior written
29  *    permission of the OpenSSL Project.
30  *
31  * 6. Redistributions of any form whatsoever must retain the following
32  *    acknowledgment:
33  *    "This product includes software developed by the OpenSSL Project
34  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47  * OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This product includes cryptographic software written by Eric Young
51  * (eay@cryptsoft.com).  This product includes software written by Tim
52  * Hudson (tjh@cryptsoft.com).
53  *
54  */
55 /* ====================================================================
56  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
57  *
58  * Portions of the attached software ("Contribution") are developed by
59  * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
60  *
61  * The Contribution is licensed pursuant to the OpenSSL open source
62  * license provided above.
63  *
64  * The elliptic curve binary polynomial software is originally written by
65  * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
66  * Laboratories. */
67 
68 #include <openssl/ec.h>
69 
70 #include <string.h>
71 
72 #include <openssl/bn.h>
73 #include <openssl/err.h>
74 #include <openssl/mem.h>
75 #include <openssl/obj.h>
76 
77 #include "internal.h"
78 
79 
80 static const struct curve_data P224 = {
81     "NIST P-224",
82     28,
83     1,
84     {/* p */
85      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
86      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87      0x00, 0x00, 0x00, 0x01,
88      /* a */
89      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
90      0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
91      0xFF, 0xFF, 0xFF, 0xFE,
92      /* b */
93      0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
94      0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
95      0x23, 0x55, 0xFF, 0xB4,
96      /* x */
97      0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
98      0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
99      0x11, 0x5C, 0x1D, 0x21,
100      /* y */
101      0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
102      0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
103      0x85, 0x00, 0x7e, 0x34,
104      /* order */
105      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
106      0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
107      0x5C, 0x5C, 0x2A, 0x3D,
108     }};
109 
110 static const struct curve_data P256 = {
111     "NIST P-256",
112     32,
113     1,
114     {/* p */
115      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
116      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
117      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
118      /* a */
119      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
120      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
121      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
122      /* b */
123      0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
124      0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
125      0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
126      /* x */
127      0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
128      0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
129      0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
130      /* y */
131      0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
132      0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
133      0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
134      /* order */
135      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
136      0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
137      0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}};
138 
139 static const struct curve_data P384 = {
140     "NIST P-384",
141     48,
142     1,
143     {/* p */
144      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
145      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
146      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
147      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
148      /* a */
149      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
150      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
151      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
152      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
153      /* b */
154      0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
155      0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
156      0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
157      0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
158      /* x */
159      0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
160      0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
161      0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
162      0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
163      /* y */
164      0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
165      0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
166      0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
167      0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
168      /* order */
169      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
170      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
171      0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
172      0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73}};
173 
174 static const struct curve_data P521 = {
175     "NIST P-521",
176     66,
177     1,
178     {/* p */
179      0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
180      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
181      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
182      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
183      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
184      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
185      /* a */
186      0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
187      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
188      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
189      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
190      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
191      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
192      /* b */
193      0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
194      0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
195      0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
196      0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
197      0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
198      0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
199      /* x */
200      0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
201      0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
202      0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
203      0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
204      0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
205      0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
206      /* y */
207      0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
208      0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
209      0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
210      0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
211      0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
212      0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
213      /* order */
214      0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
215      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
216      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
217      0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
218      0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
219      0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09}};
220 
221 const struct built_in_curve OPENSSL_built_in_curves[] = {
222     {NID_secp224r1, &P224, 0},
223     {
224         NID_X9_62_prime256v1, &P256,
225 #if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS)
226         EC_GFp_nistp256_method,
227 #else
228         0,
229 #endif
230     },
231     {NID_secp384r1, &P384, 0},
232     {NID_secp521r1, &P521, 0},
233     {NID_undef, 0, 0},
234 };
235 
ec_group_new(const EC_METHOD * meth)236 EC_GROUP *ec_group_new(const EC_METHOD *meth) {
237   EC_GROUP *ret;
238 
239   if (meth == NULL) {
240     OPENSSL_PUT_ERROR(EC, ec_group_new, EC_R_SLOT_FULL);
241     return NULL;
242   }
243 
244   if (meth->group_init == 0) {
245     OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
246     return NULL;
247   }
248 
249   ret = OPENSSL_malloc(sizeof(EC_GROUP));
250   if (ret == NULL) {
251     OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_MALLOC_FAILURE);
252     return NULL;
253   }
254   memset(ret, 0, sizeof(EC_GROUP));
255 
256   ret->meth = meth;
257   BN_init(&ret->order);
258   BN_init(&ret->cofactor);
259 
260   if (!meth->group_init(ret)) {
261     OPENSSL_free(ret);
262     return NULL;
263   }
264 
265   return ret;
266 }
267 
EC_GROUP_new_curve_GFp(const BIGNUM * p,const BIGNUM * a,const BIGNUM * b,BN_CTX * ctx)268 EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
269                                  const BIGNUM *b, BN_CTX *ctx) {
270   const EC_METHOD *meth = EC_GFp_mont_method();
271   EC_GROUP *ret;
272 
273   ret = ec_group_new(meth);
274   if (ret == NULL) {
275     return NULL;
276   }
277 
278   if (ret->meth->group_set_curve == 0) {
279     OPENSSL_PUT_ERROR(EC, EC_GROUP_new_curve_GFp,
280                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
281     return 0;
282   }
283   if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
284     EC_GROUP_free(ret);
285     return NULL;
286   }
287   return ret;
288 }
289 
EC_GROUP_set_generator(EC_GROUP * group,const EC_POINT * generator,const BIGNUM * order,const BIGNUM * cofactor)290 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
291                            const BIGNUM *order, const BIGNUM *cofactor) {
292   if (group->curve_name != NID_undef) {
293     /* |EC_GROUP_set_generator| should only be used with |EC_GROUP|s returned
294      * by |EC_GROUP_new_curve_GFp|. */
295     return 0;
296   }
297 
298   if (group->generator == NULL) {
299     group->generator = EC_POINT_new(group);
300     if (group->generator == NULL) {
301       return 0;
302     }
303   }
304 
305   if (!EC_POINT_copy(group->generator, generator)) {
306     return 0;
307   }
308 
309   if (order != NULL) {
310     if (!BN_copy(&group->order, order)) {
311       return 0;
312     }
313   } else {
314     BN_zero(&group->order);
315   }
316 
317   if (cofactor != NULL) {
318     if (!BN_copy(&group->cofactor, cofactor)) {
319       return 0;
320     }
321   } else {
322     BN_zero(&group->cofactor);
323   }
324 
325   return 1;
326 }
327 
ec_group_new_from_data(const struct built_in_curve * curve)328 static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
329   EC_GROUP *group = NULL;
330   EC_POINT *P = NULL;
331   BN_CTX *ctx = NULL;
332   BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL;
333   int ok = 0;
334   unsigned param_len;
335   const EC_METHOD *meth;
336   const struct curve_data *data;
337   const uint8_t *params;
338 
339   if ((ctx = BN_CTX_new()) == NULL) {
340     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_MALLOC_FAILURE);
341     goto err;
342   }
343 
344   data = curve->data;
345   param_len = data->param_len;
346   params = data->data;
347 
348   if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
349       !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
350       !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
351     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
352     goto err;
353   }
354 
355   if (curve->method != 0) {
356     meth = curve->method();
357     if (((group = ec_group_new(meth)) == NULL) ||
358         (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
359       OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
360       goto err;
361     }
362   } else {
363     if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
364       OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
365       goto err;
366     }
367   }
368 
369   if ((P = EC_POINT_new(group)) == NULL) {
370     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
371     goto err;
372   }
373 
374   if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
375       !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
376     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
377     goto err;
378   }
379 
380   if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
381     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
382     goto err;
383   }
384   if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) ||
385       !BN_set_word(x, (BN_ULONG)data->cofactor)) {
386     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
387     goto err;
388   }
389 
390   group->generator = P;
391   P = NULL;
392   if (!BN_copy(&group->order, order) ||
393       !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
394     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
395     goto err;
396   }
397 
398   ok = 1;
399 
400 err:
401   if (!ok) {
402     EC_GROUP_free(group);
403     group = NULL;
404   }
405   EC_POINT_free(P);
406   BN_CTX_free(ctx);
407   BN_free(p);
408   BN_free(a);
409   BN_free(b);
410   BN_free(order);
411   BN_free(x);
412   BN_free(y);
413   return group;
414 }
415 
EC_GROUP_new_by_curve_name(int nid)416 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
417   unsigned i;
418   const struct built_in_curve *curve;
419   EC_GROUP *ret = NULL;
420 
421   for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
422     curve = &OPENSSL_built_in_curves[i];
423     if (curve->nid == nid) {
424       ret = ec_group_new_from_data(curve);
425       break;
426     }
427   }
428 
429   if (ret == NULL) {
430     OPENSSL_PUT_ERROR(EC, EC_GROUP_new_by_curve_name, EC_R_UNKNOWN_GROUP);
431     return NULL;
432   }
433 
434   ret->curve_name = nid;
435   return ret;
436 }
437 
EC_GROUP_free(EC_GROUP * group)438 void EC_GROUP_free(EC_GROUP *group) {
439   if (!group) {
440     return;
441   }
442 
443   if (group->meth->group_finish != 0) {
444     group->meth->group_finish(group);
445   }
446 
447   ec_pre_comp_free(group->pre_comp);
448 
449   EC_POINT_free(group->generator);
450   BN_free(&group->order);
451   BN_free(&group->cofactor);
452 
453   OPENSSL_free(group);
454 }
455 
ec_group_copy(EC_GROUP * dest,const EC_GROUP * src)456 int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
457   if (dest->meth->group_copy == 0) {
458     OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
459     return 0;
460   }
461   if (dest->meth != src->meth) {
462     OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, EC_R_INCOMPATIBLE_OBJECTS);
463     return 0;
464   }
465   if (dest == src) {
466     return 1;
467   }
468 
469   ec_pre_comp_free(dest->pre_comp);
470   dest->pre_comp = ec_pre_comp_dup(src->pre_comp);
471 
472   if (src->generator != NULL) {
473     if (dest->generator == NULL) {
474       dest->generator = EC_POINT_new(dest);
475       if (dest->generator == NULL) {
476         return 0;
477       }
478     }
479     if (!EC_POINT_copy(dest->generator, src->generator)) {
480       return 0;
481     }
482   } else {
483     /* src->generator == NULL */
484     if (dest->generator != NULL) {
485       EC_POINT_clear_free(dest->generator);
486       dest->generator = NULL;
487     }
488   }
489 
490   if (!BN_copy(&dest->order, &src->order) ||
491       !BN_copy(&dest->cofactor, &src->cofactor)) {
492     return 0;
493   }
494 
495   dest->curve_name = src->curve_name;
496 
497   return dest->meth->group_copy(dest, src);
498 }
499 
EC_GROUP_dup(const EC_GROUP * a)500 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
501   EC_GROUP *t = NULL;
502   int ok = 0;
503 
504   if (a == NULL) {
505     return NULL;
506   }
507 
508   t = ec_group_new(a->meth);
509   if (t == NULL) {
510     return NULL;
511   }
512   if (!ec_group_copy(t, a)) {
513     goto err;
514   }
515 
516   ok = 1;
517 
518 err:
519   if (!ok) {
520     EC_GROUP_free(t);
521     return NULL;
522   } else {
523     return t;
524   }
525 }
526 
EC_GROUP_cmp(const EC_GROUP * a,const EC_GROUP * b,BN_CTX * ignored)527 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
528   return a->curve_name == NID_undef ||
529          b->curve_name == NID_undef ||
530          a->curve_name != b->curve_name;
531 }
532 
EC_GROUP_get0_generator(const EC_GROUP * group)533 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
534   return group->generator;
535 }
536 
EC_GROUP_get_order(const EC_GROUP * group,BIGNUM * order,BN_CTX * ctx)537 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
538   if (!BN_copy(order, &group->order)) {
539     return 0;
540   }
541 
542   return !BN_is_zero(order);
543 }
544 
EC_GROUP_get_cofactor(const EC_GROUP * group,BIGNUM * cofactor,BN_CTX * ctx)545 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
546                           BN_CTX *ctx) {
547   if (!BN_copy(cofactor, &group->cofactor)) {
548     return 0;
549   }
550 
551   return !BN_is_zero(&group->cofactor);
552 }
553 
EC_GROUP_get_curve_GFp(const EC_GROUP * group,BIGNUM * out_p,BIGNUM * out_a,BIGNUM * out_b,BN_CTX * ctx)554 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
555                            BIGNUM *out_b, BN_CTX *ctx) {
556   if (group->meth->group_get_curve == 0) {
557     OPENSSL_PUT_ERROR(EC, EC_GROUP_get_curve_GFp,
558                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
559     return 0;
560   }
561   return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx);
562 }
563 
EC_GROUP_get_curve_name(const EC_GROUP * group)564 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
565 
EC_GROUP_get_degree(const EC_GROUP * group)566 int EC_GROUP_get_degree(const EC_GROUP *group) {
567   if (group->meth->group_get_degree == 0) {
568     OPENSSL_PUT_ERROR(EC, EC_GROUP_get_degree,
569                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
570     return 0;
571   }
572   return group->meth->group_get_degree(group);
573 }
574 
EC_GROUP_precompute_mult(EC_GROUP * group,BN_CTX * ctx)575 int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
576   if (group->meth->mul == 0) {
577     /* use default */
578     return ec_wNAF_precompute_mult(group, ctx);
579   }
580 
581   if (group->meth->precompute_mult != 0) {
582     return group->meth->precompute_mult(group, ctx);
583   }
584 
585   return 1; /* nothing to do, so report success */
586 }
587 
EC_GROUP_have_precompute_mult(const EC_GROUP * group)588 int EC_GROUP_have_precompute_mult(const EC_GROUP *group) {
589   if (group->meth->mul == 0) {
590     /* use default */
591     return ec_wNAF_have_precompute_mult(group);
592   }
593 
594   if (group->meth->have_precompute_mult != 0) {
595     return group->meth->have_precompute_mult(group);
596   }
597 
598   return 0; /* cannot tell whether precomputation has been performed */
599 }
600 
EC_POINT_new(const EC_GROUP * group)601 EC_POINT *EC_POINT_new(const EC_GROUP *group) {
602   EC_POINT *ret;
603 
604   if (group == NULL) {
605     OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_PASSED_NULL_PARAMETER);
606     return NULL;
607   }
608   if (group->meth->point_init == 0) {
609     OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
610     return NULL;
611   }
612 
613   ret = OPENSSL_malloc(sizeof *ret);
614   if (ret == NULL) {
615     OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_MALLOC_FAILURE);
616     return NULL;
617   }
618 
619   ret->meth = group->meth;
620 
621   if (!ret->meth->point_init(ret)) {
622     OPENSSL_free(ret);
623     return NULL;
624   }
625 
626   return ret;
627 }
628 
EC_POINT_free(EC_POINT * point)629 void EC_POINT_free(EC_POINT *point) {
630   if (!point) {
631     return;
632   }
633 
634   if (point->meth->point_finish != 0) {
635     point->meth->point_finish(point);
636   }
637   OPENSSL_free(point);
638 }
639 
EC_POINT_clear_free(EC_POINT * point)640 void EC_POINT_clear_free(EC_POINT *point) {
641   if (!point) {
642     return;
643   }
644 
645   if (point->meth->point_clear_finish != 0) {
646     point->meth->point_clear_finish(point);
647   } else if (point->meth->point_finish != 0) {
648     point->meth->point_finish(point);
649   }
650   OPENSSL_cleanse(point, sizeof *point);
651   OPENSSL_free(point);
652 }
653 
EC_POINT_copy(EC_POINT * dest,const EC_POINT * src)654 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
655   if (dest->meth->point_copy == 0) {
656     OPENSSL_PUT_ERROR(EC, EC_POINT_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
657     return 0;
658   }
659   if (dest->meth != src->meth) {
660     OPENSSL_PUT_ERROR(EC, EC_POINT_copy, EC_R_INCOMPATIBLE_OBJECTS);
661     return 0;
662   }
663   if (dest == src) {
664     return 1;
665   }
666   return dest->meth->point_copy(dest, src);
667 }
668 
EC_POINT_dup(const EC_POINT * a,const EC_GROUP * group)669 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
670   EC_POINT *t;
671   int r;
672 
673   if (a == NULL) {
674     return NULL;
675   }
676 
677   t = EC_POINT_new(group);
678   if (t == NULL) {
679     OPENSSL_PUT_ERROR(EC, EC_POINT_dup, ERR_R_MALLOC_FAILURE);
680     return NULL;
681   }
682   r = EC_POINT_copy(t, a);
683   if (!r) {
684     EC_POINT_free(t);
685     return NULL;
686   } else {
687     return t;
688   }
689 }
690 
EC_POINT_set_to_infinity(const EC_GROUP * group,EC_POINT * point)691 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
692   if (group->meth->point_set_to_infinity == 0) {
693     OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity,
694                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
695     return 0;
696   }
697   if (group->meth != point->meth) {
698     OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity, EC_R_INCOMPATIBLE_OBJECTS);
699     return 0;
700   }
701   return group->meth->point_set_to_infinity(group, point);
702 }
703 
EC_POINT_is_at_infinity(const EC_GROUP * group,const EC_POINT * point)704 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
705   if (group->meth->is_at_infinity == 0) {
706     OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity,
707                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
708     return 0;
709   }
710   if (group->meth != point->meth) {
711     OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity, EC_R_INCOMPATIBLE_OBJECTS);
712     return 0;
713   }
714   return group->meth->is_at_infinity(group, point);
715 }
716 
EC_POINT_is_on_curve(const EC_GROUP * group,const EC_POINT * point,BN_CTX * ctx)717 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
718                          BN_CTX *ctx) {
719   if (group->meth->is_on_curve == 0) {
720     OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve,
721                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
722     return 0;
723   }
724   if (group->meth != point->meth) {
725     OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve, EC_R_INCOMPATIBLE_OBJECTS);
726     return 0;
727   }
728   return group->meth->is_on_curve(group, point, ctx);
729 }
730 
EC_POINT_cmp(const EC_GROUP * group,const EC_POINT * a,const EC_POINT * b,BN_CTX * ctx)731 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
732                  BN_CTX *ctx) {
733   if (group->meth->point_cmp == 0) {
734     OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
735     return -1;
736   }
737   if ((group->meth != a->meth) || (a->meth != b->meth)) {
738     OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, EC_R_INCOMPATIBLE_OBJECTS);
739     return -1;
740   }
741   return group->meth->point_cmp(group, a, b, ctx);
742 }
743 
EC_POINT_make_affine(const EC_GROUP * group,EC_POINT * point,BN_CTX * ctx)744 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
745   if (group->meth->make_affine == 0) {
746     OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine,
747                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
748     return 0;
749   }
750   if (group->meth != point->meth) {
751     OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
752     return 0;
753   }
754   return group->meth->make_affine(group, point, ctx);
755 }
756 
EC_POINTs_make_affine(const EC_GROUP * group,size_t num,EC_POINT * points[],BN_CTX * ctx)757 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
758                           BN_CTX *ctx) {
759   size_t i;
760 
761   if (group->meth->points_make_affine == 0) {
762     OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine,
763                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
764     return 0;
765   }
766   for (i = 0; i < num; i++) {
767     if (group->meth != points[i]->meth) {
768       OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
769       return 0;
770     }
771   }
772   return group->meth->points_make_affine(group, num, points, ctx);
773 }
774 
EC_POINT_get_affine_coordinates_GFp(const EC_GROUP * group,const EC_POINT * point,BIGNUM * x,BIGNUM * y,BN_CTX * ctx)775 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
776                                         const EC_POINT *point, BIGNUM *x,
777                                         BIGNUM *y, BN_CTX *ctx) {
778   if (group->meth->point_get_affine_coordinates == 0) {
779     OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
780                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
781     return 0;
782   }
783   if (group->meth != point->meth) {
784     OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
785                       EC_R_INCOMPATIBLE_OBJECTS);
786     return 0;
787   }
788   return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
789 }
790 
EC_POINT_set_affine_coordinates_GFp(const EC_GROUP * group,EC_POINT * point,const BIGNUM * x,const BIGNUM * y,BN_CTX * ctx)791 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
792                                         const BIGNUM *x, const BIGNUM *y,
793                                         BN_CTX *ctx) {
794   if (group->meth->point_set_affine_coordinates == 0) {
795     OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
796                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
797     return 0;
798   }
799   if (group->meth != point->meth) {
800     OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
801                       EC_R_INCOMPATIBLE_OBJECTS);
802     return 0;
803   }
804   return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
805 }
806 
EC_POINT_add(const EC_GROUP * group,EC_POINT * r,const EC_POINT * a,const EC_POINT * b,BN_CTX * ctx)807 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
808                  const EC_POINT *b, BN_CTX *ctx) {
809   if (group->meth->add == 0) {
810     OPENSSL_PUT_ERROR(EC, EC_POINT_add, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
811     return 0;
812   }
813   if ((group->meth != r->meth) || (r->meth != a->meth) ||
814       (a->meth != b->meth)) {
815     OPENSSL_PUT_ERROR(EC, EC_POINT_add, EC_R_INCOMPATIBLE_OBJECTS);
816     return 0;
817   }
818   return group->meth->add(group, r, a, b, ctx);
819 }
820 
821 
EC_POINT_dbl(const EC_GROUP * group,EC_POINT * r,const EC_POINT * a,BN_CTX * ctx)822 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
823                  BN_CTX *ctx) {
824   if (group->meth->dbl == 0) {
825     OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
826     return 0;
827   }
828   if ((group->meth != r->meth) || (r->meth != a->meth)) {
829     OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, EC_R_INCOMPATIBLE_OBJECTS);
830     return 0;
831   }
832   return group->meth->dbl(group, r, a, ctx);
833 }
834 
835 
EC_POINT_invert(const EC_GROUP * group,EC_POINT * a,BN_CTX * ctx)836 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
837   if (group->meth->invert == 0) {
838     OPENSSL_PUT_ERROR(EC, EC_POINT_invert, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
839     return 0;
840   }
841   if (group->meth != a->meth) {
842     OPENSSL_PUT_ERROR(EC, EC_POINT_invert, EC_R_INCOMPATIBLE_OBJECTS);
843     return 0;
844   }
845   return group->meth->invert(group, a, ctx);
846 }
847 
EC_POINT_mul(const EC_GROUP * group,EC_POINT * r,const BIGNUM * g_scalar,const EC_POINT * point,const BIGNUM * p_scalar,BN_CTX * ctx)848 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
849                  const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) {
850   /* just a convenient interface to EC_POINTs_mul() */
851 
852   const EC_POINT *points[1];
853   const BIGNUM *scalars[1];
854 
855   points[0] = point;
856   scalars[0] = p_scalar;
857 
858   return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL),
859                        points, scalars, ctx);
860 }
861 
EC_POINTs_mul(const EC_GROUP * group,EC_POINT * r,const BIGNUM * scalar,size_t num,const EC_POINT * points[],const BIGNUM * scalars[],BN_CTX * ctx)862 int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
863                   size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
864                   BN_CTX *ctx) {
865   if (group->meth->mul == 0) {
866     /* use default. Warning, not constant-time. */
867     return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
868   }
869 
870   return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
871 }
872 
ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP * group,EC_POINT * point,const BIGNUM * x,const BIGNUM * y,const BIGNUM * z,BN_CTX * ctx)873 int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
874                                              const BIGNUM *x, const BIGNUM *y,
875                                              const BIGNUM *z, BN_CTX *ctx) {
876   if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
877     OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
878                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
879     return 0;
880   }
881   if (group->meth != point->meth) {
882     OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
883                       EC_R_INCOMPATIBLE_OBJECTS);
884     return 0;
885   }
886   return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y,
887                                                             z, ctx);
888 }
889 
EC_GROUP_set_asn1_flag(EC_GROUP * group,int flag)890 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
891 
EC_GROUP_method_of(const EC_GROUP * group)892 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
893   return NULL;
894 }
895 
EC_METHOD_get_field_type(const EC_METHOD * meth)896 int EC_METHOD_get_field_type(const EC_METHOD *meth) {
897   return NID_X9_62_prime_field;
898 }
899 
EC_GROUP_set_point_conversion_form(EC_GROUP * group,point_conversion_form_t form)900 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
901                                         point_conversion_form_t form) {
902   if (form != POINT_CONVERSION_UNCOMPRESSED) {
903     abort();
904   }
905 }
906