blob: 96bb703702940e6a3230dd6fb54aaa5131cb7fbd [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
Adam Langleyfad63272015-11-12 12:15:39 -080070#include <assert.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080071#include <string.h>
72
73#include <openssl/bn.h>
74#include <openssl/err.h>
75#include <openssl/mem.h>
David Benjamin4969cc92016-04-22 15:02:23 -040076#include <openssl/nid.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080077
78#include "internal.h"
Adam Langleyfad63272015-11-12 12:15:39 -080079#include "../internal.h"
Adam Langleyd9e397b2015-01-22 14:27:53 -080080
81
82static const struct curve_data P224 = {
83 "NIST P-224",
84 28,
Adam Langleyd9e397b2015-01-22 14:27:53 -080085 {/* 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
111static const struct curve_data P256 = {
112 "NIST P-256",
113 32,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800114 {/* 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,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800142 {/* 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
173static const struct curve_data P521 = {
174 "NIST P-521",
175 66,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800176 {/* 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
Kenny Roote99801b2015-11-06 15:31:15 -0800219/* 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. */
Kenny Root03bcf612015-11-05 20:20:27 +0000221#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
222 !defined(MEMORY_SANITIZER)
Kenny Roote99801b2015-11-06 15:31:15 -0800223#define BORINGSSL_USE_INT128_CODE
224#endif
225
226const struct built_in_curve OPENSSL_built_in_curves[] = {
Adam Langleyfad63272015-11-12 12:15:39 -0800227 {
David Benjamin4969cc92016-04-22 15:02:23 -0400228 NID_secp521r1,
229 /* 1.3.132.0.35 */
230 {0x2b, 0x81, 0x04, 0x00, 0x23}, 5,
231 &P521,
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400232 &EC_GFp_mont_method,
David Benjamin4969cc92016-04-22 15:02:23 -0400233 },
234 {
235 NID_secp384r1,
236 /* 1.3.132.0.34 */
237 {0x2b, 0x81, 0x04, 0x00, 0x22}, 5,
238 &P384,
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400239 &EC_GFp_mont_method,
David Benjamin4969cc92016-04-22 15:02:23 -0400240 },
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,
Adam Langleyfad63272015-11-12 12:15:39 -0800246#if defined(BORINGSSL_USE_INT128_CODE)
247#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
248 !defined(OPENSSL_SMALL)
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400249 &EC_GFp_nistz256_method,
Adam Langleyfad63272015-11-12 12:15:39 -0800250#else
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400251 &EC_GFp_nistp256_method,
Adam Langleyfad63272015-11-12 12:15:39 -0800252#endif
253#else
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400254 &EC_GFp_mont_method,
Adam Langleyfad63272015-11-12 12:15:39 -0800255#endif
256 },
Kenny Roote99801b2015-11-06 15:31:15 -0800257 {
David Benjamin4969cc92016-04-22 15:02:23 -0400258 NID_secp224r1,
259 /* 1.3.132.0.33 */
260 {0x2b, 0x81, 0x04, 0x00, 0x21}, 5,
261 &P224,
Kenny Roote99801b2015-11-06 15:31:15 -0800262#if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL)
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400263 &EC_GFp_nistp224_method,
Kenny Roote99801b2015-11-06 15:31:15 -0800264#else
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400265 &EC_GFp_mont_method,
Kenny Roote99801b2015-11-06 15:31:15 -0800266#endif
267 },
David Benjamin4969cc92016-04-22 15:02:23 -0400268 {NID_undef, {0}, 0, NULL, NULL},
Adam Langleyd9e397b2015-01-22 14:27:53 -0800269};
270
Adam Langleyfad63272015-11-12 12:15:39 -0800271/* 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|. */
274static const BN_MONT_CTX **built_in_curve_scalar_field_monts;
275
276static CRYPTO_once_t built_in_curve_scalar_field_monts_once;
277
278static 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
325err:
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
330out:
331 BN_free(order);
332 BN_CTX_free(bn_ctx);
333}
334
Adam Langleyd9e397b2015-01-22 14:27:53 -0800335EC_GROUP *ec_group_new(const EC_METHOD *meth) {
336 EC_GROUP *ret;
337
338 if (meth == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000339 OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800340 return NULL;
341 }
342
343 if (meth->group_init == 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000344 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800345 return NULL;
346 }
347
348 ret = OPENSSL_malloc(sizeof(EC_GROUP));
349 if (ret == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000350 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800351 return NULL;
352 }
Robert Sloan69939df2017-01-09 10:53:07 -0800353 OPENSSL_memset(ret, 0, sizeof(EC_GROUP));
Adam Langleyd9e397b2015-01-22 14:27:53 -0800354
355 ret->meth = meth;
356 BN_init(&ret->order);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800357
358 if (!meth->group_init(ret)) {
359 OPENSSL_free(ret);
360 return NULL;
361 }
362
363 return ret;
364}
365
Adam Langley430091c2015-05-12 19:09:47 -0700366EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
367 const BIGNUM *b, BN_CTX *ctx) {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400368 EC_GROUP *ret = ec_group_new(&EC_GFp_mont_method);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800369 if (ret == NULL) {
370 return NULL;
371 }
372
373 if (ret->meth->group_set_curve == 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000374 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800375 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
Adam Langley430091c2015-05-12 19:09:47 -0700384int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
385 const BIGNUM *order, const BIGNUM *cofactor) {
David Benjamin4969cc92016-04-22 15:02:23 -0400386 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. */
Adam Langleyf4e42722015-06-04 17:45:09 -0700389 return 0;
390 }
391
David Benjaminc895d6b2016-08-11 13:26:41 -0400392 /* 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
David Benjamin4969cc92016-04-22 15:02:23 -0400398 group->generator = EC_POINT_new(group);
399 return group->generator != NULL &&
400 EC_POINT_copy(group->generator, generator) &&
David Benjaminc895d6b2016-08-11 13:26:41 -0400401 BN_copy(&group->order, order);
Adam Langley430091c2015-05-12 19:09:47 -0700402}
403
Adam Langleyfad63272015-11-12 12:15:39 -0800404static 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];
Adam Langleyd9e397b2015-01-22 14:27:53 -0800406 EC_GROUP *group = NULL;
407 EC_POINT *P = NULL;
Kenny Rootb8494592015-09-25 02:29:14 +0000408 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
Adam Langleyfad63272015-11-12 12:15:39 -0800409 int ok = 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800410
Adam Langleyfad63272015-11-12 12:15:39 -0800411 BN_CTX *ctx = BN_CTX_new();
412 if (ctx == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000413 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800414 goto err;
415 }
416
Adam Langleyfad63272015-11-12 12:15:39 -0800417 const struct curve_data *data = curve->data;
418 const unsigned param_len = data->param_len;
419 const uint8_t *params = data->data;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800420
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))) {
Kenny Rootb8494592015-09-25 02:29:14 +0000424 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800425 goto err;
426 }
427
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400428 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;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800433 }
434
435 if ((P = EC_POINT_new(group)) == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000436 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800437 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))) {
Kenny Rootb8494592015-09-25 02:29:14 +0000442 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800443 goto err;
444 }
445
446 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000447 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800448 goto err;
449 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400450 if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000451 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800452 goto err;
453 }
454
Adam Langleyfad63272015-11-12 12:15:39 -0800455 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
Adam Langleyd9e397b2015-01-22 14:27:53 -0800461 group->generator = P;
462 P = NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800463 ok = 1;
464
465err:
466 if (!ok) {
467 EC_GROUP_free(group);
468 group = NULL;
469 }
Adam Langleye9ada862015-05-11 17:20:37 -0700470 EC_POINT_free(P);
471 BN_CTX_free(ctx);
472 BN_free(p);
473 BN_free(a);
474 BN_free(b);
Adam Langleye9ada862015-05-11 17:20:37 -0700475 BN_free(x);
476 BN_free(y);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800477 return group;
478}
479
480EC_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) {
Adam Langleyfad63272015-11-12 12:15:39 -0800488 ret = ec_group_new_from_data(i);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800489 break;
490 }
491 }
492
493 if (ret == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000494 OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800495 return NULL;
496 }
497
498 ret->curve_name = nid;
499 return ret;
500}
501
502void 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
Adam Langleye9ada862015-05-11 17:20:37 -0700511 EC_POINT_free(group->generator);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800512 BN_free(&group->order);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800513
514 OPENSSL_free(group);
515}
516
Adam Langleyfad63272015-11-12 12:15:39 -0800517const BN_MONT_CTX *ec_group_get_mont_data(const EC_GROUP *group) {
518 return group->mont_data;
519}
520
Adam Langleyd9e397b2015-01-22 14:27:53 -0800521EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800522 if (a == NULL) {
523 return NULL;
524 }
525
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400526 if (a->meth->group_copy == NULL) {
527 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800528 return NULL;
529 }
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400530
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)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800548 goto err;
549 }
550
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400551 return ret;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800552
553err:
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400554 EC_GROUP_free(ret);
555 return NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800556}
557
Kenny Rootc897c7e2015-02-27 13:00:38 -0800558int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
Adam Langleyef935712015-02-25 11:16:32 -0800559 return a->curve_name == NID_undef ||
560 b->curve_name == NID_undef ||
561 a->curve_name != b->curve_name;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800562}
563
564const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
565 return group->generator;
566}
567
Adam Langley4139edb2016-01-13 15:00:54 -0800568const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
569 assert(!BN_is_zero(&group->order));
570 return &group->order;
571}
572
Adam Langleyd9e397b2015-01-22 14:27:53 -0800573int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
Adam Langley4139edb2016-01-13 15:00:54 -0800574 if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800575 return 0;
576 }
Adam Langley4139edb2016-01-13 15:00:54 -0800577 return 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800578}
579
580int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
581 BN_CTX *ctx) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400582 /* All |EC_GROUP|s have cofactor 1. */
583 return BN_set_word(cofactor, 1);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800584}
585
586int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
587 BIGNUM *out_b, BN_CTX *ctx) {
Kenny Roote99801b2015-11-06 15:31:15 -0800588 return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800589}
590
591int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
592
Kenny Roote99801b2015-11-06 15:31:15 -0800593unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
594 return ec_GFp_simple_group_get_degree(group);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800595}
596
Adam Langleyd9e397b2015-01-22 14:27:53 -0800597EC_POINT *EC_POINT_new(const EC_GROUP *group) {
598 EC_POINT *ret;
599
600 if (group == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000601 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800602 return NULL;
603 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800604
605 ret = OPENSSL_malloc(sizeof *ret);
606 if (ret == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000607 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800608 return NULL;
609 }
610
611 ret->meth = group->meth;
612
Kenny Roote99801b2015-11-06 15:31:15 -0800613 if (!ec_GFp_simple_point_init(ret)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800614 OPENSSL_free(ret);
615 return NULL;
616 }
617
618 return ret;
619}
620
621void EC_POINT_free(EC_POINT *point) {
622 if (!point) {
623 return;
624 }
625
Kenny Roote99801b2015-11-06 15:31:15 -0800626 ec_GFp_simple_point_finish(point);
627
Adam Langleyd9e397b2015-01-22 14:27:53 -0800628 OPENSSL_free(point);
629}
630
631void EC_POINT_clear_free(EC_POINT *point) {
632 if (!point) {
633 return;
634 }
635
Kenny Roote99801b2015-11-06 15:31:15 -0800636 ec_GFp_simple_point_clear_finish(point);
637
Adam Langleyd9e397b2015-01-22 14:27:53 -0800638 OPENSSL_cleanse(point, sizeof *point);
639 OPENSSL_free(point);
640}
641
642int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800643 if (dest->meth != src->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000644 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800645 return 0;
646 }
647 if (dest == src) {
648 return 1;
649 }
Kenny Roote99801b2015-11-06 15:31:15 -0800650 return ec_GFp_simple_point_copy(dest, src);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800651}
652
653EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800654 if (a == NULL) {
655 return NULL;
656 }
657
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400658 EC_POINT *ret = EC_POINT_new(group);
659 if (ret == NULL ||
660 !EC_POINT_copy(ret, a)) {
661 EC_POINT_free(ret);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800662 return NULL;
663 }
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400664
665 return ret;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800666}
667
668int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800669 if (group->meth != point->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000670 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800671 return 0;
672 }
Kenny Roote99801b2015-11-06 15:31:15 -0800673 return ec_GFp_simple_point_set_to_infinity(group, point);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800674}
675
676int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800677 if (group->meth != point->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000678 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800679 return 0;
680 }
Kenny Roote99801b2015-11-06 15:31:15 -0800681 return ec_GFp_simple_is_at_infinity(group, point);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800682}
683
684int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
685 BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800686 if (group->meth != point->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000687 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800688 return 0;
689 }
Kenny Roote99801b2015-11-06 15:31:15 -0800690 return ec_GFp_simple_is_on_curve(group, point, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800691}
692
693int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
694 BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800695 if ((group->meth != a->meth) || (a->meth != b->meth)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000696 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800697 return -1;
698 }
Kenny Roote99801b2015-11-06 15:31:15 -0800699 return ec_GFp_simple_cmp(group, a, b, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800700}
701
702int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800703 if (group->meth != point->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000704 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800705 return 0;
706 }
Kenny Roote99801b2015-11-06 15:31:15 -0800707 return ec_GFp_simple_make_affine(group, point, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800708}
709
710int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
711 BN_CTX *ctx) {
David Benjamin7c0d06c2016-08-11 13:26:41 -0400712 for (size_t i = 0; i < num; i++) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800713 if (group->meth != points[i]->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000714 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800715 return 0;
716 }
717 }
Kenny Roote99801b2015-11-06 15:31:15 -0800718 return ec_GFp_simple_points_make_affine(group, num, points, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800719}
720
721int 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) {
Kenny Rootb8494592015-09-25 02:29:14 +0000725 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800726 return 0;
727 }
728 if (group->meth != point->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000729 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800730 return 0;
731 }
732 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
733}
734
735int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
736 const BIGNUM *x, const BIGNUM *y,
737 BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800738 if (group->meth != point->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000739 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800740 return 0;
741 }
Adam Langleyfad63272015-11-12 12:15:39 -0800742 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;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800752}
753
754int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
755 const EC_POINT *b, BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800756 if ((group->meth != r->meth) || (r->meth != a->meth) ||
757 (a->meth != b->meth)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000758 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800759 return 0;
760 }
Kenny Roote99801b2015-11-06 15:31:15 -0800761 return ec_GFp_simple_add(group, r, a, b, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800762}
763
764
765int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
766 BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800767 if ((group->meth != r->meth) || (r->meth != a->meth)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000768 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800769 return 0;
770 }
Kenny Roote99801b2015-11-06 15:31:15 -0800771 return ec_GFp_simple_dbl(group, r, a, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800772}
773
774
775int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800776 if (group->meth != a->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000777 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800778 return 0;
779 }
Kenny Roote99801b2015-11-06 15:31:15 -0800780 return ec_GFp_simple_invert(group, a, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800781}
782
783int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
Adam Langley4139edb2016-01-13 15:00:54 -0800784 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 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800793
Adam Langley4139edb2016-01-13 15:00:54 -0800794 if (group->meth != r->meth ||
795 (p != NULL && group->meth != p->meth)) {
Adam Langleyfad63272015-11-12 12:15:39 -0800796 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
797 return 0;
798 }
799
Adam Langley4139edb2016-01-13 15:00:54 -0800800 return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800801}
802
803int 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) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800806 if (group->meth != point->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000807 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800808 return 0;
809 }
Kenny Roote99801b2015-11-06 15:31:15 -0800810 return ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point, x, y, z,
811 ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800812}
Adam Langleyf7e890d2015-03-31 18:58:05 -0700813
814void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
815
816const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
817 return NULL;
818}
819
820int EC_METHOD_get_field_type(const EC_METHOD *meth) {
821 return NID_X9_62_prime_field;
822}
Adam Langley830beae2015-04-20 10:49:33 -0700823
824void 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}
David Benjamin4969cc92016-04-22 15:02:23 -0400830
831size_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}