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 <assert.h>
71 #include <string.h>
72 
73 #include <openssl/bn.h>
74 #include <openssl/err.h>
75 #include <openssl/mem.h>
76 #include <openssl/obj.h>
77 
78 #include "internal.h"
79 #include "../internal.h"
80 
81 
82 static const struct curve_data P224 = {
83     "NIST P-224",
84     28,
85     1,
86     {/* p */
87      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
88      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89      0x00, 0x00, 0x00, 0x01,
90      /* a */
91      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
92      0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
93      0xFF, 0xFF, 0xFF, 0xFE,
94      /* b */
95      0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
96      0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
97      0x23, 0x55, 0xFF, 0xB4,
98      /* x */
99      0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
100      0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
101      0x11, 0x5C, 0x1D, 0x21,
102      /* y */
103      0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
104      0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
105      0x85, 0x00, 0x7e, 0x34,
106      /* order */
107      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
108      0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
109      0x5C, 0x5C, 0x2A, 0x3D,
110     }};
111 
112 static const struct curve_data P256 = {
113     "NIST P-256",
114     32,
115     1,
116     {/* p */
117      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
118      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
119      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
120      /* a */
121      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
122      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
123      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
124      /* b */
125      0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
126      0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
127      0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
128      /* x */
129      0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
130      0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
131      0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
132      /* y */
133      0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
134      0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
135      0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
136      /* order */
137      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
138      0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
139      0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}};
140 
141 static const struct curve_data P384 = {
142     "NIST P-384",
143     48,
144     1,
145     {/* p */
146      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
147      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
148      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
149      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
150      /* a */
151      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
152      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
153      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
154      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
155      /* b */
156      0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
157      0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
158      0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
159      0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
160      /* x */
161      0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
162      0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
163      0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
164      0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
165      /* y */
166      0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
167      0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
168      0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
169      0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
170      /* order */
171      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
172      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
173      0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
174      0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73}};
175 
176 static const struct curve_data P521 = {
177     "NIST P-521",
178     66,
179     1,
180     {/* p */
181      0x01, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
185      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
186      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
187      /* a */
188      0x01, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
192      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
193      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
194      /* b */
195      0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
196      0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
197      0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
198      0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
199      0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
200      0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
201      /* x */
202      0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
203      0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
204      0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
205      0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
206      0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
207      0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
208      /* y */
209      0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
210      0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
211      0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
212      0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
213      0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
214      0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
215      /* order */
216      0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
217      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
218      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
219      0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
220      0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
221      0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09}};
222 
223 /* MSan appears to have a bug that causes code to be miscompiled in opt mode.
224  * While that is being looked at, don't run the uint128_t code under MSan. */
225 #if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
226     !defined(MEMORY_SANITIZER)
227 #define BORINGSSL_USE_INT128_CODE
228 #endif
229 
230 const struct built_in_curve OPENSSL_built_in_curves[] = {
231     {NID_secp521r1, &P521, 0},
232     {NID_secp384r1, &P384, 0},
233     {
234         NID_X9_62_prime256v1, &P256,
235 #if defined(BORINGSSL_USE_INT128_CODE)
236 #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
237     !defined(OPENSSL_SMALL)
238         EC_GFp_nistz256_method,
239 #else
240         EC_GFp_nistp256_method,
241 #endif
242 #else
243         0,
244 #endif
245     },
246     {
247         NID_secp224r1, &P224,
248 #if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL)
249         EC_GFp_nistp224_method,
250 #else
251         0,
252 #endif
253     },
254     {NID_undef, 0, 0},
255 };
256 
257 /* built_in_curve_scalar_field_monts contains Montgomery contexts for
258  * performing inversions in the scalar fields of each of the built-in
259  * curves. It's protected by |built_in_curve_scalar_field_monts_once|. */
260 static const BN_MONT_CTX **built_in_curve_scalar_field_monts;
261 
262 static CRYPTO_once_t built_in_curve_scalar_field_monts_once;
263 
built_in_curve_scalar_field_monts_init(void)264 static void built_in_curve_scalar_field_monts_init(void) {
265   unsigned num_built_in_curves;
266   for (num_built_in_curves = 0;; num_built_in_curves++) {
267     if (OPENSSL_built_in_curves[num_built_in_curves].nid == NID_undef) {
268       break;
269     }
270   }
271 
272   assert(0 < num_built_in_curves);
273 
274   built_in_curve_scalar_field_monts =
275       OPENSSL_malloc(sizeof(BN_MONT_CTX *) * num_built_in_curves);
276   if (built_in_curve_scalar_field_monts == NULL) {
277     return;
278   }
279 
280   BIGNUM *order = BN_new();
281   BN_CTX *bn_ctx = BN_CTX_new();
282   BN_MONT_CTX *mont_ctx = NULL;
283 
284   if (bn_ctx == NULL ||
285       order == NULL) {
286     goto err;
287   }
288 
289   unsigned i;
290   for (i = 0; i < num_built_in_curves; i++) {
291     const struct curve_data *curve = OPENSSL_built_in_curves[i].data;
292     const unsigned param_len = curve->param_len;
293     const uint8_t *params = curve->data;
294 
295     mont_ctx = BN_MONT_CTX_new();
296     if (mont_ctx == NULL) {
297       goto err;
298     }
299 
300     if (!BN_bin2bn(params + 5 * param_len, param_len, order) ||
301         !BN_MONT_CTX_set(mont_ctx, order, bn_ctx)) {
302       goto err;
303     }
304 
305     built_in_curve_scalar_field_monts[i] = mont_ctx;
306     mont_ctx = NULL;
307   }
308 
309   goto out;
310 
311 err:
312   BN_MONT_CTX_free(mont_ctx);
313   OPENSSL_free((BN_MONT_CTX**) built_in_curve_scalar_field_monts);
314   built_in_curve_scalar_field_monts = NULL;
315 
316 out:
317   BN_free(order);
318   BN_CTX_free(bn_ctx);
319 }
320 
ec_group_new(const EC_METHOD * meth)321 EC_GROUP *ec_group_new(const EC_METHOD *meth) {
322   EC_GROUP *ret;
323 
324   if (meth == NULL) {
325     OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
326     return NULL;
327   }
328 
329   if (meth->group_init == 0) {
330     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
331     return NULL;
332   }
333 
334   ret = OPENSSL_malloc(sizeof(EC_GROUP));
335   if (ret == NULL) {
336     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
337     return NULL;
338   }
339   memset(ret, 0, sizeof(EC_GROUP));
340 
341   ret->meth = meth;
342   BN_init(&ret->order);
343   BN_init(&ret->cofactor);
344 
345   if (!meth->group_init(ret)) {
346     OPENSSL_free(ret);
347     return NULL;
348   }
349 
350   return ret;
351 }
352 
EC_GROUP_new_curve_GFp(const BIGNUM * p,const BIGNUM * a,const BIGNUM * b,BN_CTX * ctx)353 EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
354                                  const BIGNUM *b, BN_CTX *ctx) {
355   const EC_METHOD *meth = EC_GFp_mont_method();
356   EC_GROUP *ret;
357 
358   ret = ec_group_new(meth);
359   if (ret == NULL) {
360     return NULL;
361   }
362 
363   if (ret->meth->group_set_curve == 0) {
364     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
365     return 0;
366   }
367   if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
368     EC_GROUP_free(ret);
369     return NULL;
370   }
371   return ret;
372 }
373 
EC_GROUP_set_generator(EC_GROUP * group,const EC_POINT * generator,const BIGNUM * order,const BIGNUM * cofactor)374 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
375                            const BIGNUM *order, const BIGNUM *cofactor) {
376   if (group->curve_name != NID_undef) {
377     /* |EC_GROUP_set_generator| should only be used with |EC_GROUP|s returned
378      * by |EC_GROUP_new_curve_GFp|. */
379     return 0;
380   }
381 
382   if (group->generator == NULL) {
383     group->generator = EC_POINT_new(group);
384     if (group->generator == NULL) {
385       return 0;
386     }
387   }
388 
389   if (!EC_POINT_copy(group->generator, generator)) {
390     return 0;
391   }
392 
393   if (order != NULL) {
394     if (!BN_copy(&group->order, order)) {
395       return 0;
396     }
397   } else {
398     BN_zero(&group->order);
399   }
400 
401   if (cofactor != NULL) {
402     if (!BN_copy(&group->cofactor, cofactor)) {
403       return 0;
404     }
405   } else {
406     BN_zero(&group->cofactor);
407   }
408 
409   return 1;
410 }
411 
ec_group_new_from_data(unsigned built_in_index)412 static EC_GROUP *ec_group_new_from_data(unsigned built_in_index) {
413   const struct built_in_curve *curve = &OPENSSL_built_in_curves[built_in_index];
414   EC_GROUP *group = NULL;
415   EC_POINT *P = NULL;
416   BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
417   const EC_METHOD *meth;
418   int ok = 0;
419 
420   BN_CTX *ctx = BN_CTX_new();
421   if (ctx == NULL) {
422     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
423     goto err;
424   }
425 
426   const struct curve_data *data = curve->data;
427   const unsigned param_len = data->param_len;
428   const uint8_t *params = data->data;
429 
430   if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
431       !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
432       !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
433     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
434     goto err;
435   }
436 
437   if (curve->method != 0) {
438     meth = curve->method();
439     if (((group = ec_group_new(meth)) == NULL) ||
440         (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
441       OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
442       goto err;
443     }
444   } else {
445     if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
446       OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
447       goto err;
448     }
449   }
450 
451   if ((P = EC_POINT_new(group)) == NULL) {
452     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
453     goto err;
454   }
455 
456   if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
457       !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
458     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
459     goto err;
460   }
461 
462   if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
463     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
464     goto err;
465   }
466   if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order) ||
467       !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
468     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
469     goto err;
470   }
471 
472   CRYPTO_once(&built_in_curve_scalar_field_monts_once,
473               built_in_curve_scalar_field_monts_init);
474   if (built_in_curve_scalar_field_monts != NULL) {
475     group->mont_data = built_in_curve_scalar_field_monts[built_in_index];
476   }
477 
478   group->generator = P;
479   P = NULL;
480   ok = 1;
481 
482 err:
483   if (!ok) {
484     EC_GROUP_free(group);
485     group = NULL;
486   }
487   EC_POINT_free(P);
488   BN_CTX_free(ctx);
489   BN_free(p);
490   BN_free(a);
491   BN_free(b);
492   BN_free(x);
493   BN_free(y);
494   return group;
495 }
496 
EC_GROUP_new_by_curve_name(int nid)497 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
498   unsigned i;
499   const struct built_in_curve *curve;
500   EC_GROUP *ret = NULL;
501 
502   for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
503     curve = &OPENSSL_built_in_curves[i];
504     if (curve->nid == nid) {
505       ret = ec_group_new_from_data(i);
506       break;
507     }
508   }
509 
510   if (ret == NULL) {
511     OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
512     return NULL;
513   }
514 
515   ret->curve_name = nid;
516   return ret;
517 }
518 
EC_GROUP_free(EC_GROUP * group)519 void EC_GROUP_free(EC_GROUP *group) {
520   if (!group) {
521     return;
522   }
523 
524   if (group->meth->group_finish != 0) {
525     group->meth->group_finish(group);
526   }
527 
528   EC_POINT_free(group->generator);
529   BN_free(&group->order);
530   BN_free(&group->cofactor);
531 
532   OPENSSL_free(group);
533 }
534 
ec_group_copy(EC_GROUP * dest,const EC_GROUP * src)535 int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
536   if (dest->meth->group_copy == 0) {
537     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
538     return 0;
539   }
540   if (dest->meth != src->meth) {
541     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
542     return 0;
543   }
544   if (dest == src) {
545     return 1;
546   }
547 
548   dest->mont_data = src->mont_data;
549 
550   if (src->generator != NULL) {
551     if (dest->generator == NULL) {
552       dest->generator = EC_POINT_new(dest);
553       if (dest->generator == NULL) {
554         return 0;
555       }
556     }
557     if (!EC_POINT_copy(dest->generator, src->generator)) {
558       return 0;
559     }
560   } else {
561     EC_POINT_clear_free(dest->generator);
562     dest->generator = NULL;
563   }
564 
565   if (!BN_copy(&dest->order, &src->order) ||
566       !BN_copy(&dest->cofactor, &src->cofactor)) {
567     return 0;
568   }
569 
570   dest->curve_name = src->curve_name;
571 
572   return dest->meth->group_copy(dest, src);
573 }
574 
ec_group_get_mont_data(const EC_GROUP * group)575 const BN_MONT_CTX *ec_group_get_mont_data(const EC_GROUP *group) {
576   return group->mont_data;
577 }
578 
EC_GROUP_dup(const EC_GROUP * a)579 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
580   EC_GROUP *t = NULL;
581   int ok = 0;
582 
583   if (a == NULL) {
584     return NULL;
585   }
586 
587   t = ec_group_new(a->meth);
588   if (t == NULL) {
589     return NULL;
590   }
591   if (!ec_group_copy(t, a)) {
592     goto err;
593   }
594 
595   ok = 1;
596 
597 err:
598   if (!ok) {
599     EC_GROUP_free(t);
600     return NULL;
601   } else {
602     return t;
603   }
604 }
605 
EC_GROUP_cmp(const EC_GROUP * a,const EC_GROUP * b,BN_CTX * ignored)606 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
607   return a->curve_name == NID_undef ||
608          b->curve_name == NID_undef ||
609          a->curve_name != b->curve_name;
610 }
611 
EC_GROUP_get0_generator(const EC_GROUP * group)612 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
613   return group->generator;
614 }
615 
EC_GROUP_get0_order(const EC_GROUP * group)616 const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
617   assert(!BN_is_zero(&group->order));
618   return &group->order;
619 }
620 
EC_GROUP_get_order(const EC_GROUP * group,BIGNUM * order,BN_CTX * ctx)621 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
622   if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
623     return 0;
624   }
625   return 1;
626 }
627 
EC_GROUP_get_cofactor(const EC_GROUP * group,BIGNUM * cofactor,BN_CTX * ctx)628 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
629                           BN_CTX *ctx) {
630   if (!BN_copy(cofactor, &group->cofactor)) {
631     return 0;
632   }
633 
634   return !BN_is_zero(&group->cofactor);
635 }
636 
EC_GROUP_get_curve_GFp(const EC_GROUP * group,BIGNUM * out_p,BIGNUM * out_a,BIGNUM * out_b,BN_CTX * ctx)637 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
638                            BIGNUM *out_b, BN_CTX *ctx) {
639   return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx);
640 }
641 
EC_GROUP_get_curve_name(const EC_GROUP * group)642 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
643 
EC_GROUP_get_degree(const EC_GROUP * group)644 unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
645   return ec_GFp_simple_group_get_degree(group);
646 }
647 
EC_POINT_new(const EC_GROUP * group)648 EC_POINT *EC_POINT_new(const EC_GROUP *group) {
649   EC_POINT *ret;
650 
651   if (group == NULL) {
652     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
653     return NULL;
654   }
655 
656   ret = OPENSSL_malloc(sizeof *ret);
657   if (ret == NULL) {
658     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
659     return NULL;
660   }
661 
662   ret->meth = group->meth;
663 
664   if (!ec_GFp_simple_point_init(ret)) {
665     OPENSSL_free(ret);
666     return NULL;
667   }
668 
669   return ret;
670 }
671 
EC_POINT_free(EC_POINT * point)672 void EC_POINT_free(EC_POINT *point) {
673   if (!point) {
674     return;
675   }
676 
677   ec_GFp_simple_point_finish(point);
678 
679   OPENSSL_free(point);
680 }
681 
EC_POINT_clear_free(EC_POINT * point)682 void EC_POINT_clear_free(EC_POINT *point) {
683   if (!point) {
684     return;
685   }
686 
687   ec_GFp_simple_point_clear_finish(point);
688 
689   OPENSSL_cleanse(point, sizeof *point);
690   OPENSSL_free(point);
691 }
692 
EC_POINT_copy(EC_POINT * dest,const EC_POINT * src)693 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
694   if (dest->meth != src->meth) {
695     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
696     return 0;
697   }
698   if (dest == src) {
699     return 1;
700   }
701   return ec_GFp_simple_point_copy(dest, src);
702 }
703 
EC_POINT_dup(const EC_POINT * a,const EC_GROUP * group)704 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
705   EC_POINT *t;
706   int r;
707 
708   if (a == NULL) {
709     return NULL;
710   }
711 
712   t = EC_POINT_new(group);
713   if (t == NULL) {
714     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
715     return NULL;
716   }
717   r = EC_POINT_copy(t, a);
718   if (!r) {
719     EC_POINT_free(t);
720     return NULL;
721   } else {
722     return t;
723   }
724 }
725 
EC_POINT_set_to_infinity(const EC_GROUP * group,EC_POINT * point)726 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
727   if (group->meth != point->meth) {
728     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
729     return 0;
730   }
731   return ec_GFp_simple_point_set_to_infinity(group, point);
732 }
733 
EC_POINT_is_at_infinity(const EC_GROUP * group,const EC_POINT * point)734 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
735   if (group->meth != point->meth) {
736     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
737     return 0;
738   }
739   return ec_GFp_simple_is_at_infinity(group, point);
740 }
741 
EC_POINT_is_on_curve(const EC_GROUP * group,const EC_POINT * point,BN_CTX * ctx)742 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
743                          BN_CTX *ctx) {
744   if (group->meth != point->meth) {
745     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
746     return 0;
747   }
748   return ec_GFp_simple_is_on_curve(group, point, ctx);
749 }
750 
EC_POINT_cmp(const EC_GROUP * group,const EC_POINT * a,const EC_POINT * b,BN_CTX * ctx)751 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
752                  BN_CTX *ctx) {
753   if ((group->meth != a->meth) || (a->meth != b->meth)) {
754     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
755     return -1;
756   }
757   return ec_GFp_simple_cmp(group, a, b, ctx);
758 }
759 
EC_POINT_make_affine(const EC_GROUP * group,EC_POINT * point,BN_CTX * ctx)760 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
761   if (group->meth != point->meth) {
762     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
763     return 0;
764   }
765   return ec_GFp_simple_make_affine(group, point, ctx);
766 }
767 
EC_POINTs_make_affine(const EC_GROUP * group,size_t num,EC_POINT * points[],BN_CTX * ctx)768 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
769                           BN_CTX *ctx) {
770   size_t i;
771 
772   for (i = 0; i < num; i++) {
773     if (group->meth != points[i]->meth) {
774       OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
775       return 0;
776     }
777   }
778   return ec_GFp_simple_points_make_affine(group, num, points, ctx);
779 }
780 
EC_POINT_get_affine_coordinates_GFp(const EC_GROUP * group,const EC_POINT * point,BIGNUM * x,BIGNUM * y,BN_CTX * ctx)781 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
782                                         const EC_POINT *point, BIGNUM *x,
783                                         BIGNUM *y, BN_CTX *ctx) {
784   if (group->meth->point_get_affine_coordinates == 0) {
785     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
786     return 0;
787   }
788   if (group->meth != point->meth) {
789     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
790     return 0;
791   }
792   return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
793 }
794 
EC_POINT_set_affine_coordinates_GFp(const EC_GROUP * group,EC_POINT * point,const BIGNUM * x,const BIGNUM * y,BN_CTX * ctx)795 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
796                                         const BIGNUM *x, const BIGNUM *y,
797                                         BN_CTX *ctx) {
798   if (group->meth != point->meth) {
799     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
800     return 0;
801   }
802   if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) {
803     return 0;
804   }
805 
806   if (!EC_POINT_is_on_curve(group, point, ctx)) {
807     OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
808     return 0;
809   }
810 
811   return 1;
812 }
813 
EC_POINT_add(const EC_GROUP * group,EC_POINT * r,const EC_POINT * a,const EC_POINT * b,BN_CTX * ctx)814 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
815                  const EC_POINT *b, BN_CTX *ctx) {
816   if ((group->meth != r->meth) || (r->meth != a->meth) ||
817       (a->meth != b->meth)) {
818     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
819     return 0;
820   }
821   return ec_GFp_simple_add(group, r, a, b, ctx);
822 }
823 
824 
EC_POINT_dbl(const EC_GROUP * group,EC_POINT * r,const EC_POINT * a,BN_CTX * ctx)825 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
826                  BN_CTX *ctx) {
827   if ((group->meth != r->meth) || (r->meth != a->meth)) {
828     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
829     return 0;
830   }
831   return ec_GFp_simple_dbl(group, r, a, ctx);
832 }
833 
834 
EC_POINT_invert(const EC_GROUP * group,EC_POINT * a,BN_CTX * ctx)835 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
836   if (group->meth != a->meth) {
837     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
838     return 0;
839   }
840   return ec_GFp_simple_invert(group, a, ctx);
841 }
842 
EC_POINT_mul(const EC_GROUP * group,EC_POINT * r,const BIGNUM * g_scalar,const EC_POINT * p,const BIGNUM * p_scalar,BN_CTX * ctx)843 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
844                  const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
845   /* Previously, this function set |r| to the point at infinity if there was
846    * nothing to multiply. But, nobody should be calling this function with
847    * nothing to multiply in the first place. */
848   if ((g_scalar == NULL && p_scalar == NULL) ||
849       ((p == NULL) != (p_scalar == NULL)))  {
850     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
851     return 0;
852   }
853 
854   if (group->meth != r->meth ||
855       (p != NULL && group->meth != p->meth)) {
856     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
857     return 0;
858   }
859 
860   return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx);
861 }
862 
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)863 int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
864                                              const BIGNUM *x, const BIGNUM *y,
865                                              const BIGNUM *z, BN_CTX *ctx) {
866   if (group->meth != point->meth) {
867     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
868     return 0;
869   }
870   return ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point, x, y, z,
871                                                        ctx);
872 }
873 
EC_GROUP_set_asn1_flag(EC_GROUP * group,int flag)874 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
875 
EC_GROUP_method_of(const EC_GROUP * group)876 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
877   return NULL;
878 }
879 
EC_METHOD_get_field_type(const EC_METHOD * meth)880 int EC_METHOD_get_field_type(const EC_METHOD *meth) {
881   return NID_X9_62_prime_field;
882 }
883 
EC_GROUP_set_point_conversion_form(EC_GROUP * group,point_conversion_form_t form)884 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
885                                         point_conversion_form_t form) {
886   if (form != POINT_CONVERSION_UNCOMPRESSED) {
887     abort();
888   }
889 }
890