blob: 30def15117dc0ae65f856838d93f137c22257410 [file] [log] [blame]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001/* 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
80static 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
110static 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
139static 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
174static 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
221const struct built_in_curve OPENSSL_built_in_curves[] = {
222 {NID_secp224r1, &P224, 0},
223 {NID_X9_62_prime256v1, &P256, 0},
224 {NID_secp384r1, &P384, 0},
225 {NID_secp521r1, &P521, 0},
226 {NID_undef, 0, 0},
227};
228
229EC_GROUP *ec_group_new(const EC_METHOD *meth) {
230 EC_GROUP *ret;
231
232 if (meth == NULL) {
233 OPENSSL_PUT_ERROR(EC, ec_group_new, EC_R_SLOT_FULL);
234 return NULL;
235 }
236
237 if (meth->group_init == 0) {
238 OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
239 return NULL;
240 }
241
242 ret = OPENSSL_malloc(sizeof(EC_GROUP));
243 if (ret == NULL) {
244 OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_MALLOC_FAILURE);
245 return NULL;
246 }
247 memset(ret, 0, sizeof(EC_GROUP));
248
249 ret->meth = meth;
250 BN_init(&ret->order);
251 BN_init(&ret->cofactor);
252
253 if (!meth->group_init(ret)) {
254 OPENSSL_free(ret);
255 return NULL;
256 }
257
258 return ret;
259}
260
261static EC_GROUP *ec_group_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
262 const BIGNUM *b, BN_CTX *ctx) {
263 const EC_METHOD *meth = EC_GFp_mont_method();
264 EC_GROUP *ret;
265
266 ret = ec_group_new(meth);
267 if (ret == NULL) {
268 return NULL;
269 }
270
271 if (ret->meth->group_set_curve == 0) {
272 OPENSSL_PUT_ERROR(EC, ec_group_new_curve_GFp,
273 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
274 return 0;
275 }
276 if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
277 EC_GROUP_free(ret);
278 return NULL;
279 }
280 return ret;
281}
282
283static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
284 EC_GROUP *group = NULL;
285 EC_POINT *P = NULL;
286 BN_CTX *ctx = NULL;
287 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL;
288 int ok = 0;
289 unsigned param_len;
290 const EC_METHOD *meth;
291 const struct curve_data *data;
292 const uint8_t *params;
293
294 if ((ctx = BN_CTX_new()) == NULL) {
295 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_MALLOC_FAILURE);
296 goto err;
297 }
298
299 data = curve->data;
300 param_len = data->param_len;
301 params = data->data;
302
303 if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
304 !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
305 !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
306 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
307 goto err;
308 }
309
310 if (curve->method != 0) {
311 meth = curve->method();
312 if (((group = ec_group_new(meth)) == NULL) ||
313 (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
314 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
315 goto err;
316 }
317 } else {
318 if ((group = ec_group_new_curve_GFp(p, a, b, ctx)) == NULL) {
319 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
320 goto err;
321 }
322 }
323
324 if ((P = EC_POINT_new(group)) == NULL) {
325 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
326 goto err;
327 }
328
329 if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
330 !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
331 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
332 goto err;
333 }
334
335 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
336 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
337 goto err;
338 }
339 if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) ||
340 !BN_set_word(x, (BN_ULONG)data->cofactor)) {
341 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
342 goto err;
343 }
344
345 group->generator = P;
346 P = NULL;
347 if (!BN_copy(&group->order, order) ||
348 !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
349 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
350 goto err;
351 }
352
353 ok = 1;
354
355err:
356 if (!ok) {
357 EC_GROUP_free(group);
358 group = NULL;
359 }
360 if (P)
361 EC_POINT_free(P);
362 if (ctx)
363 BN_CTX_free(ctx);
364 if (p)
365 BN_free(p);
366 if (a)
367 BN_free(a);
368 if (b)
369 BN_free(b);
370 if (order)
371 BN_free(order);
372 if (x)
373 BN_free(x);
374 if (y)
375 BN_free(y);
376 return group;
377}
378
379EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
380 unsigned i;
381 const struct built_in_curve *curve;
382 EC_GROUP *ret = NULL;
383
384 for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
385 curve = &OPENSSL_built_in_curves[i];
386 if (curve->nid == nid) {
387 ret = ec_group_new_from_data(curve);
388 break;
389 }
390 }
391
392 if (ret == NULL) {
393 OPENSSL_PUT_ERROR(EC, EC_GROUP_new_by_curve_name, EC_R_UNKNOWN_GROUP);
394 return NULL;
395 }
396
397 ret->curve_name = nid;
398 return ret;
399}
400
401void EC_GROUP_free(EC_GROUP *group) {
402 if (!group) {
403 return;
404 }
405
406 if (group->meth->group_finish != 0) {
407 group->meth->group_finish(group);
408 }
409
410 ec_pre_comp_free(group->pre_comp);
411
412 if (group->generator != NULL) {
413 EC_POINT_free(group->generator);
414 }
415 BN_free(&group->order);
416 BN_free(&group->cofactor);
417
418 OPENSSL_free(group);
419}
420
421int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) {
422 if (dest->meth->group_copy == 0) {
423 OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
424 return 0;
425 }
426 if (dest->meth != src->meth) {
427 OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, EC_R_INCOMPATIBLE_OBJECTS);
428 return 0;
429 }
430 if (dest == src) {
431 return 1;
432 }
433
434 ec_pre_comp_free(dest->pre_comp);
435 dest->pre_comp = ec_pre_comp_dup(src->pre_comp);
436
437 if (src->generator != NULL) {
438 if (dest->generator == NULL) {
439 dest->generator = EC_POINT_new(dest);
440 if (dest->generator == NULL) {
441 return 0;
442 }
443 }
444 if (!EC_POINT_copy(dest->generator, src->generator)) {
445 return 0;
446 }
447 } else {
448 /* src->generator == NULL */
449 if (dest->generator != NULL) {
450 EC_POINT_clear_free(dest->generator);
451 dest->generator = NULL;
452 }
453 }
454
455 if (!BN_copy(&dest->order, &src->order) ||
456 !BN_copy(&dest->cofactor, &src->cofactor)) {
457 return 0;
458 }
459
460 dest->curve_name = src->curve_name;
461
462 return dest->meth->group_copy(dest, src);
463}
464
465EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
466 EC_GROUP *t = NULL;
467 int ok = 0;
468
469 if (a == NULL) {
470 return NULL;
471 }
472
473 t = ec_group_new(a->meth);
474 if (t == NULL) {
475 return NULL;
476 }
477 if (!EC_GROUP_copy(t, a)) {
478 goto err;
479 }
480
481 ok = 1;
482
483err:
484 if (!ok) {
485 if (t) {
486 EC_GROUP_free(t);
487 }
488 return NULL;
489 } else {
490 return t;
491 }
492}
493
Kenny Rootc897c7e2015-02-27 13:00:38 -0800494int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
Adam Langleyef935712015-02-25 11:16:32 -0800495 return a->curve_name == NID_undef ||
496 b->curve_name == NID_undef ||
497 a->curve_name != b->curve_name;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800498}
499
500const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
501 return group->generator;
502}
503
504int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
505 if (!BN_copy(order, &group->order)) {
506 return 0;
507 }
508
509 return !BN_is_zero(order);
510}
511
512int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
513 BN_CTX *ctx) {
514 if (!BN_copy(cofactor, &group->cofactor)) {
515 return 0;
516 }
517
518 return !BN_is_zero(&group->cofactor);
519}
520
521int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
522 BIGNUM *out_b, BN_CTX *ctx) {
523 if (group->meth->group_get_curve == 0) {
524 OPENSSL_PUT_ERROR(EC, EC_GROUP_get_curve_GFp,
525 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
526 return 0;
527 }
528 return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx);
529}
530
531int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
532
533int EC_GROUP_get_degree(const EC_GROUP *group) {
534 if (group->meth->group_get_degree == 0) {
535 OPENSSL_PUT_ERROR(EC, EC_GROUP_get_degree,
536 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
537 return 0;
538 }
539 return group->meth->group_get_degree(group);
540}
541
542int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
543 if (group->meth->mul == 0) {
544 /* use default */
545 return ec_wNAF_precompute_mult(group, ctx);
546 }
547
548 if (group->meth->precompute_mult != 0) {
549 return group->meth->precompute_mult(group, ctx);
550 }
551
552 return 1; /* nothing to do, so report success */
553}
554
555int EC_GROUP_have_precompute_mult(const EC_GROUP *group) {
556 if (group->meth->mul == 0) {
557 /* use default */
558 return ec_wNAF_have_precompute_mult(group);
559 }
560
561 if (group->meth->have_precompute_mult != 0) {
562 return group->meth->have_precompute_mult(group);
563 }
564
565 return 0; /* cannot tell whether precomputation has been performed */
566}
567
568EC_POINT *EC_POINT_new(const EC_GROUP *group) {
569 EC_POINT *ret;
570
571 if (group == NULL) {
572 OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_PASSED_NULL_PARAMETER);
573 return NULL;
574 }
575 if (group->meth->point_init == 0) {
576 OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
577 return NULL;
578 }
579
580 ret = OPENSSL_malloc(sizeof *ret);
581 if (ret == NULL) {
582 OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_MALLOC_FAILURE);
583 return NULL;
584 }
585
586 ret->meth = group->meth;
587
588 if (!ret->meth->point_init(ret)) {
589 OPENSSL_free(ret);
590 return NULL;
591 }
592
593 return ret;
594}
595
596void EC_POINT_free(EC_POINT *point) {
597 if (!point) {
598 return;
599 }
600
601 if (point->meth->point_finish != 0) {
602 point->meth->point_finish(point);
603 }
604 OPENSSL_free(point);
605}
606
607void EC_POINT_clear_free(EC_POINT *point) {
608 if (!point) {
609 return;
610 }
611
612 if (point->meth->point_clear_finish != 0) {
613 point->meth->point_clear_finish(point);
614 } else if (point->meth->point_finish != 0) {
615 point->meth->point_finish(point);
616 }
617 OPENSSL_cleanse(point, sizeof *point);
618 OPENSSL_free(point);
619}
620
621int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
622 if (dest->meth->point_copy == 0) {
623 OPENSSL_PUT_ERROR(EC, EC_POINT_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
624 return 0;
625 }
626 if (dest->meth != src->meth) {
627 OPENSSL_PUT_ERROR(EC, EC_POINT_copy, EC_R_INCOMPATIBLE_OBJECTS);
628 return 0;
629 }
630 if (dest == src) {
631 return 1;
632 }
633 return dest->meth->point_copy(dest, src);
634}
635
636EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
637 EC_POINT *t;
638 int r;
639
640 if (a == NULL) {
641 return NULL;
642 }
643
644 t = EC_POINT_new(group);
645 if (t == NULL) {
646 OPENSSL_PUT_ERROR(EC, EC_POINT_dup, ERR_R_MALLOC_FAILURE);
647 return NULL;
648 }
649 r = EC_POINT_copy(t, a);
650 if (!r) {
651 EC_POINT_free(t);
652 return NULL;
653 } else {
654 return t;
655 }
656}
657
658int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
659 if (group->meth->point_set_to_infinity == 0) {
660 OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity,
661 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
662 return 0;
663 }
664 if (group->meth != point->meth) {
665 OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity, EC_R_INCOMPATIBLE_OBJECTS);
666 return 0;
667 }
668 return group->meth->point_set_to_infinity(group, point);
669}
670
671int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
672 if (group->meth->is_at_infinity == 0) {
673 OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity,
674 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
675 return 0;
676 }
677 if (group->meth != point->meth) {
678 OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity, EC_R_INCOMPATIBLE_OBJECTS);
679 return 0;
680 }
681 return group->meth->is_at_infinity(group, point);
682}
683
684int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
685 BN_CTX *ctx) {
686 if (group->meth->is_on_curve == 0) {
687 OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve,
688 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
689 return 0;
690 }
691 if (group->meth != point->meth) {
692 OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve, EC_R_INCOMPATIBLE_OBJECTS);
693 return 0;
694 }
695 return group->meth->is_on_curve(group, point, ctx);
696}
697
698int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
699 BN_CTX *ctx) {
700 if (group->meth->point_cmp == 0) {
701 OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
702 return -1;
703 }
704 if ((group->meth != a->meth) || (a->meth != b->meth)) {
705 OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, EC_R_INCOMPATIBLE_OBJECTS);
706 return -1;
707 }
708 return group->meth->point_cmp(group, a, b, ctx);
709}
710
711int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
712 if (group->meth->make_affine == 0) {
713 OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine,
714 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
715 return 0;
716 }
717 if (group->meth != point->meth) {
718 OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
719 return 0;
720 }
721 return group->meth->make_affine(group, point, ctx);
722}
723
724int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
725 BN_CTX *ctx) {
726 size_t i;
727
728 if (group->meth->points_make_affine == 0) {
729 OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine,
730 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
731 return 0;
732 }
733 for (i = 0; i < num; i++) {
734 if (group->meth != points[i]->meth) {
735 OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
736 return 0;
737 }
738 }
739 return group->meth->points_make_affine(group, num, points, ctx);
740}
741
742int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
743 const EC_POINT *point, BIGNUM *x,
744 BIGNUM *y, BN_CTX *ctx) {
745 if (group->meth->point_get_affine_coordinates == 0) {
746 OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
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_get_affine_coordinates_GFp,
752 EC_R_INCOMPATIBLE_OBJECTS);
753 return 0;
754 }
755 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
756}
757
758int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
759 const BIGNUM *x, const BIGNUM *y,
760 BN_CTX *ctx) {
761 if (group->meth->point_set_affine_coordinates == 0) {
762 OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
763 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
764 return 0;
765 }
766 if (group->meth != point->meth) {
767 OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
768 EC_R_INCOMPATIBLE_OBJECTS);
769 return 0;
770 }
771 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
772}
773
774int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
775 const EC_POINT *b, BN_CTX *ctx) {
776 if (group->meth->add == 0) {
777 OPENSSL_PUT_ERROR(EC, EC_POINT_add, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
778 return 0;
779 }
780 if ((group->meth != r->meth) || (r->meth != a->meth) ||
781 (a->meth != b->meth)) {
782 OPENSSL_PUT_ERROR(EC, EC_POINT_add, EC_R_INCOMPATIBLE_OBJECTS);
783 return 0;
784 }
785 return group->meth->add(group, r, a, b, ctx);
786}
787
788
789int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
790 BN_CTX *ctx) {
791 if (group->meth->dbl == 0) {
792 OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
793 return 0;
794 }
795 if ((group->meth != r->meth) || (r->meth != a->meth)) {
796 OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, EC_R_INCOMPATIBLE_OBJECTS);
797 return 0;
798 }
799 return group->meth->dbl(group, r, a, ctx);
800}
801
802
803int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
804 if (group->meth->invert == 0) {
805 OPENSSL_PUT_ERROR(EC, EC_POINT_invert, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
806 return 0;
807 }
808 if (group->meth != a->meth) {
809 OPENSSL_PUT_ERROR(EC, EC_POINT_invert, EC_R_INCOMPATIBLE_OBJECTS);
810 return 0;
811 }
812 return group->meth->invert(group, a, ctx);
813}
814
815int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
816 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) {
817 /* just a convenient interface to EC_POINTs_mul() */
818
819 const EC_POINT *points[1];
820 const BIGNUM *scalars[1];
821
822 points[0] = point;
823 scalars[0] = p_scalar;
824
825 return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL),
826 points, scalars, ctx);
827}
828
829int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
830 size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
831 BN_CTX *ctx) {
832 if (group->meth->mul == 0) {
833 /* use default. Warning, not constant-time. */
834 return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
835 }
836
837 return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
838}
839
840int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
841 const BIGNUM *x, const BIGNUM *y,
842 const BIGNUM *z, BN_CTX *ctx) {
843 if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
844 OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
845 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
846 return 0;
847 }
848 if (group->meth != point->meth) {
849 OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
850 EC_R_INCOMPATIBLE_OBJECTS);
851 return 0;
852 }
853 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y,
854 z, ctx);
855}