1 /* Originally written by Bodo Moeller for the OpenSSL project.
2 * ====================================================================
3 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
31 * 6. Redistributions of any form whatsoever must retain the following
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
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 * ====================================================================
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).
55 /* ====================================================================
56 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
58 * Portions of the attached software ("Contribution") are developed by
59 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
61 * The Contribution is licensed pursuant to the OpenSSL open source
62 * license provided above.
64 * The elliptic curve binary polynomial software is originally written by
65 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
68 #include <openssl/ec.h>
73 #include <openssl/bn.h>
74 #include <openssl/err.h>
75 #include <openssl/mem.h>
76 #include <openssl/nid.h>
79 #include "../../internal.h"
80 #include "../bn/internal.h"
81 #include "../delocate.h"
84 static void ec_point_free(EC_POINT *point, int free_group);
86 static const uint8_t kP224Params[6 * 28] = {
88 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
89 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x01,
92 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
93 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
94 0xFF, 0xFF, 0xFF, 0xFE,
96 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
97 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
98 0x23, 0x55, 0xFF, 0xB4,
100 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
101 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
102 0x11, 0x5C, 0x1D, 0x21,
104 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
105 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
106 0x85, 0x00, 0x7e, 0x34,
108 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
109 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
110 0x5C, 0x5C, 0x2A, 0x3D,
113 static const uint8_t kP256Params[6 * 32] = {
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,
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,
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,
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,
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,
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,
140 static const uint8_t kP384Params[6 * 48] = {
142 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
143 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
144 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
149 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
152 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
153 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
154 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
155 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
157 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
158 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
159 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
160 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
162 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
163 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
164 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
165 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
167 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
168 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
169 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
170 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73,
173 static const uint8_t kP521Params[6 * 66] = {
175 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
176 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
177 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
178 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
179 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
180 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
182 0x01, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
187 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
189 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
190 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
191 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
192 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
193 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
194 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
196 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
197 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
198 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
199 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
200 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
201 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
203 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
204 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
205 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
206 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
207 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
208 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
210 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
211 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
212 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
213 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
214 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
215 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09,
218 DEFINE_METHOD_FUNCTION(struct built_in_curves, OPENSSL_built_in_curves) {
220 static const uint8_t kOIDP521[] = {0x2b, 0x81, 0x04, 0x00, 0x23};
221 out->curves[0].nid = NID_secp521r1;
222 out->curves[0].oid = kOIDP521;
223 out->curves[0].oid_len = sizeof(kOIDP521);
224 out->curves[0].comment = "NIST P-521";
225 out->curves[0].param_len = 66;
226 out->curves[0].params = kP521Params;
227 out->curves[0].method = EC_GFp_mont_method();
230 static const uint8_t kOIDP384[] = {0x2b, 0x81, 0x04, 0x00, 0x22};
231 out->curves[1].nid = NID_secp384r1;
232 out->curves[1].oid = kOIDP384;
233 out->curves[1].oid_len = sizeof(kOIDP384);
234 out->curves[1].comment = "NIST P-384";
235 out->curves[1].param_len = 48;
236 out->curves[1].params = kP384Params;
237 out->curves[1].method = EC_GFp_mont_method();
239 // 1.2.840.10045.3.1.7
240 static const uint8_t kOIDP256[] = {0x2a, 0x86, 0x48, 0xce,
241 0x3d, 0x03, 0x01, 0x07};
242 out->curves[2].nid = NID_X9_62_prime256v1;
243 out->curves[2].oid = kOIDP256;
244 out->curves[2].oid_len = sizeof(kOIDP256);
245 out->curves[2].comment = "NIST P-256";
246 out->curves[2].param_len = 32;
247 out->curves[2].params = kP256Params;
248 out->curves[2].method =
249 #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
250 !defined(OPENSSL_SMALL)
251 EC_GFp_nistz256_method();
253 EC_GFp_nistp256_method();
257 static const uint8_t kOIDP224[] = {0x2b, 0x81, 0x04, 0x00, 0x21};
258 out->curves[3].nid = NID_secp224r1;
259 out->curves[3].oid = kOIDP224;
260 out->curves[3].oid_len = sizeof(kOIDP224);
261 out->curves[3].comment = "NIST P-224";
262 out->curves[3].param_len = 28;
263 out->curves[3].params = kP224Params;
264 out->curves[3].method =
265 #if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL)
266 EC_GFp_nistp224_method();
268 EC_GFp_mont_method();
272 EC_GROUP *ec_group_new(const EC_METHOD *meth) {
276 OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
280 if (meth->group_init == 0) {
281 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
285 ret = OPENSSL_malloc(sizeof(EC_GROUP));
287 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
290 OPENSSL_memset(ret, 0, sizeof(EC_GROUP));
294 BN_init(&ret->order);
296 if (!meth->group_init(ret)) {
304 static void ec_group_set0_generator(EC_GROUP *group, EC_POINT *generator) {
305 assert(group->generator == NULL);
306 assert(group == generator->group);
308 // Avoid a reference cycle. |group->generator| does not maintain an owning
309 // pointer to |group|.
310 group->generator = generator;
311 int is_zero = CRYPTO_refcount_dec_and_test_zero(&group->references);
317 EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
318 const BIGNUM *b, BN_CTX *ctx) {
319 if (BN_num_bytes(p) > EC_MAX_SCALAR_BYTES) {
320 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
324 EC_GROUP *ret = ec_group_new(EC_GFp_mont_method());
329 if (ret->meth->group_set_curve == NULL) {
330 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
334 if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
341 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
342 const BIGNUM *order, const BIGNUM *cofactor) {
343 if (group->curve_name != NID_undef || group->generator != NULL ||
344 generator->group != group) {
345 // |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by
346 // |EC_GROUP_new_curve_GFp| and may only used once on each group.
347 // Additionally, |generator| must been created from
348 // |EC_GROUP_new_curve_GFp|, not a copy, so that
349 // |generator->group->generator| is set correctly.
350 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
354 if (BN_num_bytes(order) > EC_MAX_SCALAR_BYTES) {
355 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
359 // Require a cofactor of one for custom curves, which implies prime order.
360 if (!BN_is_one(cofactor)) {
361 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COFACTOR);
365 // Require that p < 2×order. This simplifies some ECDSA operations.
367 // Note any curve which did not satisfy this must have been invalid or use a
368 // tiny prime (less than 17). See the proof in |field_element_to_scalar| in
369 // the ECDSA implementation.
370 BIGNUM *tmp = BN_new();
372 !BN_lshift1(tmp, order)) {
376 int ok = BN_cmp(tmp, &group->field) > 0;
379 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
383 EC_POINT *copy = EC_POINT_new(group);
385 !EC_POINT_copy(copy, generator) ||
386 !BN_copy(&group->order, order)) {
390 // Store the order in minimal form, so it can be used with |BN_ULONG| arrays.
391 bn_set_minimal_width(&group->order);
393 BN_MONT_CTX_free(group->order_mont);
394 group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, NULL);
395 if (group->order_mont == NULL) {
399 ec_group_set0_generator(group, copy);
403 static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
404 EC_GROUP *group = NULL;
406 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
409 BN_CTX *ctx = BN_CTX_new();
411 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
415 const unsigned param_len = curve->param_len;
416 const uint8_t *params = curve->params;
418 if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
419 !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
420 !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
421 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
425 group = ec_group_new(curve->method);
427 !group->meth->group_set_curve(group, p, a, b, ctx)) {
428 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
432 if ((P = EC_POINT_new(group)) == NULL) {
433 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
437 if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
438 !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
439 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
443 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
444 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
447 if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order)) {
448 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
452 group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, ctx);
453 if (group->order_mont == NULL) {
454 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
458 ec_group_set0_generator(group, P);
464 EC_GROUP_free(group);
477 // Built-in groups are allocated lazily and static once allocated.
478 // TODO(davidben): Make these actually static. https://crbug.com/boringssl/20.
479 struct built_in_groups_st {
480 EC_GROUP *groups[OPENSSL_NUM_BUILT_IN_CURVES];
482 DEFINE_BSS_GET(struct built_in_groups_st, built_in_groups);
483 DEFINE_STATIC_MUTEX(built_in_groups_lock);
485 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
486 struct built_in_groups_st *groups = built_in_groups_bss_get();
487 EC_GROUP **group_ptr = NULL;
488 const struct built_in_curves *const curves = OPENSSL_built_in_curves();
489 const struct built_in_curve *curve = NULL;
490 for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
491 if (curves->curves[i].nid == nid) {
492 curve = &curves->curves[i];
493 group_ptr = &groups->groups[i];
499 OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
503 CRYPTO_STATIC_MUTEX_lock_read(built_in_groups_lock_bss_get());
504 EC_GROUP *ret = *group_ptr;
505 CRYPTO_STATIC_MUTEX_unlock_read(built_in_groups_lock_bss_get());
510 ret = ec_group_new_from_data(curve);
515 EC_GROUP *to_free = NULL;
516 CRYPTO_STATIC_MUTEX_lock_write(built_in_groups_lock_bss_get());
517 if (*group_ptr == NULL) {
519 // Filling in |ret->curve_name| makes |EC_GROUP_free| and |EC_GROUP_dup|
520 // into no-ops. At this point, |ret| is considered static.
521 ret->curve_name = nid;
526 CRYPTO_STATIC_MUTEX_unlock_write(built_in_groups_lock_bss_get());
528 EC_GROUP_free(to_free);
532 void EC_GROUP_free(EC_GROUP *group) {
534 // Built-in curves are static.
535 group->curve_name != NID_undef ||
536 !CRYPTO_refcount_dec_and_test_zero(&group->references)) {
540 if (group->meth->group_finish != NULL) {
541 group->meth->group_finish(group);
544 ec_point_free(group->generator, 0 /* don't free group */);
545 BN_free(&group->order);
546 BN_MONT_CTX_free(group->order_mont);
551 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
553 // Built-in curves are static.
554 a->curve_name != NID_undef) {
555 return (EC_GROUP *)a;
558 // Groups are logically immutable (but for |EC_GROUP_set_generator| which must
559 // be called early on), so we simply take a reference.
560 EC_GROUP *group = (EC_GROUP *)a;
561 CRYPTO_refcount_inc(&group->references);
565 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
566 // Note this function returns 0 if equal and non-zero otherwise.
570 if (a->curve_name != b->curve_name) {
573 if (a->curve_name != NID_undef) {
574 // Built-in curves may be compared by curve name alone.
578 // |a| and |b| are both custom curves. We compare the entire curve
579 // structure. If |a| or |b| is incomplete (due to legacy OpenSSL mistakes,
580 // custom curve construction is sadly done in two parts) but otherwise not the
581 // same object, we consider them always unequal.
582 return a->generator == NULL ||
583 b->generator == NULL ||
584 BN_cmp(&a->order, &b->order) != 0 ||
585 BN_cmp(&a->field, &b->field) != 0 ||
586 BN_cmp(&a->a, &b->a) != 0 ||
587 BN_cmp(&a->b, &b->b) != 0 ||
588 ec_GFp_simple_cmp(a, a->generator, b->generator, NULL) != 0;
591 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
592 return group->generator;
595 const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
596 assert(!BN_is_zero(&group->order));
597 return &group->order;
600 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
601 if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
607 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
609 // All |EC_GROUP|s have cofactor 1.
610 return BN_set_word(cofactor, 1);
613 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
614 BIGNUM *out_b, BN_CTX *ctx) {
615 return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx);
618 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
620 unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
621 return ec_GFp_simple_group_get_degree(group);
624 EC_POINT *EC_POINT_new(const EC_GROUP *group) {
628 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
632 ret = OPENSSL_malloc(sizeof *ret);
634 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
638 ret->group = EC_GROUP_dup(group);
639 if (ret->group == NULL ||
640 !ec_GFp_simple_point_init(ret)) {
648 static void ec_point_free(EC_POINT *point, int free_group) {
652 ec_GFp_simple_point_finish(point);
654 EC_GROUP_free(point->group);
659 void EC_POINT_free(EC_POINT *point) {
660 ec_point_free(point, 1 /* free group */);
663 void EC_POINT_clear_free(EC_POINT *point) { EC_POINT_free(point); }
665 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
666 if (EC_GROUP_cmp(dest->group, src->group, NULL) != 0) {
667 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
673 return ec_GFp_simple_point_copy(dest, src);
676 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
681 EC_POINT *ret = EC_POINT_new(group);
683 !EC_POINT_copy(ret, a)) {
691 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
692 if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
693 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
696 return ec_GFp_simple_point_set_to_infinity(group, point);
699 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
700 if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
701 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
704 return ec_GFp_simple_is_at_infinity(group, point);
707 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
709 if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
710 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
713 return ec_GFp_simple_is_on_curve(group, point, ctx);
716 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
718 if (EC_GROUP_cmp(group, a->group, NULL) != 0 ||
719 EC_GROUP_cmp(group, b->group, NULL) != 0) {
720 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
723 return ec_GFp_simple_cmp(group, a, b, ctx);
726 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
727 if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
728 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
731 return ec_GFp_simple_make_affine(group, point, ctx);
734 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
736 for (size_t i = 0; i < num; i++) {
737 if (EC_GROUP_cmp(group, points[i]->group, NULL) != 0) {
738 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
742 return ec_GFp_simple_points_make_affine(group, num, points, ctx);
745 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
746 const EC_POINT *point, BIGNUM *x,
747 BIGNUM *y, BN_CTX *ctx) {
748 if (group->meth->point_get_affine_coordinates == 0) {
749 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
752 if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
753 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
756 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
759 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
760 const BIGNUM *x, const BIGNUM *y,
762 if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
763 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
766 if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) {
770 if (!EC_POINT_is_on_curve(group, point, ctx)) {
771 // In the event of an error, defend against the caller not checking the
772 // return value by setting a known safe value: the base point.
773 const EC_POINT *generator = EC_GROUP_get0_generator(group);
774 // The generator can be missing if the caller is in the process of
775 // constructing an arbitrary group. In this, we give up and hope they're
776 // checking the return value.
778 EC_POINT_copy(point, generator);
780 OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
787 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
788 const EC_POINT *b, BN_CTX *ctx) {
789 if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
790 EC_GROUP_cmp(group, a->group, NULL) != 0 ||
791 EC_GROUP_cmp(group, b->group, NULL) != 0) {
792 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
795 return ec_GFp_simple_add(group, r, a, b, ctx);
799 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
801 if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
802 EC_GROUP_cmp(group, a->group, NULL) != 0) {
803 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
806 return ec_GFp_simple_dbl(group, r, a, ctx);
810 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
811 if (EC_GROUP_cmp(group, a->group, NULL) != 0) {
812 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
815 return ec_GFp_simple_invert(group, a, ctx);
818 static int arbitrary_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
819 const BIGNUM *in, BN_CTX *ctx) {
820 if (ec_bignum_to_scalar(group, out, in)) {
826 // This is an unusual input, so we do not guarantee constant-time processing.
827 const BIGNUM *order = &group->order;
829 BIGNUM *tmp = BN_CTX_get(ctx);
830 int ok = tmp != NULL &&
831 BN_nnmod(tmp, in, order, ctx) &&
832 ec_bignum_to_scalar_unchecked(group, out, tmp);
837 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
838 const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
839 // Previously, this function set |r| to the point at infinity if there was
840 // nothing to multiply. But, nobody should be calling this function with
841 // nothing to multiply in the first place.
842 if ((g_scalar == NULL && p_scalar == NULL) ||
843 (p == NULL) != (p_scalar == NULL)) {
844 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
849 EC_SCALAR g_scalar_storage, p_scalar_storage;
850 EC_SCALAR *g_scalar_arg = NULL, *p_scalar_arg = NULL;
851 BN_CTX *new_ctx = NULL;
853 new_ctx = BN_CTX_new();
854 if (new_ctx == NULL) {
860 if (g_scalar != NULL) {
861 if (!arbitrary_bignum_to_scalar(group, &g_scalar_storage, g_scalar, ctx)) {
864 g_scalar_arg = &g_scalar_storage;
867 if (p_scalar != NULL) {
868 if (!arbitrary_bignum_to_scalar(group, &p_scalar_storage, p_scalar, ctx)) {
871 p_scalar_arg = &p_scalar_storage;
874 ret = ec_point_mul_scalar(group, r, g_scalar_arg, p, p_scalar_arg, ctx);
877 BN_CTX_free(new_ctx);
878 OPENSSL_cleanse(&g_scalar_storage, sizeof(g_scalar_storage));
879 OPENSSL_cleanse(&p_scalar_storage, sizeof(p_scalar_storage));
883 int ec_point_mul_scalar_public(const EC_GROUP *group, EC_POINT *r,
884 const EC_SCALAR *g_scalar, const EC_POINT *p,
885 const EC_SCALAR *p_scalar, BN_CTX *ctx) {
886 if ((g_scalar == NULL && p_scalar == NULL) ||
887 (p == NULL) != (p_scalar == NULL)) {
888 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
892 if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
893 (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) {
894 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
898 return group->meth->mul_public(group, r, g_scalar, p, p_scalar, ctx);
901 int ec_point_mul_scalar(const EC_GROUP *group, EC_POINT *r,
902 const EC_SCALAR *g_scalar, const EC_POINT *p,
903 const EC_SCALAR *p_scalar, BN_CTX *ctx) {
904 if ((g_scalar == NULL && p_scalar == NULL) ||
905 (p == NULL) != (p_scalar == NULL)) {
906 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
910 if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
911 (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) {
912 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
916 return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx);
919 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
921 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
925 int EC_METHOD_get_field_type(const EC_METHOD *meth) {
926 return NID_X9_62_prime_field;
929 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
930 point_conversion_form_t form) {
931 if (form != POINT_CONVERSION_UNCOMPRESSED) {
936 size_t EC_get_builtin_curves(EC_builtin_curve *out_curves,
937 size_t max_num_curves) {
938 const struct built_in_curves *const curves = OPENSSL_built_in_curves();
940 for (size_t i = 0; i < max_num_curves && i < OPENSSL_NUM_BUILT_IN_CURVES;
942 out_curves[i].comment = curves->curves[i].comment;
943 out_curves[i].nid = curves->curves[i].nid;
946 return OPENSSL_NUM_BUILT_IN_CURVES;
949 int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
951 if (!ec_bignum_to_scalar_unchecked(group, out, in)) {
954 if (!bn_less_than_words(out->words, group->order.d, group->order.width)) {
955 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
961 int ec_bignum_to_scalar_unchecked(const EC_GROUP *group, EC_SCALAR *out,
963 if (!bn_copy_words(out->words, group->order.width, in)) {
964 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
970 int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out,
971 const uint8_t additional_data[32]) {
972 return bn_rand_range_words(out->words, 1, group->order.d, group->order.width,