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