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