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