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