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