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