• 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 <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   /* Require a cofactor of one for custom curves, which implies prime order. */
383   if (!BN_is_one(cofactor)) {
384     OPENSSL_PUT_ERROR(EC, EC_R_WRONG_CURVE_PARAMETERS);
385     return 0;
386   }
387 
388   if (group->generator == NULL) {
389     group->generator = EC_POINT_new(group);
390     if (group->generator == NULL) {
391       return 0;
392     }
393   }
394 
395   if (!EC_POINT_copy(group->generator, generator)) {
396     return 0;
397   }
398 
399   if (order != NULL) {
400     if (!BN_copy(&group->order, order)) {
401       return 0;
402     }
403   } else {
404     BN_zero(&group->order);
405   }
406 
407   if (cofactor != NULL) {
408     if (!BN_copy(&group->cofactor, cofactor)) {
409       return 0;
410     }
411   } else {
412     BN_zero(&group->cofactor);
413   }
414 
415   return 1;
416 }
417 
ec_group_new_from_data(unsigned built_in_index)418 static EC_GROUP *ec_group_new_from_data(unsigned built_in_index) {
419   const struct built_in_curve *curve = &OPENSSL_built_in_curves[built_in_index];
420   EC_GROUP *group = NULL;
421   EC_POINT *P = NULL;
422   BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
423   const EC_METHOD *meth;
424   int ok = 0;
425 
426   BN_CTX *ctx = BN_CTX_new();
427   if (ctx == NULL) {
428     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
429     goto err;
430   }
431 
432   const struct curve_data *data = curve->data;
433   const unsigned param_len = data->param_len;
434   const uint8_t *params = data->data;
435 
436   if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
437       !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
438       !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
439     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
440     goto err;
441   }
442 
443   if (curve->method != 0) {
444     meth = curve->method();
445     if (((group = ec_group_new(meth)) == NULL) ||
446         (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
447       OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
448       goto err;
449     }
450   } else {
451     if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
452       OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
453       goto err;
454     }
455   }
456 
457   if ((P = EC_POINT_new(group)) == NULL) {
458     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
459     goto err;
460   }
461 
462   if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
463       !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
464     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
465     goto err;
466   }
467 
468   if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
469     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
470     goto err;
471   }
472   if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order) ||
473       !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
474     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
475     goto err;
476   }
477 
478   CRYPTO_once(&built_in_curve_scalar_field_monts_once,
479               built_in_curve_scalar_field_monts_init);
480   if (built_in_curve_scalar_field_monts != NULL) {
481     group->mont_data = built_in_curve_scalar_field_monts[built_in_index];
482   }
483 
484   group->generator = P;
485   P = NULL;
486   ok = 1;
487 
488 err:
489   if (!ok) {
490     EC_GROUP_free(group);
491     group = NULL;
492   }
493   EC_POINT_free(P);
494   BN_CTX_free(ctx);
495   BN_free(p);
496   BN_free(a);
497   BN_free(b);
498   BN_free(x);
499   BN_free(y);
500   return group;
501 }
502 
EC_GROUP_new_by_curve_name(int nid)503 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
504   unsigned i;
505   const struct built_in_curve *curve;
506   EC_GROUP *ret = NULL;
507 
508   for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
509     curve = &OPENSSL_built_in_curves[i];
510     if (curve->nid == nid) {
511       ret = ec_group_new_from_data(i);
512       break;
513     }
514   }
515 
516   if (ret == NULL) {
517     OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
518     return NULL;
519   }
520 
521   ret->curve_name = nid;
522   return ret;
523 }
524 
EC_GROUP_free(EC_GROUP * group)525 void EC_GROUP_free(EC_GROUP *group) {
526   if (!group) {
527     return;
528   }
529 
530   if (group->meth->group_finish != 0) {
531     group->meth->group_finish(group);
532   }
533 
534   EC_POINT_free(group->generator);
535   BN_free(&group->order);
536   BN_free(&group->cofactor);
537 
538   OPENSSL_free(group);
539 }
540 
ec_group_copy(EC_GROUP * dest,const EC_GROUP * src)541 int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
542   if (dest->meth->group_copy == 0) {
543     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
544     return 0;
545   }
546   if (dest->meth != src->meth) {
547     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
548     return 0;
549   }
550   if (dest == src) {
551     return 1;
552   }
553 
554   dest->mont_data = src->mont_data;
555 
556   if (src->generator != NULL) {
557     if (dest->generator == NULL) {
558       dest->generator = EC_POINT_new(dest);
559       if (dest->generator == NULL) {
560         return 0;
561       }
562     }
563     if (!EC_POINT_copy(dest->generator, src->generator)) {
564       return 0;
565     }
566   } else {
567     EC_POINT_clear_free(dest->generator);
568     dest->generator = NULL;
569   }
570 
571   if (!BN_copy(&dest->order, &src->order) ||
572       !BN_copy(&dest->cofactor, &src->cofactor)) {
573     return 0;
574   }
575 
576   dest->curve_name = src->curve_name;
577 
578   return dest->meth->group_copy(dest, src);
579 }
580 
ec_group_get_mont_data(const EC_GROUP * group)581 const BN_MONT_CTX *ec_group_get_mont_data(const EC_GROUP *group) {
582   return group->mont_data;
583 }
584 
EC_GROUP_dup(const EC_GROUP * a)585 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
586   EC_GROUP *t = NULL;
587   int ok = 0;
588 
589   if (a == NULL) {
590     return NULL;
591   }
592 
593   t = ec_group_new(a->meth);
594   if (t == NULL) {
595     return NULL;
596   }
597   if (!ec_group_copy(t, a)) {
598     goto err;
599   }
600 
601   ok = 1;
602 
603 err:
604   if (!ok) {
605     EC_GROUP_free(t);
606     return NULL;
607   } else {
608     return t;
609   }
610 }
611 
EC_GROUP_cmp(const EC_GROUP * a,const EC_GROUP * b,BN_CTX * ignored)612 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
613   return a->curve_name == NID_undef ||
614          b->curve_name == NID_undef ||
615          a->curve_name != b->curve_name;
616 }
617 
EC_GROUP_get0_generator(const EC_GROUP * group)618 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
619   return group->generator;
620 }
621 
EC_GROUP_get0_order(const EC_GROUP * group)622 const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
623   assert(!BN_is_zero(&group->order));
624   return &group->order;
625 }
626 
EC_GROUP_get_order(const EC_GROUP * group,BIGNUM * order,BN_CTX * ctx)627 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
628   if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
629     return 0;
630   }
631   return 1;
632 }
633 
EC_GROUP_get_cofactor(const EC_GROUP * group,BIGNUM * cofactor,BN_CTX * ctx)634 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
635                           BN_CTX *ctx) {
636   if (!BN_copy(cofactor, &group->cofactor)) {
637     return 0;
638   }
639 
640   return !BN_is_zero(&group->cofactor);
641 }
642 
EC_GROUP_get_curve_GFp(const EC_GROUP * group,BIGNUM * out_p,BIGNUM * out_a,BIGNUM * out_b,BN_CTX * ctx)643 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
644                            BIGNUM *out_b, BN_CTX *ctx) {
645   return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx);
646 }
647 
EC_GROUP_get_curve_name(const EC_GROUP * group)648 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
649 
EC_GROUP_get_degree(const EC_GROUP * group)650 unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
651   return ec_GFp_simple_group_get_degree(group);
652 }
653 
EC_POINT_new(const EC_GROUP * group)654 EC_POINT *EC_POINT_new(const EC_GROUP *group) {
655   EC_POINT *ret;
656 
657   if (group == NULL) {
658     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
659     return NULL;
660   }
661 
662   ret = OPENSSL_malloc(sizeof *ret);
663   if (ret == NULL) {
664     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
665     return NULL;
666   }
667 
668   ret->meth = group->meth;
669 
670   if (!ec_GFp_simple_point_init(ret)) {
671     OPENSSL_free(ret);
672     return NULL;
673   }
674 
675   return ret;
676 }
677 
EC_POINT_free(EC_POINT * point)678 void EC_POINT_free(EC_POINT *point) {
679   if (!point) {
680     return;
681   }
682 
683   ec_GFp_simple_point_finish(point);
684 
685   OPENSSL_free(point);
686 }
687 
EC_POINT_clear_free(EC_POINT * point)688 void EC_POINT_clear_free(EC_POINT *point) {
689   if (!point) {
690     return;
691   }
692 
693   ec_GFp_simple_point_clear_finish(point);
694 
695   OPENSSL_cleanse(point, sizeof *point);
696   OPENSSL_free(point);
697 }
698 
EC_POINT_copy(EC_POINT * dest,const EC_POINT * src)699 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
700   if (dest->meth != src->meth) {
701     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
702     return 0;
703   }
704   if (dest == src) {
705     return 1;
706   }
707   return ec_GFp_simple_point_copy(dest, src);
708 }
709 
EC_POINT_dup(const EC_POINT * a,const EC_GROUP * group)710 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
711   EC_POINT *t;
712   int r;
713 
714   if (a == NULL) {
715     return NULL;
716   }
717 
718   t = EC_POINT_new(group);
719   if (t == NULL) {
720     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
721     return NULL;
722   }
723   r = EC_POINT_copy(t, a);
724   if (!r) {
725     EC_POINT_free(t);
726     return NULL;
727   } else {
728     return t;
729   }
730 }
731 
EC_POINT_set_to_infinity(const EC_GROUP * group,EC_POINT * point)732 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
733   if (group->meth != point->meth) {
734     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
735     return 0;
736   }
737   return ec_GFp_simple_point_set_to_infinity(group, point);
738 }
739 
EC_POINT_is_at_infinity(const EC_GROUP * group,const EC_POINT * point)740 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
741   if (group->meth != point->meth) {
742     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
743     return 0;
744   }
745   return ec_GFp_simple_is_at_infinity(group, point);
746 }
747 
EC_POINT_is_on_curve(const EC_GROUP * group,const EC_POINT * point,BN_CTX * ctx)748 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
749                          BN_CTX *ctx) {
750   if (group->meth != point->meth) {
751     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
752     return 0;
753   }
754   return ec_GFp_simple_is_on_curve(group, point, ctx);
755 }
756 
EC_POINT_cmp(const EC_GROUP * group,const EC_POINT * a,const EC_POINT * b,BN_CTX * ctx)757 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
758                  BN_CTX *ctx) {
759   if ((group->meth != a->meth) || (a->meth != b->meth)) {
760     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
761     return -1;
762   }
763   return ec_GFp_simple_cmp(group, a, b, ctx);
764 }
765 
EC_POINT_make_affine(const EC_GROUP * group,EC_POINT * point,BN_CTX * ctx)766 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
767   if (group->meth != point->meth) {
768     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
769     return 0;
770   }
771   return ec_GFp_simple_make_affine(group, point, ctx);
772 }
773 
EC_POINTs_make_affine(const EC_GROUP * group,size_t num,EC_POINT * points[],BN_CTX * ctx)774 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
775                           BN_CTX *ctx) {
776   size_t i;
777 
778   for (i = 0; i < num; i++) {
779     if (group->meth != points[i]->meth) {
780       OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
781       return 0;
782     }
783   }
784   return ec_GFp_simple_points_make_affine(group, num, points, ctx);
785 }
786 
EC_POINT_get_affine_coordinates_GFp(const EC_GROUP * group,const EC_POINT * point,BIGNUM * x,BIGNUM * y,BN_CTX * ctx)787 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
788                                         const EC_POINT *point, BIGNUM *x,
789                                         BIGNUM *y, BN_CTX *ctx) {
790   if (group->meth->point_get_affine_coordinates == 0) {
791     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
792     return 0;
793   }
794   if (group->meth != point->meth) {
795     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
796     return 0;
797   }
798   return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
799 }
800 
EC_POINT_set_affine_coordinates_GFp(const EC_GROUP * group,EC_POINT * point,const BIGNUM * x,const BIGNUM * y,BN_CTX * ctx)801 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
802                                         const BIGNUM *x, const BIGNUM *y,
803                                         BN_CTX *ctx) {
804   if (group->meth != point->meth) {
805     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
806     return 0;
807   }
808   if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) {
809     return 0;
810   }
811 
812   if (!EC_POINT_is_on_curve(group, point, ctx)) {
813     OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
814     return 0;
815   }
816 
817   return 1;
818 }
819 
EC_POINT_add(const EC_GROUP * group,EC_POINT * r,const EC_POINT * a,const EC_POINT * b,BN_CTX * ctx)820 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
821                  const EC_POINT *b, BN_CTX *ctx) {
822   if ((group->meth != r->meth) || (r->meth != a->meth) ||
823       (a->meth != b->meth)) {
824     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
825     return 0;
826   }
827   return ec_GFp_simple_add(group, r, a, b, ctx);
828 }
829 
830 
EC_POINT_dbl(const EC_GROUP * group,EC_POINT * r,const EC_POINT * a,BN_CTX * ctx)831 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
832                  BN_CTX *ctx) {
833   if ((group->meth != r->meth) || (r->meth != a->meth)) {
834     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
835     return 0;
836   }
837   return ec_GFp_simple_dbl(group, r, a, ctx);
838 }
839 
840 
EC_POINT_invert(const EC_GROUP * group,EC_POINT * a,BN_CTX * ctx)841 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
842   if (group->meth != a->meth) {
843     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
844     return 0;
845   }
846   return ec_GFp_simple_invert(group, a, ctx);
847 }
848 
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)849 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
850                  const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
851   /* Previously, this function set |r| to the point at infinity if there was
852    * nothing to multiply. But, nobody should be calling this function with
853    * nothing to multiply in the first place. */
854   if ((g_scalar == NULL && p_scalar == NULL) ||
855       ((p == NULL) != (p_scalar == NULL)))  {
856     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
857     return 0;
858   }
859 
860   if (group->meth != r->meth ||
861       (p != NULL && group->meth != p->meth)) {
862     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
863     return 0;
864   }
865 
866   return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx);
867 }
868 
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)869 int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
870                                              const BIGNUM *x, const BIGNUM *y,
871                                              const BIGNUM *z, BN_CTX *ctx) {
872   if (group->meth != point->meth) {
873     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
874     return 0;
875   }
876   return ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point, x, y, z,
877                                                        ctx);
878 }
879 
EC_GROUP_set_asn1_flag(EC_GROUP * group,int flag)880 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
881 
EC_GROUP_method_of(const EC_GROUP * group)882 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
883   return NULL;
884 }
885 
EC_METHOD_get_field_type(const EC_METHOD * meth)886 int EC_METHOD_get_field_type(const EC_METHOD *meth) {
887   return NID_X9_62_prime_field;
888 }
889 
EC_GROUP_set_point_conversion_form(EC_GROUP * group,point_conversion_form_t form)890 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
891                                         point_conversion_form_t form) {
892   if (form != POINT_CONVERSION_UNCOMPRESSED) {
893     abort();
894   }
895 }
896