blob: 7e6eecc9a937513788dba2a87c2328c6ac2d9b11 [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"
Robert Sloan8ff03552017-06-14 12:40:58 -070079#include "../../internal.h"
80#include "../delocate.h"
Adam Langleyd9e397b2015-01-22 14:27:53 -080081
82
Robert Sloan8ff03552017-06-14 12:40:58 -070083DEFINE_LOCAL_DATA(struct curve_data, P224_data) {
84 static const uint8_t kData[6 * 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 };
Adam Langleyd9e397b2015-01-22 14:27:53 -0800110
Robert Sloan8ff03552017-06-14 12:40:58 -0700111 out->comment = "NIST P-224";
112 out->param_len = 28;
113 out->data = kData;
114};
Adam Langleyd9e397b2015-01-22 14:27:53 -0800115
Robert Sloan8ff03552017-06-14 12:40:58 -0700116DEFINE_LOCAL_DATA(struct curve_data, P256_data) {
117 static const uint8_t kData[6 * 32] = {
118 /* p */
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, 0xFF,
122 /* a */
123 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
125 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
126 /* b */
127 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
128 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
129 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
130 /* x */
131 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
132 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
133 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
134 /* y */
135 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
136 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
137 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
138 /* order */
139 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
140 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
141 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
142 };
Adam Langleyd9e397b2015-01-22 14:27:53 -0800143
Robert Sloan8ff03552017-06-14 12:40:58 -0700144 out->comment = "NIST P-256";
145 out->param_len = 32;
146 out->data = kData;
147}
148
149DEFINE_LOCAL_DATA(struct curve_data, P384_data) {
150 static const uint8_t kData[6 * 48] = {
151 /* p */
152 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
153 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
154 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
156 /* a */
157 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
158 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
161 /* b */
162 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
163 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
164 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
165 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
166 /* x */
167 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
168 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
169 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
170 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
171 /* y */
172 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
173 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
174 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
175 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
176 /* order */
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 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
180 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
181 };
182
183 out->comment = "NIST P-384";
184 out->param_len = 48;
185 out->data = kData;
186}
187
188DEFINE_LOCAL_DATA(struct curve_data, P521_data) {
189 static const uint8_t kData[6 * 66] = {
190 /* p */
191 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
192 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
193 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
194 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
195 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
196 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
197 /* a */
198 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
199 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
200 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
201 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
202 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
203 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
204 /* b */
205 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
206 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
207 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
208 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
209 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
210 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
211 /* x */
212 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
213 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
214 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
215 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
216 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
217 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
218 /* y */
219 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
220 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
221 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
222 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
223 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
224 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
225 /* order */
226 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
227 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
228 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
229 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
230 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
231 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09
232 };
233
234 out->comment = "NIST P-521";
235 out->param_len = 66;
236 out->data = kData;
237}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800238
Kenny Roote99801b2015-11-06 15:31:15 -0800239/* MSan appears to have a bug that causes code to be miscompiled in opt mode.
240 * While that is being looked at, don't run the uint128_t code under MSan. */
Kenny Root03bcf612015-11-05 20:20:27 +0000241#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
242 !defined(MEMORY_SANITIZER)
Kenny Roote99801b2015-11-06 15:31:15 -0800243#define BORINGSSL_USE_INT128_CODE
244#endif
245
Robert Sloan8ff03552017-06-14 12:40:58 -0700246DEFINE_METHOD_FUNCTION(struct built_in_curves, OPENSSL_built_in_curves) {
247 /* 1.3.132.0.35 */
248 static const uint8_t kOIDP521[] = {0x2b, 0x81, 0x04, 0x00, 0x23};
249 out->curves[0].nid = NID_secp521r1;
250 out->curves[0].oid = kOIDP521;
251 out->curves[0].oid_len = sizeof(kOIDP521);
252 out->curves[0].data = P521_data();
253 out->curves[0].method = EC_GFp_mont_method();
254
255 /* 1.3.132.0.34 */
256 static const uint8_t kOIDP384[] = {0x2b, 0x81, 0x04, 0x00, 0x22};
257 out->curves[1].nid = NID_secp384r1;
258 out->curves[1].oid = kOIDP384;
259 out->curves[1].oid_len = sizeof(kOIDP384);
260 out->curves[1].data = P384_data();
261 out->curves[1].method = EC_GFp_mont_method();
262
263 /* 1.2.840.10045.3.1.7 */
264 static const uint8_t kOIDP256[] = {0x2a, 0x86, 0x48, 0xce,
265 0x3d, 0x03, 0x01, 0x07};
266 out->curves[2].nid = NID_X9_62_prime256v1;
267 out->curves[2].oid = kOIDP256;
268 out->curves[2].oid_len = sizeof(kOIDP256);
269 out->curves[2].data = P256_data();
270 out->curves[2].method =
Adam Langleyfad63272015-11-12 12:15:39 -0800271#if defined(BORINGSSL_USE_INT128_CODE)
272#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
273 !defined(OPENSSL_SMALL)
Robert Sloan8ff03552017-06-14 12:40:58 -0700274 EC_GFp_nistz256_method();
Adam Langleyfad63272015-11-12 12:15:39 -0800275#else
Robert Sloan8ff03552017-06-14 12:40:58 -0700276 EC_GFp_nistp256_method();
Adam Langleyfad63272015-11-12 12:15:39 -0800277#endif
278#else
Robert Sloan8ff03552017-06-14 12:40:58 -0700279 EC_GFp_mont_method();
Adam Langleyfad63272015-11-12 12:15:39 -0800280#endif
Robert Sloan8ff03552017-06-14 12:40:58 -0700281
282 /* 1.3.132.0.33 */
283 static const uint8_t kOIDP224[] = {0x2b, 0x81, 0x04, 0x00, 0x21};
284 out->curves[3].nid = NID_secp224r1;
285 out->curves[3].oid = kOIDP224;
286 out->curves[3].oid_len = sizeof(kOIDP224);
287 out->curves[3].data = P224_data();
288 out->curves[3].method =
Kenny Roote99801b2015-11-06 15:31:15 -0800289#if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL)
Robert Sloan8ff03552017-06-14 12:40:58 -0700290 EC_GFp_nistp224_method();
Kenny Roote99801b2015-11-06 15:31:15 -0800291#else
Robert Sloan8ff03552017-06-14 12:40:58 -0700292 EC_GFp_mont_method();
Kenny Roote99801b2015-11-06 15:31:15 -0800293#endif
Robert Sloan8ff03552017-06-14 12:40:58 -0700294}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800295
Adam Langleyfad63272015-11-12 12:15:39 -0800296/* built_in_curve_scalar_field_monts contains Montgomery contexts for
297 * performing inversions in the scalar fields of each of the built-in
298 * curves. It's protected by |built_in_curve_scalar_field_monts_once|. */
Robert Sloan8ff03552017-06-14 12:40:58 -0700299DEFINE_LOCAL_DATA(BN_MONT_CTX **, built_in_curve_scalar_field_monts) {
300 const struct built_in_curves *const curves = OPENSSL_built_in_curves();
Adam Langleyfad63272015-11-12 12:15:39 -0800301
Robert Sloan8ff03552017-06-14 12:40:58 -0700302 BN_MONT_CTX **monts =
303 OPENSSL_malloc(sizeof(BN_MONT_CTX *) * OPENSSL_NUM_BUILT_IN_CURVES);
304 if (monts == NULL) {
Adam Langleyfad63272015-11-12 12:15:39 -0800305 return;
306 }
307
Robert Sloan8ff03552017-06-14 12:40:58 -0700308 OPENSSL_memset(monts, 0, sizeof(BN_MONT_CTX *) * OPENSSL_NUM_BUILT_IN_CURVES);
309
Adam Langleyfad63272015-11-12 12:15:39 -0800310 BIGNUM *order = BN_new();
311 BN_CTX *bn_ctx = BN_CTX_new();
312 BN_MONT_CTX *mont_ctx = NULL;
313
314 if (bn_ctx == NULL ||
315 order == NULL) {
316 goto err;
317 }
318
Robert Sloan8ff03552017-06-14 12:40:58 -0700319 for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
320 const struct curve_data *curve = curves->curves[i].data;
Adam Langleyfad63272015-11-12 12:15:39 -0800321 const unsigned param_len = curve->param_len;
322 const uint8_t *params = curve->data;
323
324 mont_ctx = BN_MONT_CTX_new();
325 if (mont_ctx == NULL) {
326 goto err;
327 }
328
329 if (!BN_bin2bn(params + 5 * param_len, param_len, order) ||
330 !BN_MONT_CTX_set(mont_ctx, order, bn_ctx)) {
331 goto err;
332 }
333
Robert Sloan8ff03552017-06-14 12:40:58 -0700334 monts[i] = mont_ctx;
Adam Langleyfad63272015-11-12 12:15:39 -0800335 mont_ctx = NULL;
336 }
337
Robert Sloan8ff03552017-06-14 12:40:58 -0700338 *out = monts;
339 goto done;
Adam Langleyfad63272015-11-12 12:15:39 -0800340
341err:
342 BN_MONT_CTX_free(mont_ctx);
Robert Sloan8ff03552017-06-14 12:40:58 -0700343 for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
344 BN_MONT_CTX_free(monts[i]);
345 }
346 OPENSSL_free((BN_MONT_CTX**) monts);
Adam Langleyfad63272015-11-12 12:15:39 -0800347
Robert Sloan8ff03552017-06-14 12:40:58 -0700348done:
Adam Langleyfad63272015-11-12 12:15:39 -0800349 BN_free(order);
350 BN_CTX_free(bn_ctx);
351}
352
Adam Langleyd9e397b2015-01-22 14:27:53 -0800353EC_GROUP *ec_group_new(const EC_METHOD *meth) {
354 EC_GROUP *ret;
355
356 if (meth == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000357 OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800358 return NULL;
359 }
360
361 if (meth->group_init == 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000362 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800363 return NULL;
364 }
365
366 ret = OPENSSL_malloc(sizeof(EC_GROUP));
367 if (ret == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000368 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800369 return NULL;
370 }
Robert Sloan69939df2017-01-09 10:53:07 -0800371 OPENSSL_memset(ret, 0, sizeof(EC_GROUP));
Adam Langleyd9e397b2015-01-22 14:27:53 -0800372
373 ret->meth = meth;
374 BN_init(&ret->order);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800375
376 if (!meth->group_init(ret)) {
377 OPENSSL_free(ret);
378 return NULL;
379 }
380
381 return ret;
382}
383
Adam Langley430091c2015-05-12 19:09:47 -0700384EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
385 const BIGNUM *b, BN_CTX *ctx) {
Robert Sloan8ff03552017-06-14 12:40:58 -0700386 EC_GROUP *ret = ec_group_new(EC_GFp_mont_method());
Adam Langleyd9e397b2015-01-22 14:27:53 -0800387 if (ret == NULL) {
388 return NULL;
389 }
390
391 if (ret->meth->group_set_curve == 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000392 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800393 return 0;
394 }
395 if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
396 EC_GROUP_free(ret);
397 return NULL;
398 }
399 return ret;
400}
401
Adam Langley430091c2015-05-12 19:09:47 -0700402int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
403 const BIGNUM *order, const BIGNUM *cofactor) {
David Benjamin4969cc92016-04-22 15:02:23 -0400404 if (group->curve_name != NID_undef || group->generator != NULL) {
405 /* |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by
406 * |EC_GROUP_new_curve_GFp| and may only used once on each group. */
Adam Langleyf4e42722015-06-04 17:45:09 -0700407 return 0;
408 }
409
David Benjaminc895d6b2016-08-11 13:26:41 -0400410 /* Require a cofactor of one for custom curves, which implies prime order. */
411 if (!BN_is_one(cofactor)) {
412 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COFACTOR);
413 return 0;
414 }
415
David Benjamin4969cc92016-04-22 15:02:23 -0400416 group->generator = EC_POINT_new(group);
417 return group->generator != NULL &&
418 EC_POINT_copy(group->generator, generator) &&
David Benjaminc895d6b2016-08-11 13:26:41 -0400419 BN_copy(&group->order, order);
Adam Langley430091c2015-05-12 19:09:47 -0700420}
421
Adam Langleyfad63272015-11-12 12:15:39 -0800422static EC_GROUP *ec_group_new_from_data(unsigned built_in_index) {
Robert Sloan8ff03552017-06-14 12:40:58 -0700423 const struct built_in_curves *const curves = OPENSSL_built_in_curves();
424 const struct built_in_curve *curve = &curves->curves[built_in_index];
Adam Langleyd9e397b2015-01-22 14:27:53 -0800425 EC_GROUP *group = NULL;
426 EC_POINT *P = NULL;
Kenny Rootb8494592015-09-25 02:29:14 +0000427 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
Adam Langleyfad63272015-11-12 12:15:39 -0800428 int ok = 0;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800429
Adam Langleyfad63272015-11-12 12:15:39 -0800430 BN_CTX *ctx = BN_CTX_new();
431 if (ctx == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000432 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800433 goto err;
434 }
435
Adam Langleyfad63272015-11-12 12:15:39 -0800436 const struct curve_data *data = curve->data;
437 const unsigned param_len = data->param_len;
438 const uint8_t *params = data->data;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800439
440 if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
441 !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
442 !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
Kenny Rootb8494592015-09-25 02:29:14 +0000443 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800444 goto err;
445 }
446
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400447 group = ec_group_new(curve->method);
448 if (group == NULL ||
449 !group->meth->group_set_curve(group, p, a, b, ctx)) {
450 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
451 goto err;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800452 }
453
454 if ((P = EC_POINT_new(group)) == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000455 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800456 goto err;
457 }
458
459 if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
460 !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
Kenny Rootb8494592015-09-25 02:29:14 +0000461 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800462 goto err;
463 }
464
465 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000466 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800467 goto err;
468 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400469 if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000470 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800471 goto err;
472 }
473
Robert Sloan8ff03552017-06-14 12:40:58 -0700474 const BN_MONT_CTX **monts = *built_in_curve_scalar_field_monts();
475 if (monts != NULL) {
476 group->mont_data = monts[built_in_index];
Adam Langleyfad63272015-11-12 12:15:39 -0800477 }
478
Adam Langleyd9e397b2015-01-22 14:27:53 -0800479 group->generator = P;
480 P = NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800481 ok = 1;
482
483err:
484 if (!ok) {
485 EC_GROUP_free(group);
486 group = NULL;
487 }
Adam Langleye9ada862015-05-11 17:20:37 -0700488 EC_POINT_free(P);
489 BN_CTX_free(ctx);
490 BN_free(p);
491 BN_free(a);
492 BN_free(b);
Adam Langleye9ada862015-05-11 17:20:37 -0700493 BN_free(x);
494 BN_free(y);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800495 return group;
496}
497
498EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
Robert Sloan8ff03552017-06-14 12:40:58 -0700499 const struct built_in_curves *const curves = OPENSSL_built_in_curves();
Adam Langleyd9e397b2015-01-22 14:27:53 -0800500 EC_GROUP *ret = NULL;
501
Robert Sloan8ff03552017-06-14 12:40:58 -0700502 for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
503 const struct built_in_curve *curve = &curves->curves[i];
Adam Langleyd9e397b2015-01-22 14:27:53 -0800504 if (curve->nid == nid) {
Adam Langleyfad63272015-11-12 12:15:39 -0800505 ret = ec_group_new_from_data(i);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800506 break;
507 }
508 }
509
510 if (ret == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000511 OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800512 return NULL;
513 }
514
515 ret->curve_name = nid;
516 return ret;
517}
518
519void EC_GROUP_free(EC_GROUP *group) {
520 if (!group) {
521 return;
522 }
523
524 if (group->meth->group_finish != 0) {
525 group->meth->group_finish(group);
526 }
527
Adam Langleye9ada862015-05-11 17:20:37 -0700528 EC_POINT_free(group->generator);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800529 BN_free(&group->order);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800530
531 OPENSSL_free(group);
532}
533
Adam Langleyfad63272015-11-12 12:15:39 -0800534const BN_MONT_CTX *ec_group_get_mont_data(const EC_GROUP *group) {
535 return group->mont_data;
536}
537
Adam Langleyd9e397b2015-01-22 14:27:53 -0800538EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800539 if (a == NULL) {
540 return NULL;
541 }
542
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400543 if (a->meth->group_copy == NULL) {
544 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800545 return NULL;
546 }
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400547
548 EC_GROUP *ret = ec_group_new(a->meth);
549 if (ret == NULL) {
550 return NULL;
551 }
552
553 ret->mont_data = a->mont_data;
554 ret->curve_name = a->curve_name;
555
556 if (a->generator != NULL) {
557 ret->generator = EC_POINT_dup(a->generator, ret);
558 if (ret->generator == NULL) {
559 goto err;
560 }
561 }
562
563 if (!BN_copy(&ret->order, &a->order) ||
564 !ret->meth->group_copy(ret, a)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800565 goto err;
566 }
567
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400568 return ret;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800569
570err:
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400571 EC_GROUP_free(ret);
572 return NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800573}
574
Kenny Rootc897c7e2015-02-27 13:00:38 -0800575int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
Adam Langleyef935712015-02-25 11:16:32 -0800576 return a->curve_name == NID_undef ||
577 b->curve_name == NID_undef ||
578 a->curve_name != b->curve_name;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800579}
580
581const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
582 return group->generator;
583}
584
Adam Langley4139edb2016-01-13 15:00:54 -0800585const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
586 assert(!BN_is_zero(&group->order));
587 return &group->order;
588}
589
Adam Langleyd9e397b2015-01-22 14:27:53 -0800590int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
Adam Langley4139edb2016-01-13 15:00:54 -0800591 if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800592 return 0;
593 }
Adam Langley4139edb2016-01-13 15:00:54 -0800594 return 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800595}
596
597int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
598 BN_CTX *ctx) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400599 /* All |EC_GROUP|s have cofactor 1. */
600 return BN_set_word(cofactor, 1);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800601}
602
603int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
604 BIGNUM *out_b, BN_CTX *ctx) {
Kenny Roote99801b2015-11-06 15:31:15 -0800605 return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800606}
607
608int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
609
Kenny Roote99801b2015-11-06 15:31:15 -0800610unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
611 return ec_GFp_simple_group_get_degree(group);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800612}
613
Adam Langleyd9e397b2015-01-22 14:27:53 -0800614EC_POINT *EC_POINT_new(const EC_GROUP *group) {
615 EC_POINT *ret;
616
617 if (group == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000618 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800619 return NULL;
620 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800621
622 ret = OPENSSL_malloc(sizeof *ret);
623 if (ret == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +0000624 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800625 return NULL;
626 }
627
628 ret->meth = group->meth;
629
Kenny Roote99801b2015-11-06 15:31:15 -0800630 if (!ec_GFp_simple_point_init(ret)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800631 OPENSSL_free(ret);
632 return NULL;
633 }
634
635 return ret;
636}
637
638void EC_POINT_free(EC_POINT *point) {
639 if (!point) {
640 return;
641 }
642
Kenny Roote99801b2015-11-06 15:31:15 -0800643 ec_GFp_simple_point_finish(point);
644
Adam Langleyd9e397b2015-01-22 14:27:53 -0800645 OPENSSL_free(point);
646}
647
648void EC_POINT_clear_free(EC_POINT *point) {
649 if (!point) {
650 return;
651 }
652
Kenny Roote99801b2015-11-06 15:31:15 -0800653 ec_GFp_simple_point_clear_finish(point);
654
Adam Langleyd9e397b2015-01-22 14:27:53 -0800655 OPENSSL_cleanse(point, sizeof *point);
656 OPENSSL_free(point);
657}
658
659int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800660 if (dest->meth != src->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000661 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800662 return 0;
663 }
664 if (dest == src) {
665 return 1;
666 }
Kenny Roote99801b2015-11-06 15:31:15 -0800667 return ec_GFp_simple_point_copy(dest, src);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800668}
669
670EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800671 if (a == NULL) {
672 return NULL;
673 }
674
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400675 EC_POINT *ret = EC_POINT_new(group);
676 if (ret == NULL ||
677 !EC_POINT_copy(ret, a)) {
678 EC_POINT_free(ret);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800679 return NULL;
680 }
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400681
682 return ret;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800683}
684
685int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
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_point_set_to_infinity(group, point);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800691}
692
693int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800694 if (group->meth != point->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000695 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800696 return 0;
697 }
Kenny Roote99801b2015-11-06 15:31:15 -0800698 return ec_GFp_simple_is_at_infinity(group, point);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800699}
700
701int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
702 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_is_on_curve(group, point, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800708}
709
710int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
711 BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800712 if ((group->meth != a->meth) || (a->meth != b->meth)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000713 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800714 return -1;
715 }
Kenny Roote99801b2015-11-06 15:31:15 -0800716 return ec_GFp_simple_cmp(group, a, b, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800717}
718
719int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800720 if (group->meth != point->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000721 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800722 return 0;
723 }
Kenny Roote99801b2015-11-06 15:31:15 -0800724 return ec_GFp_simple_make_affine(group, point, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800725}
726
727int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
728 BN_CTX *ctx) {
David Benjamin7c0d06c2016-08-11 13:26:41 -0400729 for (size_t i = 0; i < num; i++) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800730 if (group->meth != points[i]->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000731 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800732 return 0;
733 }
734 }
Kenny Roote99801b2015-11-06 15:31:15 -0800735 return ec_GFp_simple_points_make_affine(group, num, points, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800736}
737
738int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
739 const EC_POINT *point, BIGNUM *x,
740 BIGNUM *y, BN_CTX *ctx) {
741 if (group->meth->point_get_affine_coordinates == 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000742 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800743 return 0;
744 }
745 if (group->meth != point->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000746 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800747 return 0;
748 }
749 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
750}
751
752int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
753 const BIGNUM *x, const BIGNUM *y,
754 BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800755 if (group->meth != point->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000756 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800757 return 0;
758 }
Adam Langleyfad63272015-11-12 12:15:39 -0800759 if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) {
760 return 0;
761 }
762
763 if (!EC_POINT_is_on_curve(group, point, ctx)) {
764 OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
765 return 0;
766 }
767
768 return 1;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800769}
770
771int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
772 const EC_POINT *b, BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800773 if ((group->meth != r->meth) || (r->meth != a->meth) ||
774 (a->meth != b->meth)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000775 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800776 return 0;
777 }
Kenny Roote99801b2015-11-06 15:31:15 -0800778 return ec_GFp_simple_add(group, r, a, b, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800779}
780
781
782int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
783 BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800784 if ((group->meth != r->meth) || (r->meth != a->meth)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000785 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800786 return 0;
787 }
Kenny Roote99801b2015-11-06 15:31:15 -0800788 return ec_GFp_simple_dbl(group, r, a, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800789}
790
791
792int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800793 if (group->meth != a->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000794 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800795 return 0;
796 }
Kenny Roote99801b2015-11-06 15:31:15 -0800797 return ec_GFp_simple_invert(group, a, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800798}
799
800int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
Adam Langley4139edb2016-01-13 15:00:54 -0800801 const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
802 /* Previously, this function set |r| to the point at infinity if there was
803 * nothing to multiply. But, nobody should be calling this function with
804 * nothing to multiply in the first place. */
805 if ((g_scalar == NULL && p_scalar == NULL) ||
806 ((p == NULL) != (p_scalar == NULL))) {
807 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
808 return 0;
809 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800810
Adam Langley4139edb2016-01-13 15:00:54 -0800811 if (group->meth != r->meth ||
812 (p != NULL && group->meth != p->meth)) {
Adam Langleyfad63272015-11-12 12:15:39 -0800813 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
814 return 0;
815 }
816
Adam Langley4139edb2016-01-13 15:00:54 -0800817 return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800818}
819
Robert Sloan8ff03552017-06-14 12:40:58 -0700820int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
821 EC_POINT *point, const BIGNUM *x,
822 const BIGNUM *y, const BIGNUM *z,
823 BN_CTX *ctx) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800824 if (group->meth != point->meth) {
Kenny Rootb8494592015-09-25 02:29:14 +0000825 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800826 return 0;
827 }
Kenny Roote99801b2015-11-06 15:31:15 -0800828 return ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point, x, y, z,
829 ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800830}
Adam Langleyf7e890d2015-03-31 18:58:05 -0700831
832void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
833
834const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
835 return NULL;
836}
837
838int EC_METHOD_get_field_type(const EC_METHOD *meth) {
839 return NID_X9_62_prime_field;
840}
Adam Langley830beae2015-04-20 10:49:33 -0700841
842void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
843 point_conversion_form_t form) {
844 if (form != POINT_CONVERSION_UNCOMPRESSED) {
845 abort();
846 }
847}
David Benjamin4969cc92016-04-22 15:02:23 -0400848
849size_t EC_get_builtin_curves(EC_builtin_curve *out_curves,
850 size_t max_num_curves) {
Robert Sloan8ff03552017-06-14 12:40:58 -0700851 const struct built_in_curves *const curves = OPENSSL_built_in_curves();
852
853 for (size_t i = 0; i < max_num_curves && i < OPENSSL_NUM_BUILT_IN_CURVES;
854 i++) {
855 out_curves[i].comment = curves->curves[i].data->comment;
856 out_curves[i].nid = curves->curves[i].nid;
David Benjamin4969cc92016-04-22 15:02:23 -0400857 }
858
Robert Sloan8ff03552017-06-14 12:40:58 -0700859 return OPENSSL_NUM_BUILT_IN_CURVES;
David Benjamin4969cc92016-04-22 15:02:23 -0400860}