summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ec')
-rw-r--r--src/lib/libcrypto/ec/ec2_mult.c380
-rw-r--r--src/lib/libcrypto/ec/ec2_smpl.c971
-rw-r--r--src/lib/libcrypto/ec/ec_asn1.c1429
-rw-r--r--src/lib/libcrypto/ec/ec_check.c123
-rw-r--r--src/lib/libcrypto/ec/ec_curve.c1270
-rw-r--r--src/lib/libcrypto/ec/ec_key.c465
-rw-r--r--src/lib/libcrypto/ec/ec_print.c195
7 files changed, 4833 insertions, 0 deletions
diff --git a/src/lib/libcrypto/ec/ec2_mult.c b/src/lib/libcrypto/ec/ec2_mult.c
new file mode 100644
index 0000000000..ff368fd7d7
--- /dev/null
+++ b/src/lib/libcrypto/ec/ec2_mult.c
@@ -0,0 +1,380 @@
1/* crypto/ec/ec2_mult.c */
2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 *
5 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
6 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
7 * to the OpenSSL project.
8 *
9 * The ECC Code is licensed pursuant to the OpenSSL open source
10 * license provided below.
11 *
12 * The software is originally written by Sheueling Chang Shantz and
13 * Douglas Stebila of Sun Microsystems Laboratories.
14 *
15 */
16/* ====================================================================
17 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 *
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
29 * distribution.
30 *
31 * 3. All advertising materials mentioning features or use of this
32 * software must display the following acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
35 *
36 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
37 * endorse or promote products derived from this software without
38 * prior written permission. For written permission, please contact
39 * openssl-core@openssl.org.
40 *
41 * 5. Products derived from this software may not be called "OpenSSL"
42 * nor may "OpenSSL" appear in their names without prior written
43 * permission of the OpenSSL Project.
44 *
45 * 6. Redistributions of any form whatsoever must retain the following
46 * acknowledgment:
47 * "This product includes software developed by the OpenSSL Project
48 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
51 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
54 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
61 * OF THE POSSIBILITY OF SUCH DAMAGE.
62 * ====================================================================
63 *
64 * This product includes cryptographic software written by Eric Young
65 * (eay@cryptsoft.com). This product includes software written by Tim
66 * Hudson (tjh@cryptsoft.com).
67 *
68 */
69
70#include <openssl/err.h>
71
72#include "ec_lcl.h"
73
74
75/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
76 * coordinates.
77 * Uses algorithm Mdouble in appendix of
78 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
79 * GF(2^m) without precomputation".
80 * modified to not require precomputation of c=b^{2^{m-1}}.
81 */
82static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx)
83 {
84 BIGNUM *t1;
85 int ret = 0;
86
87 /* Since Mdouble is static we can guarantee that ctx != NULL. */
88 BN_CTX_start(ctx);
89 t1 = BN_CTX_get(ctx);
90 if (t1 == NULL) goto err;
91
92 if (!group->meth->field_sqr(group, x, x, ctx)) goto err;
93 if (!group->meth->field_sqr(group, t1, z, ctx)) goto err;
94 if (!group->meth->field_mul(group, z, x, t1, ctx)) goto err;
95 if (!group->meth->field_sqr(group, x, x, ctx)) goto err;
96 if (!group->meth->field_sqr(group, t1, t1, ctx)) goto err;
97 if (!group->meth->field_mul(group, t1, &group->b, t1, ctx)) goto err;
98 if (!BN_GF2m_add(x, x, t1)) goto err;
99
100 ret = 1;
101
102 err:
103 BN_CTX_end(ctx);
104 return ret;
105 }
106
107/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery
108 * projective coordinates.
109 * Uses algorithm Madd in appendix of
110 * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
111 * GF(2^m) without precomputation".
112 */
113static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1,
114 const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx)
115 {
116 BIGNUM *t1, *t2;
117 int ret = 0;
118
119 /* Since Madd is static we can guarantee that ctx != NULL. */
120 BN_CTX_start(ctx);
121 t1 = BN_CTX_get(ctx);
122 t2 = BN_CTX_get(ctx);
123 if (t2 == NULL) goto err;
124
125 if (!BN_copy(t1, x)) goto err;
126 if (!group->meth->field_mul(group, x1, x1, z2, ctx)) goto err;
127 if (!group->meth->field_mul(group, z1, z1, x2, ctx)) goto err;
128 if (!group->meth->field_mul(group, t2, x1, z1, ctx)) goto err;
129 if (!BN_GF2m_add(z1, z1, x1)) goto err;
130 if (!group->meth->field_sqr(group, z1, z1, ctx)) goto err;
131 if (!group->meth->field_mul(group, x1, z1, t1, ctx)) goto err;
132 if (!BN_GF2m_add(x1, x1, t2)) goto err;
133
134 ret = 1;
135
136 err:
137 BN_CTX_end(ctx);
138 return ret;
139 }
140
141/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
142 * using Montgomery point multiplication algorithm Mxy() in appendix of
143 * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
144 * GF(2^m) without precomputation".
145 * Returns:
146 * 0 on error
147 * 1 if return value should be the point at infinity
148 * 2 otherwise
149 */
150static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIGNUM *x1,
151 BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, BN_CTX *ctx)
152 {
153 BIGNUM *t3, *t4, *t5;
154 int ret = 0;
155
156 if (BN_is_zero(z1))
157 {
158 BN_zero(x2);
159 BN_zero(z2);
160 return 1;
161 }
162
163 if (BN_is_zero(z2))
164 {
165 if (!BN_copy(x2, x)) return 0;
166 if (!BN_GF2m_add(z2, x, y)) return 0;
167 return 2;
168 }
169
170 /* Since Mxy is static we can guarantee that ctx != NULL. */
171 BN_CTX_start(ctx);
172 t3 = BN_CTX_get(ctx);
173 t4 = BN_CTX_get(ctx);
174 t5 = BN_CTX_get(ctx);
175 if (t5 == NULL) goto err;
176
177 if (!BN_one(t5)) goto err;
178
179 if (!group->meth->field_mul(group, t3, z1, z2, ctx)) goto err;
180
181 if (!group->meth->field_mul(group, z1, z1, x, ctx)) goto err;
182 if (!BN_GF2m_add(z1, z1, x1)) goto err;
183 if (!group->meth->field_mul(group, z2, z2, x, ctx)) goto err;
184 if (!group->meth->field_mul(group, x1, z2, x1, ctx)) goto err;
185 if (!BN_GF2m_add(z2, z2, x2)) goto err;
186
187 if (!group->meth->field_mul(group, z2, z2, z1, ctx)) goto err;
188 if (!group->meth->field_sqr(group, t4, x, ctx)) goto err;
189 if (!BN_GF2m_add(t4, t4, y)) goto err;
190 if (!group->meth->field_mul(group, t4, t4, t3, ctx)) goto err;
191 if (!BN_GF2m_add(t4, t4, z2)) goto err;
192
193 if (!group->meth->field_mul(group, t3, t3, x, ctx)) goto err;
194 if (!group->meth->field_div(group, t3, t5, t3, ctx)) goto err;
195 if (!group->meth->field_mul(group, t4, t3, t4, ctx)) goto err;
196 if (!group->meth->field_mul(group, x2, x1, t3, ctx)) goto err;
197 if (!BN_GF2m_add(z2, x2, x)) goto err;
198
199 if (!group->meth->field_mul(group, z2, z2, t4, ctx)) goto err;
200 if (!BN_GF2m_add(z2, z2, y)) goto err;
201
202 ret = 2;
203
204 err:
205 BN_CTX_end(ctx);
206 return ret;
207 }
208
209/* Computes scalar*point and stores the result in r.
210 * point can not equal r.
211 * Uses algorithm 2P of
212 * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
213 * GF(2^m) without precomputation".
214 */
215static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
216 const EC_POINT *point, BN_CTX *ctx)
217 {
218 BIGNUM *x1, *x2, *z1, *z2;
219 int ret = 0, i, j;
220 BN_ULONG mask;
221
222 if (r == point)
223 {
224 ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT);
225 return 0;
226 }
227
228 /* if result should be point at infinity */
229 if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) ||
230 EC_POINT_is_at_infinity(group, point))
231 {
232 return EC_POINT_set_to_infinity(group, r);
233 }
234
235 /* only support affine coordinates */
236 if (!point->Z_is_one) return 0;
237
238 /* Since point_multiply is static we can guarantee that ctx != NULL. */
239 BN_CTX_start(ctx);
240 x1 = BN_CTX_get(ctx);
241 z1 = BN_CTX_get(ctx);
242 if (z1 == NULL) goto err;
243
244 x2 = &r->X;
245 z2 = &r->Y;
246
247 if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */
248 if (!BN_one(z1)) goto err; /* z1 = 1 */
249 if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */
250 if (!group->meth->field_sqr(group, x2, z2, ctx)) goto err;
251 if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */
252
253 /* find top most bit and go one past it */
254 i = scalar->top - 1; j = BN_BITS2 - 1;
255 mask = BN_TBIT;
256 while (!(scalar->d[i] & mask)) { mask >>= 1; j--; }
257 mask >>= 1; j--;
258 /* if top most bit was at word break, go to next word */
259 if (!mask)
260 {
261 i--; j = BN_BITS2 - 1;
262 mask = BN_TBIT;
263 }
264
265 for (; i >= 0; i--)
266 {
267 for (; j >= 0; j--)
268 {
269 if (scalar->d[i] & mask)
270 {
271 if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
272 if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
273 }
274 else
275 {
276 if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
277 if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
278 }
279 mask >>= 1;
280 }
281 j = BN_BITS2 - 1;
282 mask = BN_TBIT;
283 }
284
285 /* convert out of "projective" coordinates */
286 i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx);
287 if (i == 0) goto err;
288 else if (i == 1)
289 {
290 if (!EC_POINT_set_to_infinity(group, r)) goto err;
291 }
292 else
293 {
294 if (!BN_one(&r->Z)) goto err;
295 r->Z_is_one = 1;
296 }
297
298 /* GF(2^m) field elements should always have BIGNUM::neg = 0 */
299 BN_set_negative(&r->X, 0);
300 BN_set_negative(&r->Y, 0);
301
302 ret = 1;
303
304 err:
305 BN_CTX_end(ctx);
306 return ret;
307 }
308
309
310/* Computes the sum
311 * scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
312 * gracefully ignoring NULL scalar values.
313 */
314int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
315 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
316 {
317 BN_CTX *new_ctx = NULL;
318 int ret = 0;
319 size_t i;
320 EC_POINT *p=NULL;
321
322 if (ctx == NULL)
323 {
324 ctx = new_ctx = BN_CTX_new();
325 if (ctx == NULL)
326 return 0;
327 }
328
329 /* This implementation is more efficient than the wNAF implementation for 2
330 * or fewer points. Use the ec_wNAF_mul implementation for 3 or more points,
331 * or if we can perform a fast multiplication based on precomputation.
332 */
333 if ((scalar && (num > 1)) || (num > 2) || (num == 0 && EC_GROUP_have_precompute_mult(group)))
334 {
335 ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
336 goto err;
337 }
338
339 if ((p = EC_POINT_new(group)) == NULL) goto err;
340
341 if (!EC_POINT_set_to_infinity(group, r)) goto err;
342
343 if (scalar)
344 {
345 if (!ec_GF2m_montgomery_point_multiply(group, p, scalar, group->generator, ctx)) goto err;
346 if (BN_is_negative(scalar))
347 if (!group->meth->invert(group, p, ctx)) goto err;
348 if (!group->meth->add(group, r, r, p, ctx)) goto err;
349 }
350
351 for (i = 0; i < num; i++)
352 {
353 if (!ec_GF2m_montgomery_point_multiply(group, p, scalars[i], points[i], ctx)) goto err;
354 if (BN_is_negative(scalars[i]))
355 if (!group->meth->invert(group, p, ctx)) goto err;
356 if (!group->meth->add(group, r, r, p, ctx)) goto err;
357 }
358
359 ret = 1;
360
361 err:
362 if (p) EC_POINT_free(p);
363 if (new_ctx != NULL)
364 BN_CTX_free(new_ctx);
365 return ret;
366 }
367
368
369/* Precomputation for point multiplication: fall back to wNAF methods
370 * because ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate */
371
372int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
373 {
374 return ec_wNAF_precompute_mult(group, ctx);
375 }
376
377int ec_GF2m_have_precompute_mult(const EC_GROUP *group)
378 {
379 return ec_wNAF_have_precompute_mult(group);
380 }
diff --git a/src/lib/libcrypto/ec/ec2_smpl.c b/src/lib/libcrypto/ec/ec2_smpl.c
new file mode 100644
index 0000000000..5cd1eac41f
--- /dev/null
+++ b/src/lib/libcrypto/ec/ec2_smpl.c
@@ -0,0 +1,971 @@
1/* crypto/ec/ec2_smpl.c */
2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 *
5 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
6 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
7 * to the OpenSSL project.
8 *
9 * The ECC Code is licensed pursuant to the OpenSSL open source
10 * license provided below.
11 *
12 * The software is originally written by Sheueling Chang Shantz and
13 * Douglas Stebila of Sun Microsystems Laboratories.
14 *
15 */
16/* ====================================================================
17 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 *
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
29 * distribution.
30 *
31 * 3. All advertising materials mentioning features or use of this
32 * software must display the following acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
35 *
36 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
37 * endorse or promote products derived from this software without
38 * prior written permission. For written permission, please contact
39 * openssl-core@openssl.org.
40 *
41 * 5. Products derived from this software may not be called "OpenSSL"
42 * nor may "OpenSSL" appear in their names without prior written
43 * permission of the OpenSSL Project.
44 *
45 * 6. Redistributions of any form whatsoever must retain the following
46 * acknowledgment:
47 * "This product includes software developed by the OpenSSL Project
48 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
51 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
54 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
61 * OF THE POSSIBILITY OF SUCH DAMAGE.
62 * ====================================================================
63 *
64 * This product includes cryptographic software written by Eric Young
65 * (eay@cryptsoft.com). This product includes software written by Tim
66 * Hudson (tjh@cryptsoft.com).
67 *
68 */
69
70#include <openssl/err.h>
71
72#include "ec_lcl.h"
73
74
75const EC_METHOD *EC_GF2m_simple_method(void)
76 {
77 static const EC_METHOD ret = {
78 NID_X9_62_characteristic_two_field,
79 ec_GF2m_simple_group_init,
80 ec_GF2m_simple_group_finish,
81 ec_GF2m_simple_group_clear_finish,
82 ec_GF2m_simple_group_copy,
83 ec_GF2m_simple_group_set_curve,
84 ec_GF2m_simple_group_get_curve,
85 ec_GF2m_simple_group_get_degree,
86 ec_GF2m_simple_group_check_discriminant,
87 ec_GF2m_simple_point_init,
88 ec_GF2m_simple_point_finish,
89 ec_GF2m_simple_point_clear_finish,
90 ec_GF2m_simple_point_copy,
91 ec_GF2m_simple_point_set_to_infinity,
92 0 /* set_Jprojective_coordinates_GFp */,
93 0 /* get_Jprojective_coordinates_GFp */,
94 ec_GF2m_simple_point_set_affine_coordinates,
95 ec_GF2m_simple_point_get_affine_coordinates,
96 ec_GF2m_simple_set_compressed_coordinates,
97 ec_GF2m_simple_point2oct,
98 ec_GF2m_simple_oct2point,
99 ec_GF2m_simple_add,
100 ec_GF2m_simple_dbl,
101 ec_GF2m_simple_invert,
102 ec_GF2m_simple_is_at_infinity,
103 ec_GF2m_simple_is_on_curve,
104 ec_GF2m_simple_cmp,
105 ec_GF2m_simple_make_affine,
106 ec_GF2m_simple_points_make_affine,
107
108 /* the following three method functions are defined in ec2_mult.c */
109 ec_GF2m_simple_mul,
110 ec_GF2m_precompute_mult,
111 ec_GF2m_have_precompute_mult,
112
113 ec_GF2m_simple_field_mul,
114 ec_GF2m_simple_field_sqr,
115 ec_GF2m_simple_field_div,
116 0 /* field_encode */,
117 0 /* field_decode */,
118 0 /* field_set_to_one */ };
119
120 return &ret;
121 }
122
123
124/* Initialize a GF(2^m)-based EC_GROUP structure.
125 * Note that all other members are handled by EC_GROUP_new.
126 */
127int ec_GF2m_simple_group_init(EC_GROUP *group)
128 {
129 BN_init(&group->field);
130 BN_init(&group->a);
131 BN_init(&group->b);
132 return 1;
133 }
134
135
136/* Free a GF(2^m)-based EC_GROUP structure.
137 * Note that all other members are handled by EC_GROUP_free.
138 */
139void ec_GF2m_simple_group_finish(EC_GROUP *group)
140 {
141 BN_free(&group->field);
142 BN_free(&group->a);
143 BN_free(&group->b);
144 }
145
146
147/* Clear and free a GF(2^m)-based EC_GROUP structure.
148 * Note that all other members are handled by EC_GROUP_clear_free.
149 */
150void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
151 {
152 BN_clear_free(&group->field);
153 BN_clear_free(&group->a);
154 BN_clear_free(&group->b);
155 group->poly[0] = 0;
156 group->poly[1] = 0;
157 group->poly[2] = 0;
158 group->poly[3] = 0;
159 group->poly[4] = 0;
160 }
161
162
163/* Copy a GF(2^m)-based EC_GROUP structure.
164 * Note that all other members are handled by EC_GROUP_copy.
165 */
166int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
167 {
168 int i;
169 if (!BN_copy(&dest->field, &src->field)) return 0;
170 if (!BN_copy(&dest->a, &src->a)) return 0;
171 if (!BN_copy(&dest->b, &src->b)) return 0;
172 dest->poly[0] = src->poly[0];
173 dest->poly[1] = src->poly[1];
174 dest->poly[2] = src->poly[2];
175 dest->poly[3] = src->poly[3];
176 dest->poly[4] = src->poly[4];
177 bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2);
178 bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2);
179 for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0;
180 for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0;
181 return 1;
182 }
183
184
185/* Set the curve parameters of an EC_GROUP structure. */
186int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
187 const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
188 {
189 int ret = 0, i;
190
191 /* group->field */
192 if (!BN_copy(&group->field, p)) goto err;
193 i = BN_GF2m_poly2arr(&group->field, group->poly, 5);
194 if ((i != 5) && (i != 3))
195 {
196 ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
197 goto err;
198 }
199
200 /* group->a */
201 if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err;
202 bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2);
203 for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0;
204
205 /* group->b */
206 if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err;
207 bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2);
208 for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0;
209
210 ret = 1;
211 err:
212 return ret;
213 }
214
215
216/* Get the curve parameters of an EC_GROUP structure.
217 * If p, a, or b are NULL then there values will not be set but the method will return with success.
218 */
219int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
220 {
221 int ret = 0;
222
223 if (p != NULL)
224 {
225 if (!BN_copy(p, &group->field)) return 0;
226 }
227
228 if (a != NULL)
229 {
230 if (!BN_copy(a, &group->a)) goto err;
231 }
232
233 if (b != NULL)
234 {
235 if (!BN_copy(b, &group->b)) goto err;
236 }
237
238 ret = 1;
239
240 err:
241 return ret;
242 }
243
244
245/* Gets the degree of the field. For a curve over GF(2^m) this is the value m. */
246int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
247 {
248 return BN_num_bits(&group->field)-1;
249 }
250
251
252/* Checks the discriminant of the curve.
253 * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
254 */
255int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
256 {
257 int ret = 0;
258 BIGNUM *b;
259 BN_CTX *new_ctx = NULL;
260
261 if (ctx == NULL)
262 {
263 ctx = new_ctx = BN_CTX_new();
264 if (ctx == NULL)
265 {
266 ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
267 goto err;
268 }
269 }
270 BN_CTX_start(ctx);
271 b = BN_CTX_get(ctx);
272 if (b == NULL) goto err;
273
274 if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) goto err;
275
276 /* check the discriminant:
277 * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
278 */
279 if (BN_is_zero(b)) goto err;
280
281 ret = 1;
282
283err:
284 if (ctx != NULL)
285 BN_CTX_end(ctx);
286 if (new_ctx != NULL)
287 BN_CTX_free(new_ctx);
288 return ret;
289 }
290
291
292/* Initializes an EC_POINT. */
293int ec_GF2m_simple_point_init(EC_POINT *point)
294 {
295 BN_init(&point->X);
296 BN_init(&point->Y);
297 BN_init(&point->Z);
298 return 1;
299 }
300
301
302/* Frees an EC_POINT. */
303void ec_GF2m_simple_point_finish(EC_POINT *point)
304 {
305 BN_free(&point->X);
306 BN_free(&point->Y);
307 BN_free(&point->Z);
308 }
309
310
311/* Clears and frees an EC_POINT. */
312void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
313 {
314 BN_clear_free(&point->X);
315 BN_clear_free(&point->Y);
316 BN_clear_free(&point->Z);
317 point->Z_is_one = 0;
318 }
319
320
321/* Copy the contents of one EC_POINT into another. Assumes dest is initialized. */
322int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
323 {
324 if (!BN_copy(&dest->X, &src->X)) return 0;
325 if (!BN_copy(&dest->Y, &src->Y)) return 0;
326 if (!BN_copy(&dest->Z, &src->Z)) return 0;
327 dest->Z_is_one = src->Z_is_one;
328
329 return 1;
330 }
331
332
333/* Set an EC_POINT to the point at infinity.
334 * A point at infinity is represented by having Z=0.
335 */
336int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
337 {
338 point->Z_is_one = 0;
339 BN_zero(&point->Z);
340 return 1;
341 }
342
343
344/* Set the coordinates of an EC_POINT using affine coordinates.
345 * Note that the simple implementation only uses affine coordinates.
346 */
347int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
348 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
349 {
350 int ret = 0;
351 if (x == NULL || y == NULL)
352 {
353 ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
354 return 0;
355 }
356
357 if (!BN_copy(&point->X, x)) goto err;
358 BN_set_negative(&point->X, 0);
359 if (!BN_copy(&point->Y, y)) goto err;
360 BN_set_negative(&point->Y, 0);
361 if (!BN_copy(&point->Z, BN_value_one())) goto err;
362 BN_set_negative(&point->Z, 0);
363 point->Z_is_one = 1;
364 ret = 1;
365
366 err:
367 return ret;
368 }
369
370
371/* Gets the affine coordinates of an EC_POINT.
372 * Note that the simple implementation only uses affine coordinates.
373 */
374int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
375 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
376 {
377 int ret = 0;
378
379 if (EC_POINT_is_at_infinity(group, point))
380 {
381 ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
382 return 0;
383 }
384
385 if (BN_cmp(&point->Z, BN_value_one()))
386 {
387 ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
388 return 0;
389 }
390 if (x != NULL)
391 {
392 if (!BN_copy(x, &point->X)) goto err;
393 BN_set_negative(x, 0);
394 }
395 if (y != NULL)
396 {
397 if (!BN_copy(y, &point->Y)) goto err;
398 BN_set_negative(y, 0);
399 }
400 ret = 1;
401
402 err:
403 return ret;
404 }
405
406
407/* Include patented algorithms. */
408#include "ec2_smpt.c"
409
410
411/* Converts an EC_POINT to an octet string.
412 * If buf is NULL, the encoded length will be returned.
413 * If the length len of buf is smaller than required an error will be returned.
414 *
415 * The point compression section of this function is patented by Certicom Corp.
416 * under US Patent 6,141,420. Point compression is disabled by default and can
417 * be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at
418 * Configure-time.
419 */
420size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
421 unsigned char *buf, size_t len, BN_CTX *ctx)
422 {
423 size_t ret;
424 BN_CTX *new_ctx = NULL;
425 int used_ctx = 0;
426 BIGNUM *x, *y, *yxi;
427 size_t field_len, i, skip;
428
429#ifndef OPENSSL_EC_BIN_PT_COMP
430 if ((form == POINT_CONVERSION_COMPRESSED) || (form == POINT_CONVERSION_HYBRID))
431 {
432 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_DISABLED);
433 goto err;
434 }
435#endif
436
437 if ((form != POINT_CONVERSION_COMPRESSED)
438 && (form != POINT_CONVERSION_UNCOMPRESSED)
439 && (form != POINT_CONVERSION_HYBRID))
440 {
441 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
442 goto err;
443 }
444
445 if (EC_POINT_is_at_infinity(group, point))
446 {
447 /* encodes to a single 0 octet */
448 if (buf != NULL)
449 {
450 if (len < 1)
451 {
452 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
453 return 0;
454 }
455 buf[0] = 0;
456 }
457 return 1;
458 }
459
460
461 /* ret := required output buffer length */
462 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
463 ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
464
465 /* if 'buf' is NULL, just return required length */
466 if (buf != NULL)
467 {
468 if (len < ret)
469 {
470 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
471 goto err;
472 }
473
474 if (ctx == NULL)
475 {
476 ctx = new_ctx = BN_CTX_new();
477 if (ctx == NULL)
478 return 0;
479 }
480
481 BN_CTX_start(ctx);
482 used_ctx = 1;
483 x = BN_CTX_get(ctx);
484 y = BN_CTX_get(ctx);
485 yxi = BN_CTX_get(ctx);
486 if (yxi == NULL) goto err;
487
488 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
489
490 buf[0] = form;
491#ifdef OPENSSL_EC_BIN_PT_COMP
492 if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
493 {
494 if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
495 if (BN_is_odd(yxi)) buf[0]++;
496 }
497#endif
498
499 i = 1;
500
501 skip = field_len - BN_num_bytes(x);
502 if (skip > field_len)
503 {
504 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
505 goto err;
506 }
507 while (skip > 0)
508 {
509 buf[i++] = 0;
510 skip--;
511 }
512 skip = BN_bn2bin(x, buf + i);
513 i += skip;
514 if (i != 1 + field_len)
515 {
516 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
517 goto err;
518 }
519
520 if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
521 {
522 skip = field_len - BN_num_bytes(y);
523 if (skip > field_len)
524 {
525 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
526 goto err;
527 }
528 while (skip > 0)
529 {
530 buf[i++] = 0;
531 skip--;
532 }
533 skip = BN_bn2bin(y, buf + i);
534 i += skip;
535 }
536
537 if (i != ret)
538 {
539 ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
540 goto err;
541 }
542 }
543
544 if (used_ctx)
545 BN_CTX_end(ctx);
546 if (new_ctx != NULL)
547 BN_CTX_free(new_ctx);
548 return ret;
549
550 err:
551 if (used_ctx)
552 BN_CTX_end(ctx);
553 if (new_ctx != NULL)
554 BN_CTX_free(new_ctx);
555 return 0;
556 }
557
558
559/* Converts an octet string representation to an EC_POINT.
560 * Note that the simple implementation only uses affine coordinates.
561 */
562int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
563 const unsigned char *buf, size_t len, BN_CTX *ctx)
564 {
565 point_conversion_form_t form;
566 int y_bit;
567 BN_CTX *new_ctx = NULL;
568 BIGNUM *x, *y, *yxi;
569 size_t field_len, enc_len;
570 int ret = 0;
571
572 if (len == 0)
573 {
574 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
575 return 0;
576 }
577 form = buf[0];
578 y_bit = form & 1;
579 form = form & ~1U;
580 if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
581 && (form != POINT_CONVERSION_UNCOMPRESSED)
582 && (form != POINT_CONVERSION_HYBRID))
583 {
584 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
585 return 0;
586 }
587 if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
588 {
589 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
590 return 0;
591 }
592
593 if (form == 0)
594 {
595 if (len != 1)
596 {
597 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
598 return 0;
599 }
600
601 return EC_POINT_set_to_infinity(group, point);
602 }
603
604 field_len = (EC_GROUP_get_degree(group) + 7) / 8;
605 enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
606
607 if (len != enc_len)
608 {
609 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
610 return 0;
611 }
612
613 if (ctx == NULL)
614 {
615 ctx = new_ctx = BN_CTX_new();
616 if (ctx == NULL)
617 return 0;
618 }
619
620 BN_CTX_start(ctx);
621 x = BN_CTX_get(ctx);
622 y = BN_CTX_get(ctx);
623 yxi = BN_CTX_get(ctx);
624 if (yxi == NULL) goto err;
625
626 if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
627 if (BN_ucmp(x, &group->field) >= 0)
628 {
629 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
630 goto err;
631 }
632
633 if (form == POINT_CONVERSION_COMPRESSED)
634 {
635 if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;
636 }
637 else
638 {
639 if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
640 if (BN_ucmp(y, &group->field) >= 0)
641 {
642 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
643 goto err;
644 }
645 if (form == POINT_CONVERSION_HYBRID)
646 {
647 if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
648 if (y_bit != BN_is_odd(yxi))
649 {
650 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
651 goto err;
652 }
653 }
654
655 if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
656 }
657
658 if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
659 {
660 ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
661 goto err;
662 }
663
664 ret = 1;
665
666 err:
667 BN_CTX_end(ctx);
668 if (new_ctx != NULL)
669 BN_CTX_free(new_ctx);
670 return ret;
671 }
672
673
674/* Computes a + b and stores the result in r. r could be a or b, a could be b.
675 * Uses algorithm A.10.2 of IEEE P1363.
676 */
677int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
678 {
679 BN_CTX *new_ctx = NULL;
680 BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
681 int ret = 0;
682
683 if (EC_POINT_is_at_infinity(group, a))
684 {
685 if (!EC_POINT_copy(r, b)) return 0;
686 return 1;
687 }
688
689 if (EC_POINT_is_at_infinity(group, b))
690 {
691 if (!EC_POINT_copy(r, a)) return 0;
692 return 1;
693 }
694
695 if (ctx == NULL)
696 {
697 ctx = new_ctx = BN_CTX_new();
698 if (ctx == NULL)
699 return 0;
700 }
701
702 BN_CTX_start(ctx);
703 x0 = BN_CTX_get(ctx);
704 y0 = BN_CTX_get(ctx);
705 x1 = BN_CTX_get(ctx);
706 y1 = BN_CTX_get(ctx);
707 x2 = BN_CTX_get(ctx);
708 y2 = BN_CTX_get(ctx);
709 s = BN_CTX_get(ctx);
710 t = BN_CTX_get(ctx);
711 if (t == NULL) goto err;
712
713 if (a->Z_is_one)
714 {
715 if (!BN_copy(x0, &a->X)) goto err;
716 if (!BN_copy(y0, &a->Y)) goto err;
717 }
718 else
719 {
720 if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err;
721 }
722 if (b->Z_is_one)
723 {
724 if (!BN_copy(x1, &b->X)) goto err;
725 if (!BN_copy(y1, &b->Y)) goto err;
726 }
727 else
728 {
729 if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err;
730 }
731
732
733 if (BN_GF2m_cmp(x0, x1))
734 {
735 if (!BN_GF2m_add(t, x0, x1)) goto err;
736 if (!BN_GF2m_add(s, y0, y1)) goto err;
737 if (!group->meth->field_div(group, s, s, t, ctx)) goto err;
738 if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
739 if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
740 if (!BN_GF2m_add(x2, x2, s)) goto err;
741 if (!BN_GF2m_add(x2, x2, t)) goto err;
742 }
743 else
744 {
745 if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1))
746 {
747 if (!EC_POINT_set_to_infinity(group, r)) goto err;
748 ret = 1;
749 goto err;
750 }
751 if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err;
752 if (!BN_GF2m_add(s, s, x1)) goto err;
753
754 if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
755 if (!BN_GF2m_add(x2, x2, s)) goto err;
756 if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
757 }
758
759 if (!BN_GF2m_add(y2, x1, x2)) goto err;
760 if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err;
761 if (!BN_GF2m_add(y2, y2, x2)) goto err;
762 if (!BN_GF2m_add(y2, y2, y1)) goto err;
763
764 if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err;
765
766 ret = 1;
767
768 err:
769 BN_CTX_end(ctx);
770 if (new_ctx != NULL)
771 BN_CTX_free(new_ctx);
772 return ret;
773 }
774
775
776/* Computes 2 * a and stores the result in r. r could be a.
777 * Uses algorithm A.10.2 of IEEE P1363.
778 */
779int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
780 {
781 return ec_GF2m_simple_add(group, r, a, a, ctx);
782 }
783
784
785int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
786 {
787 if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
788 /* point is its own inverse */
789 return 1;
790
791 if (!EC_POINT_make_affine(group, point, ctx)) return 0;
792 return BN_GF2m_add(&point->Y, &point->X, &point->Y);
793 }
794
795
796/* Indicates whether the given point is the point at infinity. */
797int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
798 {
799 return BN_is_zero(&point->Z);
800 }
801
802
803/* Determines whether the given EC_POINT is an actual point on the curve defined
804 * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation:
805 * y^2 + x*y = x^3 + a*x^2 + b.
806 */
807int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
808 {
809 int ret = -1;
810 BN_CTX *new_ctx = NULL;
811 BIGNUM *lh, *y2;
812 int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
813 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
814
815 if (EC_POINT_is_at_infinity(group, point))
816 return 1;
817
818 field_mul = group->meth->field_mul;
819 field_sqr = group->meth->field_sqr;
820
821 /* only support affine coordinates */
822 if (!point->Z_is_one) goto err;
823
824 if (ctx == NULL)
825 {
826 ctx = new_ctx = BN_CTX_new();
827 if (ctx == NULL)
828 return -1;
829 }
830
831 BN_CTX_start(ctx);
832 y2 = BN_CTX_get(ctx);
833 lh = BN_CTX_get(ctx);
834 if (lh == NULL) goto err;
835
836 /* We have a curve defined by a Weierstrass equation
837 * y^2 + x*y = x^3 + a*x^2 + b.
838 * <=> x^3 + a*x^2 + x*y + b + y^2 = 0
839 * <=> ((x + a) * x + y ) * x + b + y^2 = 0
840 */
841 if (!BN_GF2m_add(lh, &point->X, &group->a)) goto err;
842 if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
843 if (!BN_GF2m_add(lh, lh, &point->Y)) goto err;
844 if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
845 if (!BN_GF2m_add(lh, lh, &group->b)) goto err;
846 if (!field_sqr(group, y2, &point->Y, ctx)) goto err;
847 if (!BN_GF2m_add(lh, lh, y2)) goto err;
848 ret = BN_is_zero(lh);
849 err:
850 if (ctx) BN_CTX_end(ctx);
851 if (new_ctx) BN_CTX_free(new_ctx);
852 return ret;
853 }
854
855
856/* Indicates whether two points are equal.
857 * Return values:
858 * -1 error
859 * 0 equal (in affine coordinates)
860 * 1 not equal
861 */
862int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
863 {
864 BIGNUM *aX, *aY, *bX, *bY;
865 BN_CTX *new_ctx = NULL;
866 int ret = -1;
867
868 if (EC_POINT_is_at_infinity(group, a))
869 {
870 return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
871 }
872
873 if (a->Z_is_one && b->Z_is_one)
874 {
875 return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
876 }
877
878 if (ctx == NULL)
879 {
880 ctx = new_ctx = BN_CTX_new();
881 if (ctx == NULL)
882 return -1;
883 }
884
885 BN_CTX_start(ctx);
886 aX = BN_CTX_get(ctx);
887 aY = BN_CTX_get(ctx);
888 bX = BN_CTX_get(ctx);
889 bY = BN_CTX_get(ctx);
890 if (bY == NULL) goto err;
891
892 if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) goto err;
893 if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) goto err;
894 ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
895
896 err:
897 if (ctx) BN_CTX_end(ctx);
898 if (new_ctx) BN_CTX_free(new_ctx);
899 return ret;
900 }
901
902
903/* Forces the given EC_POINT to internally use affine coordinates. */
904int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
905 {
906 BN_CTX *new_ctx = NULL;
907 BIGNUM *x, *y;
908 int ret = 0;
909
910 if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
911 return 1;
912
913 if (ctx == NULL)
914 {
915 ctx = new_ctx = BN_CTX_new();
916 if (ctx == NULL)
917 return 0;
918 }
919
920 BN_CTX_start(ctx);
921 x = BN_CTX_get(ctx);
922 y = BN_CTX_get(ctx);
923 if (y == NULL) goto err;
924
925 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
926 if (!BN_copy(&point->X, x)) goto err;
927 if (!BN_copy(&point->Y, y)) goto err;
928 if (!BN_one(&point->Z)) goto err;
929
930 ret = 1;
931
932 err:
933 if (ctx) BN_CTX_end(ctx);
934 if (new_ctx) BN_CTX_free(new_ctx);
935 return ret;
936 }
937
938
939/* Forces each of the EC_POINTs in the given array to use affine coordinates. */
940int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
941 {
942 size_t i;
943
944 for (i = 0; i < num; i++)
945 {
946 if (!group->meth->make_affine(group, points[i], ctx)) return 0;
947 }
948
949 return 1;
950 }
951
952
953/* Wrapper to simple binary polynomial field multiplication implementation. */
954int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
955 {
956 return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
957 }
958
959
960/* Wrapper to simple binary polynomial field squaring implementation. */
961int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
962 {
963 return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
964 }
965
966
967/* Wrapper to simple binary polynomial field division implementation. */
968int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
969 {
970 return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
971 }
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c
new file mode 100644
index 0000000000..ae55539859
--- /dev/null
+++ b/src/lib/libcrypto/ec/ec_asn1.c
@@ -0,0 +1,1429 @@
1/* crypto/ec/ec_asn1.c */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <string.h>
60#include "ec_lcl.h"
61#include <openssl/err.h>
62#include <openssl/asn1t.h>
63#include <openssl/objects.h>
64
65
66int EC_GROUP_get_basis_type(const EC_GROUP *group)
67 {
68 int i=0;
69
70 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
71 NID_X9_62_characteristic_two_field)
72 /* everything else is currently not supported */
73 return 0;
74
75 while (group->poly[i] != 0)
76 i++;
77
78 if (i == 4)
79 return NID_X9_62_ppBasis;
80 else if (i == 2)
81 return NID_X9_62_tpBasis;
82 else
83 /* everything else is currently not supported */
84 return 0;
85 }
86
87int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
88 {
89 if (group == NULL)
90 return 0;
91
92 if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
93 || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0)))
94 {
95 ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
96 return 0;
97 }
98
99 if (k)
100 *k = group->poly[1];
101
102 return 1;
103 }
104
105int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
106 unsigned int *k2, unsigned int *k3)
107 {
108 if (group == NULL)
109 return 0;
110
111 if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
112 || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0)))
113 {
114 ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
115 return 0;
116 }
117
118 if (k1)
119 *k1 = group->poly[3];
120 if (k2)
121 *k2 = group->poly[2];
122 if (k3)
123 *k3 = group->poly[1];
124
125 return 1;
126 }
127
128
129
130/* some structures needed for the asn1 encoding */
131typedef struct x9_62_pentanomial_st {
132 long k1;
133 long k2;
134 long k3;
135 } X9_62_PENTANOMIAL;
136
137typedef struct x9_62_characteristic_two_st {
138 long m;
139 ASN1_OBJECT *type;
140 union {
141 char *ptr;
142 /* NID_X9_62_onBasis */
143 ASN1_NULL *onBasis;
144 /* NID_X9_62_tpBasis */
145 ASN1_INTEGER *tpBasis;
146 /* NID_X9_62_ppBasis */
147 X9_62_PENTANOMIAL *ppBasis;
148 /* anything else */
149 ASN1_TYPE *other;
150 } p;
151 } X9_62_CHARACTERISTIC_TWO;
152
153typedef struct x9_62_fieldid_st {
154 ASN1_OBJECT *fieldType;
155 union {
156 char *ptr;
157 /* NID_X9_62_prime_field */
158 ASN1_INTEGER *prime;
159 /* NID_X9_62_characteristic_two_field */
160 X9_62_CHARACTERISTIC_TWO *char_two;
161 /* anything else */
162 ASN1_TYPE *other;
163 } p;
164 } X9_62_FIELDID;
165
166typedef struct x9_62_curve_st {
167 ASN1_OCTET_STRING *a;
168 ASN1_OCTET_STRING *b;
169 ASN1_BIT_STRING *seed;
170 } X9_62_CURVE;
171
172typedef struct ec_parameters_st {
173 long version;
174 X9_62_FIELDID *fieldID;
175 X9_62_CURVE *curve;
176 ASN1_OCTET_STRING *base;
177 ASN1_INTEGER *order;
178 ASN1_INTEGER *cofactor;
179 } ECPARAMETERS;
180
181struct ecpk_parameters_st {
182 int type;
183 union {
184 ASN1_OBJECT *named_curve;
185 ECPARAMETERS *parameters;
186 ASN1_NULL *implicitlyCA;
187 } value;
188 }/* ECPKPARAMETERS */;
189
190/* SEC1 ECPrivateKey */
191typedef struct ec_privatekey_st {
192 long version;
193 ASN1_OCTET_STRING *privateKey;
194 ECPKPARAMETERS *parameters;
195 ASN1_BIT_STRING *publicKey;
196 } EC_PRIVATEKEY;
197
198/* the OpenSSL ASN.1 definitions */
199ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
200 ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
201 ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
202 ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
203} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
204
205DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
206IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
207
208ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
209
210ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
211 ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
212 ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
213 ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
214} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
215
216ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
217 ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
218 ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
219 ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
220} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
221
222DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
223IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
224
225ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
226
227ASN1_ADB(X9_62_FIELDID) = {
228 ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
229 ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
230} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
231
232ASN1_SEQUENCE(X9_62_FIELDID) = {
233 ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
234 ASN1_ADB_OBJECT(X9_62_FIELDID)
235} ASN1_SEQUENCE_END(X9_62_FIELDID)
236
237ASN1_SEQUENCE(X9_62_CURVE) = {
238 ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
239 ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
240 ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
241} ASN1_SEQUENCE_END(X9_62_CURVE)
242
243ASN1_SEQUENCE(ECPARAMETERS) = {
244 ASN1_SIMPLE(ECPARAMETERS, version, LONG),
245 ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
246 ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
247 ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
248 ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
249 ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
250} ASN1_SEQUENCE_END(ECPARAMETERS)
251
252DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
253IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
254
255ASN1_CHOICE(ECPKPARAMETERS) = {
256 ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
257 ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
258 ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
259} ASN1_CHOICE_END(ECPKPARAMETERS)
260
261DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
262DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
263IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
264
265ASN1_SEQUENCE(EC_PRIVATEKEY) = {
266 ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
267 ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
268 ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
269 ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
270} ASN1_SEQUENCE_END(EC_PRIVATEKEY)
271
272DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
273DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
274IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
275
276/* some declarations of internal function */
277
278/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
279static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
280/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
281static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
282/* ec_asn1_parameters2group() creates a EC_GROUP object from a
283 * ECPARAMETERS object */
284static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
285/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a
286 * EC_GROUP object */
287static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,ECPARAMETERS *);
288/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a
289 * ECPKPARAMETERS object */
290static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *);
291/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a
292 * EC_GROUP object */
293static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *,
294 ECPKPARAMETERS *);
295
296
297/* the function definitions */
298
299static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
300 {
301 int ok=0, nid;
302 BIGNUM *tmp = NULL;
303
304 if (group == NULL || field == NULL)
305 return 0;
306
307 /* clear the old values (if necessary) */
308 if (field->fieldType != NULL)
309 ASN1_OBJECT_free(field->fieldType);
310 if (field->p.other != NULL)
311 ASN1_TYPE_free(field->p.other);
312
313 nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
314 /* set OID for the field */
315 if ((field->fieldType = OBJ_nid2obj(nid)) == NULL)
316 {
317 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
318 goto err;
319 }
320
321 if (nid == NID_X9_62_prime_field)
322 {
323 if ((tmp = BN_new()) == NULL)
324 {
325 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
326 goto err;
327 }
328 /* the parameters are specified by the prime number p */
329 if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL))
330 {
331 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
332 goto err;
333 }
334 /* set the prime number */
335 field->p.prime = BN_to_ASN1_INTEGER(tmp,NULL);
336 if (field->p.prime == NULL)
337 {
338 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
339 goto err;
340 }
341 }
342 else /* nid == NID_X9_62_characteristic_two_field */
343 {
344 int field_type;
345 X9_62_CHARACTERISTIC_TWO *char_two;
346
347 field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
348 char_two = field->p.char_two;
349
350 if (char_two == NULL)
351 {
352 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
353 goto err;
354 }
355
356 char_two->m = (long)EC_GROUP_get_degree(group);
357
358 field_type = EC_GROUP_get_basis_type(group);
359
360 if (field_type == 0)
361 {
362 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
363 goto err;
364 }
365 /* set base type OID */
366 if ((char_two->type = OBJ_nid2obj(field_type)) == NULL)
367 {
368 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
369 goto err;
370 }
371
372 if (field_type == NID_X9_62_tpBasis)
373 {
374 unsigned int k;
375
376 if (!EC_GROUP_get_trinomial_basis(group, &k))
377 goto err;
378
379 char_two->p.tpBasis = ASN1_INTEGER_new();
380 if (!char_two->p.tpBasis)
381 {
382 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
383 goto err;
384 }
385 if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k))
386 {
387 ECerr(EC_F_EC_ASN1_GROUP2FIELDID,
388 ERR_R_ASN1_LIB);
389 goto err;
390 }
391 }
392 else if (field_type == NID_X9_62_ppBasis)
393 {
394 unsigned int k1, k2, k3;
395
396 if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
397 goto err;
398
399 char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
400 if (!char_two->p.ppBasis)
401 {
402 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
403 goto err;
404 }
405
406 /* set k? values */
407 char_two->p.ppBasis->k1 = (long)k1;
408 char_two->p.ppBasis->k2 = (long)k2;
409 char_two->p.ppBasis->k3 = (long)k3;
410 }
411 else /* field_type == NID_X9_62_onBasis */
412 {
413 /* for ONB the parameters are (asn1) NULL */
414 char_two->p.onBasis = ASN1_NULL_new();
415 if (!char_two->p.onBasis)
416 {
417 ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
418 goto err;
419 }
420 }
421 }
422
423 ok = 1;
424
425err : if (tmp)
426 BN_free(tmp);
427 return(ok);
428}
429
430static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
431 {
432 int ok=0, nid;
433 BIGNUM *tmp_1=NULL, *tmp_2=NULL;
434 unsigned char *buffer_1=NULL, *buffer_2=NULL,
435 *a_buf=NULL, *b_buf=NULL;
436 size_t len_1, len_2;
437 unsigned char char_zero = 0;
438
439 if (!group || !curve || !curve->a || !curve->b)
440 return 0;
441
442 if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL)
443 {
444 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
445 goto err;
446 }
447
448 nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
449
450 /* get a and b */
451 if (nid == NID_X9_62_prime_field)
452 {
453 if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL))
454 {
455 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
456 goto err;
457 }
458 }
459 else /* nid == NID_X9_62_characteristic_two_field */
460 {
461 if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL))
462 {
463 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
464 goto err;
465 }
466 }
467
468 len_1 = (size_t)BN_num_bytes(tmp_1);
469 len_2 = (size_t)BN_num_bytes(tmp_2);
470
471 if (len_1 == 0)
472 {
473 /* len_1 == 0 => a == 0 */
474 a_buf = &char_zero;
475 len_1 = 1;
476 }
477 else
478 {
479 if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL)
480 {
481 ECerr(EC_F_EC_ASN1_GROUP2CURVE,
482 ERR_R_MALLOC_FAILURE);
483 goto err;
484 }
485 if ( (len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0)
486 {
487 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
488 goto err;
489 }
490 a_buf = buffer_1;
491 }
492
493 if (len_2 == 0)
494 {
495 /* len_2 == 0 => b == 0 */
496 b_buf = &char_zero;
497 len_2 = 1;
498 }
499 else
500 {
501 if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL)
502 {
503 ECerr(EC_F_EC_ASN1_GROUP2CURVE,
504 ERR_R_MALLOC_FAILURE);
505 goto err;
506 }
507 if ( (len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0)
508 {
509 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
510 goto err;
511 }
512 b_buf = buffer_2;
513 }
514
515 /* set a and b */
516 if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
517 !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2))
518 {
519 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
520 goto err;
521 }
522
523 /* set the seed (optional) */
524 if (group->seed)
525 {
526 if (!curve->seed)
527 if ((curve->seed = ASN1_BIT_STRING_new()) == NULL)
528 {
529 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
530 goto err;
531 }
532 curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
533 curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
534 if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
535 (int)group->seed_len))
536 {
537 ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
538 goto err;
539 }
540 }
541 else
542 {
543 if (curve->seed)
544 {
545 ASN1_BIT_STRING_free(curve->seed);
546 curve->seed = NULL;
547 }
548 }
549
550 ok = 1;
551
552err: if (buffer_1)
553 OPENSSL_free(buffer_1);
554 if (buffer_2)
555 OPENSSL_free(buffer_2);
556 if (tmp_1)
557 BN_free(tmp_1);
558 if (tmp_2)
559 BN_free(tmp_2);
560 return(ok);
561 }
562
563static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group,
564 ECPARAMETERS *param)
565 {
566 int ok=0;
567 size_t len=0;
568 ECPARAMETERS *ret=NULL;
569 BIGNUM *tmp=NULL;
570 unsigned char *buffer=NULL;
571 const EC_POINT *point=NULL;
572 point_conversion_form_t form;
573
574 if ((tmp = BN_new()) == NULL)
575 {
576 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
577 goto err;
578 }
579
580 if (param == NULL)
581 {
582 if ((ret = ECPARAMETERS_new()) == NULL)
583 {
584 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS,
585 ERR_R_MALLOC_FAILURE);
586 goto err;
587 }
588 }
589 else
590 ret = param;
591
592 /* set the version (always one) */
593 ret->version = (long)0x1;
594
595 /* set the fieldID */
596 if (!ec_asn1_group2fieldid(group, ret->fieldID))
597 {
598 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
599 goto err;
600 }
601
602 /* set the curve */
603 if (!ec_asn1_group2curve(group, ret->curve))
604 {
605 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
606 goto err;
607 }
608
609 /* set the base point */
610 if ((point = EC_GROUP_get0_generator(group)) == NULL)
611 {
612 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
613 goto err;
614 }
615
616 form = EC_GROUP_get_point_conversion_form(group);
617
618 len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
619 if (len == 0)
620 {
621 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
622 goto err;
623 }
624 if ((buffer = OPENSSL_malloc(len)) == NULL)
625 {
626 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
627 goto err;
628 }
629 if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL))
630 {
631 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
632 goto err;
633 }
634 if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL)
635 {
636 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
637 goto err;
638 }
639 if (!ASN1_OCTET_STRING_set(ret->base, buffer, len))
640 {
641 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
642 goto err;
643 }
644
645 /* set the order */
646 if (!EC_GROUP_get_order(group, tmp, NULL))
647 {
648 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
649 goto err;
650 }
651 ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
652 if (ret->order == NULL)
653 {
654 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
655 goto err;
656 }
657
658 /* set the cofactor (optional) */
659 if (EC_GROUP_get_cofactor(group, tmp, NULL))
660 {
661 ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
662 if (ret->cofactor == NULL)
663 {
664 ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
665 goto err;
666 }
667 }
668
669 ok = 1;
670
671err : if(!ok)
672 {
673 if (ret && !param)
674 ECPARAMETERS_free(ret);
675 ret = NULL;
676 }
677 if (tmp)
678 BN_free(tmp);
679 if (buffer)
680 OPENSSL_free(buffer);
681 return(ret);
682 }
683
684ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
685 ECPKPARAMETERS *params)
686 {
687 int ok = 1, tmp;
688 ECPKPARAMETERS *ret = params;
689
690 if (ret == NULL)
691 {
692 if ((ret = ECPKPARAMETERS_new()) == NULL)
693 {
694 ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS,
695 ERR_R_MALLOC_FAILURE);
696 return NULL;
697 }
698 }
699 else
700 {
701 if (ret->type == 0 && ret->value.named_curve)
702 ASN1_OBJECT_free(ret->value.named_curve);
703 else if (ret->type == 1 && ret->value.parameters)
704 ECPARAMETERS_free(ret->value.parameters);
705 }
706
707 if (EC_GROUP_get_asn1_flag(group))
708 {
709 /* use the asn1 OID to describe the
710 * the elliptic curve parameters
711 */
712 tmp = EC_GROUP_get_curve_name(group);
713 if (tmp)
714 {
715 ret->type = 0;
716 if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
717 ok = 0;
718 }
719 else
720 /* we don't kmow the nid => ERROR */
721 ok = 0;
722 }
723 else
724 {
725 /* use the ECPARAMETERS structure */
726 ret->type = 1;
727 if ((ret->value.parameters = ec_asn1_group2parameters(
728 group, NULL)) == NULL)
729 ok = 0;
730 }
731
732 if (!ok)
733 {
734 ECPKPARAMETERS_free(ret);
735 return NULL;
736 }
737 return ret;
738 }
739
740static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
741 {
742 int ok = 0, tmp;
743 EC_GROUP *ret = NULL;
744 BIGNUM *p = NULL, *a = NULL, *b = NULL;
745 EC_POINT *point=NULL;
746 long field_bits;
747
748 if (!params->fieldID || !params->fieldID->fieldType ||
749 !params->fieldID->p.ptr)
750 {
751 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
752 goto err;
753 }
754
755 /* now extract the curve parameters a and b */
756 if (!params->curve || !params->curve->a ||
757 !params->curve->a->data || !params->curve->b ||
758 !params->curve->b->data)
759 {
760 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
761 goto err;
762 }
763 a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
764 if (a == NULL)
765 {
766 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
767 goto err;
768 }
769 b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
770 if (b == NULL)
771 {
772 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
773 goto err;
774 }
775
776 /* get the field parameters */
777 tmp = OBJ_obj2nid(params->fieldID->fieldType);
778
779 if (tmp == NID_X9_62_characteristic_two_field)
780 {
781 X9_62_CHARACTERISTIC_TWO *char_two;
782
783 char_two = params->fieldID->p.char_two;
784
785 field_bits = char_two->m;
786 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
787 {
788 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
789 goto err;
790 }
791
792 if ((p = BN_new()) == NULL)
793 {
794 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
795 goto err;
796 }
797
798 /* get the base type */
799 tmp = OBJ_obj2nid(char_two->type);
800
801 if (tmp == NID_X9_62_tpBasis)
802 {
803 long tmp_long;
804
805 if (!char_two->p.tpBasis)
806 {
807 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
808 goto err;
809 }
810
811 tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
812
813 if (!(char_two->m > tmp_long && tmp_long > 0))
814 {
815 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS);
816 goto err;
817 }
818
819 /* create the polynomial */
820 if (!BN_set_bit(p, (int)char_two->m))
821 goto err;
822 if (!BN_set_bit(p, (int)tmp_long))
823 goto err;
824 if (!BN_set_bit(p, 0))
825 goto err;
826 }
827 else if (tmp == NID_X9_62_ppBasis)
828 {
829 X9_62_PENTANOMIAL *penta;
830
831 penta = char_two->p.ppBasis;
832 if (!penta)
833 {
834 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
835 goto err;
836 }
837
838 if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0))
839 {
840 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS);
841 goto err;
842 }
843
844 /* create the polynomial */
845 if (!BN_set_bit(p, (int)char_two->m)) goto err;
846 if (!BN_set_bit(p, (int)penta->k1)) goto err;
847 if (!BN_set_bit(p, (int)penta->k2)) goto err;
848 if (!BN_set_bit(p, (int)penta->k3)) goto err;
849 if (!BN_set_bit(p, 0)) goto err;
850 }
851 else if (tmp == NID_X9_62_onBasis)
852 {
853 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
854 goto err;
855 }
856 else /* error */
857 {
858 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
859 goto err;
860 }
861
862 /* create the EC_GROUP structure */
863 ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
864 }
865 else if (tmp == NID_X9_62_prime_field)
866 {
867 /* we have a curve over a prime field */
868 /* extract the prime number */
869 if (!params->fieldID->p.prime)
870 {
871 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
872 goto err;
873 }
874 p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
875 if (p == NULL)
876 {
877 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
878 goto err;
879 }
880
881 if (BN_is_negative(p) || BN_is_zero(p))
882 {
883 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
884 goto err;
885 }
886
887 field_bits = BN_num_bits(p);
888 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS)
889 {
890 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
891 goto err;
892 }
893
894 /* create the EC_GROUP structure */
895 ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
896 }
897 else
898 {
899 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
900 goto err;
901 }
902
903 if (ret == NULL)
904 {
905 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
906 goto err;
907 }
908
909 /* extract seed (optional) */
910 if (params->curve->seed != NULL)
911 {
912 if (ret->seed != NULL)
913 OPENSSL_free(ret->seed);
914 if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length)))
915 {
916 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
917 ERR_R_MALLOC_FAILURE);
918 goto err;
919 }
920 memcpy(ret->seed, params->curve->seed->data,
921 params->curve->seed->length);
922 ret->seed_len = params->curve->seed->length;
923 }
924
925 if (!params->order || !params->base || !params->base->data)
926 {
927 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
928 goto err;
929 }
930
931 if ((point = EC_POINT_new(ret)) == NULL) goto err;
932
933 /* set the point conversion form */
934 EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
935 (params->base->data[0] & ~0x01));
936
937 /* extract the ec point */
938 if (!EC_POINT_oct2point(ret, point, params->base->data,
939 params->base->length, NULL))
940 {
941 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
942 goto err;
943 }
944
945 /* extract the order */
946 if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL)
947 {
948 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
949 goto err;
950 }
951 if (BN_is_negative(a) || BN_is_zero(a))
952 {
953 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
954 goto err;
955 }
956 if (BN_num_bits(a) > (int)field_bits + 1) /* Hasse bound */
957 {
958 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
959 goto err;
960 }
961
962 /* extract the cofactor (optional) */
963 if (params->cofactor == NULL)
964 {
965 if (b)
966 {
967 BN_free(b);
968 b = NULL;
969 }
970 }
971 else
972 if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL)
973 {
974 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
975 goto err;
976 }
977 /* set the generator, order and cofactor (if present) */
978 if (!EC_GROUP_set_generator(ret, point, a, b))
979 {
980 ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
981 goto err;
982 }
983
984 ok = 1;
985
986err: if (!ok)
987 {
988 if (ret)
989 EC_GROUP_clear_free(ret);
990 ret = NULL;
991 }
992
993 if (p)
994 BN_free(p);
995 if (a)
996 BN_free(a);
997 if (b)
998 BN_free(b);
999 if (point)
1000 EC_POINT_free(point);
1001 return(ret);
1002}
1003
1004EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
1005 {
1006 EC_GROUP *ret=NULL;
1007 int tmp=0;
1008
1009 if (params == NULL)
1010 {
1011 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
1012 EC_R_MISSING_PARAMETERS);
1013 return NULL;
1014 }
1015
1016 if (params->type == 0)
1017 { /* the curve is given by an OID */
1018 tmp = OBJ_obj2nid(params->value.named_curve);
1019 if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL)
1020 {
1021 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
1022 EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
1023 return NULL;
1024 }
1025 EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
1026 }
1027 else if (params->type == 1)
1028 { /* the parameters are given by a ECPARAMETERS
1029 * structure */
1030 ret = ec_asn1_parameters2group(params->value.parameters);
1031 if (!ret)
1032 {
1033 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
1034 return NULL;
1035 }
1036 EC_GROUP_set_asn1_flag(ret, 0x0);
1037 }
1038 else if (params->type == 2)
1039 { /* implicitlyCA */
1040 return NULL;
1041 }
1042 else
1043 {
1044 ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
1045 return NULL;
1046 }
1047
1048 return ret;
1049 }
1050
1051/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
1052
1053EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
1054 {
1055 EC_GROUP *group = NULL;
1056 ECPKPARAMETERS *params = NULL;
1057
1058 if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL)
1059 {
1060 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
1061 ECPKPARAMETERS_free(params);
1062 return NULL;
1063 }
1064
1065 if ((group = ec_asn1_pkparameters2group(params)) == NULL)
1066 {
1067 ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
1068 return NULL;
1069 }
1070
1071
1072 if (a && *a)
1073 EC_GROUP_clear_free(*a);
1074 if (a)
1075 *a = group;
1076
1077 ECPKPARAMETERS_free(params);
1078 return(group);
1079 }
1080
1081int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
1082 {
1083 int ret=0;
1084 ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL);
1085 if (tmp == NULL)
1086 {
1087 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
1088 return 0;
1089 }
1090 if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0)
1091 {
1092 ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
1093 ECPKPARAMETERS_free(tmp);
1094 return 0;
1095 }
1096 ECPKPARAMETERS_free(tmp);
1097 return(ret);
1098 }
1099
1100/* some EC_KEY functions */
1101
1102EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
1103 {
1104 int ok=0;
1105 EC_KEY *ret=NULL;
1106 EC_PRIVATEKEY *priv_key=NULL;
1107
1108 if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1109 {
1110 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1111 return NULL;
1112 }
1113
1114 if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL)
1115 {
1116 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1117 EC_PRIVATEKEY_free(priv_key);
1118 return NULL;
1119 }
1120
1121 if (a == NULL || *a == NULL)
1122 {
1123 if ((ret = EC_KEY_new()) == NULL)
1124 {
1125 ECerr(EC_F_D2I_ECPRIVATEKEY,
1126 ERR_R_MALLOC_FAILURE);
1127 goto err;
1128 }
1129 if (a)
1130 *a = ret;
1131 }
1132 else
1133 ret = *a;
1134
1135 if (priv_key->parameters)
1136 {
1137 if (ret->group)
1138 EC_GROUP_clear_free(ret->group);
1139 ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
1140 }
1141
1142 if (ret->group == NULL)
1143 {
1144 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1145 goto err;
1146 }
1147
1148 ret->version = priv_key->version;
1149
1150 if (priv_key->privateKey)
1151 {
1152 ret->priv_key = BN_bin2bn(
1153 M_ASN1_STRING_data(priv_key->privateKey),
1154 M_ASN1_STRING_length(priv_key->privateKey),
1155 ret->priv_key);
1156 if (ret->priv_key == NULL)
1157 {
1158 ECerr(EC_F_D2I_ECPRIVATEKEY,
1159 ERR_R_BN_LIB);
1160 goto err;
1161 }
1162 }
1163 else
1164 {
1165 ECerr(EC_F_D2I_ECPRIVATEKEY,
1166 EC_R_MISSING_PRIVATE_KEY);
1167 goto err;
1168 }
1169
1170 if (priv_key->publicKey)
1171 {
1172 const unsigned char *pub_oct;
1173 size_t pub_oct_len;
1174
1175 if (ret->pub_key)
1176 EC_POINT_clear_free(ret->pub_key);
1177 ret->pub_key = EC_POINT_new(ret->group);
1178 if (ret->pub_key == NULL)
1179 {
1180 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1181 goto err;
1182 }
1183 pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
1184 pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
1185 /* save the point conversion form */
1186 ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
1187 if (!EC_POINT_oct2point(ret->group, ret->pub_key,
1188 pub_oct, pub_oct_len, NULL))
1189 {
1190 ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
1191 goto err;
1192 }
1193 }
1194
1195 ok = 1;
1196err:
1197 if (!ok)
1198 {
1199 if (ret)
1200 EC_KEY_free(ret);
1201 ret = NULL;
1202 }
1203
1204 if (priv_key)
1205 EC_PRIVATEKEY_free(priv_key);
1206
1207 return(ret);
1208 }
1209
1210int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
1211 {
1212 int ret=0, ok=0;
1213 unsigned char *buffer=NULL;
1214 size_t buf_len=0, tmp_len;
1215 EC_PRIVATEKEY *priv_key=NULL;
1216
1217 if (a == NULL || a->group == NULL || a->priv_key == NULL)
1218 {
1219 ECerr(EC_F_I2D_ECPRIVATEKEY,
1220 ERR_R_PASSED_NULL_PARAMETER);
1221 goto err;
1222 }
1223
1224 if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
1225 {
1226 ECerr(EC_F_I2D_ECPRIVATEKEY,
1227 ERR_R_MALLOC_FAILURE);
1228 goto err;
1229 }
1230
1231 priv_key->version = a->version;
1232
1233 buf_len = (size_t)BN_num_bytes(a->priv_key);
1234 buffer = OPENSSL_malloc(buf_len);
1235 if (buffer == NULL)
1236 {
1237 ECerr(EC_F_I2D_ECPRIVATEKEY,
1238 ERR_R_MALLOC_FAILURE);
1239 goto err;
1240 }
1241
1242 if (!BN_bn2bin(a->priv_key, buffer))
1243 {
1244 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
1245 goto err;
1246 }
1247
1248 if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len))
1249 {
1250 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1251 goto err;
1252 }
1253
1254 if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS))
1255 {
1256 if ((priv_key->parameters = ec_asn1_group2pkparameters(
1257 a->group, priv_key->parameters)) == NULL)
1258 {
1259 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1260 goto err;
1261 }
1262 }
1263
1264 if (!(a->enc_flag & EC_PKEY_NO_PUBKEY))
1265 {
1266 priv_key->publicKey = M_ASN1_BIT_STRING_new();
1267 if (priv_key->publicKey == NULL)
1268 {
1269 ECerr(EC_F_I2D_ECPRIVATEKEY,
1270 ERR_R_MALLOC_FAILURE);
1271 goto err;
1272 }
1273
1274 tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
1275 a->conv_form, NULL, 0, NULL);
1276
1277 if (tmp_len > buf_len)
1278 {
1279 unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
1280 if (!tmp_buffer)
1281 {
1282 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
1283 goto err;
1284 }
1285 buffer = tmp_buffer;
1286 buf_len = tmp_len;
1287 }
1288
1289 if (!EC_POINT_point2oct(a->group, a->pub_key,
1290 a->conv_form, buffer, buf_len, NULL))
1291 {
1292 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1293 goto err;
1294 }
1295
1296 priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
1297 priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
1298 if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer,
1299 buf_len))
1300 {
1301 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
1302 goto err;
1303 }
1304 }
1305
1306 if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0)
1307 {
1308 ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
1309 goto err;
1310 }
1311 ok=1;
1312err:
1313 if (buffer)
1314 OPENSSL_free(buffer);
1315 if (priv_key)
1316 EC_PRIVATEKEY_free(priv_key);
1317 return(ok?ret:0);
1318 }
1319
1320int i2d_ECParameters(EC_KEY *a, unsigned char **out)
1321 {
1322 if (a == NULL)
1323 {
1324 ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1325 return 0;
1326 }
1327 return i2d_ECPKParameters(a->group, out);
1328 }
1329
1330EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
1331 {
1332 EC_KEY *ret;
1333
1334 if (in == NULL || *in == NULL)
1335 {
1336 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
1337 return NULL;
1338 }
1339
1340 if (a == NULL || *a == NULL)
1341 {
1342 if ((ret = EC_KEY_new()) == NULL)
1343 {
1344 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
1345 return NULL;
1346 }
1347 if (a)
1348 *a = ret;
1349 }
1350 else
1351 ret = *a;
1352
1353 if (!d2i_ECPKParameters(&ret->group, in, len))
1354 {
1355 ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
1356 return NULL;
1357 }
1358
1359 return ret;
1360 }
1361
1362EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
1363 {
1364 EC_KEY *ret=NULL;
1365
1366 if (a == NULL || (*a) == NULL || (*a)->group == NULL)
1367 {
1368 /* sorry, but a EC_GROUP-structur is necessary
1369 * to set the public key */
1370 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1371 return 0;
1372 }
1373 ret = *a;
1374 if (ret->pub_key == NULL &&
1375 (ret->pub_key = EC_POINT_new(ret->group)) == NULL)
1376 {
1377 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1378 return 0;
1379 }
1380 if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL))
1381 {
1382 ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
1383 return 0;
1384 }
1385 /* save the point conversion form */
1386 ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01);
1387 *in += len;
1388 return ret;
1389 }
1390
1391int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
1392 {
1393 size_t buf_len=0;
1394 int new_buffer = 0;
1395
1396 if (a == NULL)
1397 {
1398 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
1399 return 0;
1400 }
1401
1402 buf_len = EC_POINT_point2oct(a->group, a->pub_key,
1403 a->conv_form, NULL, 0, NULL);
1404
1405 if (out == NULL || buf_len == 0)
1406 /* out == NULL => just return the length of the octet string */
1407 return buf_len;
1408
1409 if (*out == NULL)
1410 {
1411 if ((*out = OPENSSL_malloc(buf_len)) == NULL)
1412 {
1413 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
1414 return 0;
1415 }
1416 new_buffer = 1;
1417 }
1418 if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
1419 *out, buf_len, NULL))
1420 {
1421 ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
1422 OPENSSL_free(*out);
1423 *out = NULL;
1424 return 0;
1425 }
1426 if (!new_buffer)
1427 *out += buf_len;
1428 return buf_len;
1429 }
diff --git a/src/lib/libcrypto/ec/ec_check.c b/src/lib/libcrypto/ec/ec_check.c
new file mode 100644
index 0000000000..0e316b4b3f
--- /dev/null
+++ b/src/lib/libcrypto/ec/ec_check.c
@@ -0,0 +1,123 @@
1/* crypto/ec/ec_check.c */
2/* ====================================================================
3 * Copyright (c) 1998-2002 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#include "ec_lcl.h"
57#include <openssl/err.h>
58
59int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
60 {
61 int ret = 0;
62 BIGNUM *order;
63 BN_CTX *new_ctx = NULL;
64 EC_POINT *point = NULL;
65
66 if (ctx == NULL)
67 {
68 ctx = new_ctx = BN_CTX_new();
69 if (ctx == NULL)
70 {
71 ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
72 goto err;
73 }
74 }
75 BN_CTX_start(ctx);
76 if ((order = BN_CTX_get(ctx)) == NULL) goto err;
77
78 /* check the discriminant */
79 if (!EC_GROUP_check_discriminant(group, ctx))
80 {
81 ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
82 goto err;
83 }
84
85 /* check the generator */
86 if (group->generator == NULL)
87 {
88 ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
89 goto err;
90 }
91 if (!EC_POINT_is_on_curve(group, group->generator, ctx))
92 {
93 ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
94 goto err;
95 }
96
97 /* check the order of the generator */
98 if ((point = EC_POINT_new(group)) == NULL) goto err;
99 if (!EC_GROUP_get_order(group, order, ctx)) goto err;
100 if (BN_is_zero(order))
101 {
102 ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
103 goto err;
104 }
105
106 if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) goto err;
107 if (!EC_POINT_is_at_infinity(group, point))
108 {
109 ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
110 goto err;
111 }
112
113 ret = 1;
114
115err:
116 if (ctx != NULL)
117 BN_CTX_end(ctx);
118 if (new_ctx != NULL)
119 BN_CTX_free(new_ctx);
120 if (point)
121 EC_POINT_free(point);
122 return ret;
123 }
diff --git a/src/lib/libcrypto/ec/ec_curve.c b/src/lib/libcrypto/ec/ec_curve.c
new file mode 100644
index 0000000000..beac20969b
--- /dev/null
+++ b/src/lib/libcrypto/ec/ec_curve.c
@@ -0,0 +1,1270 @@
1/* crypto/ec/ec_curve.c */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * openssl-core@openssl.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 *
61 * Portions of the attached software ("Contribution") are developed by
62 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63 *
64 * The Contribution is licensed pursuant to the OpenSSL open source
65 * license provided above.
66 *
67 * The elliptic curve binary polynomial software is originally written by
68 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69 *
70 */
71
72#include "ec_lcl.h"
73#include <openssl/err.h>
74#include <openssl/obj_mac.h>
75
76typedef struct ec_curve_data_st {
77 int field_type; /* either NID_X9_62_prime_field or
78 * NID_X9_62_characteristic_two_field */
79 const char *p; /* either a prime number or a polynomial */
80 const char *a;
81 const char *b;
82 const char *x; /* the x coordinate of the generator */
83 const char *y; /* the y coordinate of the generator */
84 const char *order; /* the order of the group generated by the
85 * generator */
86 const BN_ULONG cofactor;/* the cofactor */
87 const unsigned char *seed;/* the seed (optional) */
88 size_t seed_len;
89 const char *comment; /* a short description of the curve */
90} EC_CURVE_DATA;
91
92/* the nist prime curves */
93static const unsigned char _EC_NIST_PRIME_192_SEED[] = {
94 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57,
95 0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5};
96static const EC_CURVE_DATA _EC_NIST_PRIME_192 = {
97 NID_X9_62_prime_field,
98 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
99 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
100 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
101 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
102 "07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
103 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",1,
104 _EC_NIST_PRIME_192_SEED, 20,
105 "NIST/X9.62/SECG curve over a 192 bit prime field"
106 };
107
108static const unsigned char _EC_NIST_PRIME_224_SEED[] = {
109 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45,
110 0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5};
111static const EC_CURVE_DATA _EC_NIST_PRIME_224 = {
112 NID_X9_62_prime_field,
113 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
114 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
115 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
116 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
117 "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
118 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",1,
119 _EC_NIST_PRIME_224_SEED, 20,
120 "NIST/SECG curve over a 224 bit prime field"
121 };
122
123static const unsigned char _EC_NIST_PRIME_384_SEED[] = {
124 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00,
125 0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73};
126static const EC_CURVE_DATA _EC_NIST_PRIME_384 = {
127 NID_X9_62_prime_field,
128 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF"
129 "FFF0000000000000000FFFFFFFF",
130 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF"
131 "FFF0000000000000000FFFFFFFC",
132 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC6563"
133 "98D8A2ED19D2A85C8EDD3EC2AEF",
134 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F"
135 "25DBF55296C3A545E3872760AB7",
136 "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b"
137 "1ce1d7e819d7a431d7c90ea0e5f",
138 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0"
139 "DB248B0A77AECEC196ACCC52973",1,
140 _EC_NIST_PRIME_384_SEED, 20,
141 "NIST/SECG curve over a 384 bit prime field"
142 };
143
144static const unsigned char _EC_NIST_PRIME_521_SEED[] = {
145 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC,
146 0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA};
147static const EC_CURVE_DATA _EC_NIST_PRIME_521 = {
148 NID_X9_62_prime_field,
149 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
150 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
151 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
152 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
153 "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156"
154 "193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
155 "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14"
156 "B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
157 "011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c9"
158 "7ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
159 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51"
160 "868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",1,
161 _EC_NIST_PRIME_521_SEED, 20,
162 "NIST/SECG curve over a 521 bit prime field"
163 };
164/* the x9.62 prime curves (minus the nist prime curves) */
165static const unsigned char _EC_X9_62_PRIME_192V2_SEED[] = {
166 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B,
167 0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6};
168static const EC_CURVE_DATA _EC_X9_62_PRIME_192V2 = {
169 NID_X9_62_prime_field,
170 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
171 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
172 "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
173 "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
174 "6574d11d69b6ec7a672bb82a083df2f2b0847de970b2de15",
175 "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",1,
176 _EC_X9_62_PRIME_192V2_SEED, 20,
177 "X9.62 curve over a 192 bit prime field"
178 };
179
180static const unsigned char _EC_X9_62_PRIME_192V3_SEED[] = {
181 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6,
182 0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E};
183static const EC_CURVE_DATA _EC_X9_62_PRIME_192V3 = {
184 NID_X9_62_prime_field,
185 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
186 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
187 "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
188 "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
189 "38a90f22637337334b49dcb66a6dc8f9978aca7648a943b0",
190 "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",1,
191 _EC_X9_62_PRIME_192V3_SEED, 20,
192 "X9.62 curve over a 192 bit prime field"
193 };
194
195static const unsigned char _EC_X9_62_PRIME_239V1_SEED[] = {
196 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0,
197 0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D};
198static const EC_CURVE_DATA _EC_X9_62_PRIME_239V1 = {
199 NID_X9_62_prime_field,
200 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
201 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
202 "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
203 "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
204 "7debe8e4e90a5dae6e4054ca530ba04654b36818ce226b39fccb7b02f1ae",
205 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",1,
206 _EC_X9_62_PRIME_239V1_SEED, 20,
207 "X9.62 curve over a 239 bit prime field"
208 };
209
210static const unsigned char _EC_X9_62_PRIME_239V2_SEED[] = {
211 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B,
212 0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16};
213static const EC_CURVE_DATA _EC_X9_62_PRIME_239V2 = {
214 NID_X9_62_prime_field,
215 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
216 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
217 "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
218 "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
219 "5b0125e4dbea0ec7206da0fc01d9b081329fb555de6ef460237dff8be4ba",
220 "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",1,
221 _EC_X9_62_PRIME_239V2_SEED, 20,
222 "X9.62 curve over a 239 bit prime field"
223 };
224
225static const unsigned char _EC_X9_62_PRIME_239V3_SEED[] = {
226 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A,
227 0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF};
228static const EC_CURVE_DATA _EC_X9_62_PRIME_239V3 = {
229 NID_X9_62_prime_field,
230 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
231 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
232 "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
233 "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
234 "1607e6898f390c06bc1d552bad226f3b6fcfe48b6e818499af18e3ed6cf3",
235 "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",1,
236 _EC_X9_62_PRIME_239V3_SEED, 20,
237 "X9.62 curve over a 239 bit prime field"
238 };
239
240static const unsigned char _EC_X9_62_PRIME_256V1_SEED[] = {
241 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66,
242 0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90};
243static const EC_CURVE_DATA _EC_X9_62_PRIME_256V1 = {
244 NID_X9_62_prime_field,
245 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
246 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
247 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
248 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
249 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
250 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",1,
251 _EC_X9_62_PRIME_256V1_SEED, 20,
252 "X9.62/SECG curve over a 256 bit prime field"
253 };
254/* the secg prime curves (minus the nist and x9.62 prime curves) */
255static const unsigned char _EC_SECG_PRIME_112R1_SEED[] = {
256 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68,
257 0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1};
258static const EC_CURVE_DATA _EC_SECG_PRIME_112R1 = {
259 NID_X9_62_prime_field,
260 "DB7C2ABF62E35E668076BEAD208B",
261 "DB7C2ABF62E35E668076BEAD2088",
262 "659EF8BA043916EEDE8911702B22",
263 "09487239995A5EE76B55F9C2F098",
264 "a89ce5af8724c0a23e0e0ff77500",
265 "DB7C2ABF62E35E7628DFAC6561C5",1,
266 _EC_SECG_PRIME_112R1_SEED, 20,
267 "SECG/WTLS curve over a 112 bit prime field"
268 };
269
270static const unsigned char _EC_SECG_PRIME_112R2_SEED[] = {
271 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68,
272 0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4};
273static const EC_CURVE_DATA _EC_SECG_PRIME_112R2 = {
274 NID_X9_62_prime_field,
275 "DB7C2ABF62E35E668076BEAD208B",
276 "6127C24C05F38A0AAAF65C0EF02C",
277 "51DEF1815DB5ED74FCC34C85D709",
278 "4BA30AB5E892B4E1649DD0928643",
279 "adcd46f5882e3747def36e956e97",
280 "36DF0AAFD8B8D7597CA10520D04B",4,
281 _EC_SECG_PRIME_112R2_SEED, 20,
282 "SECG curve over a 112 bit prime field"
283 };
284
285static const unsigned char _EC_SECG_PRIME_128R1_SEED[] = {
286 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,
287 0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79};
288static const EC_CURVE_DATA _EC_SECG_PRIME_128R1 = {
289 NID_X9_62_prime_field,
290 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
291 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
292 "E87579C11079F43DD824993C2CEE5ED3",
293 "161FF7528B899B2D0C28607CA52C5B86",
294 "cf5ac8395bafeb13c02da292dded7a83",
295 "FFFFFFFE0000000075A30D1B9038A115",1,
296 _EC_SECG_PRIME_128R1_SEED, 20,
297 "SECG curve over a 128 bit prime field"
298 };
299
300static const unsigned char _EC_SECG_PRIME_128R2_SEED[] = {
301 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,
302 0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4};
303static const EC_CURVE_DATA _EC_SECG_PRIME_128R2 = {
304 NID_X9_62_prime_field,
305 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
306 "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
307 "5EEEFCA380D02919DC2C6558BB6D8A5D",
308 "7B6AA5D85E572983E6FB32A7CDEBC140",
309 "27b6916a894d3aee7106fe805fc34b44",
310 "3FFFFFFF7FFFFFFFBE0024720613B5A3",4,
311 _EC_SECG_PRIME_128R2_SEED, 20,
312 "SECG curve over a 128 bit prime field"
313 };
314
315static const EC_CURVE_DATA _EC_SECG_PRIME_160K1 = {
316 NID_X9_62_prime_field,
317 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
318 "0",
319 "7",
320 "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
321 "938cf935318fdced6bc28286531733c3f03c4fee",
322 "0100000000000000000001B8FA16DFAB9ACA16B6B3",1,
323 NULL, 0,
324 "SECG curve over a 160 bit prime field"
325 };
326
327static const unsigned char _EC_SECG_PRIME_160R1_SEED[] = {
328 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76,
329 0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45};
330static const EC_CURVE_DATA _EC_SECG_PRIME_160R1 = {
331 NID_X9_62_prime_field,
332 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
333 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
334 "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
335 "4A96B5688EF573284664698968C38BB913CBFC82",
336 "23a628553168947d59dcc912042351377ac5fb32",
337 "0100000000000000000001F4C8F927AED3CA752257",1,
338 _EC_SECG_PRIME_160R1_SEED, 20,
339 "SECG curve over a 160 bit prime field"
340 };
341
342static const unsigned char _EC_SECG_PRIME_160R2_SEED[] = {
343 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09,
344 0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51};
345static const EC_CURVE_DATA _EC_SECG_PRIME_160R2 = {
346 NID_X9_62_prime_field,
347 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
348 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
349 "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
350 "52DCB034293A117E1F4FF11B30F7199D3144CE6D",
351 "feaffef2e331f296e071fa0df9982cfea7d43f2e",
352 "0100000000000000000000351EE786A818F3A1A16B",1,
353 _EC_SECG_PRIME_160R2_SEED, 20,
354 "SECG/WTLS curve over a 160 bit prime field"
355 };
356
357static const EC_CURVE_DATA _EC_SECG_PRIME_192K1 = {
358 NID_X9_62_prime_field,
359 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
360 "0",
361 "3",
362 "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
363 "9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d",
364 "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",1,
365 NULL, 20,
366 "SECG curve over a 192 bit prime field"
367 };
368
369static const EC_CURVE_DATA _EC_SECG_PRIME_224K1 = {
370 NID_X9_62_prime_field,
371 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
372 "0",
373 "5",
374 "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
375 "7e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5",
376 "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",1,
377 NULL, 20,
378 "SECG curve over a 224 bit prime field"
379 };
380
381static const EC_CURVE_DATA _EC_SECG_PRIME_256K1 = {
382 NID_X9_62_prime_field,
383 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
384 "0",
385 "7",
386 "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
387 "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
388 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",1,
389 NULL, 20,
390 "SECG curve over a 256 bit prime field"
391 };
392
393/* some wap/wtls curves */
394static const EC_CURVE_DATA _EC_WTLS_8 = {
395 NID_X9_62_prime_field,
396 "FFFFFFFFFFFFFFFFFFFFFFFFFDE7",
397 "0",
398 "3",
399 "1",
400 "2",
401 "0100000000000001ECEA551AD837E9",1,
402 NULL, 20,
403 "WTLS curve over a 112 bit prime field"
404 };
405
406static const EC_CURVE_DATA _EC_WTLS_9 = {
407 NID_X9_62_prime_field,
408 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F",
409 "0",
410 "3",
411 "1",
412 "2",
413 "0100000000000000000001CDC98AE0E2DE574ABF33",1,
414 NULL, 20,
415 "WTLS curve over a 160 bit prime field"
416 };
417
418static const EC_CURVE_DATA _EC_WTLS_12 = {
419 NID_X9_62_prime_field,
420 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
421 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
422 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
423 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
424 "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
425 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1,
426 NULL, 0,
427 "WTLS curvs over a 224 bit prime field"
428 };
429
430/* characteristic two curves */
431static const unsigned char _EC_SECG_CHAR2_113R1_SEED[] = {
432 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87,
433 0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9};
434static const EC_CURVE_DATA _EC_SECG_CHAR2_113R1 = {
435 NID_X9_62_characteristic_two_field,
436 "020000000000000000000000000201",
437 "003088250CA6E7C7FE649CE85820F7",
438 "00E8BEE4D3E2260744188BE0E9C723",
439 "009D73616F35F4AB1407D73562C10F",
440 "00A52830277958EE84D1315ED31886",
441 "0100000000000000D9CCEC8A39E56F", 2,
442 _EC_SECG_CHAR2_113R1_SEED, 20,
443 "SECG curve over a 113 bit binary field"
444 };
445
446static const unsigned char _EC_SECG_CHAR2_113R2_SEED[] = {
447 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,
448 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D};
449static const EC_CURVE_DATA _EC_SECG_CHAR2_113R2 = {
450 NID_X9_62_characteristic_two_field,
451 "020000000000000000000000000201",
452 "00689918DBEC7E5A0DD6DFC0AA55C7",
453 "0095E9A9EC9B297BD4BF36E059184F",
454 "01A57A6A7B26CA5EF52FCDB8164797",
455 "00B3ADC94ED1FE674C06E695BABA1D",
456 "010000000000000108789B2496AF93", 2,
457 _EC_SECG_CHAR2_113R2_SEED, 20,
458 "SECG curve over a 113 bit binary field"
459 };
460
461static const unsigned char _EC_SECG_CHAR2_131R1_SEED[] = {
462 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98,
463 0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2};
464static const EC_CURVE_DATA _EC_SECG_CHAR2_131R1 = {
465 NID_X9_62_characteristic_two_field,
466 "080000000000000000000000000000010D",
467 "07A11B09A76B562144418FF3FF8C2570B8",
468 "0217C05610884B63B9C6C7291678F9D341",
469 "0081BAF91FDF9833C40F9C181343638399",
470 "078C6E7EA38C001F73C8134B1B4EF9E150",
471 "0400000000000000023123953A9464B54D", 2,
472 _EC_SECG_CHAR2_131R1_SEED, 20,
473 "SECG/WTLS curve over a 131 bit binary field"
474 };
475
476static const unsigned char _EC_SECG_CHAR2_131R2_SEED[] = {
477 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76,
478 0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3};
479static const EC_CURVE_DATA _EC_SECG_CHAR2_131R2 = {
480 NID_X9_62_characteristic_two_field,
481 "080000000000000000000000000000010D",
482 "03E5A88919D7CAFCBF415F07C2176573B2",
483 "04B8266A46C55657AC734CE38F018F2192",
484 "0356DCD8F2F95031AD652D23951BB366A8",
485 "0648F06D867940A5366D9E265DE9EB240F",
486 "0400000000000000016954A233049BA98F", 2,
487 _EC_SECG_CHAR2_131R2_SEED, 20,
488 "SECG curve over a 131 bit binary field"
489 };
490
491static const EC_CURVE_DATA _EC_NIST_CHAR2_163K = {
492 NID_X9_62_characteristic_two_field,
493 "0800000000000000000000000000000000000000C9",
494 "1",
495 "1",
496 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
497 "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
498 "04000000000000000000020108A2E0CC0D99F8A5EF", 2,
499 NULL, 0,
500 "NIST/SECG/WTLS curve over a 163 bit binary field"
501 };
502
503static const unsigned char _EC_SECG_CHAR2_163R1_SEED[] = {
504 0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67,
505 0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C};
506static const EC_CURVE_DATA _EC_SECG_CHAR2_163R1 = {
507 NID_X9_62_characteristic_two_field,
508 "0800000000000000000000000000000000000000C9",
509 "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2",
510 "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9",
511 "0369979697AB43897789566789567F787A7876A654",
512 "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883",
513 "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", 2,
514/* The algorithm used to derive the curve parameters from
515 * the seed used here is slightly different than the
516 * algorithm described in X9.62 .
517 */
518#if 0
519 _EC_SECG_CHAR2_163R1_SEED, 20,
520#else
521 NULL, 0,
522#endif
523 "SECG curve over a 163 bit binary field"
524 };
525
526static const unsigned char _EC_NIST_CHAR2_163B_SEED[] = {
527 0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12,
528 0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68};
529static const EC_CURVE_DATA _EC_NIST_CHAR2_163B ={
530 NID_X9_62_characteristic_two_field,
531 "0800000000000000000000000000000000000000C9",
532 "1",
533 "020A601907B8C953CA1481EB10512F78744A3205FD",
534 "03F0EBA16286A2D57EA0991168D4994637E8343E36",
535 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
536 "040000000000000000000292FE77E70C12A4234C33", 2,
537/* The seed here was used to created the curve parameters in normal
538 * basis representation (and not the polynomial representation used here)
539 */
540#if 0
541 _EC_NIST_CHAR2_163B_SEED, 20,
542#else
543 NULL, 0,
544#endif
545 "NIST/SECG curve over a 163 bit binary field"
546 };
547
548static const unsigned char _EC_SECG_CHAR2_193R1_SEED[] = {
549 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75,
550 0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30};
551static const EC_CURVE_DATA _EC_SECG_CHAR2_193R1 = {
552 NID_X9_62_characteristic_two_field,
553 "02000000000000000000000000000000000000000000008001",
554 "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01",
555 "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814",
556 "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1",
557 "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05",
558 "01000000000000000000000000C7F34A778F443ACC920EBA49", 2,
559 _EC_SECG_CHAR2_193R1_SEED, 20,
560 "SECG curve over a 193 bit binary field"
561 };
562
563static const unsigned char _EC_SECG_CHAR2_193R2_SEED[] = {
564 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,
565 0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11};
566static const EC_CURVE_DATA _EC_SECG_CHAR2_193R2 = {
567 NID_X9_62_characteristic_two_field,
568 "02000000000000000000000000000000000000000000008001",
569 "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B",
570 "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE",
571 "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F",
572 "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C",
573 "010000000000000000000000015AAB561B005413CCD4EE99D5", 2,
574 _EC_SECG_CHAR2_193R2_SEED, 20,
575 "SECG curve over a 193 bit binary field"
576 };
577
578static const EC_CURVE_DATA _EC_NIST_CHAR2_233K = {
579 NID_X9_62_characteristic_two_field,
580 "020000000000000000000000000000000000000004000000000000000001",
581 "0",
582 "1",
583 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
584 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
585 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4,
586 NULL, 0,
587 "NIST/SECG/WTLS curve over a 233 bit binary field"
588 };
589
590static const unsigned char _EC_NIST_CHAR2_233B_SEED[] = {
591 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1,
592 0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3};
593static const EC_CURVE_DATA _EC_NIST_CHAR2_233B = {
594 NID_X9_62_characteristic_two_field,
595 "020000000000000000000000000000000000000004000000000000000001",
596 "000000000000000000000000000000000000000000000000000000000001",
597 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
598 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
599 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
600 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 2,
601 _EC_NIST_CHAR2_233B_SEED, 20,
602 "NIST/SECG/WTLS curve over a 233 bit binary field"
603 };
604
605static const EC_CURVE_DATA _EC_SECG_CHAR2_239K1 = {
606 NID_X9_62_characteristic_two_field,
607 "800000000000000000004000000000000000000000000000000000000001",
608 "0",
609 "1",
610 "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC",
611 "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA",
612 "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", 4,
613 NULL, 0,
614 "SECG curve over a 239 bit binary field"
615 };
616
617static const EC_CURVE_DATA _EC_NIST_CHAR2_283K = {
618 NID_X9_62_characteristic_two_field,
619 "080000000000000000000000000000000000000000000000000000000000000000001"
620 "0A1",
621 "0",
622 "1",
623 "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492"
624 "836",
625 "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2"
626 "259",
627 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163"
628 "C61", 4,
629 NULL, 20,
630 "NIST/SECG curve over a 283 bit binary field"
631 };
632
633static const unsigned char _EC_NIST_CHAR2_283B_SEED[] = {
634 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D,
635 0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE};
636static const EC_CURVE_DATA _EC_NIST_CHAR2_283B = {
637 NID_X9_62_characteristic_two_field,
638 "080000000000000000000000000000000000000000000000000000000000000000001"
639 "0A1",
640 "000000000000000000000000000000000000000000000000000000000000000000000"
641 "001",
642 "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A"
643 "2F5",
644 "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12"
645 "053",
646 "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE811"
647 "2F4",
648 "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB"
649 "307", 2,
650 _EC_NIST_CHAR2_283B_SEED, 20,
651 "NIST/SECG curve over a 283 bit binary field"
652 };
653
654static const EC_CURVE_DATA _EC_NIST_CHAR2_409K = {
655 NID_X9_62_characteristic_two_field,
656 "020000000000000000000000000000000000000000000000000000000000000000000"
657 "00000000000008000000000000000000001",
658 "0",
659 "1",
660 "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C4601"
661 "89EB5AAAA62EE222EB1B35540CFE9023746",
662 "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6"
663 "C42E9C55215AA9CA27A5863EC48D8E0286B",
664 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400"
665 "EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 4,
666 NULL, 0,
667 "NIST/SECG curve over a 409 bit binary field"
668 };
669
670static const unsigned char _EC_NIST_CHAR2_409B_SEED[] = {
671 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21,
672 0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B};
673static const EC_CURVE_DATA _EC_NIST_CHAR2_409B = {
674 NID_X9_62_characteristic_two_field,
675 "020000000000000000000000000000000000000000000000000000000000000000000"
676 "00000000000008000000000000000000001",
677 "000000000000000000000000000000000000000000000000000000000000000000000"
678 "00000000000000000000000000000000001",
679 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A19"
680 "7B272822F6CD57A55AA4F50AE317B13545F",
681 "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255"
682 "A868A1180515603AEAB60794E54BB7996A7",
683 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514"
684 "F1FDF4B4F40D2181B3681C364BA0273C706",
685 "010000000000000000000000000000000000000000000000000001E2AAD6A612F3330"
686 "7BE5FA47C3C9E052F838164CD37D9A21173", 2,
687 _EC_NIST_CHAR2_409B_SEED, 20,
688 "NIST/SECG curve over a 409 bit binary field"
689 };
690
691static const EC_CURVE_DATA _EC_NIST_CHAR2_571K = {
692 NID_X9_62_characteristic_two_field,
693 "800000000000000000000000000000000000000000000000000000000000000000000"
694 "000000000000000000000000000000000000000000000000000000000000000000000"
695 "00425",
696 "0",
697 "1",
698 "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709"
699 "58493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A0"
700 "1C8972",
701 "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D497"
702 "9C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143E"
703 "F1C7A3",
704 "020000000000000000000000000000000000000000000000000000000000000000000"
705 "000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F63"
706 "7C1001", 4,
707 NULL, 0,
708 "NIST/SECG curve over a 571 bit binary field"
709 };
710
711static const unsigned char _EC_NIST_CHAR2_571B_SEED[] = {
712 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B,
713 0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10};
714static const EC_CURVE_DATA _EC_NIST_CHAR2_571B = {
715 NID_X9_62_characteristic_two_field,
716 "800000000000000000000000000000000000000000000000000000000000000000000"
717 "000000000000000000000000000000000000000000000000000000000000000000000"
718 "00425",
719 "000000000000000000000000000000000000000000000000000000000000000000000"
720 "000000000000000000000000000000000000000000000000000000000000000000000"
721 "000001",
722 "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFA"
723 "BBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F29"
724 "55727A",
725 "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53"
726 "950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8E"
727 "EC2D19",
728 "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423"
729 "E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B"
730 "8AC15B",
731 "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
732 "FFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2F"
733 "E84E47", 2,
734 _EC_NIST_CHAR2_571B_SEED, 20,
735 "NIST/SECG curve over a 571 bit binary field"
736 };
737
738static const unsigned char _EC_X9_62_CHAR2_163V1_SEED[] = {
739 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE,
740 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54};
741static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V1 = {
742 NID_X9_62_characteristic_two_field,
743 "080000000000000000000000000000000000000107",
744 "072546B5435234A422E0789675F432C89435DE5242",
745 "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9",
746 "07AF69989546103D79329FCC3D74880F33BBE803CB",
747 "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F",
748 "0400000000000000000001E60FC8821CC74DAEAFC1", 2,
749 _EC_X9_62_CHAR2_163V1_SEED, 20,
750 "X9.62 curve over a 163 bit binary field"
751 };
752
753static const unsigned char _EC_X9_62_CHAR2_163V2_SEED[] = {
754 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76,
755 0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD};
756static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V2 = {
757 NID_X9_62_characteristic_two_field,
758 "080000000000000000000000000000000000000107",
759 "0108B39E77C4B108BED981ED0E890E117C511CF072",
760 "0667ACEB38AF4E488C407433FFAE4F1C811638DF20",
761 "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5",
762 "079F684DDF6684C5CD258B3890021B2386DFD19FC5",
763 "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 2,
764 _EC_X9_62_CHAR2_163V2_SEED, 20,
765 "X9.62 curve over a 163 bit binary field"
766 };
767
768static const unsigned char _EC_X9_62_CHAR2_163V3_SEED[] = {
769 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67,
770 0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8};
771static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V3 = {
772 NID_X9_62_characteristic_two_field,
773 "080000000000000000000000000000000000000107",
774 "07A526C63D3E25A256A007699F5447E32AE456B50E",
775 "03F7061798EB99E238FD6F1BF95B48FEEB4854252B",
776 "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB",
777 "05B935590C155E17EA48EB3FF3718B893DF59A05D0",
778 "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 2,
779 _EC_X9_62_CHAR2_163V3_SEED, 20,
780 "X9.62 curve over a 163 bit binary field"
781 };
782
783static const EC_CURVE_DATA _EC_X9_62_CHAR2_176V1 = {
784 NID_X9_62_characteristic_two_field,
785 "0100000000000000000000000000000000080000000007",
786 "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B",
787 "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2",
788 "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798",
789 "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C",
790 "00010092537397ECA4F6145799D62B0A19CE06FE26AD", 0xFF6E,
791 NULL, 0,
792 "X9.62 curve over a 176 bit binary field"
793 };
794
795static const unsigned char _EC_X9_62_CHAR2_191V1_SEED[] = {
796 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76,
797 0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84};
798static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V1 = {
799 NID_X9_62_characteristic_two_field,
800 "800000000000000000000000000000000000000000000201",
801 "2866537B676752636A68F56554E12640276B649EF7526267",
802 "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC",
803 "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D",
804 "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB",
805 "40000000000000000000000004A20E90C39067C893BBB9A5", 2,
806 _EC_X9_62_CHAR2_191V1_SEED, 20,
807 "X9.62 curve over a 191 bit binary field"
808 };
809
810static const unsigned char _EC_X9_62_CHAR2_191V2_SEED[] = {
811 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76,
812 0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15};
813static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V2 = {
814 NID_X9_62_characteristic_two_field,
815 "800000000000000000000000000000000000000000000201",
816 "401028774D7777C7B7666D1366EA432071274F89FF01E718",
817 "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01",
818 "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10",
819 "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A",
820 "20000000000000000000000050508CB89F652824E06B8173", 4,
821 _EC_X9_62_CHAR2_191V2_SEED, 20,
822 "X9.62 curve over a 191 bit binary field"
823 };
824
825static const unsigned char _EC_X9_62_CHAR2_191V3_SEED[] = {
826 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76,
827 0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F};
828static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V3 = {
829 NID_X9_62_characteristic_two_field,
830 "800000000000000000000000000000000000000000000201",
831 "6C01074756099122221056911C77D77E77A777E7E7E77FCB",
832 "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8",
833 "375D4CE24FDE434489DE8746E71786015009E66E38A926DD",
834 "545A39176196575D985999366E6AD34CE0A77CD7127B06BE",
835 "155555555555555555555555610C0B196812BFB6288A3EA3", 6,
836 _EC_X9_62_CHAR2_191V3_SEED, 20,
837 "X9.62 curve over a 191 bit binary field"
838 };
839
840static const EC_CURVE_DATA _EC_X9_62_CHAR2_208W1 = {
841 NID_X9_62_characteristic_two_field,
842 "010000000000000000000000000000000800000000000000000007",
843 "0000000000000000000000000000000000000000000000000000",
844 "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E",
845 "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A",
846 "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3",
847 "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 0xFE48,
848 NULL, 0,
849 "X9.62 curve over a 208 bit binary field"
850 };
851
852static const unsigned char _EC_X9_62_CHAR2_239V1_SEED[] = {
853 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,
854 0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D};
855static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V1 = {
856 NID_X9_62_characteristic_two_field,
857 "800000000000000000000000000000000000000000000000001000000001",
858 "32010857077C5431123A46B808906756F543423E8D27877578125778AC76",
859 "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16",
860 "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D",
861 "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305",
862 "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 4,
863 _EC_X9_62_CHAR2_239V1_SEED, 20,
864 "X9.62 curve over a 239 bit binary field"
865 };
866
867static const unsigned char _EC_X9_62_CHAR2_239V2_SEED[] = {
868 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76,
869 0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D};
870static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V2 = {
871 NID_X9_62_characteristic_two_field,
872 "800000000000000000000000000000000000000000000000001000000001",
873 "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F",
874 "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B",
875 "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205",
876 "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833",
877 "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 6,
878 _EC_X9_62_CHAR2_239V2_SEED, 20,
879 "X9.62 curve over a 239 bit binary field"
880 };
881
882static const unsigned char _EC_X9_62_CHAR2_239V3_SEED[] = {
883 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,
884 0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41};
885static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V3 = {
886 NID_X9_62_characteristic_two_field,
887 "800000000000000000000000000000000000000000000000001000000001",
888 "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F",
889 "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40",
890 "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92",
891 "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461",
892 "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 0xA,
893 _EC_X9_62_CHAR2_239V3_SEED, 20,
894 "X9.62 curve over a 239 bit binary field"
895 };
896
897static const EC_CURVE_DATA _EC_X9_62_CHAR2_272W1 = {
898 NID_X9_62_characteristic_two_field,
899 "010000000000000000000000000000000000000000000000000000010000000000000"
900 "B",
901 "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20",
902 "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7",
903 "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D",
904 "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23",
905 "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521",
906 0xFF06,
907 NULL, 0,
908 "X9.62 curve over a 272 bit binary field"
909 };
910
911static const EC_CURVE_DATA _EC_X9_62_CHAR2_304W1 = {
912 NID_X9_62_characteristic_two_field,
913 "010000000000000000000000000000000000000000000000000000000000000000000"
914 "000000807",
915 "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A039"
916 "6C8E681",
917 "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E558"
918 "27340BE",
919 "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F7"
920 "40A2614",
921 "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1"
922 "B92C03B",
923 "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164"
924 "443051D", 0xFE2E,
925 NULL, 0,
926 "X9.62 curve over a 304 bit binary field"
927 };
928
929static const unsigned char _EC_X9_62_CHAR2_359V1_SEED[] = {
930 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76,
931 0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6};
932static const EC_CURVE_DATA _EC_X9_62_CHAR2_359V1 = {
933 NID_X9_62_characteristic_two_field,
934 "800000000000000000000000000000000000000000000000000000000000000000000"
935 "000100000000000000001",
936 "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05"
937 "656FB549016A96656A557",
938 "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC34562608968"
939 "7742B6329E70680231988",
940 "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE9"
941 "8E8E707C07A2239B1B097",
942 "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E"
943 "4AE2DE211305A407104BD",
944 "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB9"
945 "64FE7719E74F490758D3B", 0x4C,
946 _EC_X9_62_CHAR2_359V1_SEED, 20,
947 "X9.62 curve over a 359 bit binary field"
948 };
949
950static const EC_CURVE_DATA _EC_X9_62_CHAR2_368W1 = {
951 NID_X9_62_characteristic_two_field,
952 "010000000000000000000000000000000000000000000000000000000000000000000"
953 "0002000000000000000000007",
954 "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62"
955 "F0AB7519CCD2A1A906AE30D",
956 "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112"
957 "D84D164F444F8F74786046A",
958 "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E78"
959 "9E927BE216F02E1FB136A5F",
960 "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855"
961 "ADAA81E2A0750B80FDA2310",
962 "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E90"
963 "9AE40A6F131E9CFCE5BD967", 0xFF70,
964 NULL, 0,
965 "X9.62 curve over a 368 bit binary field"
966 };
967
968static const EC_CURVE_DATA _EC_X9_62_CHAR2_431R1 = {
969 NID_X9_62_characteristic_two_field,
970 "800000000000000000000000000000000000000000000000000000000000000000000"
971 "000000001000000000000000000000000000001",
972 "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0E"
973 "B9906D0957F6C6FEACD615468DF104DE296CD8F",
974 "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B6"
975 "26D4E50A8DD731B107A9962381FB5D807BF2618",
976 "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C2"
977 "1E7C5EFE965361F6C2999C0C247B0DBD70CE6B7",
978 "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6"
979 "ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760",
980 "0340340340340340340340340340340340340340340340340340340323C313FAB5058"
981 "9703B5EC68D3587FEC60D161CC149C1AD4A91", 0x2760,
982 NULL, 0,
983 "X9.62 curve over a 431 bit binary field"
984 };
985
986static const EC_CURVE_DATA _EC_WTLS_1 = {
987 NID_X9_62_characteristic_two_field,
988 "020000000000000000000000000201",
989 "1",
990 "1",
991 "01667979A40BA497E5D5C270780617",
992 "00F44B4AF1ECC2630E08785CEBCC15",
993 "00FFFFFFFFFFFFFFFDBF91AF6DEA73", 2,
994 NULL, 0,
995 "WTLS curve over a 113 bit binary field"
996 };
997
998/* IPSec curves */
999/* NOTE: The of curves over a extension field of non prime degree
1000 * is not recommended (Weil-descent).
1001 * As the group order is not a prime this curve is not suitable
1002 * for ECDSA.
1003 */
1004static const EC_CURVE_DATA _EC_IPSEC_155_ID3 = {
1005 NID_X9_62_characteristic_two_field,
1006 "0800000000000000000000004000000000000001",
1007 "0",
1008 "07338f",
1009 "7b",
1010 "1c8",
1011 "2AAAAAAAAAAAAAAAAAAC7F3C7881BD0868FA86C",3,
1012 NULL, 0,
1013 "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
1014 "\tNot suitable for ECDSA.\n\tQuestionable extension field!"
1015 };
1016
1017/* NOTE: The of curves over a extension field of non prime degree
1018 * is not recommended (Weil-descent).
1019 * As the group order is not a prime this curve is not suitable
1020 * for ECDSA.
1021 */
1022static const EC_CURVE_DATA _EC_IPSEC_185_ID4 = {
1023 NID_X9_62_characteristic_two_field,
1024 "020000000000000000000000000000200000000000000001",
1025 "0",
1026 "1ee9",
1027 "18",
1028 "0d",
1029 "FFFFFFFFFFFFFFFFFFFFFFEDF97C44DB9F2420BAFCA75E",2,
1030 NULL, 0,
1031 "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
1032 "\tNot suitable for ECDSA.\n\tQuestionable extension field!"
1033 };
1034
1035typedef struct _ec_list_element_st {
1036 int nid;
1037 const EC_CURVE_DATA *data;
1038 } ec_list_element;
1039
1040static const ec_list_element curve_list[] = {
1041 /* prime field curves */
1042 /* secg curves */
1043 { NID_secp112r1, &_EC_SECG_PRIME_112R1},
1044 { NID_secp112r2, &_EC_SECG_PRIME_112R2},
1045 { NID_secp128r1, &_EC_SECG_PRIME_128R1},
1046 { NID_secp128r2, &_EC_SECG_PRIME_128R2},
1047 { NID_secp160k1, &_EC_SECG_PRIME_160K1},
1048 { NID_secp160r1, &_EC_SECG_PRIME_160R1},
1049 { NID_secp160r2, &_EC_SECG_PRIME_160R2},
1050 /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
1051 { NID_secp192k1, &_EC_SECG_PRIME_192K1},
1052 { NID_secp224k1, &_EC_SECG_PRIME_224K1},
1053 { NID_secp224r1, &_EC_NIST_PRIME_224},
1054 { NID_secp256k1, &_EC_SECG_PRIME_256K1},
1055 /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
1056 { NID_secp384r1, &_EC_NIST_PRIME_384},
1057 { NID_secp521r1, &_EC_NIST_PRIME_521},
1058 /* X9.62 curves */
1059 { NID_X9_62_prime192v1, &_EC_NIST_PRIME_192},
1060 { NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2},
1061 { NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3},
1062 { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1},
1063 { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2},
1064 { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3},
1065 { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1},
1066 /* characteristic two field curves */
1067 /* NIST/SECG curves */
1068 { NID_sect113r1, &_EC_SECG_CHAR2_113R1},
1069 { NID_sect113r2, &_EC_SECG_CHAR2_113R2},
1070 { NID_sect131r1, &_EC_SECG_CHAR2_131R1},
1071 { NID_sect131r2, &_EC_SECG_CHAR2_131R2},
1072 { NID_sect163k1, &_EC_NIST_CHAR2_163K },
1073 { NID_sect163r1, &_EC_SECG_CHAR2_163R1},
1074 { NID_sect163r2, &_EC_NIST_CHAR2_163B },
1075 { NID_sect193r1, &_EC_SECG_CHAR2_193R1},
1076 { NID_sect193r2, &_EC_SECG_CHAR2_193R2},
1077 { NID_sect233k1, &_EC_NIST_CHAR2_233K },
1078 { NID_sect233r1, &_EC_NIST_CHAR2_233B },
1079 { NID_sect239k1, &_EC_SECG_CHAR2_239K1},
1080 { NID_sect283k1, &_EC_NIST_CHAR2_283K },
1081 { NID_sect283r1, &_EC_NIST_CHAR2_283B },
1082 { NID_sect409k1, &_EC_NIST_CHAR2_409K },
1083 { NID_sect409r1, &_EC_NIST_CHAR2_409B },
1084 { NID_sect571k1, &_EC_NIST_CHAR2_571K },
1085 { NID_sect571r1, &_EC_NIST_CHAR2_571B },
1086 /* X9.62 curves */
1087 { NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1},
1088 { NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2},
1089 { NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3},
1090 { NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1},
1091 { NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1},
1092 { NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2},
1093 { NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3},
1094 { NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1},
1095 { NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1},
1096 { NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2},
1097 { NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3},
1098 { NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1},
1099 { NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1},
1100 { NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1},
1101 { NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1},
1102 { NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1},
1103 /* the WAP/WTLS curves
1104 * [unlike SECG, spec has its own OIDs for curves from X9.62] */
1105 { NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1},
1106 { NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K},
1107 { NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1},
1108 { NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1},
1109 { NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1},
1110 { NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2},
1111 { NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8},
1112 { NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9 },
1113 { NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K},
1114 { NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B},
1115 { NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12},
1116 /* IPSec curves */
1117 { NID_ipsec3, &_EC_IPSEC_155_ID3},
1118 { NID_ipsec4, &_EC_IPSEC_185_ID4},
1119};
1120
1121static size_t curve_list_length = sizeof(curve_list)/sizeof(ec_list_element);
1122
1123static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data)
1124 {
1125 EC_GROUP *group=NULL;
1126 EC_POINT *P=NULL;
1127 BN_CTX *ctx=NULL;
1128 BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL;
1129 int ok=0;
1130
1131 if ((ctx = BN_CTX_new()) == NULL)
1132 {
1133 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
1134 goto err;
1135 }
1136 if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
1137 (b = BN_new()) == NULL || (x = BN_new()) == NULL ||
1138 (y = BN_new()) == NULL || (order = BN_new()) == NULL)
1139 {
1140 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
1141 goto err;
1142 }
1143
1144 if (!BN_hex2bn(&p, data->p) || !BN_hex2bn(&a, data->a)
1145 || !BN_hex2bn(&b, data->b))
1146 {
1147 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
1148 goto err;
1149 }
1150
1151 if (data->field_type == NID_X9_62_prime_field)
1152 {
1153 if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL)
1154 {
1155 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1156 goto err;
1157 }
1158 }
1159 else
1160 { /* field_type == NID_X9_62_characteristic_two_field */
1161 if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL)
1162 {
1163 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1164 goto err;
1165 }
1166 }
1167
1168 if ((P = EC_POINT_new(group)) == NULL)
1169 {
1170 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1171 goto err;
1172 }
1173
1174 if (!BN_hex2bn(&x, data->x) || !BN_hex2bn(&y, data->y))
1175 {
1176 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
1177 goto err;
1178 }
1179 if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx))
1180 {
1181 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1182 goto err;
1183 }
1184 if (!BN_hex2bn(&order, data->order) || !BN_set_word(x, data->cofactor))
1185 {
1186 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
1187 goto err;
1188 }
1189 if (!EC_GROUP_set_generator(group, P, order, x))
1190 {
1191 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1192 goto err;
1193 }
1194 if (data->seed)
1195 {
1196 if (!EC_GROUP_set_seed(group, data->seed, data->seed_len))
1197 {
1198 ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
1199 goto err;
1200 }
1201 }
1202 ok=1;
1203err:
1204 if (!ok)
1205 {
1206 EC_GROUP_free(group);
1207 group = NULL;
1208 }
1209 if (P)
1210 EC_POINT_free(P);
1211 if (ctx)
1212 BN_CTX_free(ctx);
1213 if (p)
1214 BN_free(p);
1215 if (a)
1216 BN_free(a);
1217 if (b)
1218 BN_free(b);
1219 if (order)
1220 BN_free(order);
1221 if (x)
1222 BN_free(x);
1223 if (y)
1224 BN_free(y);
1225 return group;
1226 }
1227
1228EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
1229 {
1230 size_t i;
1231 EC_GROUP *ret = NULL;
1232
1233 if (nid <= 0)
1234 return NULL;
1235
1236 for (i=0; i<curve_list_length; i++)
1237 if (curve_list[i].nid == nid)
1238 {
1239 ret = ec_group_new_from_data(curve_list[i].data);
1240 break;
1241 }
1242
1243 if (ret == NULL)
1244 {
1245 ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
1246 return NULL;
1247 }
1248
1249 EC_GROUP_set_curve_name(ret, nid);
1250
1251 return ret;
1252 }
1253
1254size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
1255 {
1256 size_t i, min;
1257
1258 if (r == NULL || nitems == 0)
1259 return curve_list_length;
1260
1261 min = nitems < curve_list_length ? nitems : curve_list_length;
1262
1263 for (i = 0; i < min; i++)
1264 {
1265 r[i].nid = curve_list[i].nid;
1266 r[i].comment = curve_list[i].data->comment;
1267 }
1268
1269 return curve_list_length;
1270 }
diff --git a/src/lib/libcrypto/ec/ec_key.c b/src/lib/libcrypto/ec/ec_key.c
new file mode 100644
index 0000000000..3d6c900b95
--- /dev/null
+++ b/src/lib/libcrypto/ec/ec_key.c
@@ -0,0 +1,465 @@
1/* crypto/ec/ec_key.c */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * openssl-core@openssl.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * Portions originally developed by SUN MICROSYSTEMS, INC., and
61 * contributed to the OpenSSL project.
62 */
63
64#include <string.h>
65#include "ec_lcl.h"
66#include <openssl/err.h>
67#include <string.h>
68
69EC_KEY *EC_KEY_new(void)
70 {
71 EC_KEY *ret;
72
73 ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
74 if (ret == NULL)
75 {
76 ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);
77 return(NULL);
78 }
79
80 ret->version = 1;
81 ret->group = NULL;
82 ret->pub_key = NULL;
83 ret->priv_key= NULL;
84 ret->enc_flag= 0;
85 ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
86 ret->references= 1;
87 ret->method_data = NULL;
88 return(ret);
89 }
90
91EC_KEY *EC_KEY_new_by_curve_name(int nid)
92 {
93 EC_KEY *ret = EC_KEY_new();
94 if (ret == NULL)
95 return NULL;
96 ret->group = EC_GROUP_new_by_curve_name(nid);
97 if (ret->group == NULL)
98 {
99 EC_KEY_free(ret);
100 return NULL;
101 }
102 return ret;
103 }
104
105void EC_KEY_free(EC_KEY *r)
106 {
107 int i;
108
109 if (r == NULL) return;
110
111 i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC);
112#ifdef REF_PRINT
113 REF_PRINT("EC_KEY",r);
114#endif
115 if (i > 0) return;
116#ifdef REF_CHECK
117 if (i < 0)
118 {
119 fprintf(stderr,"EC_KEY_free, bad reference count\n");
120 abort();
121 }
122#endif
123
124 if (r->group != NULL)
125 EC_GROUP_free(r->group);
126 if (r->pub_key != NULL)
127 EC_POINT_free(r->pub_key);
128 if (r->priv_key != NULL)
129 BN_clear_free(r->priv_key);
130
131 EC_EX_DATA_free_all_data(&r->method_data);
132
133 OPENSSL_cleanse((void *)r, sizeof(EC_KEY));
134
135 OPENSSL_free(r);
136 }
137
138EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
139 {
140 EC_EXTRA_DATA *d;
141
142 if (dest == NULL || src == NULL)
143 {
144 ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
145 return NULL;
146 }
147 /* copy the parameters */
148 if (src->group)
149 {
150 const EC_METHOD *meth = EC_GROUP_method_of(src->group);
151 /* clear the old group */
152 if (dest->group)
153 EC_GROUP_free(dest->group);
154 dest->group = EC_GROUP_new(meth);
155 if (dest->group == NULL)
156 return NULL;
157 if (!EC_GROUP_copy(dest->group, src->group))
158 return NULL;
159 }
160 /* copy the public key */
161 if (src->pub_key && src->group)
162 {
163 if (dest->pub_key)
164 EC_POINT_free(dest->pub_key);
165 dest->pub_key = EC_POINT_new(src->group);
166 if (dest->pub_key == NULL)
167 return NULL;
168 if (!EC_POINT_copy(dest->pub_key, src->pub_key))
169 return NULL;
170 }
171 /* copy the private key */
172 if (src->priv_key)
173 {
174 if (dest->priv_key == NULL)
175 {
176 dest->priv_key = BN_new();
177 if (dest->priv_key == NULL)
178 return NULL;
179 }
180 if (!BN_copy(dest->priv_key, src->priv_key))
181 return NULL;
182 }
183 /* copy method/extra data */
184 EC_EX_DATA_free_all_data(&dest->method_data);
185
186 for (d = src->method_data; d != NULL; d = d->next)
187 {
188 void *t = d->dup_func(d->data);
189
190 if (t == NULL)
191 return 0;
192 if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, d->free_func, d->clear_free_func))
193 return 0;
194 }
195
196 /* copy the rest */
197 dest->enc_flag = src->enc_flag;
198 dest->conv_form = src->conv_form;
199 dest->version = src->version;
200
201 return dest;
202 }
203
204EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
205 {
206 EC_KEY *ret = EC_KEY_new();
207 if (ret == NULL)
208 return NULL;
209 if (EC_KEY_copy(ret, ec_key) == NULL)
210 {
211 EC_KEY_free(ret);
212 return NULL;
213 }
214 return ret;
215 }
216
217int EC_KEY_up_ref(EC_KEY *r)
218 {
219 int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
220#ifdef REF_PRINT
221 REF_PRINT("EC_KEY",r);
222#endif
223#ifdef REF_CHECK
224 if (i < 2)
225 {
226 fprintf(stderr, "EC_KEY_up, bad reference count\n");
227 abort();
228 }
229#endif
230 return ((i > 1) ? 1 : 0);
231 }
232
233int EC_KEY_generate_key(EC_KEY *eckey)
234 {
235 int ok = 0;
236 BN_CTX *ctx = NULL;
237 BIGNUM *priv_key = NULL, *order = NULL;
238 EC_POINT *pub_key = NULL;
239
240 if (!eckey || !eckey->group)
241 {
242 ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
243 return 0;
244 }
245
246 if ((order = BN_new()) == NULL) goto err;
247 if ((ctx = BN_CTX_new()) == NULL) goto err;
248
249 if (eckey->priv_key == NULL)
250 {
251 priv_key = BN_new();
252 if (priv_key == NULL)
253 goto err;
254 }
255 else
256 priv_key = eckey->priv_key;
257
258 if (!EC_GROUP_get_order(eckey->group, order, ctx))
259 goto err;
260
261 do
262 if (!BN_rand_range(priv_key, order))
263 goto err;
264 while (BN_is_zero(priv_key));
265
266 if (eckey->pub_key == NULL)
267 {
268 pub_key = EC_POINT_new(eckey->group);
269 if (pub_key == NULL)
270 goto err;
271 }
272 else
273 pub_key = eckey->pub_key;
274
275 if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
276 goto err;
277
278 eckey->priv_key = priv_key;
279 eckey->pub_key = pub_key;
280
281 ok=1;
282
283err:
284 if (order)
285 BN_free(order);
286 if (pub_key != NULL && eckey->pub_key == NULL)
287 EC_POINT_free(pub_key);
288 if (priv_key != NULL && eckey->priv_key == NULL)
289 BN_free(priv_key);
290 if (ctx != NULL)
291 BN_CTX_free(ctx);
292 return(ok);
293 }
294
295int EC_KEY_check_key(const EC_KEY *eckey)
296 {
297 int ok = 0;
298 BN_CTX *ctx = NULL;
299 BIGNUM *order = NULL;
300 EC_POINT *point = NULL;
301
302 if (!eckey || !eckey->group || !eckey->pub_key)
303 {
304 ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
305 return 0;
306 }
307
308 if ((ctx = BN_CTX_new()) == NULL)
309 goto err;
310 if ((order = BN_new()) == NULL)
311 goto err;
312 if ((point = EC_POINT_new(eckey->group)) == NULL)
313 goto err;
314
315 /* testing whether the pub_key is on the elliptic curve */
316 if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx))
317 {
318 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
319 goto err;
320 }
321 /* testing whether pub_key * order is the point at infinity */
322 if (!EC_GROUP_get_order(eckey->group, order, ctx))
323 {
324 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
325 goto err;
326 }
327 if (!EC_POINT_copy(point, eckey->pub_key))
328 {
329 ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
330 goto err;
331 }
332 if (!EC_POINT_mul(eckey->group, point, order, NULL, NULL, ctx))
333 {
334 ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
335 goto err;
336 }
337 if (!EC_POINT_is_at_infinity(eckey->group, point))
338 {
339 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
340 goto err;
341 }
342 /* in case the priv_key is present :
343 * check if generator * priv_key == pub_key
344 */
345 if (eckey->priv_key)
346 {
347 if (BN_cmp(eckey->priv_key, order) >= 0)
348 {
349 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
350 goto err;
351 }
352 if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
353 NULL, NULL, ctx))
354 {
355 ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
356 goto err;
357 }
358 if (EC_POINT_cmp(eckey->group, point, eckey->pub_key,
359 ctx) != 0)
360 {
361 ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
362 goto err;
363 }
364 }
365 ok = 1;
366err:
367 if (ctx != NULL)
368 BN_CTX_free(ctx);
369 if (order != NULL)
370 BN_free(order);
371 if (point != NULL)
372 EC_POINT_free(point);
373 return(ok);
374 }
375
376const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
377 {
378 return key->group;
379 }
380
381int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
382 {
383 if (key->group != NULL)
384 EC_GROUP_free(key->group);
385 key->group = EC_GROUP_dup(group);
386 return (key->group == NULL) ? 0 : 1;
387 }
388
389const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
390 {
391 return key->priv_key;
392 }
393
394int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
395 {
396 if (key->priv_key)
397 BN_clear_free(key->priv_key);
398 key->priv_key = BN_dup(priv_key);
399 return (key->priv_key == NULL) ? 0 : 1;
400 }
401
402const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
403 {
404 return key->pub_key;
405 }
406
407int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
408 {
409 if (key->pub_key != NULL)
410 EC_POINT_free(key->pub_key);
411 key->pub_key = EC_POINT_dup(pub_key, key->group);
412 return (key->pub_key == NULL) ? 0 : 1;
413 }
414
415unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
416 {
417 return key->enc_flag;
418 }
419
420void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
421 {
422 key->enc_flag = flags;
423 }
424
425point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
426 {
427 return key->conv_form;
428 }
429
430void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
431 {
432 key->conv_form = cform;
433 if (key->group != NULL)
434 EC_GROUP_set_point_conversion_form(key->group, cform);
435 }
436
437void *EC_KEY_get_key_method_data(EC_KEY *key,
438 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
439 {
440 return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
441 }
442
443void EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
444 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
445 {
446 EC_EXTRA_DATA *ex_data;
447 CRYPTO_w_lock(CRYPTO_LOCK_EC);
448 ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
449 if (ex_data == NULL)
450 EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
451 CRYPTO_w_unlock(CRYPTO_LOCK_EC);
452 }
453
454void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
455 {
456 if (key->group != NULL)
457 EC_GROUP_set_asn1_flag(key->group, flag);
458 }
459
460int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
461 {
462 if (key->group == NULL)
463 return 0;
464 return EC_GROUP_precompute_mult(key->group, ctx);
465 }
diff --git a/src/lib/libcrypto/ec/ec_print.c b/src/lib/libcrypto/ec/ec_print.c
new file mode 100644
index 0000000000..f7c8a303ac
--- /dev/null
+++ b/src/lib/libcrypto/ec/ec_print.c
@@ -0,0 +1,195 @@
1/* crypto/ec/ec_print.c */
2/* ====================================================================
3 * Copyright (c) 1998-2002 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#include <openssl/crypto.h>
57#include "ec_lcl.h"
58
59BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
60 const EC_POINT *point,
61 point_conversion_form_t form,
62 BIGNUM *ret,
63 BN_CTX *ctx)
64 {
65 size_t buf_len=0;
66 unsigned char *buf;
67
68 buf_len = EC_POINT_point2oct(group, point, form,
69 NULL, 0, ctx);
70 if (buf_len == 0)
71 return NULL;
72
73 if ((buf = OPENSSL_malloc(buf_len)) == NULL)
74 return NULL;
75
76 if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx))
77 {
78 OPENSSL_free(buf);
79 return NULL;
80 }
81
82 ret = BN_bin2bn(buf, buf_len, ret);
83
84 OPENSSL_free(buf);
85
86 return ret;
87}
88
89EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
90 const BIGNUM *bn,
91 EC_POINT *point,
92 BN_CTX *ctx)
93 {
94 size_t buf_len=0;
95 unsigned char *buf;
96 EC_POINT *ret;
97
98 if ((buf_len = BN_num_bytes(bn)) == 0) return NULL;
99 buf = OPENSSL_malloc(buf_len);
100 if (buf == NULL)
101 return NULL;
102
103 if (!BN_bn2bin(bn, buf))
104 {
105 OPENSSL_free(buf);
106 return NULL;
107 }
108
109 if (point == NULL)
110 {
111 if ((ret = EC_POINT_new(group)) == NULL)
112 {
113 OPENSSL_free(buf);
114 return NULL;
115 }
116 }
117 else
118 ret = point;
119
120 if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx))
121 {
122 if (point == NULL)
123 EC_POINT_clear_free(ret);
124 OPENSSL_free(buf);
125 return NULL;
126 }
127
128 OPENSSL_free(buf);
129 return ret;
130 }
131
132static const char *HEX_DIGITS = "0123456789ABCDEF";
133
134/* the return value must be freed (using OPENSSL_free()) */
135char *EC_POINT_point2hex(const EC_GROUP *group,
136 const EC_POINT *point,
137 point_conversion_form_t form,
138 BN_CTX *ctx)
139 {
140 char *ret, *p;
141 size_t buf_len=0,i;
142 unsigned char *buf, *pbuf;
143
144 buf_len = EC_POINT_point2oct(group, point, form,
145 NULL, 0, ctx);
146 if (buf_len == 0)
147 return NULL;
148
149 if ((buf = OPENSSL_malloc(buf_len)) == NULL)
150 return NULL;
151
152 if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx))
153 {
154 OPENSSL_free(buf);
155 return NULL;
156 }
157
158 ret = (char *)OPENSSL_malloc(buf_len*2+2);
159 if (ret == NULL)
160 {
161 OPENSSL_free(buf);
162 return NULL;
163 }
164 p = ret;
165 pbuf = buf;
166 for (i=buf_len; i > 0; i--)
167 {
168 int v = (int) *(pbuf++);
169 *(p++)=HEX_DIGITS[v>>4];
170 *(p++)=HEX_DIGITS[v&0x0F];
171 }
172 *p='\0';
173
174 OPENSSL_free(buf);
175
176 return ret;
177 }
178
179EC_POINT *EC_POINT_hex2point(const EC_GROUP *group,
180 const char *buf,
181 EC_POINT *point,
182 BN_CTX *ctx)
183 {
184 EC_POINT *ret=NULL;
185 BIGNUM *tmp_bn=NULL;
186
187 if (!BN_hex2bn(&tmp_bn, buf))
188 return NULL;
189
190 ret = EC_POINT_bn2point(group, tmp_bn, point, ctx);
191
192 BN_clear_free(tmp_bn);
193
194 return ret;
195 }