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